mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 04:11:07 +00:00
Apply WeightToFeePolynomials to pallet_transaction_payment's length fee (#10785)
* Apply WeightToFeePolynomials to length fee * Remove TransactionByteFee * Add test cases for ConstantModifierFee * Restore import * Use pallet::constant_name * Remove irrelevant TODO comment * Update frame/support/src/weights.rs * Update frame/transaction-payment/src/lib.rs * Update frame/transaction-payment/src/lib.rs * Update frame/transaction-payment/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * s/ConstantModifierFee/ConstantMultiplier/ * Impl LengthToFee for test configs * fmt * Remove unused import * Impl WeightToFeePolynomial for byte fee in ExtBuilder * Remove unused import * fix doc Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
@@ -249,15 +249,11 @@ impl pallet_balances::Config for Runtime {
|
||||
type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const TransactionByteFee: Balance = 1;
|
||||
}
|
||||
|
||||
impl pallet_transaction_payment::Config for Runtime {
|
||||
type OnChargeTransaction = CurrencyAdapter<Balances, ()>;
|
||||
type TransactionByteFee = TransactionByteFee;
|
||||
type OperationalFeeMultiplier = ConstU8<5>;
|
||||
type WeightToFee = IdentityFee<Balance>;
|
||||
type LengthToFee = IdentityFee<Balance>;
|
||||
type FeeMultiplierUpdate = ();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ use frame_support::{
|
||||
},
|
||||
weights::{
|
||||
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
|
||||
DispatchClass, IdentityFee, Weight,
|
||||
ConstantMultiplier, DispatchClass, IdentityFee, Weight,
|
||||
},
|
||||
PalletId, RuntimeDebug,
|
||||
};
|
||||
@@ -444,9 +444,9 @@ parameter_types! {
|
||||
|
||||
impl pallet_transaction_payment::Config for Runtime {
|
||||
type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees>;
|
||||
type TransactionByteFee = TransactionByteFee;
|
||||
type OperationalFeeMultiplier = OperationalFeeMultiplier;
|
||||
type WeightToFee = IdentityFee<Balance>;
|
||||
type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
|
||||
type FeeMultiplierUpdate =
|
||||
TargetedFeeAdjustment<Self, TargetBlockFullness, AdjustmentVariable, MinimumMultiplier>;
|
||||
}
|
||||
|
||||
@@ -78,9 +78,9 @@ impl frame_system::Config for Test {
|
||||
|
||||
impl pallet_transaction_payment::Config for Test {
|
||||
type OnChargeTransaction = CurrencyAdapter<Pallet<Test>, ()>;
|
||||
type TransactionByteFee = ConstU64<1>;
|
||||
type OperationalFeeMultiplier = ConstU8<5>;
|
||||
type WeightToFee = IdentityFee<u64>;
|
||||
type LengthToFee = IdentityFee<u64>;
|
||||
type FeeMultiplierUpdate = ();
|
||||
}
|
||||
|
||||
|
||||
@@ -79,9 +79,9 @@ impl frame_system::Config for Test {
|
||||
|
||||
impl pallet_transaction_payment::Config for Test {
|
||||
type OnChargeTransaction = CurrencyAdapter<Pallet<Test>, ()>;
|
||||
type TransactionByteFee = ConstU64<1>;
|
||||
type OperationalFeeMultiplier = ConstU8<5>;
|
||||
type WeightToFee = IdentityFee<u64>;
|
||||
type LengthToFee = IdentityFee<u64>;
|
||||
type FeeMultiplierUpdate = ();
|
||||
}
|
||||
|
||||
|
||||
@@ -85,9 +85,9 @@ impl frame_system::Config for Test {
|
||||
|
||||
impl pallet_transaction_payment::Config for Test {
|
||||
type OnChargeTransaction = CurrencyAdapter<Pallet<Test>, ()>;
|
||||
type TransactionByteFee = ConstU64<1>;
|
||||
type OperationalFeeMultiplier = ConstU8<5>;
|
||||
type WeightToFee = IdentityFee<u64>;
|
||||
type LengthToFee = IdentityFee<u64>;
|
||||
type FeeMultiplierUpdate = ();
|
||||
}
|
||||
|
||||
|
||||
@@ -576,7 +576,9 @@ mod tests {
|
||||
ConstU32, ConstU64, ConstU8, Currency, LockIdentifier, LockableCurrency,
|
||||
WithdrawReasons,
|
||||
},
|
||||
weights::{IdentityFee, RuntimeDbWeight, Weight, WeightToFeePolynomial},
|
||||
weights::{
|
||||
ConstantMultiplier, IdentityFee, RuntimeDbWeight, Weight, WeightToFeePolynomial,
|
||||
},
|
||||
};
|
||||
use frame_system::{Call as SystemCall, ChainContext, LastRuntimeUpgradeInfo};
|
||||
use pallet_balances::Call as BalancesCall;
|
||||
@@ -787,9 +789,9 @@ mod tests {
|
||||
}
|
||||
impl pallet_transaction_payment::Config for Runtime {
|
||||
type OnChargeTransaction = CurrencyAdapter<Balances, ()>;
|
||||
type TransactionByteFee = TransactionByteFee;
|
||||
type OperationalFeeMultiplier = ConstU8<5>;
|
||||
type WeightToFee = IdentityFee<Balance>;
|
||||
type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
|
||||
type FeeMultiplierUpdate = ();
|
||||
}
|
||||
impl custom::Config for Runtime {}
|
||||
|
||||
@@ -132,7 +132,10 @@ mod extrinsic_weights;
|
||||
mod paritydb_weights;
|
||||
mod rocksdb_weights;
|
||||
|
||||
use crate::dispatch::{DispatchError, DispatchErrorWithPostInfo, DispatchResultWithPostInfo};
|
||||
use crate::{
|
||||
dispatch::{DispatchError, DispatchErrorWithPostInfo, DispatchResultWithPostInfo},
|
||||
traits::Get,
|
||||
};
|
||||
use codec::{Decode, Encode};
|
||||
use scale_info::TypeInfo;
|
||||
#[cfg(feature = "std")]
|
||||
@@ -709,6 +712,34 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementor of [`WeightToFeePolynomial`] that uses a constant multiplier.
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use frame_support::traits::ConstU128;
|
||||
/// # use frame_support::weights::ConstantMultiplier;
|
||||
/// // Results in a multiplier of 10 for each unit of weight (or length)
|
||||
/// type LengthToFee = ConstantMultiplier::<u128, ConstU128<10u128>>;
|
||||
/// ```
|
||||
pub struct ConstantMultiplier<T, M>(sp_std::marker::PhantomData<(T, M)>);
|
||||
|
||||
impl<T, M> WeightToFeePolynomial 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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct holding value for each `DispatchClass`.
|
||||
#[derive(Clone, Eq, PartialEq, Default, RuntimeDebug, Encode, Decode, TypeInfo)]
|
||||
pub struct PerDispatchClass<T> {
|
||||
@@ -983,4 +1014,13 @@ mod tests {
|
||||
assert_eq!(IdentityFee::<Balance>::calc(&50), 50);
|
||||
assert_eq!(IdentityFee::<Balance>::calc(&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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,8 +145,8 @@ impl WeightToFeePolynomial for WeightToFee {
|
||||
|
||||
impl pallet_transaction_payment::Config for Runtime {
|
||||
type OnChargeTransaction = CurrencyAdapter<Balances, ()>;
|
||||
type TransactionByteFee = TransactionByteFee;
|
||||
type WeightToFee = WeightToFee;
|
||||
type LengthToFee = WeightToFee;
|
||||
type FeeMultiplierUpdate = ();
|
||||
type OperationalFeeMultiplier = ConstU8<5>;
|
||||
}
|
||||
|
||||
@@ -260,10 +260,6 @@ pub mod pallet {
|
||||
/// might be refunded. In the end the fees can be deposited.
|
||||
type OnChargeTransaction: OnChargeTransaction<Self>;
|
||||
|
||||
/// The fee to be paid for making a transaction; the per-byte portion.
|
||||
#[pallet::constant]
|
||||
type TransactionByteFee: Get<BalanceOf<Self>>;
|
||||
|
||||
/// A fee mulitplier for `Operational` extrinsics to compute "virtual tip" to boost their
|
||||
/// `priority`
|
||||
///
|
||||
@@ -291,6 +287,9 @@ pub mod pallet {
|
||||
/// Convert a weight value into a deductible fee based on the currency type.
|
||||
type WeightToFee: WeightToFeePolynomial<Balance = BalanceOf<Self>>;
|
||||
|
||||
/// Convert a length value into a deductible fee based on the currency type.
|
||||
type LengthToFee: WeightToFeePolynomial<Balance = BalanceOf<Self>>;
|
||||
|
||||
/// Update the multiplier of the next block, based on the previous block's weight.
|
||||
type FeeMultiplierUpdate: MultiplierUpdate;
|
||||
}
|
||||
@@ -302,6 +301,12 @@ pub mod pallet {
|
||||
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]
|
||||
@@ -510,25 +515,18 @@ where
|
||||
class: DispatchClass,
|
||||
) -> FeeDetails<BalanceOf<T>> {
|
||||
if pays_fee == Pays::Yes {
|
||||
let len = <BalanceOf<T>>::from(len);
|
||||
let per_byte = T::TransactionByteFee::get();
|
||||
|
||||
// length fee. this is not adjusted.
|
||||
let fixed_len_fee = per_byte.saturating_mul(len);
|
||||
|
||||
// the adjustable part of the fee.
|
||||
let unadjusted_weight_fee = Self::weight_to_fee(weight);
|
||||
let multiplier = Self::next_fee_multiplier();
|
||||
// final adjusted weight fee.
|
||||
let adjusted_weight_fee = multiplier.saturating_mul_int(unadjusted_weight_fee);
|
||||
|
||||
// length fee. this is adjusted via `LengthToFee`.
|
||||
let len_fee = Self::length_to_fee(len);
|
||||
|
||||
let base_fee = Self::weight_to_fee(T::BlockWeights::get().get(class).base_extrinsic);
|
||||
FeeDetails {
|
||||
inclusion_fee: Some(InclusionFee {
|
||||
base_fee,
|
||||
len_fee: fixed_len_fee,
|
||||
adjusted_weight_fee,
|
||||
}),
|
||||
inclusion_fee: Some(InclusionFee { base_fee, len_fee, adjusted_weight_fee }),
|
||||
tip,
|
||||
}
|
||||
} else {
|
||||
@@ -536,6 +534,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn length_to_fee(length: u32) -> BalanceOf<T> {
|
||||
T::LengthToFee::calc(&(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.
|
||||
@@ -835,8 +837,8 @@ mod tests {
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub static TransactionByteFee: u64 = 1;
|
||||
pub static WeightToFee: u64 = 1;
|
||||
pub static TransactionByteFee: u64 = 1;
|
||||
pub static OperationalFeeMultiplier: u8 = 5;
|
||||
}
|
||||
|
||||
@@ -892,6 +894,19 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
impl WeightToFeePolynomial 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,
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static TIP_UNBALANCED_AMOUNT: RefCell<u64> = RefCell::new(0);
|
||||
static FEE_UNBALANCED_AMOUNT: RefCell<u64> = RefCell::new(0);
|
||||
@@ -913,9 +928,9 @@ mod tests {
|
||||
|
||||
impl Config for Runtime {
|
||||
type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees>;
|
||||
type TransactionByteFee = TransactionByteFee;
|
||||
type OperationalFeeMultiplier = OperationalFeeMultiplier;
|
||||
type WeightToFee = WeightToFee;
|
||||
type LengthToFee = TransactionByteFee;
|
||||
type FeeMultiplierUpdate = ();
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ use sp_runtime::{
|
||||
use sp_std::{fmt::Debug, marker::PhantomData};
|
||||
|
||||
use frame_support::{
|
||||
traits::{Currency, ExistenceRequirement, Get, Imbalance, OnUnbalanced, WithdrawReasons},
|
||||
traits::{Currency, ExistenceRequirement, Imbalance, OnUnbalanced, WithdrawReasons},
|
||||
unsigned::TransactionValidityError,
|
||||
};
|
||||
|
||||
@@ -73,7 +73,6 @@ pub struct CurrencyAdapter<C, OU>(PhantomData<(C, OU)>);
|
||||
impl<T, C, OU> OnChargeTransaction<T> for CurrencyAdapter<C, OU>
|
||||
where
|
||||
T: Config,
|
||||
T::TransactionByteFee: Get<<C as Currency<<T as frame_system::Config>::AccountId>>::Balance>,
|
||||
C: Currency<<T as frame_system::Config>::AccountId>,
|
||||
C::PositiveImbalance: Imbalance<
|
||||
<C as Currency<<T as frame_system::Config>::AccountId>>::Balance,
|
||||
|
||||
Reference in New Issue
Block a user