diff --git a/Cargo.lock b/Cargo.lock index 47947c00aa3..6ebaf80546d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1338,9 +1338,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "e9e8aabfac534be767c909e0690571677d49f41bd8465ae876fe043d52ba5292" dependencies = [ "jobserver", "libc", @@ -6011,9 +6011,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] @@ -6359,9 +6359,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libc-print" @@ -6867,9 +6867,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.12" +version = "1.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "fdc53a7799a7496ebc9fd29f31f7df80e83c9bda5299768af5f9e59eeea74647" dependencies = [ "cc", "pkg-config", diff --git a/common/src/pallet_tests.rs b/common/src/pallet_tests.rs index 916f314b116..572d1635ed9 100644 --- a/common/src/pallet_tests.rs +++ b/common/src/pallet_tests.rs @@ -65,13 +65,13 @@ macro_rules! impl_pallet_balances_inner { }; } -pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); +pub const NORMAL_DISPATCH_WEIGHT_RATIO: Perbill = Perbill::from_percent(75); pub const MAX_BLOCK: u64 = 250_000_000_000; frame_support::parameter_types! { pub RuntimeBlockWeights: BlockWeights = BlockWeights::with_sensible_defaults( Weight::from_parts(MAX_BLOCK, u64::MAX), - NORMAL_DISPATCH_RATIO, + NORMAL_DISPATCH_WEIGHT_RATIO, ); pub const SS58Prefix: u8 = 42; pub const DbWeight: RuntimeDbWeight = RuntimeDbWeight { read: 1_110, write: 2_300 }; diff --git a/images/time-weight-synchronization.svg b/images/time-weight-synchronization.svg index b3f6a54cb3b..0979b3c6569 100644 --- a/images/time-weight-synchronization.svg +++ b/images/time-weight-synchronization.svg @@ -1,4 +1,4 @@ -
time
time
weight
weight
deadline
deadline
max_block
max_block
soft_deadline
soft_deadline
NORMAL_DISPATCH_RATIO
NORMAL_DISPATCH_RATIO
apply extrinsics
apply extrinsics
Gear::run()
Gear::run()
block proposing
block proposing
block finalization
block finalization
Text is not SVG - cannot display
\ No newline at end of file +
time
time
weight
weight
deadline
deadline
max_block
max_block
soft_deadline
soft_deadline
NORMAL_DISPATCH_WEIGHT_RATIO
NORMAL_DISPATCH_WEIGHT_RATIO
apply extrinsics
apply extrinsics
Gear::run()
Gear::run()
block proposing
block proposing
block finalization
block finalization
Text is not SVG - cannot display
diff --git a/node/authorship/README.md b/node/authorship/README.md index 90fa1b2fd7e..a6917dc2b37 100644 --- a/node/authorship/README.md +++ b/node/authorship/README.md @@ -40,7 +40,7 @@ The finalization of the block is not supposed to be included in this time frame. In Gear we have a special pseudo-inherent that is called `Gear::run()` and has to be added at the end of each block after all the normal (or operational) extrinsics have been pushed. This pseudo-inherent is responsible for processing the message queue. -The `Runtime` specifies the so-called `NORMAL_DISPATCH_RATIO` constant that defines the share of the `DispatchClass::Normal` extrinsics in the overall block weight. In Gear this constant is set to 25% (as opposed to the default 80% in Substrate). This means that the want the `DispatchClass::Normal` extrinsics to take up to 25% of the block time, leaving the rest to `DispatchClass::Mandatory` (including the `Gear::run()`) and `DispatchClass::Operational` extrinsics. +The `Runtime` specifies the so-called `NORMAL_DISPATCH_WEIGHT_RATIO` constant that defines the share of the `DispatchClass::Normal` extrinsics in the overall block weight. In Gear this constant is set to 25% (as opposed to the default 80% in Substrate). This means that the want the `DispatchClass::Normal` extrinsics to take up to 25% of the block time, leaving the rest to `DispatchClass::Mandatory` (including the `Gear::run()`) and `DispatchClass::Operational` extrinsics.

