Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
663db38
Add pallet-async-backing and update block time parameters to 6000ms
Chralt98 Nov 12, 2025
49f7e8a
Refactor constants and improve formatting in relay timestamp module
Chralt98 Nov 12, 2025
ed23039
Add sp-timestamp dependency and update runtime versions to 62 and tra…
Chralt98 Nov 13, 2025
adc4df3
Update pallet-parachain-staking source reference and remove old colla…
Chralt98 Nov 14, 2025
f08d5c2
feat: Update download script for Polkadot binaries and improve error …
Chralt98 Nov 14, 2025
b479734
refactor: Update try-runtime dependencies and improve log message for…
Chralt98 Nov 14, 2025
a944242
fix: Remove extra newline in copyright section of relay timestamp module
Chralt98 Nov 14, 2025
4f8157e
feat: Enhance relay timestamp handling and adjust block processing ve…
Chralt98 Nov 17, 2025
fa1f9a9
feat: Update block time assumptions and adjust related parameters for…
Chralt98 Nov 20, 2025
9cb3ad6
feat: Enhance Polkadot SDK download script for macOS support and impr…
Chralt98 Nov 20, 2025
b7702ac
refactor: Remove unused imports and adjust AdjustmentVariable for bet…
Chralt98 Nov 20, 2025
2172c09
feat: Add async backing configuration and improve zombienet deploymen…
Chralt98 Nov 21, 2025
82dea73
feat: Remove use-noop-message-processor flag for improved benchmarkin…
Chralt98 Nov 21, 2025
1854945
Add `AtStake` legacy migrations (#1448)
Chralt98 Nov 26, 2025
317c281
Correct copyrights (#1449)
Chralt98 Nov 26, 2025
195c690
Merge branch 'main' into chralt98-add-async-backing
Chralt98 Nov 26, 2025
4e0637c
Update copyright notices in migration files
Chralt98 Nov 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ cumulus-primitives-core = { git = "https://github.com/paritytech/polkadot-sdk",
cumulus-primitives-timestamp = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2409", default-features = false }
cumulus-primitives-utility = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2409", default-features = false }
nimbus-primitives = { git = "https://github.com/zeitgeistpm/moonkit", branch = "zeitgeist-polkadot-stable2409", default-features = false }
pallet-async-backing = { git = "https://github.com/zeitgeistpm/moonkit", branch = "zeitgeist-polkadot-stable2409", default-features = false }
pallet-author-inherent = { git = "https://github.com/zeitgeistpm/moonkit", branch = "zeitgeist-polkadot-stable2409", default-features = false }
pallet-author-mapping = { git = "https://github.com/zeitgeistpm/moonkit", branch = "zeitgeist-polkadot-stable2409", default-features = false }
pallet-author-slot-filter = { git = "https://github.com/zeitgeistpm/moonkit", branch = "zeitgeist-polkadot-stable2409", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ check-dummy:
--runtime=${RUNTIME_PATH} \
on-runtime-upgrade \
--checks=all \
--blocktime=12000 \
--blocktime=6000 \
live \
--uri=${TRYRUNTIME_URL}

Expand Down
4 changes: 2 additions & 2 deletions node/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ fn none_command(cli: Cli) -> sc_cli::Result<()> {
parachain_config,
parachain_id,
polkadot_config,
false,
true,
cli.block_authoring_duration,
hwbench,
collator_options,
Expand All @@ -515,7 +515,7 @@ fn none_command(cli: Cli) -> sc_cli::Result<()> {
parachain_config,
parachain_id,
polkadot_config,
false,
true,
cli.block_authoring_duration,
hwbench,
collator_options,
Expand Down
19 changes: 14 additions & 5 deletions primitives/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ use crate::types::{Balance, BlockNumber};
use frame_support::{parameter_types, PalletId};

// Definitions for time
pub const BLOCKS_PER_YEAR: BlockNumber = (BLOCKS_PER_DAY * 36525) / 100; // 2_629_800
pub const BLOCKS_PER_DAY: BlockNumber = BLOCKS_PER_HOUR * 24; // 7_200
pub const MILLISECS_PER_BLOCK: u32 = 12000;
pub const BLOCKS_PER_MINUTE: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); // 5
pub const BLOCKS_PER_HOUR: BlockNumber = BLOCKS_PER_MINUTE * 60; // 300
pub const BLOCKS_PER_YEAR: BlockNumber = (BLOCKS_PER_DAY * 36525) / 100; // 5_259_600
pub const BLOCKS_PER_DAY: BlockNumber = BLOCKS_PER_HOUR * 24; // 14_400
// TODO: Check what effect the updated block time has on the zeitgeist pallet implementations (block durations are then faster as originally assumed)
pub const MILLISECS_PER_BLOCK: u32 = 6000;
pub const BLOCKS_PER_MINUTE: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber); // 10
pub const BLOCKS_PER_HOUR: BlockNumber = BLOCKS_PER_MINUTE * 60; // 600

// Definitions for currency
pub const DECIMALS: u8 = 10;
Expand Down Expand Up @@ -133,3 +134,11 @@ pub const PARIMUTUEL_PALLET_ID: PalletId = PalletId(*b"zge/prmt");
// Treasury
/// Pallet identifier, used to derive treasury account
pub const TREASURY_PALLET_ID: PalletId = PalletId(*b"zge/tsry");

// ParachainSystem
/// Maximum number of blocks simultaneously accepted by the Runtime, not yet included
/// into the relay chain.
pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3;
/// How many parachain blocks are processed by the relay chain per parent. Limits the
/// number of blocks authored per slot.
pub const BLOCK_PROCESSING_VELOCITY: u32 = 1;
4 changes: 4 additions & 0 deletions runtime/battery-station/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ parachains-common = { workspace = true, optional = true }
# Parachain
async-backing-primitives = { workspace = true, optional = true }
nimbus-primitives = { workspace = true, optional = true }
pallet-async-backing = { workspace = true, optional = true }
pallet-author-inherent = { workspace = true, optional = true }
pallet-author-mapping = { workspace = true, optional = true }
pallet-author-slot-filter = { workspace = true, optional = true }
Expand Down Expand Up @@ -163,6 +164,7 @@ parachain = [
"polkadot-parachain-primitives",
"polkadot-runtime-common",
"session-keys-primitives",
"pallet-async-backing",
"async-backing-primitives",

# XCM
Expand Down Expand Up @@ -247,6 +249,7 @@ std = [
"orml-tokens/std",
"orml-traits/std",
"pallet-asset-tx-payment/std",
"pallet-async-backing?/std",
"pallet-balances/std",
"pallet-bounties/std",
"pallet-collective/std",
Expand Down Expand Up @@ -408,6 +411,7 @@ try-runtime = [
"zrml-orderbook/try-runtime",

# Parachain
"pallet-async-backing?/try-runtime",
"pallet-author-inherent?/try-runtime",
"pallet-author-mapping?/try-runtime",
"pallet-author-slot-filter?/try-runtime",
Expand Down
8 changes: 6 additions & 2 deletions runtime/battery-station/src/parachain_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ parameter_types! {
// Asset registry
pub const AssetRegistryStringLimit: u32 = 1024;

// Async backing
pub const AllowMultipleBlocksPerSlot: bool = true;
pub const ExpectedBlockTime: u64 = 6_000;

// Author-Mapping
/// The amount that should be taken as a security deposit when registering a NimbusId.
pub const CollatorDeposit: Balance = 2 * BASE;
Expand All @@ -55,7 +59,7 @@ parameter_types! {

// Staking
/// Average time beetween 2 blocks in milliseconds
pub const BlockTime: u64 = 12_000;
pub const BlockTime: u64 = 6_000;
/// Rounds before the candidate bond increase/decrease can be executed
pub const CandidateBondLessDelay: u32 = 2;
/// Default fixed percent a collator takes off the top of due rewards
Expand Down Expand Up @@ -89,7 +93,7 @@ parameter_types! {
/// Minimum collators selected per round, default at genesis and minimum forever after
pub const MinSelectedCandidates: u32 = 8;
/// Slot duration in milliseconds
pub const SlotDuration: u64 = 12_000;
pub const SlotDuration: u64 = 6_000;
/// Rounds before the delegator revocation can be executed
pub const RevokeDelegationDelay: u32 = 2;
/// Rounds before the reward is paid
Expand Down
55 changes: 41 additions & 14 deletions runtime/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
#![allow(clippy::crate_in_macro_def)]

pub mod fees;
#[cfg(feature = "parachain")]
pub mod relay_timestamp;
pub mod weights;

#[macro_export]
Expand Down Expand Up @@ -401,6 +403,7 @@ macro_rules! create_runtime_with_additional_pallets {
AuthorInherent: pallet_author_inherent::{Call, Inherent, Pallet, Storage} = 111,
AuthorFilter: pallet_author_slot_filter::{Call, Config<T>, Event, Pallet, Storage} = 112,
AuthorMapping: pallet_author_mapping::{Call, Config<T>, Event<T>, Pallet, Storage} = 113,
AsyncBacking: pallet_async_backing::{Pallet, Storage} = 114,

// XCM
CumulusXcm: cumulus_pallet_xcm::{Event<T>, Origin, Pallet} = 120,
Expand Down Expand Up @@ -440,6 +443,13 @@ macro_rules! impl_config_traits {
xcm_config::config::*,
};

#[cfg(feature = "parachain")]
type ConsensusHook = pallet_async_backing::consensus_hook::FixedVelocityConsensusHook<
Runtime,
BLOCK_PROCESSING_VELOCITY,
UNINCLUDED_SEGMENT_CAPACITY,
>;

// Configure Pallets
#[cfg(feature = "parachain")]
impl cumulus_pallet_parachain_system::Config for Runtime {
Expand All @@ -450,9 +460,22 @@ macro_rules! impl_config_traits {
type ReservedXcmpWeight = crate::parachain_params::ReservedXcmpWeight;
type SelfParaId = parachain_info::Pallet<Runtime>;
type XcmpMessageHandler = XcmpQueue;
type CheckAssociatedRelayNumber =
cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases;
type ConsensusHook = cumulus_pallet_parachain_system::ExpectParentIncluded;
type CheckAssociatedRelayNumber = cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases;
#[cfg(not(test))]
type ConsensusHook =
common_runtime::relay_timestamp::ConsensusHookWrapperForRelayTimestamp<
Runtime,
ConsensusHook,
>;
// TODO(#1426): figure out a way to have the integration tests work with the relay timestamp and BLOCK_PROCESSING_VELOCITY of 1
// Use normal consensus hook for xcm integration tests to avoid relay timestamp setting
#[cfg(test)]
type ConsensusHook = pallet_async_backing::consensus_hook::FixedVelocityConsensusHook<
Runtime,
// The xcm integration tests require to process two blocks in a single slot
2,
UNINCLUDED_SEGMENT_CAPACITY,
>;
type DmpQueue = frame_support::traits::EnqueueWithOrigin<MessageQueue, RelayOrigin>;
type WeightInfo = weights::cumulus_pallet_parachain_system::WeightInfo<Runtime>;
}
Expand Down Expand Up @@ -546,6 +569,13 @@ macro_rules! impl_config_traits {
type PostTransactions = ();
}

#[cfg(feature = "parachain")]
impl pallet_async_backing::Config for Runtime {
type AllowMultipleBlocksPerSlot = AllowMultipleBlocksPerSlot;
type GetAndVerifySlot = pallet_async_backing::RelaySlot;
type ExpectedBlockTime = ExpectedBlockTime;
}

#[cfg(not(feature = "parachain"))]
impl pallet_aura::Config for Runtime {
type AllowMultipleBlocksPerSlot = AllowMultipleBlocksPerSlot;
Expand Down Expand Up @@ -656,14 +686,13 @@ macro_rules! impl_config_traits {
}
}
#[cfg(feature = "parachain")]
pub struct StakingRoundSlotProvider;
pub struct RelayChainSlotProvider;

#[cfg(feature = "parachain")]
impl Get<Slot> for StakingRoundSlotProvider {
impl Get<Slot> for RelayChainSlotProvider {
fn get() -> Slot {
let block_number: u64 =
frame_system::pallet::Pallet::<Runtime>::block_number().into();
Slot::from(block_number)
let slot_info = pallet_async_backing::pallet::Pallet::<Runtime>::slot_info();
slot_info.unwrap_or_default().0
}
}

Expand Down Expand Up @@ -694,7 +723,7 @@ macro_rules! impl_config_traits {
type RevokeDelegationDelay = RevokeDelegationDelay;
type RewardPaymentDelay = RewardPaymentDelay;
type SlotDuration = SlotDuration;
type SlotProvider = StakingRoundSlotProvider;
type SlotProvider = RelayChainSlotProvider;
type WeightInfo = weights::pallet_parachain_staking::WeightInfo<Runtime>;
}

Expand Down Expand Up @@ -2180,12 +2209,10 @@ macro_rules! create_runtime_api {
#[cfg(feature = "parachain")]
impl async_backing_primitives::UnincludedSegmentApi<Block> for Runtime {
fn can_build_upon(
_included_hash: <Block as BlockT>::Hash,
_slot: async_backing_primitives::Slot,
included_hash: <Block as BlockT>::Hash,
slot: async_backing_primitives::Slot,
) -> bool {
// This runtime API can be called only when asynchronous backing is enabled client-side
// We return false here to force the client to not use async backing.
false
ConsensusHook::can_build_upon(included_hash, slot)
}
}

Expand Down
94 changes: 94 additions & 0 deletions runtime/common/src/relay_timestamp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright 2025 Forecasting Technologies LTD.
// Copyright 2019-2025 PureStake Inc.
// This file is part of Zeitgeist.
//
// Zeitgeist is free software: you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
//
// Zeitgeist is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Zeitgeist. If not, see <https://www.gnu.org/licenses/>.

//! A way to get a relyable timestamp
use cumulus_pallet_parachain_system::{
consensus_hook::UnincludedSegmentCapacity,
relay_state_snapshot::{self, ReadEntryErr},
ConsensusHook, RelayChainStateProof,
};
use frame_support::{
pallet_prelude::*,
storage::types::{StorageValue, ValueQuery},
traits::{StorageInstance, Time},
};
use zeitgeist_primitives::types::well_known_relay_keys;

/// Get the relay timestamp.
/// Noe that the relay timestamp is populated at the parachain system inherent.
/// If you fetch the timestamp before, you will get the timestamp of the parent block.
pub struct RelayTimestamp;
impl Time for RelayTimestamp {
type Moment = u64;

fn now() -> Self::Moment {
RelayTimestampNow::get()
}
}

/// A wrapper around the consensus hook to get the relay timestamp from the relay storage proof
pub struct ConsensusHookWrapperForRelayTimestamp<Runtime, Inner>(
core::marker::PhantomData<(Runtime, Inner)>,
);
impl<Runtime, Inner> ConsensusHook for ConsensusHookWrapperForRelayTimestamp<Runtime, Inner>
where
Runtime: frame_system::Config,
Inner: ConsensusHook,
{
fn on_state_proof(state_proof: &RelayChainStateProof) -> (Weight, UnincludedSegmentCapacity) {
let relay_timestamp: u64 =
match state_proof.read_entry(well_known_relay_keys::TIMESTAMP_NOW, None) {
Ok(relay_timestamp) => relay_timestamp,
// Log the read entry error
Err(relay_state_snapshot::Error::ReadEntry(ReadEntryErr::Proof)) => {
log::error!("Invalid relay storage proof: fail to read key TIMESTAMP_NOW");
panic!("Invalid realy storage proof: fail to read key TIMESTAMP_NOW");
}
Err(relay_state_snapshot::Error::ReadEntry(ReadEntryErr::Decode)) => {
log::error!("Corrupted relay storage: fail to decode value TIMESTAMP_NOW");
panic!("Corrupted relay storage: fail to decode value TIMESTAMP_NOW");
}
Err(relay_state_snapshot::Error::ReadEntry(ReadEntryErr::Absent)) => {
log::error!("Corrupted relay storage: value TIMESTAMP_NOW is absent!");
panic!("Corrupted relay storage: value TIMESTAMP_NOW is absent!");
}
// Can't return another kind of error, the blokc is invalid anyway, so we should panic
_ => unreachable!(),
};

let wrapper_weight = <Runtime as frame_system::Config>::DbWeight::get().writes(1);

RelayTimestampNow::put(relay_timestamp);

let (weight, capacity) = Inner::on_state_proof(state_proof);

(weight.saturating_add(wrapper_weight), capacity)
}
}

// Prefix for storage value RelayTimestampNow
struct RelayTimestampNowPrefix;
impl StorageInstance for RelayTimestampNowPrefix {
const STORAGE_PREFIX: &'static str = "RelayTimestampNow";

fn pallet_prefix() -> &'static str {
"runtime"
}
}

// Storage type used to store the last current relay timestamp
type RelayTimestampNow = StorageValue<RelayTimestampNowPrefix, u64, ValueQuery>;
Loading