diff --git a/Cargo.lock b/Cargo.lock index 14f8c87c1aa3a..c3c3e66c12e95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2472,6 +2472,7 @@ dependencies = [ "rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "safe-mix 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "sr-io 2.0.0", "sr-primitives 2.0.0", "sr-staking-primitives 2.0.0", "sr-std 2.0.0", diff --git a/core/sr-arithmetic/src/biguint.rs b/core/sr-arithmetic/src/biguint.rs index b7d93c2f0d3ca..c0836e09b301f 100644 --- a/core/sr-arithmetic/src/biguint.rs +++ b/core/sr-arithmetic/src/biguint.rs @@ -21,7 +21,7 @@ use rstd::{cmp::Ordering, ops, prelude::*, cell::RefCell, convert::TryFrom}; // A sensible value for this would be half of the dword size of the host machine. Since the // runtime is compiled to 32bit webassembly, using 32 and 64 for single and double respectively -// should yield the most performance. TODO #3745 we could benchmark this and verify. +// should yield the most performance. /// Representation of a single limb. pub type Single = u32; /// Representation of two limbs. diff --git a/core/sr-arithmetic/src/fixed64.rs b/core/sr-arithmetic/src/fixed64.rs index 3bac75898efbb..bd58e36940ae6 100644 --- a/core/sr-arithmetic/src/fixed64.rs +++ b/core/sr-arithmetic/src/fixed64.rs @@ -48,6 +48,12 @@ impl Fixed64 { DIV } + /// Consume self and return the inner value. + /// + /// This should only be used for testing. + #[cfg(any(feature = "std", test))] + pub fn into_inner(self) -> i64 { self.0 } + /// Raw constructor. Equal to `parts / 1_000_000_000`. pub fn from_parts(parts: i64) -> Self { Self(parts) diff --git a/node/executor/src/lib.rs b/node/executor/src/lib.rs index 3c97b3cd11c12..39727d1d5503e 100644 --- a/node/executor/src/lib.rs +++ b/node/executor/src/lib.rs @@ -38,9 +38,7 @@ mod tests { use super::Executor; use {balances, contracts, indices, system, timestamp}; use codec::{Encode, Decode, Joiner}; - use runtime_support::{ - Hashable, StorageValue, StorageMap, traits::Currency, - }; + use runtime_support::{Hashable, StorageValue, StorageMap, traits::Currency}; use state_machine::TestExternalities as CoreTestExternalities; use primitives::{ Blake2Hasher, NeverNativeValue, NativeOrEncoded, map, @@ -57,8 +55,9 @@ mod tests { use node_runtime::{ Header, Block, UncheckedExtrinsic, CheckedExtrinsic, Call, Runtime, Balances, BuildStorage, System, TransactionPayment, Event, TransferFee, TransactionBaseFee, TransactionByteFee, - constants::currency::*, impls::WeightToFee, + WeightFeeCoefficient, constants::currency::*, }; + use node_runtime::impls::LinearWeightToFee; use node_primitives::{Balance, Hash, BlockNumber}; use node_testing::keyring::*; use wabt; @@ -501,8 +500,6 @@ mod tests { ).0.unwrap(); t.execute_with(|| { - // NOTE: fees differ slightly in tests that execute more than one block due to the - // weight update. Hence, using `assert_eq_error_rate`. assert_eq!( Balances::total_balance(&alice()), alice_last_known_balance - 10 * DOLLARS - transfer_fee(&xt(), fm), @@ -1069,7 +1066,7 @@ mod tests { balance_alice -= length_fee; let weight = default_transfer_call().get_dispatch_info().weight; - let weight_fee = WeightToFee::convert(weight); + let weight_fee = LinearWeightToFee::::convert(weight); // we know that weight to fee multiplier is effect-less in block 1. assert_eq!(weight_fee as Balance, MILLICENTS); diff --git a/node/runtime/Cargo.toml b/node/runtime/Cargo.toml index 252a7767ea587..5a6a2b6772c1e 100644 --- a/node/runtime/Cargo.toml +++ b/node/runtime/Cargo.toml @@ -57,6 +57,9 @@ transaction-payment = { package = "srml-transaction-payment", path = "../../srml [build-dependencies] wasm-builder-runner = { package = "substrate-wasm-builder-runner", version = "1.0.4", path = "../../core/utils/wasm-builder-runner" } +[dev-dependencies] +runtime_io = { package = "sr-io", path = "../../core/sr-io" } + [features] default = ["std"] std = [ diff --git a/node/runtime/src/constants.rs b/node/runtime/src/constants.rs index ca57bdc8ba9fc..fba4c7ac79e56 100644 --- a/node/runtime/src/constants.rs +++ b/node/runtime/src/constants.rs @@ -66,19 +66,3 @@ pub mod time { pub const HOURS: BlockNumber = MINUTES * 60; pub const DAYS: BlockNumber = HOURS * 24; } - -// CRITICAL NOTE: The system module maintains two constants: a _maximum_ block weight and a _ratio_ -// of it yielding the portion which is accessible to normal transactions (reserving the rest for -// operational ones). `TARGET_BLOCK_FULLNESS` is entirely independent and the system module is not -// aware of if, nor should it care about it. This constant simply denotes on which ratio of the -// _maximum_ block weight we tweak the fees. It does NOT care about the type of the dispatch. -// -// For the system to be configured in a sane way, `TARGET_BLOCK_FULLNESS` should always be less than -// the ratio that `system` module uses to find normal transaction quota. -/// Fee-related. -pub mod fee { - pub use sr_primitives::Perbill; - - /// The block saturation level. Fees will be updates based on this value. - pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25); -} diff --git a/node/runtime/src/impls.rs b/node/runtime/src/impls.rs index 219384502032c..2e9bd38c8f822 100644 --- a/node/runtime/src/impls.rs +++ b/node/runtime/src/impls.rs @@ -19,10 +19,9 @@ use node_primitives::Balance; use sr_primitives::weights::Weight; use sr_primitives::traits::{Convert, Saturating}; -use sr_primitives::Fixed64; -use support::traits::{OnUnbalanced, Currency}; -use crate::{Balances, Authorship, MaximumBlockWeight, NegativeImbalance}; -use crate::constants::fee::TARGET_BLOCK_FULLNESS; +use sr_primitives::{Fixed64, Perbill}; +use support::traits::{OnUnbalanced, Currency, Get}; +use crate::{Balances, System, Authorship, MaximumBlockWeight, NegativeImbalance}; pub struct Author; impl OnUnbalanced for Author { @@ -47,48 +46,34 @@ impl Convert for CurrencyToVoteHandler { fn convert(x: u128) -> Balance { x * Self::factor() } } -/// Handles converting a weight scalar to a fee value, based on the scale and granularity of the -/// node's balance type. -/// -/// This should typically create a mapping between the following ranges: -/// - [0, system::MaximumBlockWeight] -/// - [Balance::min, Balance::max] -/// -/// Yet, it can be used for any other sort of change to weight-fee. Some examples being: -/// - Setting it to `0` will essentially disable the weight fee. -/// - Setting it to `1` will cause the literal `#[weight = x]` values to be charged. -/// -/// By default, substrate node will have a weight range of [0, 1_000_000_000]. -pub struct WeightToFee; -impl Convert for WeightToFee { - fn convert(x: Weight) -> Balance { +/// Convert from weight to balance via a simple coefficient multiplication +/// The associated type C encapsulates a constant in units of balance per weight +pub struct LinearWeightToFee(rstd::marker::PhantomData); + +impl> Convert for LinearWeightToFee { + fn convert(w: Weight) -> Balance { // substrate-node a weight of 10_000 (smallest non-zero weight) to be mapped to 10^7 units of // fees, hence: - Balance::from(x).saturating_mul(1_000) + let coefficient = C::get(); + Balance::from(w).saturating_mul(coefficient) } } -/// A struct that updates the weight multiplier based on the saturation level of the previous block. -/// This should typically be called once per-block. +/// Update the given multiplier based on the following formula /// -/// This assumes that weight is a numeric value in the u32 range. -/// -/// Given `TARGET_BLOCK_FULLNESS = 1/2`, a block saturation greater than 1/2 will cause the system -/// fees to slightly grow and the opposite for block saturations less than 1/2. -/// -/// Formula: -/// diff = (target_weight - current_block_weight) +/// diff = (target_weight - previous_block_weight) /// v = 0.00004 /// next_weight = weight * (1 + (v . diff) + (v . diff)^2 / 2) /// +/// Where `target_weight` must be given as the `Get` implementation of the `T` generic type. /// https://research.web3.foundation/en/latest/polkadot/Token%20Economics/#relay-chain-transaction-fees -pub struct FeeMultiplierUpdateHandler; +pub struct TargetedFeeAdjustment(rstd::marker::PhantomData); -impl Convert<(Weight, Fixed64), Fixed64> for FeeMultiplierUpdateHandler { - fn convert(previous_state: (Weight, Fixed64)) -> Fixed64 { - let (block_weight, multiplier) = previous_state; +impl> Convert for TargetedFeeAdjustment { + fn convert(multiplier: Fixed64) -> Fixed64 { + let block_weight = System::all_extrinsics_weight(); let max_weight = MaximumBlockWeight::get(); - let target_weight = (TARGET_BLOCK_FULLNESS * max_weight) as u128; + let target_weight = (T::get() * max_weight) as u128; let block_weight = block_weight as u128; // determines if the first_term is positive @@ -100,8 +85,8 @@ impl Convert<(Weight, Fixed64), Fixed64> for FeeMultiplierUpdateHandler { // 0.00004 = 4/100_000 = 40_000/10^9 let v = Fixed64::from_rational(4, 100_000); - // 0.00004^2 = 16/10^10 ~= 2/10^9. Taking the future /2 into account, then it is just 1 parts - // from a billionth. + // 0.00004^2 = 16/10^10 ~= 2/10^9. Taking the future /2 into account, then it is just 1 + // parts from a billionth. let v_squared_2 = Fixed64::from_rational(1, 1_000_000_000); let first_term = v.saturating_mul(diff); @@ -132,15 +117,16 @@ impl Convert<(Weight, Fixed64), Fixed64> for FeeMultiplierUpdateHandler { mod tests { use super::*; use sr_primitives::weights::Weight; + use sr_primitives::assert_eq_error_rate; use crate::{MaximumBlockWeight, AvailableBlockRatio, Runtime}; - use crate::constants::currency::*; + use crate::{constants::currency::*, TransactionPayment, TargetBlockFullness}; fn max() -> Weight { MaximumBlockWeight::get() } fn target() -> Weight { - TARGET_BLOCK_FULLNESS * max() + TargetBlockFullness::get() * max() } // poc reference implementation. @@ -155,50 +141,68 @@ mod tests { // Current saturation in terms of weight let s = block_weight; - let fm = (v * (s/m - ss/m)) + (v.powi(2) * (s/m - ss/m).powi(2)) / 2.0; - let addition_fm = Fixed64::from_parts((fm * 1_000_000_000_f32) as i64); + let fm = v * (s/m - ss/m) + v.powi(2) * (s/m - ss/m).powi(2) / 2.0; + let addition_fm = Fixed64::from_parts((fm * 1_000_000_000_f32).round() as i64); previous.saturating_add(addition_fm) } - fn fm(parts: i64) -> Fixed64 { + fn feemul(parts: i64) -> Fixed64 { Fixed64::from_parts(parts) } + fn run_with_system_weight(w: Weight, assertions: F) where F: Fn() -> () { + let mut t: runtime_io::TestExternalities = + system::GenesisConfig::default().build_storage::().unwrap().into(); + t.execute_with(|| { + System::set_block_limits(w, 0); + assertions() + }); + } + #[test] fn fee_multiplier_update_poc_works() { let fm = Fixed64::from_rational(0, 1); let test_set = vec![ - // TODO: this has a rounding error and fails. - // (0, fm.clone()), + (0, fm.clone()), (100, fm.clone()), (target(), fm.clone()), (max() / 2, fm.clone()), (max(), fm.clone()), ]; test_set.into_iter().for_each(|(w, fm)| { - assert_eq!( - fee_multiplier_update(w, fm), - FeeMultiplierUpdateHandler::convert((w, fm)), - "failed for weight {} and prev fm {:?}", - w, - fm, - ); + run_with_system_weight(w, || { + assert_eq_error_rate!( + fee_multiplier_update(w, fm).into_inner(), + TargetedFeeAdjustment::::convert(fm).into_inner(), + 5, + ); + }) }) } #[test] fn empty_chain_simulation() { // just a few txs per_block. - let block_weight = 1000; - let mut fm = Fixed64::default(); - let mut iterations: u64 = 0; - loop { - let next = FeeMultiplierUpdateHandler::convert((block_weight, fm)); - fm = next; - if fm == Fixed64::from_rational(-1, 1) { break; } - iterations += 1; - } - println!("iteration {}, new fm = {:?}. Weight fee is now zero", iterations, fm); + let block_weight = 0; + run_with_system_weight(block_weight, || { + let mut fm = Fixed64::default(); + let mut iterations: u64 = 0; + loop { + let next = TargetedFeeAdjustment::::convert(fm); + fm = next; + if fm == Fixed64::from_rational(-1, 1) { break; } + iterations += 1; + } + println!("iteration {}, new fm = {:?}. Weight fee is now zero", iterations, fm); + assert!(iterations > 50_000, "This assertion is just a warning; Don't panic. \ + Current substrate/polkadot node are configured with a _slow adjusting fee_ \ + mechanism. Hence, it is really unlikely that fees collapse to zero even on an \ + empty chain in less than at least of couple of thousands of empty blocks. But this \ + simulation indicates that fees collapsed to zero after {} almost-empty blocks. \ + Check it", + iterations, + ); + }) } #[test] @@ -207,100 +211,116 @@ mod 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(); - - // default minimum substrate weight - let tx_weight = 10_000u32; - - // initial value of system - let mut fm = Fixed64::default(); - assert_eq!(fm, Fixed64::from_parts(0)); - - let mut iterations: u64 = 0; - loop { - let next = FeeMultiplierUpdateHandler::convert((block_weight, fm)); - if fm == next { break; } - fm = next; - iterations += 1; - let fee = ::WeightToFee::convert(tx_weight); - let adjusted_fee = fm.saturated_multiply_accumulate(fee); - println!( - "iteration {}, new fm = {:?}. Fee at this point is: \ - {} units, {} millicents, {} cents, {} dollars", - iterations, - fm, - adjusted_fee, - adjusted_fee / MILLICENTS, - adjusted_fee / CENTS, - adjusted_fee / DOLLARS - ); - } + let block_weight = AvailableBlockRatio::get() * max() - 100; + + // Default substrate minimum. + let tx_weight = 10_000; + + run_with_system_weight(block_weight, || { + // initial value configured on module + let mut fm = Fixed64::default(); + assert_eq!(fm, TransactionPayment::next_fee_multiplier()); + + let mut iterations: u64 = 0; + loop { + let next = TargetedFeeAdjustment::::convert(fm); + // if no change, panic. This should never happen in this case. + if fm == next { panic!("The fee should ever increase"); } + fm = next; + iterations += 1; + let fee = ::WeightToFee::convert(tx_weight); + let adjusted_fee = fm.saturated_multiply_accumulate(fee); + println!( + "iteration {}, new fm = {:?}. Fee at this point is: {} units / {} millicents, \ + {} cents, {} dollars", + iterations, + fm, + adjusted_fee, + adjusted_fee / MILLICENTS, + adjusted_fee / CENTS, + adjusted_fee / DOLLARS, + ); + } + }); } #[test] fn stateless_weight_mul() { - // Light block. Fee is reduced a little. - assert_eq!( - FeeMultiplierUpdateHandler::convert((target() / 4, Fixed64::default())), - fm(-7500) - ); - // a bit more. Fee is decreased less, meaning that the fee increases as the block grows. - assert_eq!( - FeeMultiplierUpdateHandler::convert((target() / 2, Fixed64::default())), - fm(-5000) - ); - // ideal. Original fee. No changes. - assert_eq!( - FeeMultiplierUpdateHandler::convert((target(), Fixed64::default())), - fm(0) - ); - // // More than ideal. Fee is increased. - assert_eq!( - FeeMultiplierUpdateHandler::convert(((target() * 2), Fixed64::default())), - fm(10000) - ); + run_with_system_weight(target() / 4, || { + // Light block. Fee is reduced a little. + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(-7500), + ); + }); + run_with_system_weight(target() / 2, || { + // a bit more. Fee is decreased less, meaning that the fee increases as the block grows. + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(-5000), + ); + + }); + run_with_system_weight(target(), || { + // ideal. Original fee. No changes. + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(0), + ); + }); + run_with_system_weight(target() * 2, || { + // // More than ideal. Fee is increased. + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(10000), + ); + }); } #[test] fn stateful_weight_mul_grow_to_infinity() { - assert_eq!( - FeeMultiplierUpdateHandler::convert((target() * 2, Fixed64::default())), - fm(10000) - ); - assert_eq!( - FeeMultiplierUpdateHandler::convert((target() * 2, fm(10000))), - fm(20000) - ); - assert_eq!( - FeeMultiplierUpdateHandler::convert((target() * 2, fm(20000))), - fm(30000) - ); - // ... - assert_eq!( - FeeMultiplierUpdateHandler::convert((target() * 2, fm(1_000_000_000))), - fm(1_000_000_000 + 10000) - ); + run_with_system_weight(target() * 2, || { + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(10000) + ); + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(10000)), + feemul(20000) + ); + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(20000)), + feemul(30000) + ); + // ... + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(1_000_000_000)), + feemul(1_000_000_000 + 10000) + ); + }); } #[test] fn stateful_weight_mil_collapse_to_minus_one() { - assert_eq!( - FeeMultiplierUpdateHandler::convert((0, Fixed64::default())), - fm(-10000) - ); - assert_eq!( - FeeMultiplierUpdateHandler::convert((0, fm(-10000))), - fm(-20000) - ); - assert_eq!( - FeeMultiplierUpdateHandler::convert((0, fm(-20000))), - fm(-30000) - ); - // ... - assert_eq!( - FeeMultiplierUpdateHandler::convert((0, fm(1_000_000_000 * -1))), - fm(-1_000_000_000) - ); + run_with_system_weight(0, || { + assert_eq!( + TargetedFeeAdjustment::::convert(Fixed64::default()), + feemul(-10000) + ); + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(-10000)), + feemul(-20000) + ); + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(-20000)), + feemul(-30000) + ); + // ... + assert_eq!( + TargetedFeeAdjustment::::convert(feemul(1_000_000_000 * -1)), + feemul(-1_000_000_000) + ); + }) } #[test] @@ -309,6 +329,7 @@ mod tests { let mb = kb * kb; let max_fm = Fixed64::from_natural(i64::max_value()); + // check that for all values it can compute, correctly. vec![ 0, 1, @@ -322,7 +343,11 @@ mod tests { Weight::max_value() / 2, Weight::max_value() ].into_iter().for_each(|i| { - FeeMultiplierUpdateHandler::convert((i, Fixed64::default())); + run_with_system_weight(i, || { + let next = TargetedFeeAdjustment::::convert(Fixed64::default()); + let truth = fee_multiplier_update(i, Fixed64::default()); + assert_eq_error_rate!(truth.into_inner(), next.into_inner(), 5); + }); }); // Some values that are all above the target and will cause an increase. @@ -330,12 +355,11 @@ mod tests { vec![t + 100, t * 2, t * 4] .into_iter() .for_each(|i| { - let fm = FeeMultiplierUpdateHandler::convert(( - i, - max_fm - )); - // won't grow. The convert saturates everything. - assert_eq!(fm, max_fm); + run_with_system_weight(i, || { + let fm = TargetedFeeAdjustment::::convert(max_fm); + // won't grow. The convert saturates everything. + assert_eq!(fm, max_fm); + }) }); } } diff --git a/node/runtime/src/lib.rs b/node/runtime/src/lib.rs index d7008dd893276..9097dd22a3c05 100644 --- a/node/runtime/src/lib.rs +++ b/node/runtime/src/lib.rs @@ -64,7 +64,7 @@ pub use staking::StakerStatus; /// Implementations of some helper traits passed into runtime modules as associated types. pub mod impls; -use impls::{CurrencyToVoteHandler, FeeMultiplierUpdateHandler, Author, WeightToFee}; +use impls::{CurrencyToVoteHandler, Author, LinearWeightToFee, TargetedFeeAdjustment}; /// Constant values used within the runtime. pub mod constants; @@ -109,9 +109,9 @@ pub type DealWithFees = SplitTwoWays< parameter_types! { pub const BlockHashCount: BlockNumber = 250; pub const MaximumBlockWeight: Weight = 1_000_000_000; - pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); pub const MaximumBlockLength: u32 = 5 * 1024 * 1024; pub const Version: RuntimeVersion = VERSION; + pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75); } impl system::Trait for Runtime { @@ -176,6 +176,10 @@ impl balances::Trait for Runtime { parameter_types! { pub const TransactionBaseFee: Balance = 1 * CENTS; pub const TransactionByteFee: Balance = 10 * MILLICENTS; + // setting this to zero will disable the weight fee. + pub const WeightFeeCoefficient: Balance = 1_000; + // for a sane configuration, this should always be less than `AvailableBlockRatio`. + pub const TargetBlockFullness: Perbill = Perbill::from_percent(25); } impl transaction_payment::Trait for Runtime { @@ -183,8 +187,8 @@ impl transaction_payment::Trait for Runtime { type OnTransactionPayment = DealWithFees; type TransactionBaseFee = TransactionBaseFee; type TransactionByteFee = TransactionByteFee; - type WeightToFee = WeightToFee; - type FeeMultiplierUpdate = FeeMultiplierUpdateHandler; + type WeightToFee = LinearWeightToFee; + type FeeMultiplierUpdate = TargetedFeeAdjustment; } parameter_types! { diff --git a/srml/system/src/lib.rs b/srml/system/src/lib.rs index c9dcca53cb4ad..87c38096ab934 100644 --- a/srml/system/src/lib.rs +++ b/srml/system/src/lib.rs @@ -157,15 +157,17 @@ pub fn extrinsics_data_root(xts: Vec>) -> H::Output { pub trait Trait: 'static + Eq + Clone { /// The aggregated `Origin` type used by dispatchable calls. - type Origin: Into, Self::Origin>> + From>; + type Origin: + Into, Self::Origin>> + From>; /// The aggregated `Call` type. type Call: Debug; - /// Account index (aka nonce) type. This stores the number of previous transactions associated with a sender - /// account. + /// Account index (aka nonce) type. This stores the number of previous transactions associated + /// with a sender account. type Index: - Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + SimpleArithmetic + Copy; + Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + SimpleArithmetic + + Copy; /// The block number type used by the runtime. type BlockNumber: @@ -181,13 +183,15 @@ pub trait Trait: 'static + Eq + Clone { type Hashing: Hash; /// The user account identifier type for the runtime. - type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord + Default; + type AccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord + + Default; /// Converting trait to take a source type and convert to `AccountId`. /// - /// Used to define the type and conversion mechanism for referencing accounts in transactions. It's perfectly - /// reasonable for this to be an identity conversion (with the source type being `AccountId`), but other modules - /// (e.g. Indices module) may provide more functional/efficient alternatives. + /// Used to define the type and conversion mechanism for referencing accounts in transactions. + /// It's perfectly reasonable for this to be an identity conversion (with the source type being + /// `AccountId`), but other modules (e.g. Indices module) may provide more functional/efficient + /// alternatives. type Lookup: StaticLookup; /// The block header. @@ -701,6 +705,13 @@ impl Module { >::put(n); } + /// Set the current block weight. This should only be used in some integration tests. + #[cfg(any(feature = "std", test))] + pub fn set_block_limits(weight: Weight, len: usize) { + AllExtrinsicsWeight::put(weight); + AllExtrinsicsLen::put(len as u32); + } + /// Return the chain's current runtime version. pub fn runtime_version() -> RuntimeVersion { T::Version::get() } diff --git a/srml/transaction-payment/src/lib.rs b/srml/transaction-payment/src/lib.rs index ab120322f6b7c..5ad5c650af8a0 100644 --- a/srml/transaction-payment/src/lib.rs +++ b/srml/transaction-payment/src/lib.rs @@ -70,8 +70,7 @@ pub trait Trait: system::Trait { type WeightToFee: Convert>; /// Update the multiplier of the next block, based on the previous block's weight. - // TODO: maybe this does not need previous weight and can just read it - type FeeMultiplierUpdate: Convert<(Weight, Multiplier), Multiplier>; + type FeeMultiplierUpdate: Convert; } decl_storage! { @@ -89,9 +88,8 @@ decl_module! { const TransactionByteFee: BalanceOf = T::TransactionByteFee::get(); fn on_finalize() { - let current_weight = >::all_extrinsics_weight(); NextFeeMultiplier::mutate(|fm| { - *fm = T::FeeMultiplierUpdate::convert((current_weight, *fm)) + *fm = T::FeeMultiplierUpdate::convert(*fm) }); } }