Streamline frame_system weight parametrization (#6629)

* 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>
This commit is contained in:
Tomasz Drwięga
2020-12-08 13:18:34 +01:00
committed by GitHub
parent f6198b4c1b
commit 39a776cd00
66 changed files with 1275 additions and 929 deletions
+20 -14
View File
@@ -34,13 +34,15 @@ 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 {
@@ -48,7 +50,7 @@ mod multiplier_tests {
}
fn target() -> Weight {
TargetBlockFullness::get() * max()
TargetBlockFullness::get() * max_normal()
}
// update based on runtime impl.
@@ -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();
@@ -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()
});
}
@@ -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, || {
@@ -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`.
@@ -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();
@@ -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)
);
});
});
+47 -24
View File
@@ -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::{
@@ -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))]
@@ -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;
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!(AvailableBlockRatio::get().deconstruct() >= AVERAGE_ON_INITIALIZE_WEIGHT.deconstruct());
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;
@@ -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>;
@@ -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;
}
@@ -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 {
@@ -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 {