diff --git a/Cargo.lock b/Cargo.lock index a8c1591024..145f688950 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6450,6 +6450,7 @@ dependencies = [ "cumulus-pallet-parachain-system", "cumulus-pallet-xcm", "cumulus-pallet-xcmp-queue", + "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-timestamp", "cumulus-primitives-utility", @@ -8109,12 +8110,14 @@ dependencies = [ "pallet-evm-coder-substrate", "pallet-nonfungible", "pallet-refungible", + "pallet-structure", "parity-scale-codec", "scale-info", "sp-core", "sp-io", "sp-runtime", "sp-std", + "up-common", "up-data-structs", ] @@ -14732,6 +14735,7 @@ dependencies = [ "cumulus-client-consensus-proposer", "cumulus-client-network", "cumulus-client-service", + "cumulus-primitives-aura", "cumulus-primitives-core", "cumulus-primitives-parachain-inherent", "cumulus-relay-chain-inprocess-interface", diff --git a/Cargo.toml b/Cargo.toml index 14a4294e82..748f2ada65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,6 +100,7 @@ cumulus-pallet-dmp-queue = { default-features = false, git = "https://github.com cumulus-pallet-parachain-system = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } cumulus-pallet-xcm = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } cumulus-pallet-xcmp-queue = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } +cumulus-primitives-aura = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } cumulus-primitives-core = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } cumulus-primitives-parachain-inherent = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } cumulus-primitives-timestamp = { default-features = false, git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.1.0" } diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml index 64de1b786c..32acce376d 100644 --- a/node/cli/Cargo.toml +++ b/node/cli/Cargo.toml @@ -36,6 +36,7 @@ cumulus-client-consensus-common = { workspace = true } cumulus-client-consensus-proposer = { workspace = true } cumulus-client-network = { workspace = true } cumulus-client-service = { workspace = true } +cumulus-primitives-aura = { workspace = true } cumulus-primitives-core = { workspace = true } cumulus-primitives-parachain-inherent = { features = ["std"], workspace = true } cumulus-relay-chain-inprocess-interface = { workspace = true } @@ -113,7 +114,9 @@ gov-test-timings = [ 'quartz-runtime?/gov-test-timings', 'unique-runtime?/gov-test-timings', ] -lookahead = [] +lookahead = [ + 'opal-runtime/lookahead' +] pov-estimate = [ 'opal-runtime/pov-estimate', 'quartz-runtime?/pov-estimate', diff --git a/node/cli/src/command.rs b/node/cli/src/command.rs index 945014c606..6ed625d191 100644 --- a/node/cli/src/command.rs +++ b/node/cli/src/command.rs @@ -396,6 +396,8 @@ pub fn run() -> Result<()> { } } #[cfg(feature = "try-runtime")] + // embedded try-runtime cli will be removed soon. + #[allow(deprecated)] Some(Subcommand::TryRuntime(cmd)) => { use std::{future::Future, pin::Pin}; diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index ce16688038..f16e6e799c 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -221,6 +221,14 @@ ez_bounds!( { } ); +#[cfg(not(feature = "lookahead"))] +ez_bounds!( + pub trait LookaheadApiDep {} +); +#[cfg(feature = "lookahead")] +ez_bounds!( + pub trait LookaheadApiDep: cumulus_primitives_aura::AuraUnincludedSegmentApi {} +); /// Starts a `ServiceBuilder` for a full service. /// @@ -358,6 +366,7 @@ where + Sync + 'static, RuntimeApi::RuntimeApi: RuntimeApiDep + 'static, + RuntimeApi::RuntimeApi: LookaheadApiDep, Runtime: RuntimeInstance, ExecutorDispatch: NativeExecutionDispatch + 'static, { @@ -687,6 +696,8 @@ pub struct StartConsensusParameters<'a> { announce_block: Arc>) + Send + Sync>, } +// Clones ignored for optional lookahead collator +#[allow(clippy::redundant_clone)] pub fn start_consensus( client: Arc>, transaction_pool: Arc< @@ -701,6 +712,7 @@ where + Sync + 'static, RuntimeApi::RuntimeApi: RuntimeApiDep + 'static, + RuntimeApi::RuntimeApi: LookaheadApiDep, Runtime: RuntimeInstance, { let StartConsensusParameters { @@ -735,12 +747,12 @@ where client.clone(), ); - let block_import = ParachainBlockImport::new(client.clone(), backend); + let block_import = ParachainBlockImport::new(client.clone(), backend.clone()); let params = BuildAuraConsensusParams { create_inherent_data_providers: move |_, ()| async move { Ok(()) }, block_import, - para_client: client, + para_client: client.clone(), #[cfg(feature = "lookahead")] para_backend: backend, para_id, @@ -751,10 +763,19 @@ where proposer, collator_service, // With async-baking, we allowed to be both slower (longer authoring) and faster (multiple para blocks per relay block) + #[cfg(not(feature = "lookahead"))] authoring_duration: Duration::from_millis(500), + #[cfg(feature = "lookahead")] + authoring_duration: Duration::from_millis(1500), overseer_handle, #[cfg(feature = "lookahead")] - code_hash_provider: || {}, + code_hash_provider: move |block_hash| { + client + .code_at(block_hash) + .ok() + .map(cumulus_primitives_core::relay_chain::ValidationCode) + .map(|c| c.hash()) + }, collator_key, relay_chain_slot_duration, }; @@ -762,7 +783,10 @@ where task_manager.spawn_essential_handle().spawn( "aura", None, + #[cfg(not(feature = "lookahead"))] run_aura::<_, AuraAuthorityPair, _, _, _, _, _, _, _>(params), + #[cfg(feature = "lookahead")] + run_aura::<_, AuraAuthorityPair, _, _, _, _, _, _, _, _, _>(params), ); Ok(()) } diff --git a/pallets/inflation/src/lib.rs b/pallets/inflation/src/lib.rs index e49af7e0f4..2ecbd88dff 100644 --- a/pallets/inflation/src/lib.rs +++ b/pallets/inflation/src/lib.rs @@ -70,8 +70,10 @@ pub mod pallet { + Mutate; type TreasuryAccountId: Get; - // The block number provider - type BlockNumberProvider: BlockNumberProvider>; + // The block number provider, which should be callable from `on_initialize` hook. + type OnInitializeBlockNumberProvider: BlockNumberProvider< + BlockNumber = BlockNumberFor, + >; /// Number of blocks that pass between treasury balance updates due to inflation #[pallet::constant] @@ -118,7 +120,7 @@ pub mod pallet { }; let block_interval: u32 = T::InflationBlockInterval::get().try_into().unwrap_or(0); - let current_relay_block = T::BlockNumberProvider::current_block_number(); + let current_relay_block = T::OnInitializeBlockNumberProvider::current_block_number(); let next_inflation: BlockNumberFor = >::get(); add_weight(1, 0, Weight::from_parts(5_000_000, 0)); diff --git a/primitives/common/src/constants.rs b/primitives/common/src/constants.rs index ced66a2f6c..df7ae1db60 100644 --- a/primitives/common/src/constants.rs +++ b/primitives/common/src/constants.rs @@ -23,7 +23,10 @@ use sp_runtime::Perbill; use crate::types::{Balance, BlockNumber}; +#[cfg(not(feature = "lookahead"))] pub const MILLISECS_PER_BLOCK: u64 = 12000; +#[cfg(feature = "lookahead")] +pub const MILLISECS_PER_BLOCK: u64 = 3000; pub const MILLISECS_PER_RELAY_BLOCK: u64 = 6000; pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK; diff --git a/runtime/common/config/pallets/mod.rs b/runtime/common/config/pallets/mod.rs index ee0694582c..0da0638340 100644 --- a/runtime/common/config/pallets/mod.rs +++ b/runtime/common/config/pallets/mod.rs @@ -21,7 +21,7 @@ use frame_support::{ traits::{ConstU32, ConstU64, Currency}, }; use sp_arithmetic::Perbill; -use sp_runtime::traits::AccountIdConversion; +use sp_runtime::traits::{AccountIdConversion, BlockNumberProvider}; use up_common::{ constants::*, types::{AccountId, Balance, BlockNumber}, @@ -105,12 +105,34 @@ parameter_types! { pub const InflationBlockInterval: BlockNumber = 100; // every time per how many blocks inflation is applied } +/// Pallet-inflation needs block number in on_initialize, where there is no `validation_data` exists yet +pub struct OnInitializeBlockNumberProvider; +impl BlockNumberProvider for OnInitializeBlockNumberProvider { + type BlockNumber = BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + use hex_literal::hex; + use parity_scale_codec::Decode; + use sp_io::storage; + // TODO: Replace with the following code after https://github.com/paritytech/polkadot-sdk/commit/3ea497b5a0fdda252f9c5a3c257cfaf8685f02fd lands + // >::last_relay_block_number() + + // ParachainSystem.LastRelayChainBlockNumber + let Some(encoded) = storage::get(&hex!("45323df7cc47150b3930e2666b0aa313a2bca190d36bd834cc73a38fc213ecbd")) else { + // First parachain block + return Default::default() + }; + BlockNumber::decode(&mut encoded.as_ref()) + .expect("typeof(RelayBlockNumber) == typeof(BlockNumber) == u32; qed") + } +} + /// Used for the pallet inflation impl pallet_inflation::Config for Runtime { type Currency = Balances; type TreasuryAccountId = TreasuryAccountId; type InflationBlockInterval = InflationBlockInterval; - type BlockNumberProvider = RelayChainBlockNumberProvider; + type OnInitializeBlockNumberProvider = OnInitializeBlockNumberProvider; } impl pallet_unique::Config for Runtime { diff --git a/runtime/common/config/parachain.rs b/runtime/common/config/parachain.rs index ad42e39958..d56da711ca 100644 --- a/runtime/common/config/parachain.rs +++ b/runtime/common/config/parachain.rs @@ -38,9 +38,29 @@ impl cumulus_pallet_parachain_system::Config for Runtime { type ReservedDmpWeight = ReservedDmpWeight; type ReservedXcmpWeight = ReservedXcmpWeight; type XcmpMessageHandler = XcmpQueue; + #[cfg(not(feature = "lookahead"))] type CheckAssociatedRelayNumber = cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; + #[cfg(feature = "lookahead")] + type CheckAssociatedRelayNumber = + cumulus_pallet_parachain_system::RelayNumberMonotonicallyIncreases; } impl parachain_info::Config for Runtime {} impl cumulus_pallet_aura_ext::Config for Runtime {} + +/// Maximum number of blocks simultaneously accepted by the Runtime, not yet included +/// into the relay chain. +#[cfg(feature = "lookahead")] +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. +#[cfg(feature = "lookahead")] +const BLOCK_PROCESSING_VELOCITY: u32 = 2; +#[cfg(feature = "lookahead")] +pub type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< + Runtime, + { MILLISECS_PER_RELAY_BLOCK as u32 }, + BLOCK_PROCESSING_VELOCITY, + UNINCLUDED_SEGMENT_CAPACITY, +>; diff --git a/runtime/common/runtime_apis.rs b/runtime/common/runtime_apis.rs index 04910ae2dc..f15a5c6ae6 100644 --- a/runtime/common/runtime_apis.rs +++ b/runtime/common/runtime_apis.rs @@ -679,6 +679,16 @@ macro_rules! impl_common_runtime_apis { } } + #[cfg(feature = "lookahead")] + impl cumulus_primitives_aura::AuraUnincludedSegmentApi for Runtime { + fn can_build_upon( + included_hash: ::Hash, + slot: cumulus_primitives_aura::Slot, + ) -> bool { + $crate::config::parachain::ConsensusHook::can_build_upon(included_hash, slot) + } + } + /// Should never be used, yet still required because of https://github.com/paritytech/polkadot-sdk/issues/27 /// Not allowed to panic, because rpc may be called using native runtime, thus causing thread panic. impl fp_rpc::ConvertTransactionRuntimeApi for Runtime { diff --git a/runtime/opal/Cargo.toml b/runtime/opal/Cargo.toml index 5e9e63723b..ee11854589 100644 --- a/runtime/opal/Cargo.toml +++ b/runtime/opal/Cargo.toml @@ -69,6 +69,7 @@ std = [ 'cumulus-pallet-parachain-system/std', 'cumulus-pallet-xcm/std', 'cumulus-pallet-xcmp-queue/std', + 'cumulus-primitives-aura/std', 'cumulus-primitives-core/std', 'cumulus-primitives-utility/std', 'frame-executive/std', @@ -230,6 +231,7 @@ governance = [] preimage = [] refungible = [] session-test-timings = [] +lookahead = [] ################################################################################ # local dependencies @@ -240,6 +242,7 @@ cumulus-pallet-dmp-queue = { workspace = true } cumulus-pallet-parachain-system = { workspace = true } cumulus-pallet-xcm = { workspace = true } cumulus-pallet-xcmp-queue = { workspace = true } +cumulus-primitives-aura = { workspace = true } cumulus-primitives-core = { workspace = true } cumulus-primitives-timestamp = { workspace = true } cumulus-primitives-utility = { workspace = true }