mirror of
https://gitlab.com/pezkuwichain/pezkuwi-sdk.git
synced 2026-10-20 18:56:23 +00:00
feat: forward session events to staking pallet for era progression on Asset Hub
Asset Hub's pallet_staking_async era never advances because it expects SessionReport messages from the relay chain's ah_client pallet, which is not yet active. This adds a StakingSessionManager wrapper that intercepts local session rotation events and generates SessionReport messages to drive era transitions directly on Asset Hub. Changes: - Add StakingSessionManager in staking.rs that delegates to both CollatorSelection and Staking via on_relay_session_report() - Switch SessionManager from CollatorSelection to StakingSessionManager - Add FixActiveEraStart migration to correct ActiveEra.start=0 from genesis - Bump spec_version to 1_020_002
This commit is contained in:
1 parent
c29059b09b
commit
3514625d25
2 files changed
+81
-2
No files matched your search
@@ -138,7 +138,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
|||||||
spec_name: alloc::borrow::Cow::Borrowed("asset-hub-pezkuwichain"),
|
spec_name: alloc::borrow::Cow::Borrowed("asset-hub-pezkuwichain"),
|
||||||
impl_name: alloc::borrow::Cow::Borrowed("asset-hub-pezkuwichain"),
|
impl_name: alloc::borrow::Cow::Borrowed("asset-hub-pezkuwichain"),
|
||||||
authoring_version: 1,
|
authoring_version: 1,
|
||||||
spec_version: 1_020_001,
|
spec_version: 1_020_002,
|
||||||
impl_version: 0,
|
impl_version: 0,
|
||||||
apis: RUNTIME_API_VERSIONS,
|
apis: RUNTIME_API_VERSIONS,
|
||||||
transaction_version: 16,
|
transaction_version: 16,
|
||||||
@@ -844,7 +844,7 @@ impl pezpallet_session::Config for Runtime {
|
|||||||
type ValidatorIdOf = pezpallet_collator_selection::IdentityCollator;
|
type ValidatorIdOf = pezpallet_collator_selection::IdentityCollator;
|
||||||
type ShouldEndSession = pezpallet_session::PeriodicSessions<Period, Offset>;
|
type ShouldEndSession = pezpallet_session::PeriodicSessions<Period, Offset>;
|
||||||
type NextSessionRotation = pezpallet_session::PeriodicSessions<Period, Offset>;
|
type NextSessionRotation = pezpallet_session::PeriodicSessions<Period, Offset>;
|
||||||
type SessionManager = CollatorSelection;
|
type SessionManager = StakingSessionManager;
|
||||||
// Essentially just Aura, but let's be pedantic.
|
// Essentially just Aura, but let's be pedantic.
|
||||||
type SessionHandler = <SessionKeys as pezsp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
|
type SessionHandler = <SessionKeys as pezsp_runtime::traits::OpaqueKeys>::KeyTypeIdProviders;
|
||||||
type Keys = SessionKeys;
|
type Keys = SessionKeys;
|
||||||
@@ -1408,8 +1408,33 @@ pub type TxExtension = pezcumulus_pezpallet_weight_reclaim::StorageWeightReclaim
|
|||||||
/// Unchecked extrinsic type as expected by this runtime.
|
/// Unchecked extrinsic type as expected by this runtime.
|
||||||
pub type UncheckedExtrinsic =
|
pub type UncheckedExtrinsic =
|
||||||
generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
|
generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, TxExtension>;
|
||||||
|
/// One-time migration to fix ActiveEra.start which was set to 0 at genesis.
|
||||||
|
/// Without this, the first era's duration would be calculated as (now - 0) = ~56 years,
|
||||||
|
/// though MaxEraDuration caps it to 6 hours. This migration sets it to the current timestamp
|
||||||
|
/// so the first era duration is calculated correctly from the upgrade moment.
|
||||||
|
pub struct FixActiveEraStart;
|
||||||
|
impl pezframe_support::traits::OnRuntimeUpgrade for FixActiveEraStart {
|
||||||
|
fn on_runtime_upgrade() -> Weight {
|
||||||
|
let now_ms = pezpallet_timestamp::Now::<Runtime>::get();
|
||||||
|
if now_ms > 0 {
|
||||||
|
pezpallet_staking_async::ActiveEra::<Runtime>::mutate(|era| {
|
||||||
|
if let Some(ref mut info) = era {
|
||||||
|
info.start = Some(now_ms);
|
||||||
|
log::info!(
|
||||||
|
target: "runtime::staking",
|
||||||
|
"FixActiveEraStart: Set ActiveEra.start to {}",
|
||||||
|
now_ms,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
<Runtime as pezframe_system::Config>::DbWeight::get().reads_writes(2, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Migrations to apply on runtime upgrade.
|
/// Migrations to apply on runtime upgrade.
|
||||||
pub type Migrations = (
|
pub type Migrations = (
|
||||||
|
FixActiveEraStart,
|
||||||
InitStorageVersions,
|
InitStorageVersions,
|
||||||
// unreleased
|
// unreleased
|
||||||
pezcumulus_pezpallet_xcmp_queue::migration::v4::MigrationToV4<Runtime>,
|
pezcumulus_pezpallet_xcmp_queue::migration::v4::MigrationToV4<Runtime>,
|
||||||
|
|||||||
@@ -312,6 +312,60 @@ impl pezpallet_staking_async_rc_client::Config for Runtime {
|
|||||||
type MaxValidatorSetRetries = ConstU32<64>;
|
type MaxValidatorSetRetries = ConstU32<64>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Forwards session events to both CollatorSelection (collator management) and
|
||||||
|
/// Staking pallet (era management) via local SessionReport generation.
|
||||||
|
///
|
||||||
|
/// This is needed because `pallet_staking_async` expects `SessionReport` messages from
|
||||||
|
/// the relay chain's `ah_client` pallet, which is not yet active. This wrapper generates
|
||||||
|
/// local session reports from AH's own session rotation events.
|
||||||
|
pub struct StakingSessionManager;
|
||||||
|
|
||||||
|
impl pezpallet_session::SessionManager<AccountId> for StakingSessionManager {
|
||||||
|
fn new_session(new_index: u32) -> Option<Vec<AccountId>> {
|
||||||
|
<CollatorSelection as pezpallet_session::SessionManager<AccountId>>::new_session(new_index)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn end_session(end_index: u32) {
|
||||||
|
// Forward to CollatorSelection first
|
||||||
|
<CollatorSelection as pezpallet_session::SessionManager<AccountId>>::end_session(end_index);
|
||||||
|
|
||||||
|
// Build local SessionReport for staking era progression
|
||||||
|
let current_era =
|
||||||
|
pezpallet_staking_async::CurrentEra::<Runtime>::get().unwrap_or(0);
|
||||||
|
let active_era_idx = pezpallet_staking_async::ActiveEra::<Runtime>::get()
|
||||||
|
.map(|e| e.index)
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
// Provide activation_timestamp when a planned era exists (CurrentEra > ActiveEra)
|
||||||
|
let activation_timestamp = if current_era > active_era_idx {
|
||||||
|
let now_ms = pezpallet_timestamp::Now::<Runtime>::get();
|
||||||
|
Some((now_ms, current_era))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
// Equal reward points for all validators
|
||||||
|
let validator_points: Vec<(AccountId, u32)> =
|
||||||
|
pezpallet_staking_async::Validators::<Runtime>::iter_keys()
|
||||||
|
.map(|v| (v, 20u32))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let report = rc_client::SessionReport::new_terminal(
|
||||||
|
end_index,
|
||||||
|
validator_points,
|
||||||
|
activation_timestamp,
|
||||||
|
);
|
||||||
|
|
||||||
|
let _ = <Staking as rc_client::AHStakingInterface>::on_relay_session_report(report);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_session(start_index: u32) {
|
||||||
|
<CollatorSelection as pezpallet_session::SessionManager<AccountId>>::start_session(
|
||||||
|
start_index,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode)]
|
#[derive(Encode, Decode)]
|
||||||
// Call indices taken from zagros-next runtime.
|
// Call indices taken from zagros-next runtime.
|
||||||
pub enum RelayChainRuntimePallets {
|
pub enum RelayChainRuntimePallets {
|
||||||
|
|||||||
Reference in new issue
Block a user