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
This commit is contained in:
Nazar Mokrynskyi
2022-05-25 08:32:11 +03:00
committed by GitHub
parent 29474f9893
commit 0c25a2ee40
9 changed files with 86 additions and 112 deletions
+44 -39
View File
@@ -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
);
}
}