From 0c25a2ee4006f12b741828eba3d09711e17cbb6e Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi <nazar@mokrynskyi.com> Date: Wed, 25 May 2022 08:32:11 +0300 Subject: [PATCH] Introduce `WeightToFee` trait instead of `WeightToFeePolynomial` and make `WeightToFeePolynomial` implement it instead (#11415) * Introduce `WeightToFee` trait instead of `WeightToFeePolynomial` and make `WeightToFeePolynomial` implement it instead * Rename `WeightToFee::calc()` to `WeightToFee::wight_to_fee()` * Fix typo --- substrate/Cargo.lock | 2 - substrate/bin/node/executor/tests/fees.rs | 8 +- substrate/bin/node/runtime/src/impls.rs | 6 +- substrate/frame/executive/src/lib.rs | 10 +-- substrate/frame/support/src/weights.rs | 83 ++++++++++--------- .../frame/transaction-payment/Cargo.toml | 1 - .../asset-tx-payment/Cargo.toml | 1 - .../asset-tx-payment/src/tests.rs | 33 ++++---- .../frame/transaction-payment/src/lib.rs | 54 ++++-------- 9 files changed, 86 insertions(+), 112 deletions(-) diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 5b2ceb36f61..7b1a05b7067 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -5134,7 +5134,6 @@ dependencies = [ "scale-info", "serde", "serde_json", - "smallvec", "sp-core", "sp-io", "sp-runtime", @@ -6285,7 +6284,6 @@ dependencies = [ "scale-info", "serde", "serde_json", - "smallvec", "sp-core", "sp-io", "sp-runtime", diff --git a/substrate/bin/node/executor/tests/fees.rs b/substrate/bin/node/executor/tests/fees.rs index a84ce1470d8..cf794bae1d3 100644 --- a/substrate/bin/node/executor/tests/fees.rs +++ b/substrate/bin/node/executor/tests/fees.rs @@ -18,9 +18,7 @@ use codec::{Encode, Joiner}; use frame_support::{ traits::Currency, - weights::{ - constants::ExtrinsicBaseWeight, GetDispatchInfo, IdentityFee, WeightToFeePolynomial, - }, + weights::{constants::ExtrinsicBaseWeight, GetDispatchInfo, IdentityFee, WeightToFee}, }; use node_primitives::Balance; use node_runtime::{ @@ -197,13 +195,13 @@ fn transaction_fee_is_correct() { let mut balance_alice = (100 - 69) * DOLLARS; let base_weight = ExtrinsicBaseWeight::get(); - let base_fee = IdentityFee::<Balance>::calc(&base_weight); + let base_fee = IdentityFee::<Balance>::weight_to_fee(&base_weight); let length_fee = TransactionByteFee::get() * (xt.clone().encode().len() as Balance); balance_alice -= length_fee; let weight = default_transfer_call().get_dispatch_info().weight; - let weight_fee = IdentityFee::<Balance>::calc(&weight); + let weight_fee = IdentityFee::<Balance>::weight_to_fee(&weight); // we know that weight to fee multiplier is effect-less in block 1. // current weight of transfer = 200_000_000 diff --git a/substrate/bin/node/runtime/src/impls.rs b/substrate/bin/node/runtime/src/impls.rs index f73443920c2..4973aed4bd4 100644 --- a/substrate/bin/node/runtime/src/impls.rs +++ b/substrate/bin/node/runtime/src/impls.rs @@ -59,7 +59,7 @@ mod multiplier_tests { AdjustmentVariable, MinimumMultiplier, Runtime, RuntimeBlockWeights as BlockWeights, System, TargetBlockFullness, TransactionPayment, }; - use frame_support::weights::{DispatchClass, Weight, WeightToFeePolynomial}; + use frame_support::weights::{DispatchClass, Weight, WeightToFee}; fn max_normal() -> Weight { BlockWeights::get() @@ -234,7 +234,9 @@ mod multiplier_tests { fm = next; iterations += 1; let fee = - <Runtime as pallet_transaction_payment::Config>::WeightToFee::calc(&tx_weight); + <Runtime as pallet_transaction_payment::Config>::WeightToFee::weight_to_fee( + &tx_weight, + ); let adjusted_fee = fm.saturating_mul_acc_int(fee); println!( "iteration {}, new fm = {:?}. Fee at this point is: {} units / {} millicents, \ diff --git a/substrate/frame/executive/src/lib.rs b/substrate/frame/executive/src/lib.rs index 4affc26f831..55b7e926a0f 100644 --- a/substrate/frame/executive/src/lib.rs +++ b/substrate/frame/executive/src/lib.rs @@ -576,9 +576,7 @@ mod tests { ConstU32, ConstU64, ConstU8, Currency, LockIdentifier, LockableCurrency, WithdrawReasons, }, - weights::{ - ConstantMultiplier, IdentityFee, RuntimeDbWeight, Weight, WeightToFeePolynomial, - }, + weights::{ConstantMultiplier, IdentityFee, RuntimeDbWeight, Weight, WeightToFee}, }; use frame_system::{Call as SystemCall, ChainContext, LastRuntimeUpgradeInfo}; use pallet_balances::Call as BalancesCall; @@ -866,7 +864,7 @@ mod tests { .get(DispatchClass::Normal) .base_extrinsic; let fee: Balance = - <Runtime as pallet_transaction_payment::Config>::WeightToFee::calc(&weight); + <Runtime as pallet_transaction_payment::Config>::WeightToFee::weight_to_fee(&weight); let mut t = sp_io::TestExternalities::new(t); t.execute_with(|| { Executive::initialize_block(&Header::new( @@ -1153,7 +1151,9 @@ mod tests { .get(DispatchClass::Normal) .base_extrinsic; let fee: Balance = - <Runtime as pallet_transaction_payment::Config>::WeightToFee::calc(&weight); + <Runtime as pallet_transaction_payment::Config>::WeightToFee::weight_to_fee( + &weight, + ); Executive::initialize_block(&Header::new( 1, H256::default(), diff --git a/substrate/frame/support/src/weights.rs b/substrate/frame/support/src/weights.rs index fc85a031b08..a3df1994969 100644 --- a/substrate/frame/support/src/weights.rs +++ b/substrate/frame/support/src/weights.rs @@ -140,7 +140,7 @@ use codec::{Decode, Encode}; use scale_info::TypeInfo; #[cfg(feature = "std")] use serde::{Deserialize, Serialize}; -use smallvec::{smallvec, SmallVec}; +use smallvec::SmallVec; use sp_arithmetic::{ traits::{BaseArithmetic, Saturating, Unsigned}, Perbill, @@ -622,7 +622,7 @@ impl RuntimeDbWeight { } } -/// One coefficient and its position in the `WeightToFeePolynomial`. +/// One coefficient and its position in the `WeightToFee`. /// /// One term of polynomial is calculated as: /// @@ -647,6 +647,15 @@ pub struct WeightToFeeCoefficient<Balance> { /// A list of coefficients that represent one polynomial. pub type WeightToFeeCoefficients<T> = SmallVec<[WeightToFeeCoefficient<T>; 4]>; +/// A trait that describes the weight to fee calculation. +pub trait WeightToFee { + /// The type that is returned as result from calculation. + type Balance: BaseArithmetic + From<u32> + Copy + Unsigned; + + /// Calculates the fee from the passed `weight`. + fn weight_to_fee(weight: &Weight) -> Self::Balance; +} + /// A trait that describes the weight to fee calculation as polynomial. /// /// An implementor should only implement the `polynomial` function. @@ -661,12 +670,19 @@ pub trait WeightToFeePolynomial { /// that the order of coefficients is important as putting the negative coefficients /// first will most likely saturate the result to zero mid evaluation. fn polynomial() -> WeightToFeeCoefficients<Self::Balance>; +} + +impl<T> WeightToFee for T +where + T: WeightToFeePolynomial, +{ + type Balance = <Self as WeightToFeePolynomial>::Balance; /// Calculates the fee from the passed `weight` according to the `polynomial`. /// /// This should not be overriden in most circumstances. Calculation is done in the /// `Balance` type and never overflows. All evaluation is saturating. - fn calc(weight: &Weight) -> Self::Balance { + fn weight_to_fee(weight: &Weight) -> Self::Balance { Self::polynomial() .iter() .fold(Self::Balance::saturated_from(0u32), |mut acc, args| { @@ -690,30 +706,21 @@ pub trait WeightToFeePolynomial { } } -/// Implementor of `WeightToFeePolynomial` that maps one unit of weight to one unit of fee. +/// Implementor of `WeightToFee` that maps one unit of weight to one unit of fee. pub struct IdentityFee<T>(sp_std::marker::PhantomData<T>); -impl<T> WeightToFeePolynomial for IdentityFee<T> +impl<T> WeightToFee for IdentityFee<T> where T: BaseArithmetic + From<u32> + Copy + Unsigned, { type Balance = T; - fn polynomial() -> WeightToFeeCoefficients<Self::Balance> { - smallvec!(WeightToFeeCoefficient { - coeff_integer: 1u32.into(), - coeff_frac: Perbill::zero(), - negative: false, - degree: 1, - }) - } - - fn calc(weight: &Weight) -> Self::Balance { + fn weight_to_fee(weight: &Weight) -> Self::Balance { Self::Balance::saturated_from(*weight) } } -/// Implementor of [`WeightToFeePolynomial`] that uses a constant multiplier. +/// Implementor of [`WeightToFee`] that uses a constant multiplier. /// # Example /// /// ``` @@ -724,23 +731,14 @@ where /// ``` pub struct ConstantMultiplier<T, M>(sp_std::marker::PhantomData<(T, M)>); -impl<T, M> WeightToFeePolynomial for ConstantMultiplier<T, M> +impl<T, M> WeightToFee for ConstantMultiplier<T, M> where T: BaseArithmetic + From<u32> + Copy + Unsigned, M: Get<T>, { type Balance = T; - fn polynomial() -> WeightToFeeCoefficients<Self::Balance> { - smallvec!(WeightToFeeCoefficient { - coeff_integer: M::get(), - coeff_frac: Perbill::zero(), - negative: false, - degree: 1, - }) - } - - fn calc(weight: &Weight) -> Self::Balance { + fn weight_to_fee(weight: &Weight) -> Self::Balance { Self::Balance::saturated_from(*weight).saturating_mul(M::get()) } } @@ -831,6 +829,7 @@ impl PerDispatchClass<Weight> { mod tests { use super::*; use crate::{decl_module, parameter_types, traits::Get}; + use smallvec::smallvec; pub trait Config: 'static { type Origin; @@ -997,35 +996,41 @@ mod tests { #[test] fn polynomial_works() { // 100^3/2=500000 100^2*(2+1/3)=23333 700 -10000 - assert_eq!(Poly::calc(&100), 514033); + assert_eq!(Poly::weight_to_fee(&100), 514033); // 10123^3/2=518677865433 10123^2*(2+1/3)=239108634 70861 -10000 - assert_eq!(Poly::calc(&10_123), 518917034928); + assert_eq!(Poly::weight_to_fee(&10_123), 518917034928); } #[test] fn polynomial_does_not_underflow() { - assert_eq!(Poly::calc(&0), 0); - assert_eq!(Poly::calc(&10), 0); + assert_eq!(Poly::weight_to_fee(&0), 0); + assert_eq!(Poly::weight_to_fee(&10), 0); } #[test] fn polynomial_does_not_overflow() { - assert_eq!(Poly::calc(&Weight::max_value()), Balance::max_value() - 10_000); + assert_eq!(Poly::weight_to_fee(&Weight::max_value()), Balance::max_value() - 10_000); } #[test] fn identity_fee_works() { - assert_eq!(IdentityFee::<Balance>::calc(&0), 0); - assert_eq!(IdentityFee::<Balance>::calc(&50), 50); - assert_eq!(IdentityFee::<Balance>::calc(&Weight::max_value()), Balance::max_value()); + assert_eq!(IdentityFee::<Balance>::weight_to_fee(&0), 0); + assert_eq!(IdentityFee::<Balance>::weight_to_fee(&50), 50); + assert_eq!( + IdentityFee::<Balance>::weight_to_fee(&Weight::max_value()), + Balance::max_value() + ); } #[test] fn constant_fee_works() { use crate::traits::ConstU128; - assert_eq!(ConstantMultiplier::<u128, ConstU128<100u128>>::calc(&0), 0); - assert_eq!(ConstantMultiplier::<u128, ConstU128<10u128>>::calc(&50), 500); - assert_eq!(ConstantMultiplier::<u128, ConstU128<1024u128>>::calc(&16), 16384); - assert_eq!(ConstantMultiplier::<u128, ConstU128<{ u128::MAX }>>::calc(&2), u128::MAX); + assert_eq!(ConstantMultiplier::<u128, ConstU128<100u128>>::weight_to_fee(&0), 0); + assert_eq!(ConstantMultiplier::<u128, ConstU128<10u128>>::weight_to_fee(&50), 500); + assert_eq!(ConstantMultiplier::<u128, ConstU128<1024u128>>::weight_to_fee(&16), 16384); + assert_eq!( + ConstantMultiplier::<u128, ConstU128<{ u128::MAX }>>::weight_to_fee(&2), + u128::MAX + ); } } diff --git a/substrate/frame/transaction-payment/Cargo.toml b/substrate/frame/transaction-payment/Cargo.toml index 519433a8ce0..51aeeabe99d 100644 --- a/substrate/frame/transaction-payment/Cargo.toml +++ b/substrate/frame/transaction-payment/Cargo.toml @@ -18,7 +18,6 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = ] } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } serde = { version = "1.0.136", optional = true } -smallvec = "1.8.0" frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" } frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" } sp-core = { version = "6.0.0", default-features = false, path = "../../primitives/core" } diff --git a/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml b/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml index fb000dbfdb1..2d4da250212 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml +++ b/substrate/frame/transaction-payment/asset-tx-payment/Cargo.toml @@ -29,7 +29,6 @@ scale-info = { version = "2.1.1", default-features = false, features = ["derive" serde = { version = "1.0.136", optional = true } [dev-dependencies] -smallvec = "1.8.0" serde_json = "1.0.79" sp-storage = { version = "6.0.0", default-features = false, path = "../../../primitives/storage" } diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs index d72a288ac7a..5b1fa157c3f 100644 --- a/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs @@ -21,22 +21,17 @@ use frame_support::{ pallet_prelude::*, parameter_types, traits::{fungibles::Mutate, ConstU32, ConstU64, ConstU8, FindAuthor}, - weights::{ - DispatchClass, DispatchInfo, PostDispatchInfo, Weight, WeightToFeeCoefficient, - WeightToFeeCoefficients, WeightToFeePolynomial, - }, + weights::{DispatchClass, DispatchInfo, PostDispatchInfo, Weight, WeightToFee as WeightToFeeT}, ConsensusEngineId, }; use frame_system as system; use frame_system::EnsureRoot; use pallet_balances::Call as BalancesCall; use pallet_transaction_payment::CurrencyAdapter; -use smallvec::smallvec; use sp_core::H256; use sp_runtime::{ testing::Header, - traits::{BlakeTwo256, ConvertInto, IdentityLookup, StaticLookup}, - Perbill, + traits::{BlakeTwo256, ConvertInto, IdentityLookup, SaturatedConversion, StaticLookup}, }; use std::cell::RefCell; @@ -83,8 +78,8 @@ impl Get<frame_system::limits::BlockWeights> for BlockWeights { } parameter_types! { - pub static TransactionByteFee: u64 = 1; pub static WeightToFee: u64 = 1; + pub static TransactionByteFee: u64 = 1; } impl frame_system::Config for Runtime { @@ -130,23 +125,27 @@ impl pallet_balances::Config for Runtime { type ReserveIdentifier = [u8; 8]; } -impl WeightToFeePolynomial for WeightToFee { +impl WeightToFeeT for WeightToFee { + type Balance = u64; + + fn weight_to_fee(weight: &Weight) -> Self::Balance { + Self::Balance::saturated_from(*weight).saturating_mul(WEIGHT_TO_FEE.with(|v| *v.borrow())) + } +} + +impl WeightToFeeT for TransactionByteFee { type Balance = u64; - fn polynomial() -> WeightToFeeCoefficients<Self::Balance> { - smallvec![WeightToFeeCoefficient { - degree: 1, - coeff_frac: Perbill::zero(), - coeff_integer: WEIGHT_TO_FEE.with(|v| *v.borrow()), - negative: false, - }] + fn weight_to_fee(weight: &Weight) -> Self::Balance { + Self::Balance::saturated_from(*weight) + .saturating_mul(TRANSACTION_BYTE_FEE.with(|v| *v.borrow())) } } impl pallet_transaction_payment::Config for Runtime { type OnChargeTransaction = CurrencyAdapter<Balances, ()>; type WeightToFee = WeightToFee; - type LengthToFee = WeightToFee; + type LengthToFee = TransactionByteFee; type FeeMultiplierUpdate = (); type OperationalFeeMultiplier = ConstU8<5>; } diff --git a/substrate/frame/transaction-payment/src/lib.rs b/substrate/frame/transaction-payment/src/lib.rs index 45c8b8f479c..d44f8b1b894 100644 --- a/substrate/frame/transaction-payment/src/lib.rs +++ b/substrate/frame/transaction-payment/src/lib.rs @@ -66,8 +66,7 @@ use frame_support::{ dispatch::DispatchResult, traits::{EstimateCallFee, Get}, weights::{ - DispatchClass, DispatchInfo, GetDispatchInfo, Pays, PostDispatchInfo, Weight, - WeightToFeeCoefficient, WeightToFeePolynomial, + DispatchClass, DispatchInfo, GetDispatchInfo, Pays, PostDispatchInfo, Weight, WeightToFee, }, }; @@ -283,30 +282,15 @@ pub mod pallet { type OperationalFeeMultiplier: Get<u8>; /// Convert a weight value into a deductible fee based on the currency type. - type WeightToFee: WeightToFeePolynomial<Balance = BalanceOf<Self>>; + type WeightToFee: WeightToFee<Balance = BalanceOf<Self>>; /// Convert a length value into a deductible fee based on the currency type. - type LengthToFee: WeightToFeePolynomial<Balance = BalanceOf<Self>>; + type LengthToFee: WeightToFee<Balance = BalanceOf<Self>>; /// Update the multiplier of the next block, based on the previous block's weight. type FeeMultiplierUpdate: MultiplierUpdate; } - #[pallet::extra_constants] - impl<T: Config> Pallet<T> { - #[pallet::constant_name(WeightToFee)] - /// The polynomial that is applied in order to derive fee from weight. - fn weight_to_fee_polynomial() -> Vec<WeightToFeeCoefficient<BalanceOf<T>>> { - T::WeightToFee::polynomial().to_vec() - } - - /// The polynomial that is applied in order to derive fee from length. - #[pallet::constant_name(LengthToFee)] - fn length_to_fee_polynomial() -> Vec<WeightToFeeCoefficient<BalanceOf<T>>> { - T::LengthToFee::polynomial().to_vec() - } - } - #[pallet::type_value] pub fn NextFeeMultiplierOnEmpty() -> Multiplier { Multiplier::saturating_from_integer(1) @@ -533,14 +517,14 @@ where } fn length_to_fee(length: u32) -> BalanceOf<T> { - T::LengthToFee::calc(&(length as Weight)) + T::LengthToFee::weight_to_fee(&(length as Weight)) } fn weight_to_fee(weight: Weight) -> BalanceOf<T> { // cap the weight to the maximum defined in runtime, otherwise it will be the // `Bounded` maximum of its data type, which is not desired. let capped_weight = weight.min(T::BlockWeights::get().max_block); - T::WeightToFee::calc(&capped_weight) + T::WeightToFee::weight_to_fee(&capped_weight) } } @@ -776,14 +760,12 @@ mod tests { use std::cell::RefCell; use codec::Encode; - use smallvec::smallvec; use sp_core::H256; use sp_runtime::{ testing::{Header, TestXt}, traits::{BlakeTwo256, IdentityLookup, One}, transaction_validity::InvalidTransaction, - Perbill, }; use frame_support::{ @@ -791,7 +773,7 @@ mod tests { traits::{ConstU32, ConstU64, Currency, Imbalance, OnUnbalanced}, weights::{ DispatchClass, DispatchInfo, GetDispatchInfo, PostDispatchInfo, Weight, - WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial, + WeightToFee as WeightToFeeT, }, }; use frame_system as system; @@ -879,29 +861,21 @@ mod tests { type WeightInfo = (); } - impl WeightToFeePolynomial for WeightToFee { + impl WeightToFeeT for WeightToFee { type Balance = u64; - fn polynomial() -> WeightToFeeCoefficients<Self::Balance> { - smallvec![WeightToFeeCoefficient { - degree: 1, - coeff_frac: Perbill::zero(), - coeff_integer: WEIGHT_TO_FEE.with(|v| *v.borrow()), - negative: false, - }] + fn weight_to_fee(weight: &Weight) -> Self::Balance { + Self::Balance::saturated_from(*weight) + .saturating_mul(WEIGHT_TO_FEE.with(|v| *v.borrow())) } } - impl WeightToFeePolynomial for TransactionByteFee { + impl WeightToFeeT for TransactionByteFee { type Balance = u64; - fn polynomial() -> WeightToFeeCoefficients<Self::Balance> { - smallvec![WeightToFeeCoefficient { - degree: 1, - coeff_frac: Perbill::zero(), - coeff_integer: TRANSACTION_BYTE_FEE.with(|v| *v.borrow()), - negative: false, - }] + fn weight_to_fee(weight: &Weight) -> Self::Balance { + Self::Balance::saturated_from(*weight) + .saturating_mul(TRANSACTION_BYTE_FEE.with(|v| *v.borrow())) } } -- GitLab