Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Streamline frame_system weight parametrization (#6629)
Browse files Browse the repository at this point in the history
* Basic weights builder.

* Fixing WiP

* Make the tests work.

* Fix weights in node/runtime.

* WiP.

* Update pallets with new weights parameters.

* Validate returns a Result now.

* Count mandatory weight separately.

* DRY

* BREAKING: Updating state root, because of the left-over weight-tracking stuff

* Update tests affected by Mandatory tracking.

* Fixing tests.

* Fix defaults for simple_max

* Update frame/system/src/weights.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Rework the API a bit.

* Fix compilation & tests.

* Apply suggestions from code review

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Add extra docs & rename few things.

* Fix whitespace in ASCII art.

* Update frame/system/src/limits.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Fix max_extrinsic calculations.

* Fix conflicts.

* Fix compilation.

* Fix new code.

* re-remove generic asset

* Fix usage.

* Update state root.

* Update proxy.

* Fix tests.

* Move weights validity to integrity_test

* Remove redundant BlockWeights.

* Add all/non_mandatory comment

* Add test.

* Remove fn block_weights

* Make the macro prettier.

* Fix some docs.

* Make max_total behave more predictabily.

* Add BlockWeights to metadata.

* fix balances test

* Fix utility test.

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
Co-authored-by: Benjamin Kampmann <ben@gnunicorn.org>
Co-authored-by: thiolliere <gui.thiolliere@gmail.com>
  • Loading branch information
5 people authored Dec 8, 2020
1 parent 163412d commit 332399d
Show file tree
Hide file tree
Showing 66 changed files with 1,277 additions and 931 deletions.
17 changes: 5 additions & 12 deletions bin/node-template/pallets/template/src/mock.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::{Module, Config};
use sp_core::H256;
use frame_support::{impl_outer_origin, parameter_types, weights::Weight};
use frame_support::{impl_outer_origin, parameter_types};
use sp_runtime::{
traits::{BlakeTwo256, IdentityLookup}, testing::Header, Perbill,
traits::{BlakeTwo256, IdentityLookup}, testing::Header,
};
use frame_system as system;

Expand All @@ -16,13 +16,13 @@ impl_outer_origin! {
pub struct Test;
parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const MaximumBlockWeight: Weight = 1024;
pub const MaximumBlockLength: u32 = 2 * 1024;
pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
}

impl system::Config for Test {
type BaseCallFilter = ();
type BlockWeights = ();
type BlockLength = ();
type DbWeight = ();
type Origin = Origin;
type Call = ();
type Index = u64;
Expand All @@ -34,13 +34,6 @@ impl system::Config for Test {
type Header = Header;
type Event = ();
type BlockHashCount = BlockHashCount;
type MaximumBlockWeight = MaximumBlockWeight;
type DbWeight = ();
type BlockExecutionWeight = ();
type ExtrinsicBaseWeight = ();
type MaximumExtrinsicWeight = MaximumBlockWeight;
type MaximumBlockLength = MaximumBlockLength;
type AvailableBlockRatio = AvailableBlockRatio;
type Version = ();
type PalletInfo = ();
type AccountData = ();
Expand Down
36 changes: 12 additions & 24 deletions bin/node-template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use sp_runtime::{
transaction_validity::{TransactionValidity, TransactionSource},
};
use sp_runtime::traits::{
BlakeTwo256, Block as BlockT, AccountIdLookup, Verify, IdentifyAccount, NumberFor, Saturating,
BlakeTwo256, Block as BlockT, AccountIdLookup, Verify, IdentifyAccount, NumberFor,
};
use sp_api::impl_runtime_apis;
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
Expand Down Expand Up @@ -126,23 +126,27 @@ pub fn native_version() -> NativeVersion {
}
}

const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);

parameter_types! {
pub const Version: RuntimeVersion = VERSION;
pub const BlockHashCount: BlockNumber = 2400;
/// We allow for 2 seconds of compute with a 6 second average block time.
pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND;
pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
/// Assume 10% of weight for average on_initialize calls.
pub MaximumExtrinsicWeight: Weight = AvailableBlockRatio::get()
.saturating_sub(Perbill::from_percent(10)) * MaximumBlockWeight::get();
pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
pub const Version: RuntimeVersion = VERSION;
pub BlockWeights: frame_system::limits::BlockWeights = frame_system::limits::BlockWeights
::with_sensible_defaults(2 * WEIGHT_PER_SECOND, NORMAL_DISPATCH_RATIO);
pub BlockLength: frame_system::limits::BlockLength = frame_system::limits::BlockLength
::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
}

// Configure FRAME pallets to include in runtime.

impl frame_system::Config for Runtime {
/// The basic call filter to use in dispatchable.
type BaseCallFilter = ();
/// Block & extrinsics weights: base values and limits.
type BlockWeights = BlockWeights;
/// The maximum length of a block (in bytes).
type BlockLength = BlockLength;
/// The identifier used to distinguish between accounts.
type AccountId = AccountId;
/// The aggregated dispatch type that is available for extrinsics.
Expand All @@ -165,24 +169,8 @@ impl frame_system::Config for Runtime {
type Origin = Origin;
/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
type BlockHashCount = BlockHashCount;
/// Maximum weight of each block.
type MaximumBlockWeight = MaximumBlockWeight;
/// The weight of database operations that the runtime can invoke.
type DbWeight = RocksDbWeight;
/// The weight of the overhead invoked on the block import process, independent of the
/// extrinsics included in that block.
type BlockExecutionWeight = BlockExecutionWeight;
/// The base weight of any extrinsic processed by the runtime, independent of the
/// logic of that extrinsic. (Signature verification, nonce increment, fee, etc...)
type ExtrinsicBaseWeight = ExtrinsicBaseWeight;
/// The maximum weight that a single extrinsic of `Normal` dispatch class can have,
/// idependent of the logic of that extrinsics. (Roughly max block weight - average on
/// initialize cost).
type MaximumExtrinsicWeight = MaximumExtrinsicWeight;
/// Maximum size of all encoded transactions (in bytes) that are allowed in one block.
type MaximumBlockLength = MaximumBlockLength;
/// Portion of the block weight that is available to all normal transactions.
type AvailableBlockRatio = AvailableBlockRatio;
/// Version of the runtime.
type Version = Version;
/// Converts a module to the index of the module in `construct_runtime!`.
Expand Down
34 changes: 20 additions & 14 deletions bin/node/runtime/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,23 @@ mod multiplier_tests {

use crate::{
constants::{currency::*, time::*},
TransactionPayment, MaximumBlockWeight, AvailableBlockRatio, Runtime, TargetBlockFullness,
TransactionPayment, Runtime, TargetBlockFullness,
AdjustmentVariable, System, MinimumMultiplier,
RuntimeBlockWeights as BlockWeights,
};
use frame_support::weights::{Weight, WeightToFeePolynomial};
use frame_support::weights::{Weight, WeightToFeePolynomial, DispatchClass};

fn max() -> Weight {
AvailableBlockRatio::get() * MaximumBlockWeight::get()
fn max_normal() -> Weight {
BlockWeights::get().get(DispatchClass::Normal).max_total
.unwrap_or_else(|| BlockWeights::get().max_block)
}

fn min_multiplier() -> Multiplier {
MinimumMultiplier::get()
}

fn target() -> Weight {
TargetBlockFullness::get() * max()
TargetBlockFullness::get() * max_normal()
}

// update based on runtime impl.
Expand All @@ -69,7 +71,7 @@ mod multiplier_tests {
let previous_float = previous_float.max(min_multiplier().into_inner() as f64 / accuracy);

// maximum tx weight
let m = max() as f64;
let m = max_normal() as f64;
// block weight always truncated to max weight
let block_weight = (block_weight as f64).min(m);
let v: f64 = AdjustmentVariable::get().to_fraction();
Expand All @@ -89,7 +91,7 @@ mod multiplier_tests {
let mut t: sp_io::TestExternalities =
frame_system::GenesisConfig::default().build_storage::<Runtime>().unwrap().into();
t.execute_with(|| {
System::set_block_limits(w, 0);
System::set_block_consumed_resources(w, 0);
assertions()
});
}
Expand All @@ -102,8 +104,8 @@ mod multiplier_tests {
(100, fm.clone()),
(1000, fm.clone()),
(target(), fm.clone()),
(max() / 2, fm.clone()),
(max(), fm.clone()),
(max_normal() / 2, fm.clone()),
(max_normal(), fm.clone()),
];
test_set.into_iter().for_each(|(w, fm)| {
run_with_system_weight(w, || {
Expand Down Expand Up @@ -164,7 +166,7 @@ mod multiplier_tests {

#[test]
fn min_change_per_day() {
run_with_system_weight(max(), || {
run_with_system_weight(max_normal(), || {
let mut fm = Multiplier::one();
// See the example in the doc of `TargetedFeeAdjustment`. are at least 0.234, hence
// `fm > 1.234`.
Expand All @@ -182,7 +184,7 @@ mod multiplier_tests {
// `cargo test congested_chain_simulation -- --nocapture` to get some insight.

// almost full. The entire quota of normal transactions is taken.
let block_weight = AvailableBlockRatio::get() * max() - 100;
let block_weight = BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap() - 100;

// Default substrate weight.
let tx_weight = frame_support::weights::constants::ExtrinsicBaseWeight::get();
Expand Down Expand Up @@ -320,15 +322,19 @@ mod multiplier_tests {
10 * mb,
2147483647,
4294967295,
MaximumBlockWeight::get() / 2,
MaximumBlockWeight::get(),
BlockWeights::get().max_block / 2,
BlockWeights::get().max_block,
Weight::max_value() / 2,
Weight::max_value(),
].into_iter().for_each(|i| {
run_with_system_weight(i, || {
let next = runtime_multiplier_update(Multiplier::one());
let truth = truth_value_update(i, Multiplier::one());
assert_eq_error_rate!(truth, next, Multiplier::from_inner(50_000_000));
assert_eq_error_rate!(
truth,
next,
Multiplier::from_inner(50_000_000)
);
});
});

Expand Down
75 changes: 49 additions & 26 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,17 @@ use frame_support::{
construct_runtime, parameter_types, debug, RuntimeDebug,
weights::{
Weight, IdentityFee,
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, DispatchClass,
},
traits::{
Currency, Imbalance, KeyOwnerProofSystem, OnUnbalanced, Randomness, LockIdentifier,
U128CurrencyToVote,
},
};
use frame_system::{EnsureRoot, EnsureOneOf};
use frame_system::{
EnsureRoot, EnsureOneOf,
limits::{BlockWeights, BlockLength}
};
use frame_support::traits::InstanceFilter;
use codec::{Encode, Decode};
use sp_core::{
Expand All @@ -54,7 +57,7 @@ use sp_runtime::curve::PiecewiseLinear;
use sp_runtime::transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority};
use sp_runtime::traits::{
self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion,
ConvertInto, OpaqueKeys, NumberFor, Saturating,
ConvertInto, OpaqueKeys, NumberFor,
};
use sp_version::RuntimeVersion;
#[cfg(any(feature = "std", test))]
Expand Down Expand Up @@ -141,23 +144,47 @@ impl OnUnbalanced<NegativeImbalance> for DealWithFees {
}
}

const AVERAGE_ON_INITIALIZE_WEIGHT: Perbill = Perbill::from_percent(10);
/// We assume that ~10% of the block weight is consumed by `on_initalize` handlers.
/// This is used to limit the maximal weight of a single extrinsic.
const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used
/// by Operational extrinsics.
const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);
/// We allow for 2 seconds of compute with a 6 second average block time.
const MAXIMUM_BLOCK_WEIGHT: Weight = 2 * WEIGHT_PER_SECOND;

parameter_types! {
pub const BlockHashCount: BlockNumber = 2400;
/// We allow for 2 seconds of compute with a 6 second average block time.
pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND;
pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
/// Assume 10% of weight for average on_initialize calls.
pub MaximumExtrinsicWeight: Weight = AvailableBlockRatio::get().saturating_sub(AVERAGE_ON_INITIALIZE_WEIGHT)
* MaximumBlockWeight::get();
pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
pub const Version: RuntimeVersion = VERSION;
}

const_assert!(AvailableBlockRatio::get().deconstruct() >= AVERAGE_ON_INITIALIZE_WEIGHT.deconstruct());
pub RuntimeBlockLength: BlockLength =
BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
.base_block(BlockExecutionWeight::get())
.for_class(DispatchClass::all(), |weights| {
weights.base_extrinsic = ExtrinsicBaseWeight::get();
})
.for_class(DispatchClass::Normal, |weights| {
weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
})
.for_class(DispatchClass::Operational, |weights| {
weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
// Operational transactions have some extra reserved space, so that they
// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
weights.reserved = Some(
MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
);
})
.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
.build_or_panic();
}

const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct());

impl frame_system::Config for Runtime {
type BaseCallFilter = ();
type BlockWeights = RuntimeBlockWeights;
type BlockLength = RuntimeBlockLength;
type DbWeight = RocksDbWeight;
type Origin = Origin;
type Call = Call;
type Index = Index;
Expand All @@ -169,13 +196,6 @@ impl frame_system::Config for Runtime {
type Header = generic::Header<BlockNumber, BlakeTwo256>;
type Event = Event;
type BlockHashCount = BlockHashCount;
type MaximumBlockWeight = MaximumBlockWeight;
type DbWeight = RocksDbWeight;
type BlockExecutionWeight = BlockExecutionWeight;
type ExtrinsicBaseWeight = ExtrinsicBaseWeight;
type MaximumExtrinsicWeight = MaximumExtrinsicWeight;
type MaximumBlockLength = MaximumBlockLength;
type AvailableBlockRatio = AvailableBlockRatio;
type Version = Version;
type PalletInfo = PalletInfo;
type AccountData = pallet_balances::AccountData<Balance>;
Expand Down Expand Up @@ -277,7 +297,8 @@ impl pallet_proxy::Config for Runtime {
}

parameter_types! {
pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * MaximumBlockWeight::get();
pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
RuntimeBlockWeights::get().max_block;
pub const MaxScheduledPerBlock: u32 = 50;
}

Expand Down Expand Up @@ -438,9 +459,10 @@ parameter_types! {
pub const MaxIterations: u32 = 10;
// 0.05%. The higher the value, the more strict solution acceptance becomes.
pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
pub OffchainSolutionWeightLimit: Weight = MaximumExtrinsicWeight::get()
.saturating_sub(BlockExecutionWeight::get())
.saturating_sub(ExtrinsicBaseWeight::get());
pub OffchainSolutionWeightLimit: Weight = RuntimeBlockWeights::get()
.get(DispatchClass::Normal)
.max_extrinsic.expect("Normal extrinsics have a weight limit configured; qed")
.saturating_sub(BlockExecutionWeight::get());
}

impl pallet_staking::Config for Runtime {
Expand Down Expand Up @@ -779,7 +801,8 @@ impl pallet_im_online::Config for Runtime {
}

parameter_types! {
pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get();
pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) *
RuntimeBlockWeights::get().max_block;
}

impl pallet_offences::Config for Runtime {
Expand Down
20 changes: 5 additions & 15 deletions frame/assets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -905,12 +905,9 @@ impl<T: Config> Module<T> {
mod tests {
use super::*;

use frame_support::{
impl_outer_origin, impl_outer_event, assert_ok, assert_noop, parameter_types,
weights::Weight
};
use frame_support::{impl_outer_origin, assert_ok, assert_noop, parameter_types, impl_outer_event};
use sp_core::H256;
use sp_runtime::{Perbill, traits::{BlakeTwo256, IdentityLookup}, testing::Header};
use sp_runtime::{traits::{BlakeTwo256, IdentityLookup}, testing::Header};

mod pallet_assets {
pub use crate::Event;
Expand All @@ -932,12 +929,12 @@ mod tests {
pub struct Test;
parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const MaximumBlockWeight: Weight = 1024;
pub const MaximumBlockLength: u32 = 2 * 1024;
pub const AvailableBlockRatio: Perbill = Perbill::one();
}
impl frame_system::Config for Test {
type BaseCallFilter = ();
type BlockWeights = ();
type BlockLength = ();
type DbWeight = ();
type Origin = Origin;
type Index = u64;
type Call = ();
Expand All @@ -949,13 +946,6 @@ mod tests {
type Header = Header;
type Event = Event;
type BlockHashCount = BlockHashCount;
type MaximumBlockWeight = MaximumBlockWeight;
type DbWeight = ();
type BlockExecutionWeight = ();
type ExtrinsicBaseWeight = ();
type MaximumExtrinsicWeight = MaximumBlockWeight;
type AvailableBlockRatio = AvailableBlockRatio;
type MaximumBlockLength = MaximumBlockLength;
type Version = ();
type PalletInfo = ();
type AccountData = pallet_balances::AccountData<u64>;
Expand Down
Loading

0 comments on commit 332399d

Please sign in to comment.