3

How is base fee calculated?

enter image description here


My understanding is that WeightToFee is just a transformation equation(Weight -> Balance). But what is this x?

So the final transaction fee is this?:

base_fee = (-/+)coeff_integer * x^(degree) + coeff_frac * x^(degree);
inclusion_fee = base_fee + length_fee + [targeted_fee_adjustment * weight_fee];
total_fee = inclusion_fee + tip;

https://docs.substrate.io/rustdocs/latest/frame_support/weights/struct.WeightToFeeCoefficient.html

enter image description here

1 Answer 1

5

Base fee represents the fee of any extrinsic with a certain extrinsic class, not yet including the specific logic of that extrinsic. That is to say, that there is some overhead fee required for any extrinsic, even one that executes no logic, and the base fee represents that.

The documented definition is:

base fee: This is the minimum amount a user pays for a transaction. It is declared as a base weight in the runtime and converted to a fee using WeightToFee.

Weight is has a standard value across all chains representing pico-seconds. For example, 1 seconds of weight would be 1_000_000_000_000.

Since Weight has a standard representation, but all blockchains can have different representations of currencies, we need a function like WeightToFee to allow a blockchain developer to convert between the standard weight value to a representation of the blockchian currency.

For example:

Imagine I have two chains which represent a USD stable coin, however, one uses 12 decimals, and the other uses 9 decimals.

So to represent $1, you would have:

chain a: 1_000_000_000_000 UNITS
chain b: 1_000_000_000 UNITS

Where UNITS is the lowest denomination of that currency.

Now imagine you want to have both chains charge $1, for 1 second of computation on the network.

Chain a would define a WeightToFee function which is simply the identity, since these two values match 1:1.

fn weight_to_fee(weight: u64) -> Balance {
    weight.into()
}

However, chain b would need to adjust the weight value to turn it into the appropriate fee since they only use 9 decimals:

fn weight_to_fee(weight: u64) -> Balance {
    (weight / 1000).into()
}

Within the transaction payment pallet, WeightToFee is a trait that can be defined by the runtime developer, and can even have more complex logic. For example, imagine charging different amounts of fees at different tiers:

fn weight_to_fee(weight: u64) -> Balance {
    if weight > THRESHOLD_1 {
         (weight * FEE_MULTIPLIER_1).into()
    } else if (weight > THRESHOLD_2)
         (weight * FEE_MULTIPLIER_2).into()
    } else if ...
}

So to answer your question, there is no concrete way that these things are calculated for all Substrate chains. If you are asking about a specific chain like Polkadot, you can look at the implementation of the WeightToFee trait:

    /// Handles converting a weight scalar to a fee value, based on the scale and granularity of the
    /// node's balance type.
    ///
    /// This should typically create a mapping between the following ranges:
    ///   - [0, `MAXIMUM_BLOCK_WEIGHT`]
    ///   - [Balance::min, Balance::max]
    ///
    /// Yet, it can be used for any other sort of change to weight-fee. Some examples being:
    ///   - Setting it to `0` will essentially disable the weight fee.
    ///   - Setting it to `1` will cause the literal `#[weight = x]` values to be charged.
    pub struct WeightToFee;
    impl WeightToFeePolynomial for WeightToFee {
        type Balance = Balance;
        fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
            // in Polkadot, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
            let p = super::currency::CENTS;
            let q = 10 * Balance::from(ExtrinsicBaseWeight::get());
            smallvec![WeightToFeeCoefficient {
                degree: 1,
                negative: false,
                coeff_frac: Perbill::from_rational(p % q, q),
                coeff_integer: p / q,
            }]
        }
    }
8
  • Can I take it this way. base_fee = WeightToFee(ExtrinsicBaseWeight); weight_fee = WeightToFee(weight);
    – 99kies
    Apr 23, 2022 at 19:05
  • I am clear about the function of WeightToFee, but I am not clear about the independent variable of WeightToFee.
    – 99kies
    Apr 23, 2022 at 19:08
  • My understanding is that base fee is actually WeightToFee(ExtrinsicBaseWeight);.
    – 99kies
    Apr 23, 2022 at 19:09
  • And weight fee is WeightToFee(weight).
    – 99kies
    Apr 23, 2022 at 19:10
  • Do I understand this correctly?
    – 99kies
    Apr 23, 2022 at 19:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.