From 7d421adf876a9c8402ee53ff73e7afa1f986fcf9 Mon Sep 17 00:00:00 2001 From: Nazar Mokrynskyi 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 --- Cargo.lock | 2 - bin/node/executor/tests/fees.rs | 8 +- bin/node/runtime/src/impls.rs | 6 +- frame/executive/src/lib.rs | 10 +-- 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/Cargo.lock b/Cargo.lock index 5b2ceb36f6152..7b1a05b7067e2 100644 --- a/Cargo.lock +++ b/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/bin/node/executor/tests/fees.rs b/bin/node/executor/tests/fees.rs index a84ce1470d877..cf794bae1d307 100644 --- a/bin/node/executor/tests/fees.rs +++ b/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::::calc(&base_weight); + let base_fee = IdentityFee::::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::::calc(&weight); + let weight_fee = IdentityFee::::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/bin/node/runtime/src/impls.rs b/bin/node/runtime/src/impls.rs index f73443920c213..4973aed4bd4fc 100644 --- a/bin/node/runtime/src/impls.rs +++ b/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 = - ::WeightToFee::calc(&tx_weight); + ::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/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 4affc26f831fd..55b7e926a0fad 100644 --- a/frame/executive/src/lib.rs +++ b/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 = - ::WeightToFee::calc(&weight); + ::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 = - ::WeightToFee::calc(&weight); + ::WeightToFee::weight_to_fee( + &weight, + ); Executive::initialize_block(&Header::new( 1, H256::default(), diff --git a/frame/support/src/weights.rs b/frame/support/src/weights.rs index fc85a031b0852..a3df199496922 100644 --- a/frame/support/src/weights.rs +++ b/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 { /// A list of coefficients that represent one polynomial. pub type WeightToFeeCoefficients = SmallVec<[WeightToFeeCoefficient; 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 + 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; +} + +impl WeightToFee for T +where + T: WeightToFeePolynomial, +{ + type Balance = ::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(sp_std::marker::PhantomData); -impl WeightToFeePolynomial for IdentityFee +impl WeightToFee for IdentityFee where T: BaseArithmetic + From + Copy + Unsigned, { type Balance = T; - fn polynomial() -> WeightToFeeCoefficients { - 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(sp_std::marker::PhantomData<(T, M)>); -impl WeightToFeePolynomial for ConstantMultiplier +impl WeightToFee for ConstantMultiplier where T: BaseArithmetic + From + Copy + Unsigned, M: Get, { type Balance = T; - fn polynomial() -> WeightToFeeCoefficients { - 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 { 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::::calc(&0), 0); - assert_eq!(IdentityFee::::calc(&50), 50); - assert_eq!(IdentityFee::::calc(&Weight::max_value()), Balance::max_value()); + assert_eq!(IdentityFee::::weight_to_fee(&0), 0); + assert_eq!(IdentityFee::::weight_to_fee(&50), 50); + assert_eq!( + IdentityFee::::weight_to_fee(&Weight::max_value()), + Balance::max_value() + ); } #[test] fn constant_fee_works() { use crate::traits::ConstU128; - assert_eq!(ConstantMultiplier::>::calc(&0), 0); - assert_eq!(ConstantMultiplier::>::calc(&50), 500); - assert_eq!(ConstantMultiplier::>::calc(&16), 16384); - assert_eq!(ConstantMultiplier::>::calc(&2), u128::MAX); + assert_eq!(ConstantMultiplier::>::weight_to_fee(&0), 0); + assert_eq!(ConstantMultiplier::>::weight_to_fee(&50), 500); + assert_eq!(ConstantMultiplier::>::weight_to_fee(&16), 16384); + assert_eq!( + ConstantMultiplier::>::weight_to_fee(&2), + u128::MAX + ); } } diff --git a/frame/transaction-payment/Cargo.toml b/frame/transaction-payment/Cargo.toml index 519433a8ce0a8..51aeeabe99db8 100644 --- a/frame/transaction-payment/Cargo.toml +++ b/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/frame/transaction-payment/asset-tx-payment/Cargo.toml b/frame/transaction-payment/asset-tx-payment/Cargo.toml index fb000dbfdb103..2d4da250212f2 100644 --- a/frame/transaction-payment/asset-tx-payment/Cargo.toml +++ b/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/frame/transaction-payment/asset-tx-payment/src/tests.rs b/frame/transaction-payment/asset-tx-payment/src/tests.rs index d72a288ac7a33..5b1fa157c3f10 100644 --- a/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/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 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 { - 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; type WeightToFee = WeightToFee; - type LengthToFee = WeightToFee; + type LengthToFee = TransactionByteFee; type FeeMultiplierUpdate = (); type OperationalFeeMultiplier = ConstU8<5>; } diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 45c8b8f479c9f..d44f8b1b894e1 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/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; /// Convert a weight value into a deductible fee based on the currency type. - type WeightToFee: WeightToFeePolynomial>; + type WeightToFee: WeightToFee>; /// Convert a length value into a deductible fee based on the currency type. - type LengthToFee: WeightToFeePolynomial>; + type LengthToFee: WeightToFee>; /// Update the multiplier of the next block, based on the previous block's weight. type FeeMultiplierUpdate: MultiplierUpdate; } - #[pallet::extra_constants] - impl Pallet { - #[pallet::constant_name(WeightToFee)] - /// The polynomial that is applied in order to derive fee from weight. - fn weight_to_fee_polynomial() -> Vec>> { - 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>> { - 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::LengthToFee::calc(&(length as Weight)) + T::LengthToFee::weight_to_fee(&(length as Weight)) } fn weight_to_fee(weight: Weight) -> BalanceOf { // 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 { - 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 { - 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())) } }