Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Apply WeightToFeePolynomials to pallet_transaction_payment's length fee #10785

Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions bin/node-template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ();
}

Expand Down
4 changes: 2 additions & 2 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use frame_support::{
},
weights::{
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
DispatchClass, IdentityFee, Weight,
DispatchClass, IdentityFee, ConstantModifierFee, Weight,
},
PalletId, RuntimeDebug,
};
Expand Down Expand Up @@ -441,9 +441,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 = ConstantModifierFee<Balance, TransactionByteFee>;
type FeeMultiplierUpdate =
TargetedFeeAdjustment<Self, TargetBlockFullness, AdjustmentVariable, MinimumMultiplier>;
}
Expand Down
34 changes: 33 additions & 1 deletion frame/support/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@
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")]
Expand Down Expand Up @@ -709,6 +712,26 @@ where
}
}

/// Implementor of `WeightToFeePolynomial` that uses a constant modifier.
bkchr marked this conversation as resolved.
Show resolved Hide resolved
pub struct ConstantModifierFee<T, M>(sp_std::marker::PhantomData<(T, M)>);
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

impl<T, M> WeightToFeePolynomial for ConstantModifierFee<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> {
Expand Down Expand Up @@ -983,4 +1006,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!(ConstantModifierFee::<u128, ConstU128<100u128>>::calc(&0), 0);
assert_eq!(ConstantModifierFee::<u128, ConstU128<10u128>>::calc(&50), 500);
assert_eq!(ConstantModifierFee::<u128, ConstU128<1024u128>>::calc(&16), 16384);
assert_eq!(ConstantModifierFee::<u128, ConstU128<{ u128::MAX }>>::calc(&2), u128::MAX);
}
}
30 changes: 17 additions & 13 deletions frame/transaction-payment/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>>;
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

/// A fee mulitplier for `Operational` extrinsics to compute "virtual tip" to boost their
/// `priority`
///
Expand Down Expand Up @@ -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;
}
Expand All @@ -302,6 +301,12 @@ pub mod pallet {
fn weight_to_fee_polynomial() -> Vec<WeightToFeeCoefficient<BalanceOf<T>>> {
T::WeightToFee::polynomial().to_vec()
}

#[pallet::constant_name(LengthToFee)]
/// The polynomial that is a pplied in order to derive fee from length.
bkchr marked this conversation as resolved.
Show resolved Hide resolved
fn length_to_fee_polynomial() -> Vec<WeightToFeeCoefficient<BalanceOf<T>>> {
T::LengthToFee::polynomial().to_vec()
}
}

#[pallet::type_value]
Expand Down Expand Up @@ -510,23 +515,20 @@ 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
notlesh marked this conversation as resolved.
Show resolved Hide resolved
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,
len_fee,
adjusted_weight_fee,
}),
tip,
Expand All @@ -536,6 +538,10 @@ where
}
}

fn length_to_fee(length: u32) -> BalanceOf<T> {
T::LengthToFee::calc(&(length as u64)) // TODO: saturating / upper bound
Copy link
Contributor Author

@notlesh notlesh Mar 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had left this TODO here because fn weight_to_fee below provides an upper bound.

While I'm not quite sure why it's needed in weight_to_fee, it's guaranteed to be no larger than u32::MAX in the case of length_to_fee, which is likely much smaller than max_block.

Another pair of eyes would be great though.

}

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.
Expand Down Expand Up @@ -835,7 +841,6 @@ mod tests {
}

parameter_types! {
pub static TransactionByteFee: u64 = 1;
pub static WeightToFee: u64 = 1;
pub static OperationalFeeMultiplier: u8 = 5;
}
Expand Down Expand Up @@ -913,7 +918,6 @@ mod tests {

impl Config for Runtime {
type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees>;
type TransactionByteFee = TransactionByteFee;
type OperationalFeeMultiplier = OperationalFeeMultiplier;
type WeightToFee = WeightToFee;
type FeeMultiplierUpdate = ();
Expand Down
1 change: 0 additions & 1 deletion frame/transaction-payment/src/payment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down