Skip to content
Snippets Groups Projects
Select Git revision
  • 985075ea235c6c841f0e1df0577bda33e06ed52f
  • master default protected
  • 313_ci_image
  • 311_gtest_fixes
  • set_UniversalDividendApi_in_RuntimeApiCollection
  • tuxmain/fix-change-owner-key
  • network/gtest-1000 protected
  • upgradable-multisig
  • runtime/gtest-1000
  • network/gdev-800 protected
  • cgeek/issue-297-cpu
  • gdev-800-tests
  • update-docker-compose-rpc-squid-names
  • fix-252
  • 1000i100-test
  • hugo/tmp-0.9.1
  • network/gdev-803 protected
  • hugo/endpoint-gossip
  • network/gdev-802 protected
  • hugo/distance-precompute
  • network/gdev-900 protected
  • gtest-1000-0.11.1 protected
  • gtest-1000-0.11.0 protected
  • gtest-1000 protected
  • gdev-900-0.10.1 protected
  • gdev-900-0.10.0 protected
  • gdev-900-0.9.2 protected
  • gdev-800-0.8.0 protected
  • gdev-900-0.9.1 protected
  • gdev-900-0.9.0 protected
  • gdev-803 protected
  • gdev-802 protected
  • runtime-801 protected
  • gdev-800 protected
  • runtime-800-bis protected
  • runtime-800 protected
  • runtime-800-backup protected
  • runtime-701 protected
  • runtime-700 protected
  • runtime-600 protected
  • runtime-500 protected
41 results

fees.rs

