diff --git a/Cargo.lock b/Cargo.lock index 0a004b3a7364..cff745f943c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -864,6 +864,7 @@ dependencies = [ "cumulus-pallet-session-benchmarking", "cumulus-pallet-xcm", "cumulus-pallet-xcmp-queue", + "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-utility", "frame-benchmarking", diff --git a/cumulus/client/collator/src/lib.rs b/cumulus/client/collator/src/lib.rs index f17ae4883106..83249186f626 100644 --- a/cumulus/client/collator/src/lib.rs +++ b/cumulus/client/collator/src/lib.rs @@ -242,17 +242,19 @@ pub async fn initialize_collator_subsystems( overseer_handle: &mut OverseerHandle, key: CollatorPair, para_id: ParaId, + reinitialize: bool, ) { - overseer_handle - .send_msg( - CollationGenerationMessage::Initialize(CollationGenerationConfig { - key, - para_id, - collator: None, - }), - "StartCollator", - ) - .await; + let config = CollationGenerationConfig { key, para_id, collator: None }; + + if reinitialize { + overseer_handle + .send_msg(CollationGenerationMessage::Reinitialize(config), "StartCollator") + .await; + } else { + overseer_handle + .send_msg(CollationGenerationMessage::Initialize(config), "StartCollator") + .await; + } overseer_handle .send_msg(CollatorProtocolMessage::CollateOn(para_id), "StartCollator") diff --git a/cumulus/client/consensus/aura/src/collators/lookahead.rs b/cumulus/client/consensus/aura/src/collators/lookahead.rs index 5d62094e4aa1..e24b7f6f1c93 100644 --- a/cumulus/client/consensus/aura/src/collators/lookahead.rs +++ b/cumulus/client/consensus/aura/src/collators/lookahead.rs @@ -105,6 +105,8 @@ pub struct Params { pub collator_service: CS, /// The amount of time to spend authoring each block. pub authoring_duration: Duration, + /// Whether we should reinitialize the collator config (i.e. we are transitioning to aura). + pub reinitialize: bool, } /// Run async-backing-friendly Aura. @@ -149,6 +151,7 @@ where &mut params.overseer_handle, params.collator_key, params.para_id, + params.reinitialize, ) .await; diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml index 5d0cb41395f6..254aca900782 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/Cargo.toml @@ -77,6 +77,7 @@ cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system cumulus-pallet-session-benchmarking = { path = "../../../../pallets/session-benchmarking", default-features = false } cumulus-pallet-xcm = { path = "../../../../pallets/xcm", default-features = false } cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false, features = ["bridging"] } +cumulus-primitives-aura = { path = "../../../../primitives/aura", default-features = false } cumulus-primitives-core = { path = "../../../../primitives/core", default-features = false } cumulus-primitives-utility = { path = "../../../../primitives/utility", default-features = false } pallet-collator-selection = { path = "../../../../pallets/collator-selection", default-features = false } @@ -188,6 +189,7 @@ std = [ "cumulus-pallet-session-benchmarking/std", "cumulus-pallet-xcm/std", "cumulus-pallet-xcmp-queue/std", + "cumulus-primitives-aura/std", "cumulus-primitives-core/std", "cumulus-primitives-utility/std", "frame-benchmarking?/std", diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs index 0f379a6f7bc3..b1696f4c63ab 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs @@ -33,7 +33,7 @@ use assets_common::{ matching::{FromNetwork, FromSiblingParachain}, AssetIdForTrustBackedAssetsConvert, }; -use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; +use cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; use cumulus_primitives_core::AggregateMessageOrigin; use parachains_common::rococo::snowbridge::EthereumNetwork; use sp_api::impl_runtime_apis; @@ -62,7 +62,7 @@ use frame_support::{ ConstU128, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Equals, InstanceFilter, TransformOrigin, }, - weights::{ConstantMultiplier, Weight}, + weights::{constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, Weight}, BoundedVec, PalletId, }; use frame_system::{ @@ -71,14 +71,13 @@ use frame_system::{ }; use pallet_asset_conversion_tx_payment::AssetConversionAdapter; use pallet_nfts::PalletFeatures; -pub use parachains_common as common; use parachains_common::{ impls::DealWithFees, message_queue::{NarrowOriginToSibling, ParaIdToSibling}, rococo::{consensus::*, currency::*, fee::WeightToFee}, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, BlockNumber, CollectionId, Hash, Header, ItemId, Nonce, Signature, AVERAGE_ON_INITIALIZE_RATIO, DAYS, HOURS, - MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, + NORMAL_DISPATCH_RATIO, }; use sp_runtime::{Perbill, RuntimeDebug}; use xcm_config::{ @@ -141,6 +140,28 @@ pub fn native_version() -> NativeVersion { NativeVersion { runtime_version: VERSION, can_author_with: Default::default() } } +/// We allow for 2 seconds of compute with a 6 second average block. +const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts( + WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), + cumulus_primitives_core::relay_chain::MAX_POV_SIZE as u64, +); + +/// Maximum number of blocks simultaneously accepted by the Runtime, not yet included +/// into the relay chain. +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. +const BLOCK_PROCESSING_VELOCITY: u32 = 1; + +/// This determines the average expected block time that we are targeting. +/// Blocks will be produced at a minimum duration defined by `SLOT_DURATION`. +/// `SLOT_DURATION` is picked up by `pallet_timestamp` which is in turn picked +/// up by `pallet_aura` to implement `fn slot_duration()`. +/// +/// Change this to adjust the block time. +pub const MILLISECS_PER_BLOCK: u64 = 6000; +pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; + parameter_types! { pub const Version: RuntimeVersion = VERSION; pub RuntimeBlockLength: BlockLength = @@ -189,6 +210,9 @@ impl pallet_timestamp::Config for Runtime { /// A timestamp: milliseconds since the unix epoch. type Moment = u64; type OnTimestampSet = Aura; + #[cfg(feature = "experimental")] + type MinimumPeriod = ConstU64<0>; + #[cfg(not(feature = "experimental"))] type MinimumPeriod = ConstU64<{ SLOT_DURATION / 2 }>; type WeightInfo = weights::pallet_timestamp::WeightInfo; } @@ -630,15 +654,17 @@ impl cumulus_pallet_parachain_system::Config for Runtime { type OutboundXcmpMessageSource = XcmpQueue; type XcmpMessageHandler = XcmpQueue; type ReservedXcmpWeight = ReservedXcmpWeight; - type CheckAssociatedRelayNumber = RelayNumberStrictlyIncreases; - type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< - Runtime, - RELAY_CHAIN_SLOT_DURATION_MILLIS, - BLOCK_PROCESSING_VELOCITY, - UNINCLUDED_SEGMENT_CAPACITY, - >; + type CheckAssociatedRelayNumber = RelayNumberMonotonicallyIncreases; + type ConsensusHook = ConsensusHook; } +type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< + Runtime, + RELAY_CHAIN_SLOT_DURATION_MILLIS, + BLOCK_PROCESSING_VELOCITY, + UNINCLUDED_SEGMENT_CAPACITY, +>; + parameter_types! { pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; } @@ -722,9 +748,9 @@ impl pallet_aura::Config for Runtime { type AuthorityId = AuraId; type DisabledValidators = (); type MaxAuthorities = ConstU32<100_000>; - type AllowMultipleBlocksPerSlot = ConstBool; + type AllowMultipleBlocksPerSlot = ConstBool; #[cfg(feature = "experimental")] - type SlotDuration = pallet_aura::MinimumPeriodTimesTwo; + type SlotDuration = ConstU64; } parameter_types! { @@ -1070,7 +1096,7 @@ mod benches { impl_runtime_apis! { impl sp_consensus_aura::AuraApi for Runtime { fn slot_duration() -> sp_consensus_aura::SlotDuration { - sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration()) + sp_consensus_aura::SlotDuration::from_millis(SLOT_DURATION) } fn authorities() -> Vec { @@ -1078,6 +1104,15 @@ impl_runtime_apis! { } } + impl cumulus_primitives_aura::AuraUnincludedSegmentApi for Runtime { + fn can_build_upon( + included_hash: ::Hash, + slot: cumulus_primitives_aura::Slot, + ) -> bool { + ConsensusHook::can_build_upon(included_hash, slot) + } + } + impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { VERSION diff --git a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs index cb7ea34a0572..e7ac37b2d5c9 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-rococo/tests/tests.rs @@ -28,10 +28,11 @@ use asset_hub_rococo_runtime::{ AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, CollatorSelection, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime, RuntimeCall, RuntimeEvent, SessionKeys, - ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, + ToWestendXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, SLOT_DURATION, }; use asset_test_utils::{ - test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, + test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, + ExtBuilder, SlotDurations, }; use codec::{Decode, Encode}; use cumulus_primitives_utility::ChargeWeightInFungibles; @@ -46,9 +47,10 @@ use frame_support::{ weights::{Weight, WeightToFee as WeightToFeeT}, }; use parachains_common::{ - rococo::{currency::UNITS, fee::WeightToFee}, + rococo::{consensus::RELAY_CHAIN_SLOT_DURATION_MILLIS, currency::UNITS, fee::WeightToFee}, AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, }; +use sp_consensus_aura::SlotDuration; use sp_runtime::traits::MaybeEquivalence; use std::convert::Into; use xcm::latest::prelude::{Assets as XcmAssets, *}; @@ -78,6 +80,13 @@ fn collator_session_keys() -> CollatorSessionKeys { CollatorSessionKeys::default().add(collator_session_key(ALICE)) } +fn slot_durations() -> SlotDurations { + SlotDurations { + relay: SlotDuration::from_millis(RELAY_CHAIN_SLOT_DURATION_MILLIS.into()), + para: SlotDuration::from_millis(SLOT_DURATION), + } +} + #[test] fn test_buy_and_refund_weight_in_native() { ExtBuilder::::default() @@ -892,6 +901,7 @@ asset_test_utils::include_teleports_for_native_asset_works!( WeightToFee, ParachainSystem, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -912,6 +922,7 @@ asset_test_utils::include_teleports_for_foreign_assets_works!( ForeignCreatorsSovereignAccountOf, ForeignAssetsInstance, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -1023,6 +1034,7 @@ fn limited_reserve_transfer_assets_for_native_asset_over_bridge_works( LocationToAccountId, >( collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), AccountId::from(ALICE), Box::new(|runtime_event_encoded: Vec| { @@ -1194,6 +1206,7 @@ mod asset_hub_rococo_tests { LocationToAccountId, >( collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), AccountId::from(ALICE), Box::new(|runtime_event_encoded: Vec| { diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs index 310726349fa6..ed463e7e9096 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs @@ -55,7 +55,6 @@ use frame_system::{ use pallet_asset_conversion_tx_payment::AssetConversionAdapter; use pallet_nfts::{DestroyWitness, PalletFeatures}; use pallet_xcm::EnsureXcm; -pub use parachains_common as common; use parachains_common::{ impls::DealWithFees, message_queue::*, diff --git a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs index 3fc9f4a96585..381b2867c9c6 100644 --- a/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/assets/asset-hub-westend/tests/tests.rs @@ -32,7 +32,8 @@ use asset_hub_westend_runtime::{ }; pub use asset_hub_westend_runtime::{AssetConversion, AssetDeposit, CollatorSelection, System}; use asset_test_utils::{ - test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, + test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, + ExtBuilder, SlotDurations, }; use codec::{Decode, Encode}; use cumulus_primitives_utility::ChargeWeightInFungibles; @@ -47,9 +48,10 @@ use frame_support::{ weights::{Weight, WeightToFee as WeightToFeeT}, }; use parachains_common::{ - westend::{currency::UNITS, fee::WeightToFee}, - AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, + westend::{consensus::RELAY_CHAIN_SLOT_DURATION_MILLIS, currency::UNITS, fee::WeightToFee}, + AccountId, AssetIdForTrustBackedAssets, AuraId, Balance, SLOT_DURATION, }; +use sp_consensus_aura::SlotDuration; use sp_runtime::traits::MaybeEquivalence; use std::convert::Into; use xcm::latest::prelude::{Assets as XcmAssets, *}; @@ -79,6 +81,13 @@ fn collator_session_keys() -> CollatorSessionKeys { CollatorSessionKeys::default().add(collator_session_key(ALICE)) } +fn slot_durations() -> SlotDurations { + SlotDurations { + relay: SlotDuration::from_millis(RELAY_CHAIN_SLOT_DURATION_MILLIS.into()), + para: SlotDuration::from_millis(SLOT_DURATION), + } +} + #[test] fn test_buy_and_refund_weight_in_native() { ExtBuilder::::default() @@ -895,6 +904,7 @@ asset_test_utils::include_teleports_for_native_asset_works!( WeightToFee, ParachainSystem, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -915,6 +925,7 @@ asset_test_utils::include_teleports_for_foreign_assets_works!( ForeignCreatorsSovereignAccountOf, ForeignAssetsInstance, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -1041,6 +1052,7 @@ fn limited_reserve_transfer_assets_for_native_asset_to_asset_hub_rococo_works() LocationToAccountId, >( collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), AccountId::from(ALICE), Box::new(|runtime_event_encoded: Vec| { @@ -1208,6 +1220,7 @@ fn reserve_transfer_native_asset_to_non_teleport_para_works() { LocationToAccountId, >( collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), AccountId::from(ALICE), Box::new(|runtime_event_encoded: Vec| { diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs index e981fae80154..4007d926983e 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases.rs @@ -31,7 +31,7 @@ use frame_system::pallet_prelude::BlockNumberFor; use parachains_common::{AccountId, Balance}; use parachains_runtimes_test_utils::{ assert_metadata, assert_total, mock_open_hrmp_channel, AccountIdOf, BalanceOf, - CollatorSessionKeys, ExtBuilder, ValidatorIdOf, XcmReceivedFrom, + CollatorSessionKeys, ExtBuilder, SlotDurations, ValidatorIdOf, XcmReceivedFrom, }; use sp_runtime::{ traits::{MaybeEquivalence, StaticLookup, Zero}, @@ -57,6 +57,7 @@ pub fn teleports_for_native_asset_works< HrmpChannelOpener, >( collator_session_keys: CollatorSessionKeys, + slot_durations: SlotDurations, existential_deposit: BalanceOf, target_account: AccountIdOf, unwrap_pallet_xcm_event: Box) -> Option>>, @@ -205,6 +206,7 @@ pub fn teleports_for_native_asset_works< None, included_head.clone(), &alice, + &slot_durations, )); // check balances @@ -257,6 +259,7 @@ pub fn teleports_for_native_asset_works< Some((runtime_para_id, other_para_id)), included_head, &alice, + &slot_durations, ), Err(DispatchError::Module(sp_runtime::ModuleError { index: 31, @@ -288,6 +291,7 @@ macro_rules! include_teleports_for_native_asset_works( $weight_to_fee:path, $hrmp_channel_opener:path, $collator_session_key:expr, + $slot_durations:expr, $existential_deposit:expr, $unwrap_pallet_xcm_event:expr, $runtime_para_id:expr @@ -306,6 +310,7 @@ macro_rules! include_teleports_for_native_asset_works( $hrmp_channel_opener >( $collator_session_key, + $slot_durations, $existential_deposit, target_account, $unwrap_pallet_xcm_event, @@ -328,6 +333,7 @@ pub fn teleports_for_foreign_assets_works< ForeignAssetsPalletInstance, >( collator_session_keys: CollatorSessionKeys, + slot_durations: SlotDurations, target_account: AccountIdOf, existential_deposit: BalanceOf, asset_owner: AccountIdOf, @@ -592,6 +598,7 @@ pub fn teleports_for_foreign_assets_works< Some((runtime_para_id, foreign_para_id)), included_head, &alice, + &slot_durations, )); // check balances @@ -644,6 +651,7 @@ macro_rules! include_teleports_for_foreign_assets_works( $sovereign_account_of:path, $assets_pallet_instance:path, $collator_session_key:expr, + $slot_durations:expr, $existential_deposit:expr, $unwrap_pallet_xcm_event:expr, $unwrap_xcmp_queue_event:expr @@ -666,6 +674,7 @@ macro_rules! include_teleports_for_foreign_assets_works( $assets_pallet_instance >( $collator_session_key, + $slot_durations, target_account, $existential_deposit, asset_owner, @@ -1397,6 +1406,7 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< LocationToAccountId, >( collator_session_keys: CollatorSessionKeys, + slot_durations: SlotDurations, existential_deposit: BalanceOf, alice_account: AccountIdOf, unwrap_pallet_xcm_event: Box) -> Option>>, @@ -1470,6 +1480,7 @@ pub fn reserve_transfer_native_asset_to_non_teleport_para_works< other_para_id.into(), included_head, &alice, + &slot_durations, ); // we calculate exact delivery fees _after_ sending the message by weighing the sent diff --git a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs index 878dddc91372..905703a9d161 100644 --- a/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs +++ b/cumulus/parachains/runtimes/assets/test-utils/src/test_cases_over_bridge.rs @@ -27,7 +27,7 @@ use frame_system::pallet_prelude::BlockNumberFor; use parachains_common::{AccountId, Balance}; use parachains_runtimes_test_utils::{ mock_open_hrmp_channel, AccountIdOf, BalanceOf, CollatorSessionKeys, ExtBuilder, RuntimeHelper, - ValidatorIdOf, XcmReceivedFrom, + SlotDurations, ValidatorIdOf, XcmReceivedFrom, }; use sp_runtime::{traits::StaticLookup, Saturating}; use sp_std::ops::Mul; @@ -52,6 +52,7 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< LocationToAccountId, >( collator_session_keys: CollatorSessionKeys, + slot_durations: SlotDurations, existential_deposit: BalanceOf, alice_account: AccountIdOf, unwrap_pallet_xcm_event: Box) -> Option>>, @@ -125,6 +126,7 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works< local_bridge_hub_para_id.into(), included_head, &alice, + &slot_durations, ); // we calculate exact delivery fees _after_ sending the message by weighing the sent diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs index 63e64506ec75..9e46dc086548 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/tests/tests.rs @@ -24,9 +24,14 @@ use bridge_hub_rococo_runtime::{ Executive, ExistentialDeposit, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, SignedExtra, TransactionPayment, UncheckedExtrinsic, }; +use bridge_hub_test_utils::SlotDurations; use codec::{Decode, Encode}; use frame_support::{dispatch::GetDispatchInfo, parameter_types, traits::ConstU8}; -use parachains_common::{rococo::fee::WeightToFee, AccountId, AuraId, Balance}; +use parachains_common::{ + rococo::{consensus::RELAY_CHAIN_SLOT_DURATION_MILLIS, fee::WeightToFee}, + AccountId, AuraId, Balance, SLOT_DURATION, +}; +use sp_consensus_aura::SlotDuration; use sp_core::H160; use sp_keyring::AccountKeyring::Alice; use sp_runtime::{ @@ -95,6 +100,13 @@ fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys SlotDurations { + SlotDurations { + relay: SlotDuration::from_millis(RELAY_CHAIN_SLOT_DURATION_MILLIS.into()), + para: SlotDuration::from_millis(SLOT_DURATION), + } +} + bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( Runtime, AllPalletsWithoutSystem, @@ -103,6 +115,7 @@ bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( WeightToFee, ParachainSystem, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -264,6 +277,7 @@ mod bridge_hub_westend_tests { ConstU8<2>, >( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, SIBLING_PARACHAIN_ID, Box::new(|runtime_event_encoded: Vec| { @@ -288,6 +302,7 @@ mod bridge_hub_westend_tests { // from Westend from_parachain::relayed_incoming_message_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, BridgeHubWestendChainId::get(), @@ -304,6 +319,7 @@ mod bridge_hub_westend_tests { // for Westend from_parachain::complex_relay_extrinsic_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, SIBLING_PARACHAIN_ID, @@ -459,6 +475,7 @@ mod bridge_hub_bulletin_tests { ConstU8<2>, >( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, SIBLING_PARACHAIN_ID, Box::new(|runtime_event_encoded: Vec| { @@ -483,6 +500,7 @@ mod bridge_hub_bulletin_tests { // from Bulletin from_grandpa_chain::relayed_incoming_message_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, RococoBulletinChainId::get(), SIBLING_PARACHAIN_ID, @@ -498,6 +516,7 @@ mod bridge_hub_bulletin_tests { // for Bulletin from_grandpa_chain::complex_relay_extrinsic_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, SIBLING_PARACHAIN_ID, RococoBulletinChainId::get(), diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs index 1237a2313901..91d69b804208 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/tests/tests.rs @@ -18,7 +18,7 @@ use bp_polkadot_core::Signature; use bridge_common_config::{DeliveryRewardInBalance, RequiredStakeForStakeAndSlash}; -use bridge_hub_test_utils::test_cases::from_parachain; +use bridge_hub_test_utils::{test_cases::from_parachain, SlotDurations}; use bridge_hub_westend_runtime::{ bridge_common_config, bridge_to_rococo_config, xcm_config::{RelayNetwork, WestendLocation, XcmConfig}, @@ -33,7 +33,11 @@ use bridge_to_rococo_config::{ }; use codec::{Decode, Encode}; use frame_support::{dispatch::GetDispatchInfo, parameter_types, traits::ConstU8}; -use parachains_common::{westend::fee::WeightToFee, AccountId, AuraId, Balance}; +use parachains_common::{ + westend::{consensus::RELAY_CHAIN_SLOT_DURATION_MILLIS, fee::WeightToFee}, + AccountId, AuraId, Balance, SLOT_DURATION, +}; +use sp_consensus_aura::SlotDuration; use sp_keyring::AccountKeyring::Alice; use sp_runtime::{ generic::{Era, SignedPayload}, @@ -111,6 +115,13 @@ fn collator_session_keys() -> bridge_hub_test_utils::CollatorSessionKeys SlotDurations { + SlotDurations { + relay: SlotDuration::from_millis(RELAY_CHAIN_SLOT_DURATION_MILLIS.into()), + para: SlotDuration::from_millis(SLOT_DURATION), + } +} + bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( Runtime, AllPalletsWithoutSystem, @@ -119,6 +130,7 @@ bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!( WeightToFee, ParachainSystem, collator_session_keys(), + slot_durations(), ExistentialDeposit::get(), Box::new(|runtime_event_encoded: Vec| { match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) { @@ -229,6 +241,7 @@ fn message_dispatch_routing_works() { ConstU8<2>, >( collator_session_keys(), + slot_durations(), bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, SIBLING_PARACHAIN_ID, Box::new(|runtime_event_encoded: Vec| { @@ -252,6 +265,7 @@ fn message_dispatch_routing_works() { fn relayed_incoming_message_works() { from_parachain::relayed_incoming_message_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, BridgeHubRococoChainId::get(), @@ -267,6 +281,7 @@ fn relayed_incoming_message_works() { pub fn complex_relay_extrinsic_works() { from_parachain::complex_relay_extrinsic_works::( collator_session_keys(), + slot_durations(), bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID, bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID, SIBLING_PARACHAIN_ID, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs index 5eca85d3112e..acf0f2c71620 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_grandpa_chain.rs @@ -39,7 +39,7 @@ use bridge_runtime_common::{ use frame_support::traits::{Get, OnFinalize, OnInitialize}; use frame_system::pallet_prelude::BlockNumberFor; use parachains_runtimes_test_utils::{ - AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, + AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; use sp_keyring::AccountKeyring::*; use sp_runtime::{traits::Header as HeaderT, AccountId32}; @@ -107,6 +107,7 @@ where /// Also verifies relayer transaction signed extensions work as intended. pub fn relayed_incoming_message_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, bridged_chain_id: bp_runtime::ChainId, sibling_parachain_id: u32, @@ -136,6 +137,7 @@ pub fn relayed_incoming_message_works( RuntimeHelper::MPI, >( collator_session_key, + slot_durations, runtime_para_id, sibling_parachain_id, local_relay_chain_id, @@ -205,6 +207,7 @@ pub fn relayed_incoming_message_works( /// Also verifies relayer transaction signed extensions work as intended. pub fn complex_relay_extrinsic_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, sibling_parachain_id: u32, bridged_chain_id: bp_runtime::ChainId, @@ -237,6 +240,7 @@ pub fn complex_relay_extrinsic_works( RuntimeHelper::MPI, >( collator_session_key, + slot_durations, runtime_para_id, sibling_parachain_id, local_relay_chain_id, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs index 6e638b7b3503..8a86c5bb72f5 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/from_parachain.rs @@ -40,7 +40,7 @@ use bridge_runtime_common::{ use frame_support::traits::{Get, OnFinalize, OnInitialize}; use frame_system::pallet_prelude::BlockNumberFor; use parachains_runtimes_test_utils::{ - AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, + AccountIdOf, BasicParachainRuntime, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; use sp_keyring::AccountKeyring::*; use sp_runtime::{traits::Header as HeaderT, AccountId32}; @@ -112,6 +112,7 @@ where /// Also verifies relayer transaction signed extensions work as intended. pub fn relayed_incoming_message_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, bridged_para_id: u32, bridged_chain_id: bp_runtime::ChainId, @@ -146,6 +147,7 @@ pub fn relayed_incoming_message_works( RuntimeHelper::MPI, >( collator_session_key, + slot_durations, runtime_para_id, sibling_parachain_id, local_relay_chain_id, @@ -244,6 +246,7 @@ pub fn relayed_incoming_message_works( /// Also verifies relayer transaction signed extensions work as intended. pub fn complex_relay_extrinsic_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, bridged_para_id: u32, sibling_parachain_id: u32, @@ -281,6 +284,7 @@ pub fn complex_relay_extrinsic_works( RuntimeHelper::MPI, >( collator_session_key, + slot_durations, runtime_para_id, sibling_parachain_id, local_relay_chain_id, diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs index ba58aeb046e0..4f634c184aa8 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/helpers.rs @@ -31,7 +31,7 @@ use frame_system::pallet_prelude::BlockNumberFor; use pallet_bridge_grandpa::{BridgedBlockHash, BridgedHeader}; use parachains_common::AccountId; use parachains_runtimes_test_utils::{ - mock_open_hrmp_channel, AccountIdOf, CollatorSessionKeys, RuntimeCallOf, + mock_open_hrmp_channel, AccountIdOf, CollatorSessionKeys, RuntimeCallOf, SlotDurations, }; use sp_core::Get; use sp_keyring::AccountKeyring::*; @@ -220,6 +220,7 @@ pub fn relayer_id_at_bridged_chain, /// with proofs (finality, message) independently submitted. pub fn relayed_incoming_message_works( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, sibling_parachain_id: u32, local_relay_chain_id: NetworkId, @@ -272,6 +273,7 @@ pub fn relayed_incoming_message_works( sibling_parachain_id.into(), included_head, &alice, + &slot_durations, ); // set up relayer details and proofs diff --git a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs index eb7ba132168d..ce9396926449 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/test-utils/src/test_cases/mod.rs @@ -45,7 +45,7 @@ use frame_system::pallet_prelude::BlockNumberFor; use parachains_common::AccountId; use parachains_runtimes_test_utils::{ mock_open_hrmp_channel, AccountIdOf, BalanceOf, CollatorSessionKeys, ExtBuilder, RuntimeCallOf, - XcmReceivedFrom, + SlotDurations, XcmReceivedFrom, }; use sp_runtime::{traits::Zero, AccountId32}; use xcm::{latest::prelude::*, AlwaysLatest}; @@ -419,6 +419,7 @@ pub fn message_dispatch_routing_works< NetworkDistanceAsParentCount, >( collator_session_key: CollatorSessionKeys, + slot_durations: SlotDurations, runtime_para_id: u32, sibling_parachain_id: u32, unwrap_cumulus_pallet_parachain_system_event: Box< @@ -529,6 +530,7 @@ pub fn message_dispatch_routing_works< sibling_parachain_id.into(), included_head, &alice, + &slot_durations, ); let result = <>::MessageDispatch>::dispatch( diff --git a/cumulus/parachains/runtimes/test-utils/src/lib.rs b/cumulus/parachains/runtimes/test-utils/src/lib.rs index 88e878c73a35..eb75c2f7ee0a 100644 --- a/cumulus/parachains/runtimes/test-utils/src/lib.rs +++ b/cumulus/parachains/runtimes/test-utils/src/lib.rs @@ -29,7 +29,6 @@ use frame_support::{ weights::Weight, }; use frame_system::pallet_prelude::{BlockNumberFor, HeaderFor}; -use parachains_common::SLOT_DURATION; use polkadot_parachain_primitives::primitives::{ HeadData, HrmpChannelId, RelayChainBlockNumber, XcmpMessageFormat, }; @@ -115,6 +114,11 @@ impl, included_head: HeaderFor, slot_digest: &[u8], + slot_durations: &SlotDurations, ) -> DispatchResult where HrmpChannelOpener: frame_support::inherent::ProvideInherent< @@ -348,6 +353,7 @@ impl< target_para_id.into(), included_head, slot_digest, + slot_durations, ); } @@ -493,12 +499,12 @@ pub fn mock_open_hrmp_channel< recipient: ParaId, included_head: HeaderFor, mut slot_digest: &[u8], + slot_durations: &SlotDurations, ) { - const RELAY_CHAIN_SLOT_DURATION: SlotDuration = SlotDuration::from_millis(6000); let slot = Slot::decode(&mut slot_digest).expect("failed to decode digest"); // Convert para slot to relay chain. - let timestamp = slot.saturating_mul(SLOT_DURATION); - let relay_slot = Slot::from_timestamp(timestamp.into(), RELAY_CHAIN_SLOT_DURATION); + let timestamp = slot.saturating_mul(slot_durations.para.as_millis()); + let relay_slot = Slot::from_timestamp(timestamp.into(), slot_durations.relay); let n = 1_u32; let mut sproof_builder = RelayStateSproofBuilder { diff --git a/cumulus/polkadot-parachain/src/command.rs b/cumulus/polkadot-parachain/src/command.rs index 04d618f66c75..a7319b6dfbb2 100644 --- a/cumulus/polkadot-parachain/src/command.rs +++ b/cumulus/polkadot-parachain/src/command.rs @@ -695,9 +695,7 @@ pub fn run() -> Result<()> { .map(|r| r.0) .map_err(Into::into), - AssetHubKusama | - AssetHubRococo | - AssetHubWestend => + AssetHubKusama | AssetHubWestend => crate::service::start_asset_hub_node::< RuntimeApi, AuraId, @@ -706,6 +704,15 @@ pub fn run() -> Result<()> { .map(|r| r.0) .map_err(Into::into), + AssetHubRococo => + crate::service::start_asset_hub_lookahead_node::< + RuntimeApi, + AuraId, + >(config, polkadot_config, collator_options, id, hwbench) + .await + .map(|r| r.0) + .map_err(Into::into), + CollectivesPolkadot | CollectivesWestend => crate::service::start_generic_aura_node::< RuntimeApi, diff --git a/cumulus/polkadot-parachain/src/service.rs b/cumulus/polkadot-parachain/src/service.rs index 81d0c9d3980e..61b9cbbd80d9 100644 --- a/cumulus/polkadot-parachain/src/service.rs +++ b/cumulus/polkadot-parachain/src/service.rs @@ -976,6 +976,7 @@ pub async fn start_rococo_parachain_node( proposer, collator_service, authoring_duration: Duration::from_millis(1500), + reinitialize: false, }; let fut = aura::run::< @@ -1291,7 +1292,7 @@ where Ok(BasicQueue::new(verifier, Box::new(block_import), None, &spawner, registry)) } -/// Start an aura powered parachain node. Asset Hub and Collectives use this. +/// Start an aura powered parachain node. Collectives uses this. pub async fn start_generic_aura_node( parachain_config: Configuration, polkadot_config: Configuration, @@ -1530,6 +1531,159 @@ where .await } +/// Start a shell node which should later transition into an Aura powered parachain node. Asset Hub +/// uses this because at genesis, Asset Hub was on the `shell` runtime which didn't have Aura and +/// needs to sync and upgrade before it can run `AuraApi` functions. +/// +/// Uses the lookahead collator to support async backing. +#[sc_tracing::logging::prefix_logs_with("Parachain")] +pub async fn start_asset_hub_lookahead_node( + parachain_config: Configuration, + polkadot_config: Configuration, + collator_options: CollatorOptions, + para_id: ParaId, + hwbench: Option, +) -> sc_service::error::Result<(TaskManager, Arc>)> +where + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: sp_transaction_pool::runtime_api::TaggedTransactionQueue + + sp_api::Metadata + + sp_session::SessionKeys + + sp_api::ApiExt + + sp_offchain::OffchainWorkerApi + + sp_block_builder::BlockBuilder + + cumulus_primitives_core::CollectCollationInfo + + sp_consensus_aura::AuraApi::Pair as Pair>::Public> + + pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi + + frame_rpc_system::AccountNonceApi + + cumulus_primitives_aura::AuraUnincludedSegmentApi, + <::Pair as Pair>::Signature: + TryFrom> + std::hash::Hash + sp_runtime::traits::Member + Codec, +{ + start_node_impl::( + parachain_config, + polkadot_config, + collator_options, + CollatorSybilResistance::Resistant, // Aura + para_id, + |_| Ok(RpcModule::new(())), + aura_build_import_queue::<_, AuraId>, + |client, + block_import, + prometheus_registry, + telemetry, + task_manager, + relay_chain_interface, + transaction_pool, + sync_oracle, + keystore, + relay_chain_slot_duration, + para_id, + collator_key, + overseer_handle, + announce_block, + backend| { + let relay_chain_interface2 = relay_chain_interface.clone(); + + let collator_service = CollatorService::new( + client.clone(), + Arc::new(task_manager.spawn_handle()), + announce_block, + client.clone(), + ); + + let spawner = task_manager.spawn_handle(); + + let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( + spawner, + client.clone(), + transaction_pool, + prometheus_registry, + telemetry.clone(), + ); + + let collation_future = Box::pin(async move { + // Start collating with the `shell` runtime while waiting for an upgrade to an Aura + // compatible runtime. + let mut request_stream = cumulus_client_collator::relay_chain_driven::init( + collator_key.clone(), + para_id, + overseer_handle.clone(), + ) + .await; + while let Some(request) = request_stream.next().await { + let pvd = request.persisted_validation_data().clone(); + let last_head_hash = + match ::Header::decode(&mut &pvd.parent_head.0[..]) { + Ok(header) => header.hash(), + Err(e) => { + log::error!("Could not decode the head data: {e}"); + request.complete(None); + continue + }, + }; + + // Check if we have upgraded to an Aura compatible runtime and transition if + // necessary. + if client + .runtime_api() + .has_api::>(last_head_hash) + .unwrap_or(false) + { + // Respond to this request before transitioning to Aura. + request.complete(None); + break + } + } + + // Move to Aura consensus. + let slot_duration = match cumulus_client_consensus_aura::slot_duration(&*client) { + Ok(d) => d, + Err(e) => { + log::error!("Could not get Aura slot duration: {e}"); + return + }, + }; + + let proposer = Proposer::new(proposer_factory); + + let params = AuraParams { + create_inherent_data_providers: move |_, ()| async move { Ok(()) }, + block_import, + para_client: client.clone(), + para_backend: backend, + relay_client: relay_chain_interface2, + code_hash_provider: move |block_hash| { + client.code_at(block_hash).ok().map(|c| ValidationCode::from(c).hash()) + }, + sync_oracle, + keystore, + collator_key, + para_id, + overseer_handle, + slot_duration, + relay_chain_slot_duration, + proposer, + collator_service, + authoring_duration: Duration::from_millis(1500), + reinitialize: true, /* we need to always re-initialize for asset-hub moving + * to aura */ + }; + + aura::run::::Pair, _, _, _, _, _, _, _, _, _>(params) + .await + }); + + let spawner = task_manager.spawn_essential_handle(); + spawner.spawn_essential("cumulus-asset-hub-collator", None, collation_future); + + Ok(()) + }, + hwbench, + ) + .await +} + /// Start an aura powered parachain node which uses the lookahead collator to support async backing. /// This node is basic in the sense that its runtime api doesn't include common contents such as /// transaction payment. Used for aura glutton. @@ -1615,6 +1769,7 @@ where proposer, collator_service, authoring_duration: Duration::from_millis(1500), + reinitialize: false, }; let fut = diff --git a/polkadot/node/collation-generation/src/lib.rs b/polkadot/node/collation-generation/src/lib.rs index b8c9c1a36e46..cfa75d7b4411 100644 --- a/polkadot/node/collation-generation/src/lib.rs +++ b/polkadot/node/collation-generation/src/lib.rs @@ -143,6 +143,16 @@ impl CollationGenerationSubsystem { } false }, + Ok(FromOrchestra::Communication { + msg: CollationGenerationMessage::Reinitialize(config), + }) => { + if self.config.is_none() { + gum::error!(target: LOG_TARGET, "no initial initialization"); + } else { + self.config = Some(Arc::new(config)); + } + false + }, Ok(FromOrchestra::Communication { msg: CollationGenerationMessage::SubmitCollation(params), }) => { diff --git a/polkadot/node/subsystem-types/src/messages.rs b/polkadot/node/subsystem-types/src/messages.rs index c7675c84b91c..1d5d82b57fdf 100644 --- a/polkadot/node/subsystem-types/src/messages.rs +++ b/polkadot/node/subsystem-types/src/messages.rs @@ -830,8 +830,10 @@ pub enum ProvisionerMessage { /// Message to the Collation Generation subsystem. #[derive(Debug)] pub enum CollationGenerationMessage { - /// Initialize the collation generation subsystem + /// Initialize the collation generation subsystem. Initialize(CollationGenerationConfig), + /// Reinitialize the collation generation subsystem, overriding the existing config. + Reinitialize(CollationGenerationConfig), /// Submit a collation to the subsystem. This will package it into a signed /// [`CommittedCandidateReceipt`] and distribute along the network to validators. /// diff --git a/prdoc/pr_2826.prdoc b/prdoc/pr_2826.prdoc new file mode 100644 index 000000000000..70de795a1007 --- /dev/null +++ b/prdoc/pr_2826.prdoc @@ -0,0 +1,10 @@ +title: Enable async backing on asset-hub-rococo + +doc: + - audience: Runtime User + description: | + Async backing has been enabled on Asset Hub Rococo, which now targets 6s block times. + +crates: + - name: asset-hub-rococo-runtime + - name: polkadot-parachain-bin \ No newline at end of file