Gear @@ -72,8 +72,8 @@ There are two main invariants the `BlockBuilder` implementation should enforce t To guarantee these invariants, we suggest the following approach: - In addition to the overall proposal "hard" deadline introduce another "hard" deadline (as opposed to the existing `soft_deadline` which has a specific meaning and will remain) to limit the normal extrinsics application time to protect ourselves from the situation when the weight for the `DispatchClass:Normal` extrinsics hasn't been exhausted while timing-wise this stage has taken more than expected. In most cases, however, this deadline is never supposed to be hit, provided the benchmarked weights of all the extrinsics are correct; - In case the normal extrinsics application stage hit the deadline, we can't anymore rely on the remaining block `gas_allowance` in the `Runtime`; if we did, the `Gear::run()` would think it has more gas to spend when it actually does. Therefore, we need to adjust the gas budget for the `Gear::run()` by passing it an explicit `Some(max_gas)` parameter; -- To calculate the extrinsic stage deadline, we can use a "relaxed" version of the `NORMAL_DISPATCH_RATIO` constant, say, 35% instead of 25%. This means that in the worst case, if we have run the extrinsics application phase for the entire 35% of the block proposal duration, we can then still let the `Gear::run()` run for 3/4 of the original proposal duration thereby expecting to exceed the ultimate deadline by 10% tops, which is still affordable given we have 1/3 of the `SlotProportion` for the block finalization and are never supposed to use up all of that. This `max_slippage` percentage can be made configurable; +- To calculate the extrinsic stage deadline, we can use a "relaxed" version of the `NORMAL_DISPATCH_WEIGHT_RATIO` constant, say, 35% instead of 25%. This means that in the worst case, if we have run the extrinsics application phase for the entire 35% of the block proposal duration, we can then still let the `Gear::run()` run for 3/4 of the original proposal duration thereby expecting to exceed the ultimate deadline by 10% tops, which is still affordable given we have 1/3 of the `SlotProportion` for the block finalization and are never supposed to use up all of that. This `max_slippage` percentage can be made configurable; - To calculate the `max_gas` for the `Gear::run()` we have to resort to heuristic knowledge of the `time` to `gas` conversion: 1 pico-second is equivalent to 1 unit of gas. Therefore, the reasonable expectation is that if we manually set the `max_gas` to `7.5*10^11`, the `Gear::run()` will run for `750 ms`, or 3/4 of the block proposal duration so that the ultimate "relaxed" deadline is not exceeded; -- Despite the `max_gas` provided explicitly, we still make the `Gear::run()` to execute against a timeout to avoid skipping the entire block. The timeout will be set to the same value in pico-seconds as the `max_gas` absolute value. If triggered, the `Gear::run()` will be dropped entirely and all the changes in the storage overlay will be reverted. However, this is a very much undesirable situation and should be avoidedm because it'll lead to the message queue inflation, higher latency and transaction cost. +- Despite the `max_gas` provided explicitly, we still make the `Gear::run()` to execute against a timeout to avoid skipping the entire block. The timeout will be set to the same value in pico-seconds as the `max_gas` absolute value. If triggered, the `Gear::run()` will be dropped entirely and all the changes in the storage overlay will be reverted. However, this is a very much undesirable situation and should be avoidedm because it'll lead to the message queue inflation, higher latency and transaction cost. The `soft_deadline` for the extrinsics application phase can be left at `50%`, as it is in the default Substrate block authorship implementation to serve the same purpose. diff --git a/node/authorship/src/authorship.rs b/node/authorship/src/authorship.rs index 4ec7d124740..7f7c610d473 100644 --- a/node/authorship/src/authorship.rs +++ b/node/authorship/src/authorship.rs @@ -89,7 +89,7 @@ pub const DEFAULT_DEADLINE_SLIPPAGE: DurationMultiplier = DurationMultiplier(0.1 /// Default extrinsics application deadline fraction used by [`Proposer`]. /// -/// Equivalent to the `NORMAL_DISPATCH_RATIO` in `Runtime` +/// Equivalent to the `NORMAL_DISPATCH_WEIGHT_RATIO` in `Runtime` /// Can be overwritten by [`ProposerFactory::set_deadline`]. pub const DEFAULT_DISPATCH_RATIO: DurationMultiplier = DurationMultiplier(0.25); diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index d7fc1655877..ab14d5c643d 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -41,12 +41,18 @@ use sp_runtime::Perbill; /// Mostly we don't produce any calculations in `on_initialize` hook, /// so it's safe to reduce from default 10 to custom 3 percents. pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(3); -pub const NORMAL_DISPATCH_RATIO_NUM: u8 = 25; -pub const GAS_LIMIT_MIN_PERCENTAGE_NUM: u8 = 100 - NORMAL_DISPATCH_RATIO_NUM; + +pub const NORMAL_DISPATCH_LENGTH_RATIO_NUM: u8 = 50; +pub const NORMAL_DISPATCH_LENGTH_RATIO: Perbill = + Perbill::from_percent(NORMAL_DISPATCH_LENGTH_RATIO_NUM as u32); + +pub const NORMAL_DISPATCH_WEIGHT_RATIO_NUM: u8 = 25; +pub const GAS_LIMIT_MIN_PERCENTAGE_NUM: u8 = 100 - NORMAL_DISPATCH_WEIGHT_RATIO_NUM; // Extrinsics with DispatchClass::Normal only account for user messages // TODO: consider making the normal extrinsics share adjustable in runtime -pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(NORMAL_DISPATCH_RATIO_NUM as u32); +pub const NORMAL_DISPATCH_WEIGHT_RATIO: Perbill = + Perbill::from_percent(NORMAL_DISPATCH_WEIGHT_RATIO_NUM as u32); /// Returns common for gear protocol `BlockWeights` depend on given max block weight. pub fn block_weights_for(maximum_block_weight: Weight) -> BlockWeights { @@ -56,14 +62,14 @@ pub fn block_weights_for(maximum_block_weight: Weight) -> BlockWeights { weights.base_extrinsic = ExtrinsicBaseWeight::get(); }) .for_class(DispatchClass::Normal, |weights| { - weights.max_total = Some(NORMAL_DISPATCH_RATIO * maximum_block_weight); + weights.max_total = Some(NORMAL_DISPATCH_WEIGHT_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); + Some(maximum_block_weight - NORMAL_DISPATCH_WEIGHT_RATIO * maximum_block_weight); }) .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) .build_or_panic() diff --git a/runtime/vara/src/lib.rs b/runtime/vara/src/lib.rs index c3bac531559..165c2ed3737 100644 --- a/runtime/vara/src/lib.rs +++ b/runtime/vara/src/lib.rs @@ -83,7 +83,8 @@ pub use runtime_common::{ RESUME_SESSION_DURATION_HOUR_FACTOR, }, impl_runtime_apis_plus_common, BlockHashCount, DealWithFees, AVERAGE_ON_INITIALIZE_RATIO, - GAS_LIMIT_MIN_PERCENTAGE_NUM, NORMAL_DISPATCH_RATIO, VALUE_PER_GAS, + GAS_LIMIT_MIN_PERCENTAGE_NUM, NORMAL_DISPATCH_LENGTH_RATIO, NORMAL_DISPATCH_WEIGHT_RATIO, + VALUE_PER_GAS, }; pub use runtime_primitives::{AccountId, Signature, VARA_SS58_PREFIX}; use runtime_primitives::{Balance, BlockNumber, Hash, Moment, Nonce}; @@ -210,7 +211,7 @@ parameter_types! { pub const SS58Prefix: u8 = VARA_SS58_PREFIX; pub RuntimeBlockWeights: BlockWeights = runtime_common::block_weights_for(MAXIMUM_BLOCK_WEIGHT); pub RuntimeBlockLength: BlockLength = - BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO); + BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_LENGTH_RATIO); } // Configure FRAME pallets to include in runtime. diff --git a/runtime/vara/src/tests.rs b/runtime/vara/src/tests.rs index cdced34b2ab..d1aaa4bba64 100644 --- a/runtime/vara/src/tests.rs +++ b/runtime/vara/src/tests.rs @@ -25,6 +25,20 @@ use runtime_common::weights::{ PagesCosts, }; +#[test] +fn normal_dispatch_length_suits_minimal() { + const MB: u32 = 1024 * 1024; + + let block_length = ::BlockLength::get(); + + // Normal dispatch class is bigger than 2 MB. + assert!(*block_length.max.get(DispatchClass::Normal) > 2 * MB); + + // Others are on maximum. + assert_eq!(*block_length.max.get(DispatchClass::Operational), 5 * MB); + assert_eq!(*block_length.max.get(DispatchClass::Mandatory), 5 * MB); +} + #[test] fn instruction_weights_heuristics_test() { let weights = InstructionWeights::::default();