From 6a89f988d09a69fca8b72a480db6e4c6f44be1d5 Mon Sep 17 00:00:00 2001 From: koushiro Date: Tue, 7 Feb 2023 17:57:42 +0800 Subject: [PATCH] improve weight per gas calculation --- template/runtime/src/lib.rs | 42 ++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/template/runtime/src/lib.rs b/template/runtime/src/lib.rs index e7b9c9bb69..7a3e2ead0f 100644 --- a/template/runtime/src/lib.rs +++ b/template/runtime/src/lib.rs @@ -35,7 +35,7 @@ use frame_support::weights::constants::RocksDbWeight as RuntimeDbWeight; use frame_support::{ construct_runtime, parameter_types, traits::{ConstU32, ConstU8, FindAuthor, KeyOwnerProofSystem, OnTimestampSet}, - weights::{constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, IdentityFee, Weight}, + weights::{constants::WEIGHT_REF_TIME_PER_MILLIS, ConstantMultiplier, IdentityFee, Weight}, }; use pallet_grandpa::{ fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList, @@ -136,9 +136,12 @@ pub fn native_version() -> sp_version::NativeVersion { } const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); -/// We allow for 2 seconds of compute with a 6 second average block time. -pub const MAXIMUM_BLOCK_WEIGHT: Weight = - Weight::from_parts(2u64 * WEIGHT_REF_TIME_PER_SECOND, u64::MAX); +/// We allow for 2000ms of compute with a 6 second average block time. +pub const WEIGHT_MILLISECS_PER_BLOCK: u64 = 2000; +pub const MAXIMUM_BLOCK_WEIGHT: Weight = Weight::from_parts( + WEIGHT_MILLISECS_PER_BLOCK * WEIGHT_REF_TIME_PER_MILLIS, + u64::MAX, +); pub const MAXIMUM_BLOCK_LENGTH: u32 = 5 * 1024 * 1024; parameter_types! { @@ -312,11 +315,36 @@ impl> FindAuthor for FindAuthorTruncated { } } -const WEIGHT_PER_GAS: u64 = 20_000; +/// `WeightPerGas` is an approximate ratio of the amount of Weight per Gas. +/// u64 works for approximations because Weight is a very small unit compared to gas. +/// +/// `GAS_PER_MILLIS * WEIGHT_MILLIS_PER_BLOCK * TXN_RATIO ~= BLOCK_GAS_LIMIT` +/// `WEIGHT_PER_GAS = WEIGHT_REF_TIME_PER_MILLIS / GAS_PER_MILLIS +/// = WEIGHT_REF_TIME_PER_MILLIS / (BLOCK_GAS_LIMIT / TXN_RATIO / WEIGHT_MILLIS_PER_BLOCK) +/// = TXN_RATIO * (WEIGHT_REF_TIME_PER_MILLIS * WEIGHT_MILLIS_PER_BLOCK) / BLOCK_GAS_LIMIT` +/// +/// For example, given the 2000ms Weight, from which 75% only are used for transactions, +/// the total EVM execution gas limit is `GAS_PER_MILLIS * 2000 * 75% = BLOCK_GAS_LIMIT`. +pub fn weight_per_gas( + block_gas_limit: u64, + txn_ratio: Perbill, + weight_millis_per_block: u64, +) -> u64 { + let weight_per_block = WEIGHT_REF_TIME_PER_MILLIS.saturating_mul(weight_millis_per_block); + let weight_per_gas = (txn_ratio * weight_per_block).saturating_div(block_gas_limit); + assert!( + weight_per_gas >= 1, + "WeightPerGas must greater than or equal with 1" + ); + weight_per_gas +} + +const BLOCK_GAS_LIMIT: u64 = 75_000_000; + parameter_types! { - pub BlockGasLimit: U256 = U256::from(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT.ref_time() / WEIGHT_PER_GAS); + pub BlockGasLimit: U256 = U256::from(BLOCK_GAS_LIMIT); pub PrecompilesValue: FrontierPrecompiles = FrontierPrecompiles::<_>::new(); - pub WeightPerGas: Weight = Weight::from_ref_time(WEIGHT_PER_GAS); + pub WeightPerGas: Weight = Weight::from_ref_time(weight_per_gas(BLOCK_GAS_LIMIT, NORMAL_DISPATCH_RATIO, WEIGHT_MILLISECS_PER_BLOCK)); } impl pallet_evm::Config for Runtime {