Blame
  • fees.rs 9.67 KiB
    // Copyright 2021 Axiom-Team
    //
    // This file is part of Duniter-v2S.
    //
    // Duniter-v2S is free software: you can redistribute it and/or modify
    // it under the terms of the GNU Affero General Public License as published by
    // the Free Software Foundation, version 3 of the License.
    //
    // Duniter-v2S is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    // GNU Affero General Public License for more details.
    //
    // You should have received a copy of the GNU Affero General Public License
    // along with Duniter-v2S. If not, see <https://www.gnu.org/licenses/>.
    
    // In the deployed fees model, a mapping of 5 (5cG) corresponds to a base extrinsic weight,
    // achieved through a 1-dimensional polynomial. Additionally, 1 (1cG) corresponds to an extrinsic length of 100 bytes.
    //
    // For testing purposes, we adopt a human-predictable weight system that remains invariant to the chosen fees model for release.
    // This involves setting a constant weight_to_fee equal to 1 and a constant length_to_fee set to 0, resulting in each extrinsic costing 2 (2cG).
    
    pub use frame_support::weights::{Weight, WeightToFee};
    use pallet_transaction_payment::{Multiplier, MultiplierUpdate};
    use sp_arithmetic::traits::{BaseArithmetic, Unsigned};
    use sp_core::Get;
    use sp_runtime::{traits::Convert, Perquintill};
    #[cfg(not(feature = "constant-fees"))]
    use {
        crate::weights::extrinsic_weights::ExtrinsicBaseWeight,
        frame_support::pallet_prelude::DispatchClass,
        frame_support::weights::{
            WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial,
        },
        smallvec::smallvec,
        sp_arithmetic::MultiplyRational,
        sp_runtime::traits::One,
        sp_runtime::Perbill,
        sp_runtime::SaturatedConversion,
        sp_runtime::Saturating,
    };
    
    /// A structure to implement Length to Fee conversion.
    /// - `T`: The balance type.
    /// - `U`: The system configuration type, providing access to block weights.
    /// - `X`: A type providing the target block fullness.
    pub struct LengthToFeeImpl<T, U, X>(
        sp_std::marker::PhantomData<T>,
        sp_std::marker::PhantomData<U>,
        sp_std::marker::PhantomData<X>,
    );
    
    /// Trait implementation for converting transaction length to fee.
    impl<T, U, X> WeightToFee for LengthToFeeImpl<T, U, X>
    where
        T: BaseArithmetic + From<u32> + Copy + Unsigned,
        U: frame_system::Config + pallet_transaction_payment::Config,
        X: Get<Perquintill>,
    {
        type Balance = T;
    
        /// Function to convert weight to fee when "constant-fees" feature is not enabled.
        ///
        /// This function calculates the fee based on the length of the transaction in bytes.
        /// If the current block weight is less than a fraction of the max block weight and the fee multiplier is one,
        /// it returns a zero fee. Otherwise, it calculates the fee based on the length in bytes.
        #[cfg(not(feature = "constant-fees"))]
        fn weight_to_fee(length_in_bytes: &Weight) -> Self::Balance {
            let weights = U::BlockWeights::get();
            let fee_multiplier = pallet_transaction_payment::Pallet::<U>::next_fee_multiplier();
            let normal_max_weight = weights
                .get(DispatchClass::Normal)
                .max_total
                .unwrap_or(weights.max_block);
            let current_block_weight = <frame_system::Pallet<U>>::block_weight();
            if current_block_weight
                .get(DispatchClass::Normal)
                .all_lt(X::get() * normal_max_weight)
                && fee_multiplier.is_one()
            {
                0u32.into()
            } else {
                Self::Balance::saturated_from(length_in_bytes.ref_time() / 100u64)
            }
        }
    
        /// Function to convert weight to fee when "constant-fees" feature is enabled.
        ///
        /// This function always returns a constant fee of zero when the "constant-fees" feature is enabled.
        #[cfg(feature = "constant-fees")]
        fn weight_to_fee(_length_in_bytes: &Weight) -> Self::Balance {
            0u32.into()
        }
    }
    
    /// A structure to implement Weight to Fee conversion.
    /// - `T`: The balance type.
    /// - `U`: The system configuration type, providing access to block weights.
    /// - `X`: A type providing the target block fullness.
    pub struct WeightToFeeImpl<T, U, X>(
        sp_std::marker::PhantomData<T>,
        sp_std::marker::PhantomData<U>,
        sp_std::marker::PhantomData<X>,
    );
    
    /// Trait implementation for converting transaction weight to fee.
    ///
    /// This implementation is only included when the "constant-fees" feature is not enabled.
    #[cfg(not(feature = "constant-fees"))]
    impl<T, U, X> WeightToFeePolynomial for WeightToFeeImpl<T, U, X>
    where
        T: BaseArithmetic + From<u64> + Copy + Unsigned + From<u32> + MultiplyRational,
        U: frame_system::Config + pallet_transaction_payment::Config,
        X: Get<Perquintill>,
    {
        type Balance = T;
    
        /// Function to get the polynomial coefficients for weight to fee conversion.
        ///
        /// This function calculates the polynomial coefficients for converting transaction weight to fee.
        /// If the current block weight is less than a fraction of the block max weight and the fee multiplier is one,
        /// it returns zero. Otherwise, it calculates the coefficients based on the extrinsic base weight mapped to 5 cents.
        fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
            let weights = U::BlockWeights::get();
            let fee_multiplier = pallet_transaction_payment::Pallet::<U>::next_fee_multiplier();
            let normal_max_weight = weights
                .get(DispatchClass::Normal)
                .max_total
                .unwrap_or(weights.max_block);
            let current_block_weight = <frame_system::Pallet<U>>::block_weight();
            if current_block_weight
                .get(DispatchClass::Normal)
                .all_lt(X::get() * normal_max_weight)
                && fee_multiplier.is_one()
            {
                smallvec![WeightToFeeCoefficient {
                    degree: 1,
                    negative: false,
                    coeff_frac: Perbill::zero(),
                    coeff_integer: Self::Balance::zero(),
                }]
            } else {
                // The extrinsic base weight (smallest non-zero weight) is mapped to 5 cents
                let p: Self::Balance = 5u64.into();
                let q: Self::Balance = Self::Balance::from(ExtrinsicBaseWeight::get().ref_time());
                smallvec![WeightToFeeCoefficient {
                    degree: 1,
                    negative: false,
                    coeff_frac: Perbill::from_rational(p % q, q),
                    coeff_integer: p / q,
                }]
            }
        }
    }
    
    /// Trait implementation for converting transaction weight to a constant fee.
    ///
    /// This implementation is only included when the "constant-fees" feature is enabled.
    #[cfg(feature = "constant-fees")]
    impl<T, U, X> WeightToFee for WeightToFeeImpl<T, U, X>
    where
        T: BaseArithmetic + From<u32> + Copy + Unsigned,
    {
        type Balance = T;
    
        fn weight_to_fee(_weight: &Weight) -> Self::Balance {
            1u32.into()
        }
    }
    
    /// A structure to implement fee multiplier adjustments.
    ///
    /// - `T`: The system configuration type.
    /// - `S`: A type providing the target block fullness.
    /// - `X`: A type providing the maximum multiplier value.
    pub struct FeeMultiplier<T, S, X>(
        sp_std::marker::PhantomData<T>,
        sp_std::marker::PhantomData<S>,
        sp_std::marker::PhantomData<X>,
    );
    
    /// Trait implementation for updating the fee multiplier.
    impl<T, S, X> MultiplierUpdate for FeeMultiplier<T, S, X>
    where
        T: frame_system::Config,
        S: Get<Perquintill>,
        X: Get<Multiplier>,
    {
        fn min() -> Multiplier {
            0.into()
        }
    
        fn max() -> Multiplier {
            X::get()
        }
    
        fn target() -> Perquintill {
            S::get()
        }
    
        fn variability() -> Multiplier {
            Default::default()
        }
    }
    
    /// Trait implementation for converting previous `Multiplier` to another for fee adjustment.
    impl<T, S, X> Convert<Multiplier, Multiplier> for FeeMultiplier<T, S, X>
    where
        T: frame_system::Config,
        S: Get<Perquintill>,
        X: Get<Multiplier>,
    {
        /// Function to convert the previous fee multiplier to a new fee multiplier.
        ///
        /// This function adjusts the fee multiplier based on the current block weight and target block fullness.
        /// - If the current block weight is less than the target, it decreases the multiplier by one, with a minimum of one.
        /// - If the current block weight is more than the target, it increases the multiplier by one, up to the maximum multiplier.
        #[cfg(not(feature = "constant-fees"))]
        fn convert(previous: Multiplier) -> Multiplier {
            let max_multiplier = X::get();
            let target_block_fullness = S::get();
    
            let weights = T::BlockWeights::get();
            let normal_max_weight = weights
                .get(DispatchClass::Normal)
                .max_total
                .unwrap_or(weights.max_block);
    
            if <frame_system::Pallet<T>>::block_weight()
                .get(DispatchClass::Normal)
                .all_lt(target_block_fullness * normal_max_weight)
            {
                // If the current block weight is less than the target, keep the
                // multiplier at the minimum or decrease it by one to slowly
                // return to the minimum.
                previous.saturating_sub(1.into()).max(1.into())
            } else {
                // If the current block weight is more than the target, increase
                // the multiplier by one.
                previous.saturating_add(1.into()).min(max_multiplier)
            }
        }
    
        /// Function to convert the previous fee multiplier to a constant fee multiplier when "constant-fees" feature is enabled.
        ///
        /// This function always returns a constant multiplier of 1 when the "constant-fees" feature is enabled.
        #[cfg(feature = "constant-fees")]
        fn convert(_previous: Multiplier) -> Multiplier {
            1.into()
        }
    }