Parachains should charge for proof size weight (#2326)

* Generalize trait requirement

Use the trait directly instead of something that will have a blanket
implementation for it.

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Charge for proof size weight

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Fix doc comments

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>

* Fix docs

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Update lock file

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Fix imports

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Docs

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Fix imports

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

---------

Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
This commit is contained in:
Oliver Tale-Yazdi
2023-03-17 17:25:13 +01:00
committed by GitHub
parent 1782170e08
commit 91b3512427
16 changed files with 509 additions and 47 deletions
+2 -2
View File
@@ -3,7 +3,7 @@ use core::{marker::PhantomData, ops::ControlFlow};
use frame_support::{
log,
traits::{fungibles::Inspect, tokens::BalanceConversion, ContainsPair},
weights::{Weight, WeightToFee, WeightToFeePolynomial},
weights::Weight,
};
use sp_runtime::traits::Get;
use xcm::{latest::prelude::*, CreateMatcher, MatchXcm};
@@ -95,7 +95,7 @@ impl<CurrencyBalance, Runtime, WeightToFee, BalanceConverter, AssetInstance>
> for AssetFeeAsExistentialDepositMultiplier<Runtime, WeightToFee, BalanceConverter, AssetInstance>
where
Runtime: pallet_assets::Config<AssetInstance>,
WeightToFee: WeightToFeePolynomial<Balance = CurrencyBalance>,
WeightToFee: frame_support::weights::WeightToFee<Balance = CurrencyBalance>,
BalanceConverter: BalanceConversion<
CurrencyBalance,
<Runtime as pallet_assets::Config<AssetInstance>>::AssetId,
@@ -28,6 +28,7 @@ pallet-balances = { git = "https://github.com/paritytech/substrate", default-fea
pallet-multisig = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
pallet-proxy = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
pallet-session = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
pallet-state-trie-migration = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master", optional = true }
pallet-timestamp = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
@@ -44,7 +45,7 @@ sp-session = { git = "https://github.com/paritytech/substrate", default-features
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
sp-transaction-pool = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
sp-version = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
pallet-state-trie-migration = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master", optional = true }
sp-weights = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
# Polkadot
kusama-runtime-constants = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
@@ -34,8 +34,8 @@ pub mod currency {
/// Fee-related.
pub mod fee {
use frame_support::weights::{
constants::ExtrinsicBaseWeight, WeightToFeeCoefficient, WeightToFeeCoefficients,
WeightToFeePolynomial,
constants::ExtrinsicBaseWeight, FeePolynomial, Weight, WeightToFeeCoefficient,
WeightToFeeCoefficients, WeightToFeePolynomial,
};
use polkadot_core_primitives::Balance;
use smallvec::smallvec;
@@ -55,13 +55,46 @@ pub mod fee {
/// - 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 {
impl frame_support::weights::WeightToFee for WeightToFee {
type Balance = Balance;
fn weight_to_fee(weight: &Weight) -> Self::Balance {
let time_poly: FeePolynomial<Balance> = RefTimeToFee::polynomial().into();
let proof_poly: FeePolynomial<Balance> = ProofSizeToFee::polynomial().into();
// Take the maximum instead of the sum to charge by the more scarce resource.
time_poly.eval(weight.ref_time()).max(proof_poly.eval(weight.proof_size()))
}
}
/// Maps the reference time component of `Weight` to a fee.
pub struct RefTimeToFee;
impl WeightToFeePolynomial for RefTimeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// in Kusama, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
// in Statemine, we map to 1/10 of that, or 1/100 CENT
let p = super::currency::CENTS;
let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
coeff_frac: Perbill::from_rational(p % q, q),
coeff_integer: p / q,
}]
}
}
/// Maps the proof size component of `Weight` to a fee.
pub struct ProofSizeToFee;
impl WeightToFeePolynomial for ProofSizeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// Map 10kb proof to 1 CENT.
let p = super::currency::CENTS;
let q = 10_000;
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
@@ -1125,3 +1125,59 @@ fn ensure_key_ss58() {
assert_eq!(acc, RootMigController::sorted_members()[0]);
//panic!("{:x?}", acc);
}
#[cfg(test)]
mod tests {
use super::{constants::fee, *};
use crate::{CENTS, MILLICENTS};
use sp_runtime::traits::Zero;
use sp_weights::WeightToFee;
/// We can fit at least 1000 transfers in a block.
#[test]
fn sane_block_weight() {
use pallet_balances::WeightInfo;
let block = RuntimeBlockWeights::get().max_block;
let base = RuntimeBlockWeights::get().get(DispatchClass::Normal).base_extrinsic;
let transfer = base + weights::pallet_balances::WeightInfo::<Runtime>::transfer();
let fit = block.checked_div_per_component(&transfer).unwrap_or_default();
assert!(fit >= 1000, "{} should be at least 1000", fit);
}
/// The fee for one transfer is at most 1 CENT.
#[test]
fn sane_transfer_fee() {
use pallet_balances::WeightInfo;
let base = RuntimeBlockWeights::get().get(DispatchClass::Normal).base_extrinsic;
let transfer = base + weights::pallet_balances::WeightInfo::<Runtime>::transfer();
let fee: Balance = fee::WeightToFee::weight_to_fee(&transfer);
assert!(fee <= CENTS, "{} MILLICENTS should be at most 1000", fee / MILLICENTS);
}
/// Weight is being charged for both dimensions.
#[test]
fn weight_charged_for_both_components() {
let fee: Balance = fee::WeightToFee::weight_to_fee(&Weight::from_parts(10_000, 0));
assert!(!fee.is_zero(), "Charges for ref time");
let fee: Balance = fee::WeightToFee::weight_to_fee(&Weight::from_parts(0, 10_000));
assert_eq!(fee, CENTS, "10kb maps to CENT");
}
/// Filling up a block by proof size is at most 30 times more expensive than ref time.
///
/// This is just a sanity check.
#[test]
fn full_block_fee_ratio() {
let block = RuntimeBlockWeights::get().max_block;
let time_fee: Balance = fee::WeightToFee::weight_to_fee(&block.without_proof_size());
let proof_fee: Balance = fee::WeightToFee::weight_to_fee(&block.without_ref_time());
let proof_o_time = proof_fee.checked_div(time_fee).unwrap_or_default();
assert!(proof_o_time <= 30, "{} should be at most 30", proof_o_time);
let time_o_proof = time_fee.checked_div(proof_fee).unwrap_or_default();
assert!(time_o_proof <= 30, "{} should be at most 30", time_o_proof);
}
}
@@ -44,6 +44,7 @@ sp-session = { git = "https://github.com/paritytech/substrate", default-features
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
sp-transaction-pool = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
sp-version = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
sp-weights = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
# Polkadot
pallet-xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
@@ -34,12 +34,13 @@ pub mod currency {
/// Fee-related.
pub mod fee {
use frame_support::weights::{
constants::ExtrinsicBaseWeight, WeightToFeeCoefficient, WeightToFeeCoefficients,
WeightToFeePolynomial,
constants::ExtrinsicBaseWeight, FeePolynomial, WeightToFeeCoefficient,
WeightToFeeCoefficients, WeightToFeePolynomial,
};
use polkadot_core_primitives::Balance;
use smallvec::smallvec;
pub use sp_runtime::Perbill;
use sp_weights::Weight;
/// The block saturation level. Fees will be updates based on this value.
pub const TARGET_BLOCK_FULLNESS: Perbill = Perbill::from_percent(25);
@@ -55,13 +56,46 @@ pub mod fee {
/// - 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 {
impl frame_support::weights::WeightToFee for WeightToFee {
type Balance = Balance;
fn weight_to_fee(weight: &Weight) -> Self::Balance {
let time_poly: FeePolynomial<Balance> = RefTimeToFee::polynomial().into();
let proof_poly: FeePolynomial<Balance> = ProofSizeToFee::polynomial().into();
// Take the maximum instead of the sum to charge by the more scarce resource.
time_poly.eval(weight.ref_time()).max(proof_poly.eval(weight.proof_size()))
}
}
/// Maps the reference time component of `Weight` to a fee.
pub struct RefTimeToFee;
impl WeightToFeePolynomial for RefTimeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// in Polkadot, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
// in Statemint, we map to 1/10 of that, or 1/100 CENT
let p = super::currency::CENTS;
let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
coeff_frac: Perbill::from_rational(p % q, q),
coeff_integer: p / q,
}]
}
}
/// Maps the proof size component of `Weight` to a fee.
pub struct ProofSizeToFee;
impl WeightToFeePolynomial for ProofSizeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// Map 10kb proof to 1 CENT.
let p = super::currency::CENTS;
let q = 10_000;
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
@@ -1077,3 +1077,59 @@ cumulus_pallet_parachain_system::register_validate_block! {
BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
CheckInherents = CheckInherents,
}
#[cfg(test)]
mod tests {
use super::{constants::fee, *};
use crate::{CENTS, MILLICENTS};
use sp_runtime::traits::Zero;
use sp_weights::WeightToFee;
/// We can fit at least 1000 transfers in a block.
#[test]
fn sane_block_weight() {
use pallet_balances::WeightInfo;
let block = RuntimeBlockWeights::get().max_block;
let base = RuntimeBlockWeights::get().get(DispatchClass::Normal).base_extrinsic;
let transfer = base + weights::pallet_balances::WeightInfo::<Runtime>::transfer();
let fit = block.checked_div_per_component(&transfer).unwrap_or_default();
assert!(fit >= 1000, "{} should be at least 1000", fit);
}
/// The fee for one transfer is at most 1 CENT.
#[test]
fn sane_transfer_fee() {
use pallet_balances::WeightInfo;
let base = RuntimeBlockWeights::get().get(DispatchClass::Normal).base_extrinsic;
let transfer = base + weights::pallet_balances::WeightInfo::<Runtime>::transfer();
let fee: Balance = fee::WeightToFee::weight_to_fee(&transfer);
assert!(fee <= CENTS, "{} MILLICENTS should be at most 1000", fee / MILLICENTS);
}
/// Weight is being charged for both dimensions.
#[test]
fn weight_charged_for_both_components() {
let fee: Balance = fee::WeightToFee::weight_to_fee(&Weight::from_parts(10_000, 0));
assert!(!fee.is_zero(), "Charges for ref time");
let fee: Balance = fee::WeightToFee::weight_to_fee(&Weight::from_parts(0, 10_000));
assert_eq!(fee, CENTS, "10kb maps to CENT");
}
/// Filling up a block by proof size is at most 30 times more expensive than ref time.
///
/// This is just a sanity check.
#[test]
fn full_block_fee_ratio() {
let block = RuntimeBlockWeights::get().max_block;
let time_fee: Balance = fee::WeightToFee::weight_to_fee(&block.without_proof_size());
let proof_fee: Balance = fee::WeightToFee::weight_to_fee(&block.without_ref_time());
let proof_o_time = proof_fee.checked_div(time_fee).unwrap_or_default();
assert!(proof_o_time <= 30, "{} should be at most 30", proof_o_time);
let time_o_proof = time_fee.checked_div(proof_fee).unwrap_or_default();
assert!(time_o_proof <= 30, "{} should be at most 30", time_o_proof);
}
}
@@ -33,9 +33,12 @@ pub mod currency {
/// Fee-related.
pub mod fee {
use frame_support::weights::{
constants::ExtrinsicBaseWeight, WeightToFeeCoefficient, WeightToFeeCoefficients,
WeightToFeePolynomial,
use frame_support::{
pallet_prelude::Weight,
weights::{
constants::ExtrinsicBaseWeight, FeePolynomial, WeightToFeeCoefficient,
WeightToFeeCoefficients, WeightToFeePolynomial,
},
};
use polkadot_core_primitives::Balance;
use smallvec::smallvec;
@@ -55,13 +58,46 @@ pub mod fee {
/// - 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 {
impl frame_support::weights::WeightToFee for WeightToFee {
type Balance = Balance;
fn weight_to_fee(weight: &Weight) -> Self::Balance {
let time_poly: FeePolynomial<Balance> = RefTimeToFee::polynomial().into();
let proof_poly: FeePolynomial<Balance> = ProofSizeToFee::polynomial().into();
// Take the maximum instead of the sum to charge by the more scarce resource.
time_poly.eval(weight.ref_time()).max(proof_poly.eval(weight.proof_size()))
}
}
/// Maps the reference time component of `Weight` to a fee.
pub struct RefTimeToFee;
impl WeightToFeePolynomial for RefTimeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// in Polkadot, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
// in Statemint, we map to 1/10 of that, or 1/100 CENT
// in Westend, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
// in Westmint, we map to 1/10 of that, or 1/100 CENT
let p = super::currency::CENTS;
let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
coeff_frac: Perbill::from_rational(p % q, q),
coeff_integer: p / q,
}]
}
}
/// Maps the proof size component of `Weight` to a fee.
pub struct ProofSizeToFee;
impl WeightToFeePolynomial for ProofSizeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// Map 10kb proof to 1 CENT.
let p = super::currency::CENTS;
let q = 10_000;
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
@@ -32,9 +32,12 @@ pub mod currency {
/// Fee-related.
pub mod fee {
use frame_support::weights::{
constants::ExtrinsicBaseWeight, WeightToFeeCoefficient, WeightToFeeCoefficients,
WeightToFeePolynomial,
use frame_support::{
pallet_prelude::Weight,
weights::{
constants::ExtrinsicBaseWeight, FeePolynomial, WeightToFeeCoefficient,
WeightToFeeCoefficients, WeightToFeePolynomial,
},
};
use polkadot_core_primitives::Balance;
use smallvec::smallvec;
@@ -51,13 +54,46 @@ pub mod fee {
/// - 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 {
impl frame_support::weights::WeightToFee for WeightToFee {
type Balance = Balance;
fn weight_to_fee(weight: &Weight) -> Self::Balance {
let time_poly: FeePolynomial<Balance> = RefTimeToFee::polynomial().into();
let proof_poly: FeePolynomial<Balance> = ProofSizeToFee::polynomial().into();
// Take the maximum instead of the sum to charge by the more scarce resource.
time_poly.eval(weight.ref_time()).max(proof_poly.eval(weight.proof_size()))
}
}
/// Maps the reference time component of `Weight` to a fee.
pub struct RefTimeToFee;
impl WeightToFeePolynomial for RefTimeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// in Kusama, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
// in BridgeHub, we map to 1/10 of that, or 1/100 CENT
// in Bridge Hub, we map to 1/10 of that, or 1/100 CENT
let p = super::currency::CENTS;
let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
coeff_frac: Perbill::from_rational(p % q, q),
coeff_integer: p / q,
}]
}
}
/// Maps the proof size component of `Weight` to a fee.
pub struct ProofSizeToFee;
impl WeightToFeePolynomial for ProofSizeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// Map 10kb proof to 1 CENT.
let p = super::currency::CENTS;
let q = 10_000;
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
@@ -32,9 +32,12 @@ pub mod currency {
/// Fee-related.
pub mod fee {
use frame_support::weights::{
constants::ExtrinsicBaseWeight, WeightToFeeCoefficient, WeightToFeeCoefficients,
WeightToFeePolynomial,
use frame_support::{
pallet_prelude::Weight,
weights::{
constants::ExtrinsicBaseWeight, FeePolynomial, WeightToFeeCoefficient,
WeightToFeeCoefficients, WeightToFeePolynomial,
},
};
use polkadot_core_primitives::Balance;
use smallvec::smallvec;
@@ -51,13 +54,46 @@ pub mod fee {
/// - 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 {
impl frame_support::weights::WeightToFee for WeightToFee {
type Balance = Balance;
fn weight_to_fee(weight: &Weight) -> Self::Balance {
let time_poly: FeePolynomial<Balance> = RefTimeToFee::polynomial().into();
let proof_poly: FeePolynomial<Balance> = ProofSizeToFee::polynomial().into();
// Take the maximum instead of the sum to charge by the more scarce resource.
time_poly.eval(weight.ref_time()).max(proof_poly.eval(weight.proof_size()))
}
}
/// Maps the reference time component of `Weight` to a fee.
pub struct RefTimeToFee;
impl WeightToFeePolynomial for RefTimeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// in Polkadot, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
// in BridgeHub, we map to 1/10 of that, or 1/100 CENT
// in Bridge Hub, we map to 1/10 of that, or 1/100 CENT
let p = super::currency::CENTS;
let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
coeff_frac: Perbill::from_rational(p % q, q),
coeff_integer: p / q,
}]
}
}
/// Maps the proof size component of `Weight` to a fee.
pub struct ProofSizeToFee;
impl WeightToFeePolynomial for ProofSizeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// Map 10kb proof to 1 CENT.
let p = super::currency::CENTS;
let q = 10_000;
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
@@ -30,9 +30,12 @@ pub mod currency {
}
pub mod fee {
use frame_support::weights::{
constants::ExtrinsicBaseWeight, WeightToFeeCoefficient, WeightToFeeCoefficients,
WeightToFeePolynomial,
use frame_support::{
pallet_prelude::Weight,
weights::{
constants::ExtrinsicBaseWeight, FeePolynomial, WeightToFeeCoefficient,
WeightToFeeCoefficients, WeightToFeePolynomial,
},
};
use polkadot_core_primitives::Balance;
use smallvec::smallvec;
@@ -52,13 +55,46 @@ pub mod fee {
/// - 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 {
impl frame_support::weights::WeightToFee for WeightToFee {
type Balance = Balance;
fn weight_to_fee(weight: &Weight) -> Self::Balance {
let time_poly: FeePolynomial<Balance> = RefTimeToFee::polynomial().into();
let proof_poly: FeePolynomial<Balance> = ProofSizeToFee::polynomial().into();
// Take the maximum instead of the sum to charge by the more scarce resource.
time_poly.eval(weight.ref_time()).max(proof_poly.eval(weight.proof_size()))
}
}
/// Maps the reference time component of `Weight` to a fee.
pub struct RefTimeToFee;
impl WeightToFeePolynomial for RefTimeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// in Rococo, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
// in BridgeHub, we map to 1/10 of that, or 1/100 CENT
// in Bridge Hub, we map to 1/10 of that, or 1/100 CENT
let p = super::currency::CENTS;
let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
coeff_frac: Perbill::from_rational(p % q, q),
coeff_integer: p / q,
}]
}
}
/// Maps the proof size component of `Weight` to a fee.
pub struct ProofSizeToFee;
impl WeightToFeePolynomial for ProofSizeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// Map 10kb proof to 1 CENT.
let p = super::currency::CENTS;
let q = 10_000;
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
@@ -46,10 +46,11 @@ use constants::currency::*;
use frame_support::{
construct_runtime,
dispatch::DispatchClass,
pallet_prelude::Weight,
parameter_types,
traits::{ConstU32, ConstU64, ConstU8, Everything},
weights::{
ConstantMultiplier, Weight, WeightToFeeCoefficient, WeightToFeeCoefficients,
ConstantMultiplier, FeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients,
WeightToFeePolynomial,
},
PalletId,
@@ -129,13 +130,44 @@ pub type Executive = frame_executive::Executive<
/// - 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 {
impl frame_support::weights::WeightToFee for WeightToFee {
type Balance = Balance;
fn weight_to_fee(weight: &Weight) -> Self::Balance {
let time_poly: FeePolynomial<Balance> = RefTimeToFee::polynomial().into();
let proof_poly: FeePolynomial<Balance> = ProofSizeToFee::polynomial().into();
// Take the maximum instead of the sum to charge by the more scarce resource.
time_poly.eval(weight.ref_time()).max(proof_poly.eval(weight.proof_size()))
}
}
/// Maps the reference time component of `Weight` to a fee.
pub struct RefTimeToFee;
impl WeightToFeePolynomial for RefTimeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// in Rococo, extrinsic base weight (smallest non-zero weight) is mapped to 1 MILLIUNIT:
// in our template, we map to 1/10 of that, or 1/10 MILLIUNIT
let p = MILLIUNIT / 10;
let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
coeff_frac: Perbill::from_rational(p % q, q),
coeff_integer: p / q,
}]
}
}
/// Maps the proof size component of `Weight` to a fee.
pub struct ProofSizeToFee;
impl WeightToFeePolynomial for ProofSizeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// Map 10kb proof to 1/10 MILLIUNIT.
let p = MILLIUNIT / 10;
let q = 10_000;
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
@@ -43,9 +43,12 @@ pub mod currency {
/// Fee-related.
pub mod fee {
use frame_support::weights::{
constants::ExtrinsicBaseWeight, WeightToFeeCoefficient, WeightToFeeCoefficients,
WeightToFeePolynomial,
use frame_support::{
pallet_prelude::Weight,
weights::{
constants::ExtrinsicBaseWeight, FeePolynomial, WeightToFeeCoefficient,
WeightToFeeCoefficients, WeightToFeePolynomial,
},
};
use polkadot_core_primitives::Balance;
use smallvec::smallvec;
@@ -65,13 +68,46 @@ pub mod fee {
/// - 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 {
impl frame_support::weights::WeightToFee for WeightToFee {
type Balance = Balance;
fn weight_to_fee(weight: &Weight) -> Self::Balance {
let time_poly: FeePolynomial<Balance> = RefTimeToFee::polynomial().into();
let proof_poly: FeePolynomial<Balance> = ProofSizeToFee::polynomial().into();
// Take the maximum instead of the sum to charge by the more scarce resource.
time_poly.eval(weight.ref_time()).max(proof_poly.eval(weight.proof_size()))
}
}
/// Maps the reference time component of `Weight` to a fee.
pub struct RefTimeToFee;
impl WeightToFeePolynomial for RefTimeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// in Polkadot, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
// in a parachain, we map to 1/10 of that, or 1/100 CENT
let p = super::currency::CENTS;
let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
coeff_frac: Perbill::from_rational(p % q, q),
coeff_integer: p / q,
}]
}
}
/// Maps the proof size component of `Weight` to a fee.
pub struct ProofSizeToFee;
impl WeightToFeePolynomial for ProofSizeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// Map 10kb proof to 1 CENT.
let p = super::currency::CENTS;
let q = 10_000;
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
@@ -33,9 +33,12 @@ pub mod currency {
/// Fee-related.
pub mod fee {
use frame_support::weights::{
constants::ExtrinsicBaseWeight, WeightToFeeCoefficient, WeightToFeeCoefficients,
WeightToFeePolynomial,
use frame_support::{
pallet_prelude::Weight,
weights::{
constants::ExtrinsicBaseWeight, FeePolynomial, WeightToFeeCoefficient,
WeightToFeeCoefficients, WeightToFeePolynomial,
},
};
use polkadot_core_primitives::Balance;
use smallvec::smallvec;
@@ -55,13 +58,46 @@ pub mod fee {
/// - 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 {
impl frame_support::weights::WeightToFee for WeightToFee {
type Balance = Balance;
fn weight_to_fee(weight: &Weight) -> Self::Balance {
let time_poly: FeePolynomial<Balance> = RefTimeToFee::polynomial().into();
let proof_poly: FeePolynomial<Balance> = ProofSizeToFee::polynomial().into();
// Take the maximum instead of the sum to charge by the more scarce resource.
time_poly.eval(weight.ref_time()).max(proof_poly.eval(weight.proof_size()))
}
}
/// Maps the reference time component of `Weight` to a fee.
pub struct RefTimeToFee;
impl WeightToFeePolynomial for RefTimeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// in Kusama, extrinsic base weight (smallest non-zero weight) is mapped to 1/10 CENT:
// in Statemine, we map to 1/10 of that, or 1/100 CENT
let p = super::currency::CENTS;
let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
coeff_frac: Perbill::from_rational(p % q, q),
coeff_integer: p / q,
}]
}
}
/// Maps the proof size component of `Weight` to a fee.
pub struct ProofSizeToFee;
impl WeightToFeePolynomial for ProofSizeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// Map 10kb proof to 1 CENT.
let p = super::currency::CENTS;
let q = 10_000;
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
+36 -5
View File
@@ -34,11 +34,12 @@ use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases;
use frame_support::{
construct_runtime,
dispatch::DispatchClass,
pallet_prelude::Weight,
parameter_types,
traits::{AsEnsureOriginWithArg, ConstU32, ConstU64, ConstU8, Everything},
weights::{
constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, Weight, WeightToFeeCoefficient,
WeightToFeeCoefficients, WeightToFeePolynomial,
constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, FeePolynomial,
WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial,
},
PalletId,
};
@@ -149,13 +150,26 @@ pub type Executive = frame_executive::Executive<
/// - 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 {
impl frame_support::weights::WeightToFee for WeightToFee {
type Balance = Balance;
fn weight_to_fee(weight: &Weight) -> Self::Balance {
let time_poly: FeePolynomial<Balance> = RefTimeToFee::polynomial().into();
let proof_poly: FeePolynomial<Balance> = ProofSizeToFee::polynomial().into();
// Take the maximum instead of the sum to charge by the more scarce resource.
time_poly.eval(weight.ref_time()).max(proof_poly.eval(weight.proof_size()))
}
}
/// Maps the reference time component of `Weight` to a fee.
pub struct RefTimeToFee;
impl WeightToFeePolynomial for RefTimeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// in Rococo, extrinsic base weight (smallest non-zero weight) is mapped to 1 MILLIUNIT:
// in our template, we map to 1/10 of that, or 1/10 MILLIUNIT
let p = MILLIUNIT / 10;
let q = 100 * Balance::from(ExtrinsicBaseWeight::get().ref_time());
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
@@ -165,6 +179,23 @@ impl WeightToFeePolynomial for WeightToFee {
}
}
/// Maps the proof size component of `Weight` to a fee.
pub struct ProofSizeToFee;
impl WeightToFeePolynomial for ProofSizeToFee {
type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
// Map 10kb proof to 1 CENT.
let p = MILLIUNIT / 10;
let q = 10_000;
smallvec![WeightToFeeCoefficient {
degree: 1,
negative: false,
coeff_frac: Perbill::from_rational(p % q, q),
coeff_integer: p / q,
}]
}
}
/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
/// of data like extrinsics, allowing for them to continue syncing the network through upgrades