From eec58039f12a5761802bb1f5df7dbceec3abf396 Mon Sep 17 00:00:00 2001 From: Oliver Tale-Yazdi Date: Sat, 12 Mar 2022 20:37:24 +0100 Subject: [PATCH] Parachain runtime dependent weights (#5091) * Prepare for parachain runtime dependent weights Signed-off-by: Oliver Tale-Yazdi * Lockfile Signed-off-by: Oliver Tale-Yazdi * CI Signed-off-by: Oliver Tale-Yazdi * fmt Signed-off-by: Oliver Tale-Yazdi * CI Signed-off-by: Oliver Tale-Yazdi * CI Signed-off-by: Oliver Tale-Yazdi --- polkadot/Cargo.lock | 1 + polkadot/node/test/service/Cargo.toml | 1 + polkadot/node/test/service/src/lib.rs | 5 +- polkadot/runtime/common/src/lib.rs | 268 +++++++++++------------ polkadot/runtime/kusama/src/lib.rs | 2 +- polkadot/runtime/kusama/src/tests.rs | 1 + polkadot/runtime/polkadot/src/lib.rs | 3 +- polkadot/runtime/rococo/src/lib.rs | 2 +- polkadot/runtime/test-runtime/src/lib.rs | 5 +- polkadot/runtime/westend/src/lib.rs | 2 +- 10 files changed, 149 insertions(+), 141 deletions(-) diff --git a/polkadot/Cargo.lock b/polkadot/Cargo.lock index fdcf2fdc30..08c571daf6 100644 --- a/polkadot/Cargo.lock +++ b/polkadot/Cargo.lock @@ -7674,6 +7674,7 @@ dependencies = [ "polkadot-parachain", "polkadot-primitives", "polkadot-rpc", + "polkadot-runtime-common", "polkadot-runtime-parachains", "polkadot-service", "polkadot-test-runtime", diff --git a/polkadot/node/test/service/Cargo.toml b/polkadot/node/test/service/Cargo.toml index cccd60d4eb..a7d236bc64 100644 --- a/polkadot/node/test/service/Cargo.toml +++ b/polkadot/node/test/service/Cargo.toml @@ -18,6 +18,7 @@ polkadot-overseer = { path = "../../overseer" } polkadot-primitives = { path = "../../../primitives" } polkadot-parachain = { path = "../../../parachain" } polkadot-rpc = { path = "../../../rpc" } +polkadot-runtime-common = { path = "../../../runtime/common" } polkadot-service = { path = "../../service" } polkadot-node-subsystem = { path = "../../subsystem" } polkadot-node-primitives = { path = "../../primitives" } diff --git a/polkadot/node/test/service/src/lib.rs b/polkadot/node/test/service/src/lib.rs index dbcbaad144..8cf75a75f6 100644 --- a/polkadot/node/test/service/src/lib.rs +++ b/polkadot/node/test/service/src/lib.rs @@ -26,13 +26,14 @@ use polkadot_node_primitives::{CollationGenerationConfig, CollatorFn}; use polkadot_node_subsystem::messages::{CollationGenerationMessage, CollatorProtocolMessage}; use polkadot_overseer::Handle; use polkadot_primitives::v2::{Balance, CollatorPair, HeadData, Id as ParaId, ValidationCode}; +use polkadot_runtime_common::BlockHashCount; use polkadot_runtime_parachains::paras::ParaGenesisArgs; use polkadot_service::{ ClientHandle, Error, ExecuteWithClient, FullClient, IsCollator, NewFull, PrometheusConfig, }; use polkadot_test_runtime::{ - BlockHashCount, ParasSudoWrapperCall, Runtime, SignedExtra, SignedPayload, SudoCall, - UncheckedExtrinsic, VERSION, + ParasSudoWrapperCall, Runtime, SignedExtra, SignedPayload, SudoCall, UncheckedExtrinsic, + VERSION, }; use sc_chain_spec::ChainSpec; use sc_client_api::execution_extensions::ExecutionStrategies; diff --git a/polkadot/runtime/common/src/lib.rs b/polkadot/runtime/common/src/lib.rs index 40dee1a735..d9dac14a0f 100644 --- a/polkadot/runtime/common/src/lib.rs +++ b/polkadot/runtime/common/src/lib.rs @@ -38,17 +38,20 @@ mod integration_tests; mod mock; use frame_support::{ + parameter_types, traits::{ConstU32, Currency, OneSessionHandler}, weights::{constants::WEIGHT_PER_SECOND, Weight}, }; -use primitives::v2::{AssignmentId, ValidatorId}; -use sp_runtime::Perbill; +use frame_system::limits; +use primitives::v2::{AssignmentId, BlockNumber, ValidatorId}; +use sp_runtime::{FixedPointNumber, Perbill, Perquintill}; use static_assertions::const_assert; pub use pallet_balances::Call as BalancesCall; #[cfg(feature = "std")] pub use pallet_staking::StakerStatus; pub use pallet_timestamp::Call as TimestampCall; +use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment}; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -70,6 +73,29 @@ pub const MAXIMUM_BLOCK_WEIGHT: Weight = 2 * WEIGHT_PER_SECOND; const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct()); +// Common constants used in all runtimes. +parameter_types! { + pub const BlockHashCount: BlockNumber = 2400; + /// The portion of the `NORMAL_DISPATCH_RATIO` that we adjust the fees with. Blocks filled less + /// than this will decrease the weight and more will increase. + pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25); + /// The adjustment variable of the runtime. Higher values will cause `TargetBlockFullness` to + /// change the fees more rapidly. + pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(3, 100_000); + /// Minimum amount of the multiplier. This value cannot be too low. A test case should ensure + /// that combined with `AdjustmentVariable`, we can recover from the minimum. + /// See `multiplier_can_grow_from_zero`. + pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 1_000_000u128); + /// Maximum length of block. Up to 5MB. + pub BlockLength: limits::BlockLength = + limits::BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); +} + +/// Parameterized slow adjusting fee updated based on +/// https://research.web3.foundation/en/latest/polkadot/overview/2-token-economics.html#-2.-slow-adjusting-mechanism +pub type SlowAdjustingFeeUpdate = + TargetedFeeAdjustment; + /// Implements the weight types for a runtime. /// It expects the passed runtime constants to contain a `weights` module. /// The generated weight types were formerly part of the common @@ -81,37 +107,20 @@ macro_rules! impl_runtime_weights { use frame_system::limits; use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment}; pub use runtime_common::{ - impl_elections_weights, impl_multiplier_tests, AVERAGE_ON_INITIALIZE_RATIO, - MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, + impl_elections_weights, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT, + NORMAL_DISPATCH_RATIO, }; use sp_runtime::{FixedPointNumber, Perquintill}; // Implement the weight types of the elections module. impl_elections_weights!($runtime); - // Implement tests for the weight multiplier. - impl_multiplier_tests!(); // Expose the weight from the runtime constants module. pub use $runtime::weights::{ BlockExecutionWeight, ExtrinsicBaseWeight, ParityDbWeight, RocksDbWeight, }; - // Common constants used in all runtimes. parameter_types! { - pub const BlockHashCount: BlockNumber = 2400; - /// The portion of the `NORMAL_DISPATCH_RATIO` that we adjust the fees with. Blocks filled less - /// than this will decrease the weight and more will increase. - pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25); - /// The adjustment variable of the runtime. Higher values will cause `TargetBlockFullness` to - /// change the fees more rapidly. - pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(3, 100_000); - /// Minimum amount of the multiplier. This value cannot be too low. A test case should ensure - /// that combined with `AdjustmentVariable`, we can recover from the minimum. - /// See `multiplier_can_grow_from_zero`. - pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 1_000_000u128); - /// Maximum length of block. Up to 5MB. - pub BlockLength: limits::BlockLength = - limits::BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); /// Block weights base values and limits. pub BlockWeights: limits::BlockWeights = limits::BlockWeights::builder() .base_block($runtime::weights::BlockExecutionWeight::get()) @@ -132,11 +141,6 @@ macro_rules! impl_runtime_weights { .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) .build_or_panic(); } - - /// Parameterized slow adjusting fee updated based on - /// https://research.web3.foundation/en/latest/polkadot/overview/2-token-economics.html#-2.-slow-adjusting-mechanism - pub type SlowAdjustingFeeUpdate = - TargetedFeeAdjustment; }; } @@ -240,119 +244,115 @@ macro_rules! prod_or_fast { }; } -/// Generates tests that check that the different weight multiplier work together. -/// Should not be called directly, use [`impl_runtime_weights`] instead. -#[macro_export] -macro_rules! impl_multiplier_tests { - () => { - #[cfg(test)] - mod multiplier_tests { - use super::*; - use frame_support::{parameter_types, weights::Weight}; - use sp_core::H256; - use sp_runtime::{ - testing::Header, - traits::{BlakeTwo256, One, Convert, IdentityLookup}, - Perbill, - }; +#[cfg(test)] +mod multiplier_tests { + use super::*; + use frame_support::{ + parameter_types, + weights::{DispatchClass, Weight}, + }; + use sp_core::H256; + use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, Convert, IdentityLookup, One}, + Perbill, + }; - type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; - type Block = frame_system::mocking::MockBlock; + type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; + type Block = frame_system::mocking::MockBlock; - frame_support::construct_runtime!( - pub enum Runtime where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { - System: frame_system::{Pallet, Call, Config, Storage, Event} - } - ); - - parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const AvailableBlockRatio: Perbill = Perbill::one(); - pub BlockLength: frame_system::limits::BlockLength = - frame_system::limits::BlockLength::max(2 * 1024); - pub BlockWeights: frame_system::limits::BlockWeights = - frame_system::limits::BlockWeights::simple_max(1024); - } - - impl frame_system::Config for Runtime { - type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = BlockWeights; - type BlockLength = (); - type DbWeight = (); - type Origin = Origin; - type Index = u64; - type BlockNumber = u64; - type Call = Call; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = u64; - type Lookup = IdentityLookup; - type Header = Header; - type Event = Event; - type BlockHashCount = BlockHashCount; - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = (); - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = (); - type MaxConsumers = frame_support::traits::ConstU32<16>; - } - - fn run_with_system_weight(w: Weight, mut assertions: F) - where - F: FnMut() -> (), + frame_support::construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, { - let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::default() - .build_storage::() - .unwrap() - .into(); - t.execute_with(|| { - System::set_block_consumed_resources(w, 0); - assertions() - }); + System: frame_system::{Pallet, Call, Config, Storage, Event} } + ); - #[test] - fn multiplier_can_grow_from_zero() { - let minimum_multiplier = MinimumMultiplier::get(); - let target = TargetBlockFullness::get() * - BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap(); - // if the min is too small, then this will not change, and we are doomed forever. - // the weight is 1/100th bigger than target. - run_with_system_weight(target * 101 / 100, || { - let next = SlowAdjustingFeeUpdate::::convert(minimum_multiplier); - assert!(next > minimum_multiplier, "{:?} !>= {:?}", next, minimum_multiplier); - }) - } - - #[test] - #[ignore] - fn multiplier_growth_simulator() { - // assume the multiplier is initially set to its minimum. We update it with values twice the - //target (target is 25%, thus 50%) and we see at which point it reaches 1. - let mut multiplier = MinimumMultiplier::get(); - let block_weight = TargetBlockFullness::get() * - BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap() * - 2; - let mut blocks = 0; - while multiplier <= Multiplier::one() { - run_with_system_weight(block_weight, || { - let next = SlowAdjustingFeeUpdate::::convert(multiplier); - // ensure that it is growing as well. - assert!(next > multiplier, "{:?} !>= {:?}", next, multiplier); - multiplier = next; - }); - blocks += 1; - println!("block = {} multiplier {:?}", blocks, multiplier); - } - } + parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const AvailableBlockRatio: Perbill = Perbill::one(); + pub BlockLength: frame_system::limits::BlockLength = + frame_system::limits::BlockLength::max(2 * 1024); + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); } + + impl frame_system::Config for Runtime { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = BlockWeights; + type BlockLength = (); + type DbWeight = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Call = Call; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; + } + + fn run_with_system_weight(w: Weight, mut assertions: F) + where + F: FnMut() -> (), + { + let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap() + .into(); + t.execute_with(|| { + System::set_block_consumed_resources(w, 0); + assertions() + }); + } + + #[test] + fn multiplier_can_grow_from_zero() { + let minimum_multiplier = MinimumMultiplier::get(); + let target = TargetBlockFullness::get() * + BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap(); + // if the min is too small, then this will not change, and we are doomed forever. + // the weight is 1/100th bigger than target. + run_with_system_weight(target * 101 / 100, || { + let next = SlowAdjustingFeeUpdate::::convert(minimum_multiplier); + assert!(next > minimum_multiplier, "{:?} !>= {:?}", next, minimum_multiplier); + }) + } + + #[test] + #[ignore] + fn multiplier_growth_simulator() { + // assume the multiplier is initially set to its minimum. We update it with values twice the + //target (target is 25%, thus 50%) and we see at which point it reaches 1. + let mut multiplier = MinimumMultiplier::get(); + let block_weight = TargetBlockFullness::get() * + BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap() * + 2; + let mut blocks = 0; + while multiplier <= Multiplier::one() { + run_with_system_weight(block_weight, || { + let next = SlowAdjustingFeeUpdate::::convert(multiplier); + // ensure that it is growing as well. + assert!(next > multiplier, "{:?} !>= {:?}", next, multiplier); + multiplier = next; + }); + blocks += 1; + println!("block = {} multiplier {:?}", blocks, multiplier); + } } } diff --git a/polkadot/runtime/kusama/src/lib.rs b/polkadot/runtime/kusama/src/lib.rs index c3887090e5..a47ff73607 100644 --- a/polkadot/runtime/kusama/src/lib.rs +++ b/polkadot/runtime/kusama/src/lib.rs @@ -30,7 +30,7 @@ use primitives::v2::{ }; use runtime_common::{ auctions, claims, crowdloan, impl_runtime_weights, impls::DealWithFees, paras_registrar, - prod_or_fast, slots, CurrencyToVote, + prod_or_fast, slots, BlockHashCount, BlockLength, CurrencyToVote, SlowAdjustingFeeUpdate, }; use sp_std::{cmp::Ordering, collections::btree_map::BTreeMap, prelude::*}; diff --git a/polkadot/runtime/kusama/src/tests.rs b/polkadot/runtime/kusama/src/tests.rs index add97b0b87..730335891c 100644 --- a/polkadot/runtime/kusama/src/tests.rs +++ b/polkadot/runtime/kusama/src/tests.rs @@ -21,6 +21,7 @@ use frame_support::weights::{GetDispatchInfo, WeightToFeePolynomial}; use keyring::Sr25519Keyring::Charlie; use pallet_transaction_payment::Multiplier; use parity_scale_codec::Encode; +use runtime_common::MinimumMultiplier; use separator::Separatable; use sp_runtime::FixedPointNumber; diff --git a/polkadot/runtime/polkadot/src/lib.rs b/polkadot/runtime/polkadot/src/lib.rs index 6157236068..2a51340616 100644 --- a/polkadot/runtime/polkadot/src/lib.rs +++ b/polkadot/runtime/polkadot/src/lib.rs @@ -23,7 +23,7 @@ use pallet_transaction_payment::CurrencyAdapter; use runtime_common::{ auctions, claims, crowdloan, impl_runtime_weights, impls::DealWithFees, paras_registrar, - prod_or_fast, slots, CurrencyToVote, + prod_or_fast, slots, BlockHashCount, BlockLength, CurrencyToVote, SlowAdjustingFeeUpdate, }; use runtime_parachains::{ @@ -2116,6 +2116,7 @@ mod test_fees { use frame_support::weights::{GetDispatchInfo, WeightToFeePolynomial}; use keyring::Sr25519Keyring::Charlie; use pallet_transaction_payment::Multiplier; + use runtime_common::MinimumMultiplier; use separator::Separatable; use sp_runtime::{assert_eq_error_rate, FixedPointNumber}; diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index fabaed15c5..57211d3e6f 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -43,7 +43,7 @@ use primitives::v2::{ }; use runtime_common::{ assigned_slots, auctions, crowdloan, impl_runtime_weights, impls::ToAuthor, paras_registrar, - paras_sudo_wrapper, slots, + paras_sudo_wrapper, slots, BlockHashCount, BlockLength, SlowAdjustingFeeUpdate, }; use runtime_parachains::{self, runtime_api_impl::v2 as runtime_api_impl}; use scale_info::TypeInfo; diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index af7eeec920..2200e96e0f 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -51,7 +51,10 @@ use primitives::v2::{ ScrapedOnChainVotes, SessionInfo as SessionInfoData, Signature, ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, }; -use runtime_common::{claims, impl_runtime_weights, paras_sudo_wrapper}; +use runtime_common::{ + claims, impl_runtime_weights, paras_sudo_wrapper, BlockHashCount, BlockLength, + SlowAdjustingFeeUpdate, +}; use sp_core::OpaqueMetadata; use sp_runtime::{ create_runtime_str, diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index c7981645ad..482f0f668f 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -30,7 +30,7 @@ use primitives::v2::{ }; use runtime_common::{ assigned_slots, auctions, crowdloan, impl_runtime_weights, impls::ToAuthor, paras_registrar, - paras_sudo_wrapper, slots, CurrencyToVote, + paras_sudo_wrapper, slots, BlockHashCount, BlockLength, CurrencyToVote, SlowAdjustingFeeUpdate, }; use sp_std::{collections::btree_map::BTreeMap, prelude::*};