From 145af816f0847337ba5f25b79c33b6e90d9d6d07 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Wed, 8 Mar 2023 05:02:49 -0800 Subject: [PATCH 01/40] Properly set the pricing for the DMP router --- runtime/kusama/src/xcm_config.rs | 23 ++++++++++++++++++++--- runtime/parachains/src/dmp.rs | 2 +- runtime/polkadot/src/xcm_config.rs | 23 ++++++++++++++++++++--- runtime/rococo/src/xcm_config.rs | 24 +++++++++++++++++++++--- runtime/westend/src/xcm_config.rs | 23 ++++++++++++++++++++--- xcm/pallet-xcm/src/lib.rs | 12 +++++++++--- 6 files changed, 91 insertions(+), 16 deletions(-) diff --git a/runtime/kusama/src/xcm_config.rs b/runtime/kusama/src/xcm_config.rs index 33ca3a810aea..1fb49edfecb8 100644 --- a/runtime/kusama/src/xcm_config.rs +++ b/runtime/kusama/src/xcm_config.rs @@ -17,7 +17,7 @@ //! XCM configurations for the Kusama runtime. use super::{ - parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, Fellows, + parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, Dmp, Fellows, ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, StakingAdmin, WeightToFee, XcmPallet, }; @@ -26,8 +26,14 @@ use frame_support::{ traits::{Contains, Everything, Nothing}, weights::Weight, }; -use runtime_common::{paras_registrar, xcm_sender, ToAuthor}; +use kusama_runtime_constants::currency::CENTS; +use runtime_common::{ + paras_registrar, + xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, + ToAuthor, +}; use sp_core::ConstU32; +use sp_runtime::{traits::Saturating, Percent}; use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, @@ -103,11 +109,22 @@ parameter_types! { pub const MaxInstructions: u32 = 100; } +struct ExponentialKsmPrice; +impl PriceForParachainDelivery for ExponentialKsmPrice { + fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { + let factor = Percent::from_percent(101).saturating_pow(Dmp::dmq_length(para) as usize); + let base = CENTS.saturating_mul(3); + + let amount = factor * base; + (Here, amount).into() + } +} + /// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our /// individual routers. pub type XcmRouter = ( // Only one router so far - use DMP to communicate with child parachains. - xcm_sender::ChildParachainRouter, + ChildParachainRouter, ); parameter_types! { diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index 855ae1bd85b6..8b509690f1ed 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -247,7 +247,7 @@ impl Pallet { /// Returns the number of pending downward messages addressed to the given para. /// /// Returns 0 if the para doesn't have an associated downward message queue. - pub(crate) fn dmq_length(para: ParaId) -> u32 { + pub fn dmq_length(para: ParaId) -> u32 { ::DownwardMessageQueues::decode_len(¶) .unwrap_or(0) .saturated_into::() diff --git a/runtime/polkadot/src/xcm_config.rs b/runtime/polkadot/src/xcm_config.rs index 4f817093703a..4ed532b4e2a1 100644 --- a/runtime/polkadot/src/xcm_config.rs +++ b/runtime/polkadot/src/xcm_config.rs @@ -17,7 +17,7 @@ //! XCM configuration for Polkadot. use super::{ - parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, ParaId, + parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, Dmp, ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmPallet, }; use frame_support::{ @@ -25,8 +25,14 @@ use frame_support::{ traits::{Contains, Everything, Nothing}, weights::Weight, }; -use runtime_common::{paras_registrar, xcm_sender, ToAuthor}; +use polkadot_runtime_constants::currency::CENTS; +use runtime_common::{ + paras_registrar, + xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, + ToAuthor, +}; use sp_core::ConstU32; +use sp_runtime::{traits::Saturating, Percent}; use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, @@ -101,11 +107,22 @@ parameter_types! { pub const MaxInstructions: u32 = 100; } +struct ExponentialDotPrice; +impl PriceForParachainDelivery for ExponentialDotPrice { + fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { + let factor = Percent::from_percent(101).saturating_pow(Dmp::dmq_length(para) as usize); + let base = CENTS.saturating_mul(3); + + let amount = factor * base; + (Here, amount).into() + } +} + /// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our /// individual routers. pub type XcmRouter = ( // Only one router so far - use DMP to communicate with child parachains. - xcm_sender::ChildParachainRouter, + ChildParachainRouter, ); parameter_types! { diff --git a/runtime/rococo/src/xcm_config.rs b/runtime/rococo/src/xcm_config.rs index 229df3a5df95..6614b0358857 100644 --- a/runtime/rococo/src/xcm_config.rs +++ b/runtime/rococo/src/xcm_config.rs @@ -17,7 +17,7 @@ //! XCM configuration for Rococo. use super::{ - parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, ParaId, + parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, Dmp, ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmPallet, }; use frame_support::{ @@ -25,8 +25,14 @@ use frame_support::{ traits::{Contains, Everything, Nothing}, weights::Weight, }; -use runtime_common::{paras_registrar, xcm_sender, ToAuthor}; +use rococo_runtime_constants::currency::CENTS; +use runtime_common::{ + paras_registrar, + xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, + ToAuthor, +}; use sp_core::ConstU32; +use sp_runtime::{traits::Saturating, Percent}; use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, @@ -82,11 +88,23 @@ parameter_types! { /// The amount of weight an XCM operation takes. This is a safe overestimate. pub const BaseXcmWeight: Weight = Weight::from_parts(1_000_000_000, 64 * 1024); } + +struct ExponentialRocPrice; +impl PriceForParachainDelivery for ExponentialRocPrice { + fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { + let factor = Percent::from_percent(101).saturating_pow(Dmp::dmq_length(para) as usize); + let base = CENTS.saturating_mul(3); + + let amount = factor * base; + (Here, amount).into() + } +} + /// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our /// individual routers. pub type XcmRouter = ( // Only one router so far - use DMP to communicate with child parachains. - xcm_sender::ChildParachainRouter, + ChildParachainRouter, ); parameter_types! { diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index ef38ca5d2970..204de53015dc 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -17,15 +17,21 @@ //! XCM configurations for Westend. use super::{ - parachains_origin, weights, AccountId, AllPalletsWithSystem, Balances, ParaId, Runtime, + parachains_origin, weights, AccountId, AllPalletsWithSystem, Balances, Dmp, ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmPallet, }; use frame_support::{ parameter_types, traits::{Contains, Everything, Nothing}, }; -use runtime_common::{paras_registrar, xcm_sender, ToAuthor}; +use runtime_common::{ + paras_registrar, + xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, + ToAuthor, +}; use sp_core::ConstU32; +use sp_runtime::{traits::Saturating, Percent}; +use westend_runtime_constants::currency::CENTS; use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, @@ -68,11 +74,22 @@ type LocalOriginConverter = ( ChildSystemParachainAsSuperuser, ); +struct ExponentialWndPrice; +impl PriceForParachainDelivery for ExponentialWndPrice { + fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { + let factor = Percent::from_percent(101).saturating_pow(Dmp::dmq_length(para) as usize); + let base = CENTS.saturating_mul(3); + + let amount = factor * base; + (Here, amount).into() + } +} + /// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our /// individual routers. pub type XcmRouter = ( // Only one router so far - use DMP to communicate with child parachains. - xcm_sender::ChildParachainRouter, + ChildParachainRouter, ); parameter_types! { diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs index 914c177399cc..03ff1706f1da 100644 --- a/xcm/pallet-xcm/src/lib.rs +++ b/xcm/pallet-xcm/src/lib.rs @@ -1144,7 +1144,10 @@ impl Pallet { BuyExecution { fees, weight_limit }, DepositAsset { assets: Wild(AllCounted(max_assets)), beneficiary }, ]); - let mut message = Xcm(vec![TransferReserveAsset { assets, dest, xcm }]); + let mut message = Xcm(vec![ + SetFeesMode { jit_withdraw: true }, + TransferReserveAsset { assets, dest, xcm }, + ]); let weight = T::Weigher::weight(&mut message).map_err(|()| Error::::UnweighableMessage)?; let hash = message.using_encoded(sp_io::hashing::blake2_256); @@ -1201,8 +1204,11 @@ impl Pallet { BuyExecution { fees, weight_limit }, DepositAsset { assets: Wild(AllCounted(max_assets)), beneficiary }, ]); - let mut message = - Xcm(vec![WithdrawAsset(assets), InitiateTeleport { assets: Wild(All), dest, xcm }]); + let mut message = Xcm(vec![ + WithdrawAsset(assets), + SetFeesMode { jit_withdraw: true }, + InitiateTeleport { assets: Wild(All), dest, xcm }, + ]); let weight = T::Weigher::weight(&mut message).map_err(|()| Error::::UnweighableMessage)?; let hash = message.using_encoded(sp_io::hashing::blake2_256); From d489025d81b7d7d32a05fd00dfc338524b1ade46 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Wed, 8 Mar 2023 05:16:36 -0800 Subject: [PATCH 02/40] Publicize price types --- runtime/kusama/src/xcm_config.rs | 2 +- runtime/polkadot/src/xcm_config.rs | 2 +- runtime/rococo/src/xcm_config.rs | 2 +- runtime/westend/src/xcm_config.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/kusama/src/xcm_config.rs b/runtime/kusama/src/xcm_config.rs index 1fb49edfecb8..e2d612b858cd 100644 --- a/runtime/kusama/src/xcm_config.rs +++ b/runtime/kusama/src/xcm_config.rs @@ -109,7 +109,7 @@ parameter_types! { pub const MaxInstructions: u32 = 100; } -struct ExponentialKsmPrice; +pub struct ExponentialKsmPrice; impl PriceForParachainDelivery for ExponentialKsmPrice { fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { let factor = Percent::from_percent(101).saturating_pow(Dmp::dmq_length(para) as usize); diff --git a/runtime/polkadot/src/xcm_config.rs b/runtime/polkadot/src/xcm_config.rs index 4ed532b4e2a1..850d5bd84b9c 100644 --- a/runtime/polkadot/src/xcm_config.rs +++ b/runtime/polkadot/src/xcm_config.rs @@ -107,7 +107,7 @@ parameter_types! { pub const MaxInstructions: u32 = 100; } -struct ExponentialDotPrice; +pub struct ExponentialDotPrice; impl PriceForParachainDelivery for ExponentialDotPrice { fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { let factor = Percent::from_percent(101).saturating_pow(Dmp::dmq_length(para) as usize); diff --git a/runtime/rococo/src/xcm_config.rs b/runtime/rococo/src/xcm_config.rs index 6614b0358857..409b01e9574e 100644 --- a/runtime/rococo/src/xcm_config.rs +++ b/runtime/rococo/src/xcm_config.rs @@ -89,7 +89,7 @@ parameter_types! { pub const BaseXcmWeight: Weight = Weight::from_parts(1_000_000_000, 64 * 1024); } -struct ExponentialRocPrice; +pub struct ExponentialRocPrice; impl PriceForParachainDelivery for ExponentialRocPrice { fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { let factor = Percent::from_percent(101).saturating_pow(Dmp::dmq_length(para) as usize); diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index 204de53015dc..06adb46186eb 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -74,7 +74,7 @@ type LocalOriginConverter = ( ChildSystemParachainAsSuperuser, ); -struct ExponentialWndPrice; +pub struct ExponentialWndPrice; impl PriceForParachainDelivery for ExponentialWndPrice { fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { let factor = Percent::from_percent(101).saturating_pow(Dmp::dmq_length(para) as usize); From 39f90fe71bd9bcdea2f364990bd61d241975c6c8 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 9 Mar 2023 00:31:29 -0800 Subject: [PATCH 03/40] Use FixedU128 instead of Percent --- runtime/kusama/src/xcm_config.rs | 7 ++++--- runtime/polkadot/src/xcm_config.rs | 7 ++++--- runtime/rococo/src/xcm_config.rs | 7 ++++--- runtime/westend/src/xcm_config.rs | 7 ++++--- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/runtime/kusama/src/xcm_config.rs b/runtime/kusama/src/xcm_config.rs index e2d612b858cd..77623d5e39bd 100644 --- a/runtime/kusama/src/xcm_config.rs +++ b/runtime/kusama/src/xcm_config.rs @@ -32,8 +32,8 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, ToAuthor, }; +use sp_arithmetic::{traits::Saturating, FixedPointNumber, FixedU128}; use sp_core::ConstU32; -use sp_runtime::{traits::Saturating, Percent}; use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, @@ -112,10 +112,11 @@ parameter_types! { pub struct ExponentialKsmPrice; impl PriceForParachainDelivery for ExponentialKsmPrice { fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { - let factor = Percent::from_percent(101).saturating_pow(Dmp::dmq_length(para) as usize); + let factor = + FixedU128::from_rational(101, 100).saturating_pow(Dmp::dmq_length(para) as usize); let base = CENTS.saturating_mul(3); - let amount = factor * base; + let amount = factor.saturating_mul_int(base); (Here, amount).into() } } diff --git a/runtime/polkadot/src/xcm_config.rs b/runtime/polkadot/src/xcm_config.rs index 850d5bd84b9c..025bffa76e6a 100644 --- a/runtime/polkadot/src/xcm_config.rs +++ b/runtime/polkadot/src/xcm_config.rs @@ -31,8 +31,8 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, ToAuthor, }; +use sp_arithmetic::{traits::Saturating, FixedPointNumber, FixedU128}; use sp_core::ConstU32; -use sp_runtime::{traits::Saturating, Percent}; use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, @@ -110,10 +110,11 @@ parameter_types! { pub struct ExponentialDotPrice; impl PriceForParachainDelivery for ExponentialDotPrice { fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { - let factor = Percent::from_percent(101).saturating_pow(Dmp::dmq_length(para) as usize); + let factor = + FixedU128::from_rational(101, 100).saturating_pow(Dmp::dmq_length(para) as usize); let base = CENTS.saturating_mul(3); - let amount = factor * base; + let amount = factor.saturating_mul_int(base); (Here, amount).into() } } diff --git a/runtime/rococo/src/xcm_config.rs b/runtime/rococo/src/xcm_config.rs index 409b01e9574e..10c42e063059 100644 --- a/runtime/rococo/src/xcm_config.rs +++ b/runtime/rococo/src/xcm_config.rs @@ -31,8 +31,8 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, ToAuthor, }; +use sp_arithmetic::{traits::Saturating, FixedPointNumber, FixedU128}; use sp_core::ConstU32; -use sp_runtime::{traits::Saturating, Percent}; use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, @@ -92,10 +92,11 @@ parameter_types! { pub struct ExponentialRocPrice; impl PriceForParachainDelivery for ExponentialRocPrice { fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { - let factor = Percent::from_percent(101).saturating_pow(Dmp::dmq_length(para) as usize); + let factor = + FixedU128::from_rational(101, 100).saturating_pow(Dmp::dmq_length(para) as usize); let base = CENTS.saturating_mul(3); - let amount = factor * base; + let amount = factor.saturating_mul_int(base); (Here, amount).into() } } diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index 06adb46186eb..6cc86f60662a 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -29,9 +29,9 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, ToAuthor, }; +use sp_arithmetic::{traits::Saturating, FixedPointNumber, FixedU128}; use sp_core::ConstU32; use sp_runtime::{traits::Saturating, Percent}; -use westend_runtime_constants::currency::CENTS; use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, @@ -77,10 +77,11 @@ type LocalOriginConverter = ( pub struct ExponentialWndPrice; impl PriceForParachainDelivery for ExponentialWndPrice { fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { - let factor = Percent::from_percent(101).saturating_pow(Dmp::dmq_length(para) as usize); + let factor = + FixedU128::from_rational(101, 100).saturating_pow(Dmp::dmq_length(para) as usize); let base = CENTS.saturating_mul(3); - let amount = factor * base; + let amount = factor.saturating_mul_int(base); (Here, amount).into() } } From 824f0457b39eec0b7b233a5e2dc8607bf00ae341 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 9 Mar 2023 00:50:54 -0800 Subject: [PATCH 04/40] Add sp-arithmetic as a dependency for rococo runtime --- Cargo.lock | 1 + runtime/rococo/Cargo.toml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index c92212dc9265..b77b1cb026f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8763,6 +8763,7 @@ dependencies = [ "serde_json", "smallvec", "sp-api", + "sp-arithmetic", "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", diff --git a/runtime/rococo/Cargo.toml b/runtime/rococo/Cargo.toml index ee8b86311b81..4b79f0589d0d 100644 --- a/runtime/rococo/Cargo.toml +++ b/runtime/rococo/Cargo.toml @@ -27,6 +27,7 @@ sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", de sp-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } @@ -112,6 +113,7 @@ std = [ "parity-scale-codec/std", "scale-info/std", "inherents/std", + "sp-arithmetic/std", "sp-core/std", "sp-api/std", "tx-pool-api/std", From f4e0d66a8650b1ca3f4020f1cd014cefa2d88dac Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 9 Mar 2023 00:53:42 -0800 Subject: [PATCH 05/40] Add sp-arithmetic as a dependency to all runtimes --- Cargo.lock | 2 ++ runtime/kusama/Cargo.toml | 3 ++- runtime/polkadot/Cargo.toml | 2 ++ runtime/westend/Cargo.toml | 2 ++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index b77b1cb026f3..6d4a07d98f0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7472,6 +7472,7 @@ dependencies = [ "serde_json", "smallvec", "sp-api", + "sp-arithmetic", "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", @@ -13449,6 +13450,7 @@ dependencies = [ "serde_json", "smallvec", "sp-api", + "sp-arithmetic", "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", diff --git a/runtime/kusama/Cargo.toml b/runtime/kusama/Cargo.toml index 91fdad9c4c8f..ab962b2b61e7 100644 --- a/runtime/kusama/Cargo.toml +++ b/runtime/kusama/Cargo.toml @@ -24,7 +24,7 @@ sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", d inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } offchain-primitives = { package = "sp-offchain", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-std = { package = "sp-std", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } -sp-arithmetic = { package = "sp-arithmetic", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } @@ -128,6 +128,7 @@ std = [ "parity-scale-codec/std", "scale-info/std", "inherents/std", + "sp-arithmetic/std", "sp-core/std", "sp-api/std", "tx-pool-api/std", diff --git a/runtime/polkadot/Cargo.toml b/runtime/polkadot/Cargo.toml index 691963d14e80..88170abe82d9 100644 --- a/runtime/polkadot/Cargo.toml +++ b/runtime/polkadot/Cargo.toml @@ -23,6 +23,7 @@ block-builder-api = { package = "sp-block-builder", git = "https://github.com/pa inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } offchain-primitives = { package = "sp-offchain", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } tx-pool-api = { package = "sp-transaction-pool", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } @@ -120,6 +121,7 @@ std = [ "parity-scale-codec/std", "scale-info/std", "inherents/std", + "sp-arithmetic/std", "sp-core/std", "sp-api/std", "tx-pool-api/std", diff --git a/runtime/westend/Cargo.toml b/runtime/westend/Cargo.toml index d90124516c6e..43a41c1e893e 100644 --- a/runtime/westend/Cargo.toml +++ b/runtime/westend/Cargo.toml @@ -26,6 +26,7 @@ sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", de sp-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } @@ -120,6 +121,7 @@ std = [ "parity-scale-codec/std", "scale-info/std", "inherents/std", + "sp-arithmetic/std", "sp-core/std", "polkadot-parachain/std", "sp-api/std", From 7a492750f6d6f570f7421923d8d7ea5b5e9bbf61 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 9 Mar 2023 01:40:11 -0800 Subject: [PATCH 06/40] Remove duplicate import --- runtime/westend/src/xcm_config.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index 6cc86f60662a..b40138187904 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -31,7 +31,6 @@ use runtime_common::{ }; use sp_arithmetic::{traits::Saturating, FixedPointNumber, FixedU128}; use sp_core::ConstU32; -use sp_runtime::{traits::Saturating, Percent}; use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, From 59d6693fa0e0d2f3f507405d85b6da86aa2504d8 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 9 Mar 2023 01:54:21 -0800 Subject: [PATCH 07/40] Add missing import --- runtime/westend/src/xcm_config.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index b40138187904..9a0b9accb613 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -31,6 +31,7 @@ use runtime_common::{ }; use sp_arithmetic::{traits::Saturating, FixedPointNumber, FixedU128}; use sp_core::ConstU32; +use westend_runtime_constants::currency::CENTS; use xcm::latest::prelude::*; use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses, From 500b42f484ae006b79280d06aee283df3f6ac137 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 9 Mar 2023 02:38:18 -0800 Subject: [PATCH 08/40] Fix tests --- xcm/pallet-xcm/src/tests.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs index 2700124976f1..3811f59411c9 100644 --- a/xcm/pallet-xcm/src/tests.rs +++ b/xcm/pallet-xcm/src/tests.rs @@ -349,7 +349,7 @@ fn teleport_assets_works() { (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let weight = BaseXcmWeight::get() * 2; + let weight = BaseXcmWeight::get() * 3; assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); let dest: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); assert_ok!(XcmPallet::teleport_assets( @@ -392,7 +392,7 @@ fn limited_teleport_assets_works() { (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let weight = BaseXcmWeight::get() * 2; + let weight = BaseXcmWeight::get() * 3; assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); let dest: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); assert_ok!(XcmPallet::limited_teleport_assets( @@ -436,7 +436,7 @@ fn unlimited_teleport_assets_works() { (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let weight = BaseXcmWeight::get() * 2; + let weight = BaseXcmWeight::get() * 3; assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); let dest: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into(); assert_ok!(XcmPallet::limited_teleport_assets( @@ -478,7 +478,7 @@ fn reserve_transfer_assets_works() { (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let weight = BaseXcmWeight::get(); + let weight = BaseXcmWeight::get() * 2; let dest: MultiLocation = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); assert_ok!(XcmPallet::reserve_transfer_assets( @@ -525,7 +525,7 @@ fn limited_reserve_transfer_assets_works() { (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let weight = BaseXcmWeight::get(); + let weight = BaseXcmWeight::get() * 2; let dest: MultiLocation = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); assert_ok!(XcmPallet::limited_reserve_transfer_assets( @@ -573,7 +573,7 @@ fn unlimited_reserve_transfer_assets_works() { (ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE), ]; new_test_ext_with_balances(balances).execute_with(|| { - let weight = BaseXcmWeight::get(); + let weight = BaseXcmWeight::get() * 2; let dest: MultiLocation = Junction::AccountId32 { network: None, id: ALICE.into() }.into(); assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE); assert_ok!(XcmPallet::limited_reserve_transfer_assets( From 633430cf13d09f7b398565bc9d228b852fecd00b Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 9 Mar 2023 16:03:34 -0800 Subject: [PATCH 09/40] Create an appropriate QueueDownwardMessageError variant --- runtime/parachains/src/dmp.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index 8b509690f1ed..906fca292ceb 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -36,12 +36,16 @@ pub const MAX_MESSAGE_QUEUE_SIZE: usize = 1024; pub enum QueueDownwardMessageError { /// The message being sent exceeds the configured max message size. ExceedsMaxMessageSize, + /// Enquing the message would exceed the max queue size. + ExceedsMaxQueueSize, } impl From for SendError { fn from(err: QueueDownwardMessageError) -> Self { match err { QueueDownwardMessageError::ExceedsMaxMessageSize => SendError::ExceedsMaxMessageSize, + QueueDownwardMessageError::ExceedsMaxQueueSize => + SendError::Transport("exceeds queue size"), } } } @@ -102,9 +106,6 @@ pub mod pallet { #[pallet::storage] pub(crate) type DownwardMessageQueueHeads = StorageMap<_, Twox64Concat, ParaId, Hash, ValueQuery>; - - #[pallet::call] - impl Pallet {} } /// Routines and getters related to downward message passing. @@ -155,7 +156,7 @@ impl Pallet { if ::DownwardMessageQueues::decode_len(para).unwrap_or(0) > MAX_MESSAGE_QUEUE_SIZE { - return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) + return Err(QueueDownwardMessageError::ExceedsMaxQueueSize) } Ok(()) @@ -182,7 +183,7 @@ impl Pallet { if ::DownwardMessageQueues::decode_len(para).unwrap_or(0) > MAX_MESSAGE_QUEUE_SIZE { - return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) + return Err(QueueDownwardMessageError::ExceedsMaxQueueSize) } let inbound = From 7f275215860de70ba3bcc25159aa3100c1d678af Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 9 Mar 2023 17:24:42 -0800 Subject: [PATCH 10/40] Recalculate delivery fee factor based on past queue sizes --- runtime/kusama/src/xcm_config.rs | 21 +++++++---- runtime/parachains/src/dmp.rs | 57 ++++++++++++++++++++++-------- runtime/polkadot/src/xcm_config.rs | 20 +++++++---- runtime/rococo/src/xcm_config.rs | 20 +++++++---- runtime/westend/src/xcm_config.rs | 20 +++++++---- 5 files changed, 98 insertions(+), 40 deletions(-) diff --git a/runtime/kusama/src/xcm_config.rs b/runtime/kusama/src/xcm_config.rs index 77623d5e39bd..3a97d36bb56b 100644 --- a/runtime/kusama/src/xcm_config.rs +++ b/runtime/kusama/src/xcm_config.rs @@ -17,9 +17,9 @@ //! XCM configurations for the Kusama runtime. use super::{ - parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, Dmp, Fellows, - ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, StakingAdmin, WeightToFee, - XcmPallet, + parachains_dmp, parachains_origin, AccountId, AllPalletsWithSystem, Balances, + CouncilCollective, Dmp, Fellows, ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, + StakingAdmin, TransactionByteFee, WeightToFee, XcmPallet, }; use frame_support::{ match_types, parameter_types, @@ -111,12 +111,19 @@ parameter_types! { pub struct ExponentialKsmPrice; impl PriceForParachainDelivery for ExponentialKsmPrice { - fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { - let factor = - FixedU128::from_rational(101, 100).saturating_pow(Dmp::dmq_length(para) as usize); + fn price_for_parachain_delivery(para: ParaId, msg: &Xcm<()>) -> MultiAssets { let base = CENTS.saturating_mul(3); + let msg_fee = (msg.len() as u128).saturating_mul(TransactionByteFee::get()); - let amount = factor.saturating_mul_int(base); + let excess_msgs = + Dmp::dmq_length(para).saturating_sub(parachains_dmp::MAX_MESSAGE_QUEUE_SIZE) as usize; + let factor = if excess_msgs != 0 { + Dmp::raise_fee_factor(excess_msgs) + } else { + Dmp::reduce_fee_factor(1) + }; + + let amount = factor.saturating_mul_int(base + msg_fee); (Here, amount).into() } } diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index 906fca292ceb..3142023a7544 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -20,7 +20,10 @@ use crate::{ }; use frame_support::pallet_prelude::*; use primitives::{DownwardMessage, Hash, Id as ParaId, InboundDownwardMessage}; -use sp_runtime::traits::{BlakeTwo256, Hash as HashT, SaturatedConversion}; +use sp_runtime::{ + traits::{BlakeTwo256, Hash as HashT, SaturatedConversion}, + FixedU128, Saturating, +}; use sp_std::{fmt, prelude::*}; use xcm::latest::SendError; @@ -29,7 +32,8 @@ pub use pallet::*; #[cfg(test)] mod tests; -pub const MAX_MESSAGE_QUEUE_SIZE: usize = 1024; +pub const MAX_MESSAGE_QUEUE_SIZE: u32 = 1024; +pub const MULTIPLICATIVE_FEE_FACTOR: FixedU128 = FixedU128::from_rational(101, 100); // 1.01 /// An error sending a downward message. #[cfg_attr(test, derive(Debug))] @@ -106,6 +110,15 @@ pub mod pallet { #[pallet::storage] pub(crate) type DownwardMessageQueueHeads = StorageMap<_, Twox64Concat, ParaId, Hash, ValueQuery>; + + frame_support::parameter_types! { + pub InitialFactor: FixedU128 = FixedU128::from_u32(1); + } + + /// The number to multiply the base delivery fee by. + #[pallet::storage] + pub(crate) type DeliveryFeeFactor = + StorageValue<_, FixedU128, ValueQuery, InitialFactor>; } /// Routines and getters related to downward message passing. @@ -145,7 +158,7 @@ impl Pallet { /// `queue_downward_message` with the same parameters will be successful. pub fn can_queue_downward_message( config: &HostConfiguration, - para: &ParaId, + _: &ParaId, msg: &DownwardMessage, ) -> Result<(), QueueDownwardMessageError> { let serialized_len = msg.len() as u32; @@ -153,12 +166,6 @@ impl Pallet { return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) } - if ::DownwardMessageQueues::decode_len(para).unwrap_or(0) > - MAX_MESSAGE_QUEUE_SIZE - { - return Err(QueueDownwardMessageError::ExceedsMaxQueueSize) - } - Ok(()) } @@ -180,12 +187,6 @@ impl Pallet { return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) } - if ::DownwardMessageQueues::decode_len(para).unwrap_or(0) > - MAX_MESSAGE_QUEUE_SIZE - { - return Err(QueueDownwardMessageError::ExceedsMaxQueueSize) - } - let inbound = InboundDownwardMessage { msg, sent_at: >::block_number() }; @@ -260,4 +261,30 @@ impl Pallet { pub(crate) fn dmq_contents(recipient: ParaId) -> Vec> { ::DownwardMessageQueues::get(&recipient) } + + /// Raise the delivery fee factor by a multiplicative factor to the power of `n`, and stores + /// the resulting value. + /// + /// Returns the new delivery fee factor after the raise. + pub fn raise_fee_factor(n: usize) -> FixedU128 { + >::mutate(|f| { + let factor = MULTIPLICATIVE_FEE_FACTOR.saturating_pow(n); + *f = f.saturating_mul(factor); + *f + }) + } + + /// Reduce the delivery fee factor by a multiplicative factor to the power of `n`, and stores + /// the resulting value. + /// + /// Does not reduce the fee factor below the initial value, which is currently set as 1. + /// + /// Returns the new delivery fee factor after the reduction. + pub fn reduce_fee_factor(n: usize) -> FixedU128 { + >::mutate(|f| { + let factor = MULTIPLICATIVE_FEE_FACTOR.saturating_pow(n); + *f = InitialFactor::get().min(*f / factor); + *f + }) + } } diff --git a/runtime/polkadot/src/xcm_config.rs b/runtime/polkadot/src/xcm_config.rs index 025bffa76e6a..6b69b1527381 100644 --- a/runtime/polkadot/src/xcm_config.rs +++ b/runtime/polkadot/src/xcm_config.rs @@ -17,8 +17,9 @@ //! XCM configuration for Polkadot. use super::{ - parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, Dmp, ParaId, - Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmPallet, + parachains_dmp, parachains_origin, AccountId, AllPalletsWithSystem, Balances, + CouncilCollective, Dmp, ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, + TransactionByteFee, WeightToFee, XcmPallet, }; use frame_support::{ match_types, parameter_types, @@ -109,12 +110,19 @@ parameter_types! { pub struct ExponentialDotPrice; impl PriceForParachainDelivery for ExponentialDotPrice { - fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { - let factor = - FixedU128::from_rational(101, 100).saturating_pow(Dmp::dmq_length(para) as usize); + fn price_for_parachain_delivery(para: ParaId, msg: &Xcm<()>) -> MultiAssets { let base = CENTS.saturating_mul(3); + let msg_fee = (msg.len() as u128).saturating_mul(TransactionByteFee::get()); - let amount = factor.saturating_mul_int(base); + let excess_msgs = + Dmp::dmq_length(para).saturating_sub(parachains_dmp::MAX_MESSAGE_QUEUE_SIZE) as usize; + let factor = if excess_msgs != 0 { + Dmp::raise_fee_factor(excess_msgs) + } else { + Dmp::reduce_fee_factor(1) + }; + + let amount = factor.saturating_mul_int(base + msg_fee); (Here, amount).into() } } diff --git a/runtime/rococo/src/xcm_config.rs b/runtime/rococo/src/xcm_config.rs index 10c42e063059..6c1f6bb5958d 100644 --- a/runtime/rococo/src/xcm_config.rs +++ b/runtime/rococo/src/xcm_config.rs @@ -17,8 +17,9 @@ //! XCM configuration for Rococo. use super::{ - parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, Dmp, ParaId, - Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmPallet, + parachains_dmp, parachains_origin, AccountId, AllPalletsWithSystem, Balances, + CouncilCollective, Dmp, ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, + TransactionByteFee, WeightToFee, XcmPallet, }; use frame_support::{ match_types, parameter_types, @@ -91,12 +92,19 @@ parameter_types! { pub struct ExponentialRocPrice; impl PriceForParachainDelivery for ExponentialRocPrice { - fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { - let factor = - FixedU128::from_rational(101, 100).saturating_pow(Dmp::dmq_length(para) as usize); + fn price_for_parachain_delivery(para: ParaId, msg: &Xcm<()>) -> MultiAssets { let base = CENTS.saturating_mul(3); + let msg_fee = (msg.len() as u128).saturating_mul(TransactionByteFee::get()); - let amount = factor.saturating_mul_int(base); + let excess_msgs = + Dmp::dmq_length(para).saturating_sub(parachains_dmp::MAX_MESSAGE_QUEUE_SIZE) as usize; + let factor = if excess_msgs != 0 { + Dmp::raise_fee_factor(excess_msgs) + } else { + Dmp::reduce_fee_factor(1) + }; + + let amount = factor.saturating_mul_int(base + msg_fee); (Here, amount).into() } } diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index 9a0b9accb613..3196b5255871 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -17,8 +17,9 @@ //! XCM configurations for Westend. use super::{ - parachains_origin, weights, AccountId, AllPalletsWithSystem, Balances, Dmp, ParaId, Runtime, - RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmPallet, + parachains_dmp, parachains_origin, weights, AccountId, AllPalletsWithSystem, Balances, Dmp, + ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee, WeightToFee, + XcmPallet, }; use frame_support::{ parameter_types, @@ -76,12 +77,19 @@ type LocalOriginConverter = ( pub struct ExponentialWndPrice; impl PriceForParachainDelivery for ExponentialWndPrice { - fn price_for_parachain_delivery(para: ParaId, _: &Xcm<()>) -> MultiAssets { - let factor = - FixedU128::from_rational(101, 100).saturating_pow(Dmp::dmq_length(para) as usize); + fn price_for_parachain_delivery(para: ParaId, msg: &Xcm<()>) -> MultiAssets { let base = CENTS.saturating_mul(3); + let msg_fee = (msg.len() as u128).saturating_mul(TransactionByteFee::get()); - let amount = factor.saturating_mul_int(base); + let excess_msgs = + Dmp::dmq_length(para).saturating_sub(parachains_dmp::MAX_MESSAGE_QUEUE_SIZE) as usize; + let factor = if excess_msgs != 0 { + Dmp::raise_fee_factor(excess_msgs) + } else { + Dmp::reduce_fee_factor(1) + }; + + let amount = factor.saturating_mul_int(base + msg_fee); (Here, amount).into() } } From 2fe3547f1968e3991f577bb34e2dc610a5c28e4f Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 9 Mar 2023 17:31:19 -0800 Subject: [PATCH 11/40] Remove unused error variant --- runtime/parachains/src/dmp.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index 3142023a7544..eca785d3fe23 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -40,16 +40,12 @@ pub const MULTIPLICATIVE_FEE_FACTOR: FixedU128 = FixedU128::from_rational(101, 1 pub enum QueueDownwardMessageError { /// The message being sent exceeds the configured max message size. ExceedsMaxMessageSize, - /// Enquing the message would exceed the max queue size. - ExceedsMaxQueueSize, } impl From for SendError { fn from(err: QueueDownwardMessageError) -> Self { match err { QueueDownwardMessageError::ExceedsMaxMessageSize => SendError::ExceedsMaxMessageSize, - QueueDownwardMessageError::ExceedsMaxQueueSize => - SendError::Transport("exceeds queue size"), } } } From 3f6ea59b6d12a0f23d3ddb6cd5e192ab0ce2ac99 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 9 Mar 2023 17:57:52 -0800 Subject: [PATCH 12/40] Fixes --- runtime/kusama/src/lib.rs | 2 +- runtime/kusama/src/xcm_config.rs | 2 +- runtime/polkadot/src/lib.rs | 2 +- runtime/polkadot/src/xcm_config.rs | 2 +- runtime/rococo/src/lib.rs | 2 +- runtime/rococo/src/xcm_config.rs | 2 +- runtime/westend/src/lib.rs | 2 +- runtime/westend/src/xcm_config.rs | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index fb61273892e1..ecb7e6d5df84 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -1416,7 +1416,7 @@ construct_runtime! { ParaScheduler: parachains_scheduler::{Pallet, Storage} = 55, Paras: parachains_paras::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 56, Initializer: parachains_initializer::{Pallet, Call, Storage} = 57, - Dmp: parachains_dmp::{Pallet, Call, Storage} = 58, + Dmp: parachains_dmp::{Pallet, Storage} = 58, Ump: parachains_ump::{Pallet, Call, Storage, Event} = 59, Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event, Config} = 60, ParaSessionInfo: parachains_session_info::{Pallet, Storage} = 61, diff --git a/runtime/kusama/src/xcm_config.rs b/runtime/kusama/src/xcm_config.rs index 3a97d36bb56b..58985cb9110f 100644 --- a/runtime/kusama/src/xcm_config.rs +++ b/runtime/kusama/src/xcm_config.rs @@ -32,7 +32,7 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, ToAuthor, }; -use sp_arithmetic::{traits::Saturating, FixedPointNumber, FixedU128}; +use sp_arithmetic::{traits::Saturating, FixedPointNumber}; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index b5ddb16a2800..a8e757dd81c3 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -1536,7 +1536,7 @@ construct_runtime! { ParaScheduler: parachains_scheduler::{Pallet, Storage} = 55, Paras: parachains_paras::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 56, Initializer: parachains_initializer::{Pallet, Call, Storage} = 57, - Dmp: parachains_dmp::{Pallet, Call, Storage} = 58, + Dmp: parachains_dmp::{Pallet, Storage} = 58, Ump: parachains_ump::{Pallet, Call, Storage, Event} = 59, Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event, Config} = 60, ParaSessionInfo: parachains_session_info::{Pallet, Storage} = 61, diff --git a/runtime/polkadot/src/xcm_config.rs b/runtime/polkadot/src/xcm_config.rs index 6b69b1527381..90d5cc7c3a32 100644 --- a/runtime/polkadot/src/xcm_config.rs +++ b/runtime/polkadot/src/xcm_config.rs @@ -32,7 +32,7 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, ToAuthor, }; -use sp_arithmetic::{traits::Saturating, FixedPointNumber, FixedU128}; +use sp_arithmetic::{traits::Saturating, FixedPointNumber}; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index fcfc998c700e..dc2652a72d39 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -1424,7 +1424,7 @@ construct_runtime! { ParaScheduler: parachains_scheduler::{Pallet, Storage} = 55, Paras: parachains_paras::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 56, Initializer: parachains_initializer::{Pallet, Call, Storage} = 57, - Dmp: parachains_dmp::{Pallet, Call, Storage} = 58, + Dmp: parachains_dmp::{Pallet, Storage} = 58, Ump: parachains_ump::{Pallet, Call, Storage, Event} = 59, Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event, Config} = 60, ParaSessionInfo: parachains_session_info::{Pallet, Storage} = 61, diff --git a/runtime/rococo/src/xcm_config.rs b/runtime/rococo/src/xcm_config.rs index 6c1f6bb5958d..f8f95d1cc987 100644 --- a/runtime/rococo/src/xcm_config.rs +++ b/runtime/rococo/src/xcm_config.rs @@ -32,7 +32,7 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, ToAuthor, }; -use sp_arithmetic::{traits::Saturating, FixedPointNumber, FixedU128}; +use sp_arithmetic::{traits::Saturating, FixedPointNumber}; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs index d7274fa6f9f2..6a27f82d289d 100644 --- a/runtime/westend/src/lib.rs +++ b/runtime/westend/src/lib.rs @@ -1154,7 +1154,7 @@ construct_runtime! { ParaScheduler: parachains_scheduler::{Pallet, Storage} = 46, Paras: parachains_paras::{Pallet, Call, Storage, Event, Config, ValidateUnsigned} = 47, Initializer: parachains_initializer::{Pallet, Call, Storage} = 48, - Dmp: parachains_dmp::{Pallet, Call, Storage} = 49, + Dmp: parachains_dmp::{Pallet, Storage} = 49, Ump: parachains_ump::{Pallet, Call, Storage, Event} = 50, Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event, Config} = 51, ParaSessionInfo: parachains_session_info::{Pallet, Storage} = 52, diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index 3196b5255871..8d0ba89e85d3 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -30,7 +30,7 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, ToAuthor, }; -use sp_arithmetic::{traits::Saturating, FixedPointNumber, FixedU128}; +use sp_arithmetic::{traits::Saturating, FixedPointNumber}; use sp_core::ConstU32; use westend_runtime_constants::currency::CENTS; use xcm::latest::prelude::*; From c36de96a6b3aa8f1a704859b1c73e0a8e61e9368 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 9 Mar 2023 18:35:15 -0800 Subject: [PATCH 13/40] Fixes --- runtime/test-runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/test-runtime/src/lib.rs b/runtime/test-runtime/src/lib.rs index 35ec219f4685..89628ce5b0fb 100644 --- a/runtime/test-runtime/src/lib.rs +++ b/runtime/test-runtime/src/lib.rs @@ -667,7 +667,7 @@ construct_runtime! { ParaSessionInfo: parachains_session_info::{Pallet, Storage}, Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event}, Ump: parachains_ump::{Pallet, Call, Storage, Event}, - Dmp: parachains_dmp::{Pallet, Call, Storage}, + Dmp: parachains_dmp::{Pallet, Storage}, Xcm: pallet_xcm::{Pallet, Call, Event, Origin}, ParasDisputes: parachains_disputes::{Pallet, Storage, Event}, From 7e3d876300b6ba1a23450d7fb83fa992d72a283f Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 9 Mar 2023 22:28:48 -0800 Subject: [PATCH 14/40] Remove unused imports --- runtime/kusama/src/xcm_config.rs | 2 +- runtime/polkadot/src/xcm_config.rs | 2 +- runtime/rococo/src/xcm_config.rs | 2 +- runtime/westend/src/xcm_config.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/kusama/src/xcm_config.rs b/runtime/kusama/src/xcm_config.rs index 58985cb9110f..b7eb1e4a3061 100644 --- a/runtime/kusama/src/xcm_config.rs +++ b/runtime/kusama/src/xcm_config.rs @@ -32,7 +32,7 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, ToAuthor, }; -use sp_arithmetic::{traits::Saturating, FixedPointNumber}; +use sp_arithmetic::FixedPointNumber; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ diff --git a/runtime/polkadot/src/xcm_config.rs b/runtime/polkadot/src/xcm_config.rs index 90d5cc7c3a32..0a95aae26ec6 100644 --- a/runtime/polkadot/src/xcm_config.rs +++ b/runtime/polkadot/src/xcm_config.rs @@ -32,7 +32,7 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, ToAuthor, }; -use sp_arithmetic::{traits::Saturating, FixedPointNumber}; +use sp_arithmetic::FixedPointNumber; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ diff --git a/runtime/rococo/src/xcm_config.rs b/runtime/rococo/src/xcm_config.rs index f8f95d1cc987..aee7a036b2e1 100644 --- a/runtime/rococo/src/xcm_config.rs +++ b/runtime/rococo/src/xcm_config.rs @@ -32,7 +32,7 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, ToAuthor, }; -use sp_arithmetic::{traits::Saturating, FixedPointNumber}; +use sp_arithmetic::FixedPointNumber; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index 8d0ba89e85d3..ba1487c40561 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -30,7 +30,7 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, ToAuthor, }; -use sp_arithmetic::{traits::Saturating, FixedPointNumber}; +use sp_arithmetic::FixedPointNumber; use sp_core::ConstU32; use westend_runtime_constants::currency::CENTS; use xcm::latest::prelude::*; From c5a622dbe4ebb12b106923071079f2b7ae10449a Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Wed, 15 Mar 2023 12:27:43 +0000 Subject: [PATCH 15/40] Rewrite fee factor update mechanism --- runtime/common/src/xcm_sender.rs | 18 ++++++++++++++ runtime/kusama/src/xcm_config.rs | 40 ++++++++++++------------------ runtime/parachains/src/dmp.rs | 40 +++++++++++++++++------------- runtime/polkadot/src/xcm_config.rs | 39 +++++++++++------------------ runtime/rococo/src/xcm_config.rs | 39 +++++++++++------------------ runtime/westend/src/xcm_config.rs | 39 +++++++++++------------------ xcm/src/v3/mod.rs | 2 +- 7 files changed, 103 insertions(+), 114 deletions(-) diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs index e4cc02ae756b..e3c030526c0f 100644 --- a/runtime/common/src/xcm_sender.rs +++ b/runtime/common/src/xcm_sender.rs @@ -47,6 +47,24 @@ impl> PriceForParachainDelivery for ConstantPrice { } } +/// Implementation of `PriceForParachainDelivery` which returns an exponentially increasing price. +/// The `A` type parameter is used to denote the asset ID that will be used for paying the delivery +/// fee. +/// +/// The formula for the fee is based on the sum of a base fee plus a message length fee, multiplied +/// by a specified factor. In mathematical form, it is `F * (B + msg_len * M)`. +pub struct ExponentialPrice(sp_std::marker::PhantomData<(A, B, M, F)>); +impl, B: Get, M: Get, F: Get> PriceForParachainDelivery + for ExponentialPrice +{ + fn price_for_parachain_delivery(_: ParaId, msg: &Xcm<()>) -> MultiAssets { + let msg_fee = (msg.encoded_size() as u128).saturating_mul(M::get()); + let fee_sum = B::get().saturating_add(msg_fee); + let amount = F::get().saturating_mul(fee_sum); + (A::get(), amount).into() + } +} + /// XCM sender for relay chain. It only sends downward message. pub struct ChildParachainRouter(PhantomData<(T, W, P)>); diff --git a/runtime/kusama/src/xcm_config.rs b/runtime/kusama/src/xcm_config.rs index b7eb1e4a3061..57d85d0fca5b 100644 --- a/runtime/kusama/src/xcm_config.rs +++ b/runtime/kusama/src/xcm_config.rs @@ -17,9 +17,9 @@ //! XCM configurations for the Kusama runtime. use super::{ - parachains_dmp, parachains_origin, AccountId, AllPalletsWithSystem, Balances, - CouncilCollective, Dmp, Fellows, ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, - StakingAdmin, TransactionByteFee, WeightToFee, XcmPallet, + parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, Dmp, Fellows, + ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, StakingAdmin, TransactionByteFee, + WeightToFee, XcmPallet, }; use frame_support::{ match_types, parameter_types, @@ -27,9 +27,10 @@ use frame_support::{ weights::Weight, }; use kusama_runtime_constants::currency::CENTS; +use parity_scale_codec::Encode; use runtime_common::{ paras_registrar, - xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, + xcm_sender::{ChildParachainRouter, ExponentialPrice, PriceForParachainDelivery}, ToAuthor, }; use sp_arithmetic::FixedPointNumber; @@ -107,32 +108,23 @@ parameter_types! { /// Maximum number of instructions in a single XCM fragment. A sanity check against weight /// calculations getting too crazy. pub const MaxInstructions: u32 = 100; -} - -pub struct ExponentialKsmPrice; -impl PriceForParachainDelivery for ExponentialKsmPrice { - fn price_for_parachain_delivery(para: ParaId, msg: &Xcm<()>) -> MultiAssets { - let base = CENTS.saturating_mul(3); - let msg_fee = (msg.len() as u128).saturating_mul(TransactionByteFee::get()); - - let excess_msgs = - Dmp::dmq_length(para).saturating_sub(parachains_dmp::MAX_MESSAGE_QUEUE_SIZE) as usize; - let factor = if excess_msgs != 0 { - Dmp::raise_fee_factor(excess_msgs) - } else { - Dmp::reduce_fee_factor(1) - }; - - let amount = factor.saturating_mul_int(base + msg_fee); - (Here, amount).into() - } + /// The asset ID for the asset that we use to pay for message delivery fees. + pub FeeAssetId: AssetId = Concrete(Here.into()); + /// The base fee for the message delivery fees. + pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); + /// The factor to multiply by for the message delivery fees. + pub FeeFactor: u128 = Dmp::delivery_fee_factor(); } /// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our /// individual routers. pub type XcmRouter = ( // Only one router so far - use DMP to communicate with child parachains. - ChildParachainRouter, + ChildParachainRouter< + Runtime, + XcmPallet, + ExponentialPrice, + >, ); parameter_types! { diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index eca785d3fe23..84d04d0750d4 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -32,7 +32,7 @@ pub use pallet::*; #[cfg(test)] mod tests; -pub const MAX_MESSAGE_QUEUE_SIZE: u32 = 1024; +pub const MAX_MESSAGE_QUEUE_SIZE: usize = 1024; pub const MULTIPLICATIVE_FEE_FACTOR: FixedU128 = FixedU128::from_rational(101, 100); // 1.01 /// An error sending a downward message. @@ -113,6 +113,7 @@ pub mod pallet { /// The number to multiply the base delivery fee by. #[pallet::storage] + #[pallet::getter(fn delivery_fee_factor)] pub(crate) type DeliveryFeeFactor = StorageValue<_, FixedU128, ValueQuery, InitialFactor>; } @@ -187,16 +188,21 @@ impl Pallet { InboundDownwardMessage { msg, sent_at: >::block_number() }; // obtain the new link in the MQC and update the head. - ::DownwardMessageQueueHeads::mutate(para, |head| { + DownwardMessageQueueHeads::::mutate(para, |head| { let new_head = BlakeTwo256::hash_of(&(*head, inbound.sent_at, T::Hashing::hash_of(&inbound.msg))); *head = new_head; }); - ::DownwardMessageQueues::mutate(para, |v| { + let q_len = DownwardMessageQueues::::mutate(para, |v| { v.push(inbound); + v.len() }); + if q_len > MAX_MESSAGE_QUEUE_SIZE { + Self::increment_fee_factor(); + } + Ok(()) } @@ -222,7 +228,7 @@ impl Pallet { /// Prunes the specified number of messages from the downward message queue of the given para. pub(crate) fn prune_dmq(para: ParaId, processed_downward_messages: u32) -> Weight { - ::DownwardMessageQueues::mutate(para, |q| { + let q_len = DownwardMessageQueues::::mutate(para, |q| { let processed_downward_messages = processed_downward_messages as usize; if processed_downward_messages > q.len() { // reaching this branch is unexpected due to the constraint established by @@ -231,7 +237,11 @@ impl Pallet { } else { *q = q.split_off(processed_downward_messages); } + q.len() }); + if q_len <= MAX_MESSAGE_QUEUE_SIZE { + Self::decrement_fee_factor(); + } T::DbWeight::get().reads_writes(1, 1) } @@ -245,7 +255,7 @@ impl Pallet { /// Returns the number of pending downward messages addressed to the given para. /// /// Returns 0 if the para doesn't have an associated downward message queue. - pub fn dmq_length(para: ParaId) -> u32 { + pub(crate) fn dmq_length(para: ParaId) -> u32 { ::DownwardMessageQueues::decode_len(¶) .unwrap_or(0) .saturated_into::() @@ -258,28 +268,24 @@ impl Pallet { ::DownwardMessageQueues::get(&recipient) } - /// Raise the delivery fee factor by a multiplicative factor to the power of `n`, and stores - /// the resulting value. + /// Raise the delivery fee factor by a multiplicative factor and stores the resulting value. /// - /// Returns the new delivery fee factor after the raise. - pub fn raise_fee_factor(n: usize) -> FixedU128 { + /// Returns the new delivery fee factor after the increment. + pub(crate) fn increment_fee_factor() -> FixedU128 { >::mutate(|f| { - let factor = MULTIPLICATIVE_FEE_FACTOR.saturating_pow(n); - *f = f.saturating_mul(factor); + *f = f.saturating_mul(MULTIPLICATIVE_FEE_FACTOR); *f }) } - /// Reduce the delivery fee factor by a multiplicative factor to the power of `n`, and stores - /// the resulting value. + /// Reduce the delivery fee factor by a multiplicative factor and stores the resulting value. /// /// Does not reduce the fee factor below the initial value, which is currently set as 1. /// - /// Returns the new delivery fee factor after the reduction. - pub fn reduce_fee_factor(n: usize) -> FixedU128 { + /// Returns the new delivery fee factor after the decrement. + pub(crate) fn decrement_fee_factor() -> FixedU128 { >::mutate(|f| { - let factor = MULTIPLICATIVE_FEE_FACTOR.saturating_pow(n); - *f = InitialFactor::get().min(*f / factor); + *f = InitialFactor::get().min(*f / MULTIPLICATIVE_FEE_FACTOR); *f }) } diff --git a/runtime/polkadot/src/xcm_config.rs b/runtime/polkadot/src/xcm_config.rs index 0a95aae26ec6..6a831b204728 100644 --- a/runtime/polkadot/src/xcm_config.rs +++ b/runtime/polkadot/src/xcm_config.rs @@ -17,19 +17,19 @@ //! XCM configuration for Polkadot. use super::{ - parachains_dmp, parachains_origin, AccountId, AllPalletsWithSystem, Balances, - CouncilCollective, Dmp, ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, - TransactionByteFee, WeightToFee, XcmPallet, + parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, Dmp, ParaId, + Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee, WeightToFee, XcmPallet, }; use frame_support::{ match_types, parameter_types, traits::{Contains, Everything, Nothing}, weights::Weight, }; +use parity_scale_codec::Encode; use polkadot_runtime_constants::currency::CENTS; use runtime_common::{ paras_registrar, - xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, + xcm_sender::{ChildParachainRouter, ExponentialPrice, PriceForParachainDelivery}, ToAuthor, }; use sp_arithmetic::FixedPointNumber; @@ -106,32 +106,23 @@ parameter_types! { /// Maximum number of instructions in a single XCM fragment. A sanity check against weight /// calculations getting too crazy. pub const MaxInstructions: u32 = 100; -} - -pub struct ExponentialDotPrice; -impl PriceForParachainDelivery for ExponentialDotPrice { - fn price_for_parachain_delivery(para: ParaId, msg: &Xcm<()>) -> MultiAssets { - let base = CENTS.saturating_mul(3); - let msg_fee = (msg.len() as u128).saturating_mul(TransactionByteFee::get()); - - let excess_msgs = - Dmp::dmq_length(para).saturating_sub(parachains_dmp::MAX_MESSAGE_QUEUE_SIZE) as usize; - let factor = if excess_msgs != 0 { - Dmp::raise_fee_factor(excess_msgs) - } else { - Dmp::reduce_fee_factor(1) - }; - - let amount = factor.saturating_mul_int(base + msg_fee); - (Here, amount).into() - } + /// The asset ID for the asset that we use to pay for message delivery fees. + pub FeeAssetId: AssetId = Concrete(Here.into()); + /// The base fee for the message delivery fees. + pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); + /// The factor to multiply by for the message delivery fees. + pub FeeFactor: u128 = Dmp::delivery_fee_factor(); } /// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our /// individual routers. pub type XcmRouter = ( // Only one router so far - use DMP to communicate with child parachains. - ChildParachainRouter, + ChildParachainRouter< + Runtime, + XcmPallet, + ExponentialPrice, + >, ); parameter_types! { diff --git a/runtime/rococo/src/xcm_config.rs b/runtime/rococo/src/xcm_config.rs index aee7a036b2e1..480923bb2aa5 100644 --- a/runtime/rococo/src/xcm_config.rs +++ b/runtime/rococo/src/xcm_config.rs @@ -17,19 +17,19 @@ //! XCM configuration for Rococo. use super::{ - parachains_dmp, parachains_origin, AccountId, AllPalletsWithSystem, Balances, - CouncilCollective, Dmp, ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, - TransactionByteFee, WeightToFee, XcmPallet, + parachains_origin, AccountId, AllPalletsWithSystem, Balances, CouncilCollective, Dmp, ParaId, + Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee, WeightToFee, XcmPallet, }; use frame_support::{ match_types, parameter_types, traits::{Contains, Everything, Nothing}, weights::Weight, }; +use parity_scale_codec::Encode; use rococo_runtime_constants::currency::CENTS; use runtime_common::{ paras_registrar, - xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, + xcm_sender::{ChildParachainRouter, ExponentialPrice, PriceForParachainDelivery}, ToAuthor, }; use sp_arithmetic::FixedPointNumber; @@ -88,32 +88,23 @@ type LocalOriginConverter = ( parameter_types! { /// The amount of weight an XCM operation takes. This is a safe overestimate. pub const BaseXcmWeight: Weight = Weight::from_parts(1_000_000_000, 64 * 1024); -} - -pub struct ExponentialRocPrice; -impl PriceForParachainDelivery for ExponentialRocPrice { - fn price_for_parachain_delivery(para: ParaId, msg: &Xcm<()>) -> MultiAssets { - let base = CENTS.saturating_mul(3); - let msg_fee = (msg.len() as u128).saturating_mul(TransactionByteFee::get()); - - let excess_msgs = - Dmp::dmq_length(para).saturating_sub(parachains_dmp::MAX_MESSAGE_QUEUE_SIZE) as usize; - let factor = if excess_msgs != 0 { - Dmp::raise_fee_factor(excess_msgs) - } else { - Dmp::reduce_fee_factor(1) - }; - - let amount = factor.saturating_mul_int(base + msg_fee); - (Here, amount).into() - } + /// The asset ID for the asset that we use to pay for message delivery fees. + pub FeeAssetId: AssetId = Concrete(Here.into()); + /// The base fee for the message delivery fees. + pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); + /// The factor to multiply by for the message delivery fees. + pub FeeFactor: u128 = Dmp::delivery_fee_factor(); } /// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our /// individual routers. pub type XcmRouter = ( // Only one router so far - use DMP to communicate with child parachains. - ChildParachainRouter, + ChildParachainRouter< + Runtime, + XcmPallet, + ExponentialPrice, + >, ); parameter_types! { diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index ba1487c40561..ebb7f860c49c 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -17,17 +17,17 @@ //! XCM configurations for Westend. use super::{ - parachains_dmp, parachains_origin, weights, AccountId, AllPalletsWithSystem, Balances, Dmp, - ParaId, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee, WeightToFee, - XcmPallet, + parachains_origin, weights, AccountId, AllPalletsWithSystem, Balances, Dmp, ParaId, Runtime, + RuntimeCall, RuntimeEvent, RuntimeOrigin, TransactionByteFee, WeightToFee, XcmPallet, }; use frame_support::{ parameter_types, traits::{Contains, Everything, Nothing}, }; +use parity_scale_codec::Encode; use runtime_common::{ paras_registrar, - xcm_sender::{ChildParachainRouter, PriceForParachainDelivery}, + xcm_sender::{ChildParachainRouter, ExponentialPrice, PriceForParachainDelivery}, ToAuthor, }; use sp_arithmetic::FixedPointNumber; @@ -50,6 +50,12 @@ parameter_types! { pub UniversalLocation: InteriorMultiLocation = ThisNetwork::get().into(); pub CheckAccount: AccountId = XcmPallet::check_account(); pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); + /// The asset ID for the asset that we use to pay for message delivery fees. + pub FeeAssetId: AssetId = Concrete(Here.into()); + /// The base fee for the message delivery fees. + pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); + /// The factor to multiply by for the message delivery fees. + pub FeeFactor: u128 = Dmp::delivery_fee_factor(); } pub type LocationConverter = @@ -75,30 +81,15 @@ type LocalOriginConverter = ( ChildSystemParachainAsSuperuser, ); -pub struct ExponentialWndPrice; -impl PriceForParachainDelivery for ExponentialWndPrice { - fn price_for_parachain_delivery(para: ParaId, msg: &Xcm<()>) -> MultiAssets { - let base = CENTS.saturating_mul(3); - let msg_fee = (msg.len() as u128).saturating_mul(TransactionByteFee::get()); - - let excess_msgs = - Dmp::dmq_length(para).saturating_sub(parachains_dmp::MAX_MESSAGE_QUEUE_SIZE) as usize; - let factor = if excess_msgs != 0 { - Dmp::raise_fee_factor(excess_msgs) - } else { - Dmp::reduce_fee_factor(1) - }; - - let amount = factor.saturating_mul_int(base + msg_fee); - (Here, amount).into() - } -} - /// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our /// individual routers. pub type XcmRouter = ( // Only one router so far - use DMP to communicate with child parachains. - ChildParachainRouter, + ChildParachainRouter< + Runtime, + XcmPallet, + ExponentialPrice, + >, ); parameter_types! { diff --git a/xcm/src/v3/mod.rs b/xcm/src/v3/mod.rs index 45a960f28ffe..ea24796e605c 100644 --- a/xcm/src/v3/mod.rs +++ b/xcm/src/v3/mod.rs @@ -925,7 +925,7 @@ pub enum Instruction { /// asset to be transferred. /// /// - `asset`: The asset to be unlocked. - /// - `owner`: The owner of the asset on the local chain. + /// - `target`: The owner of the asset on the local chain. /// /// Safety: No concerns. /// From c83126bbd698cc63f382bf7bcfc0897c98afc42e Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Wed, 15 Mar 2023 13:06:30 +0000 Subject: [PATCH 16/40] Remove unused imports --- runtime/common/src/xcm_sender.rs | 5 +++-- runtime/kusama/src/xcm_config.rs | 4 +--- runtime/polkadot/src/xcm_config.rs | 4 +--- runtime/rococo/src/xcm_config.rs | 4 +--- runtime/westend/src/xcm_config.rs | 4 +--- 5 files changed, 7 insertions(+), 14 deletions(-) diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs index e3c030526c0f..0d5db7ae1a8c 100644 --- a/runtime/common/src/xcm_sender.rs +++ b/runtime/common/src/xcm_sender.rs @@ -23,6 +23,7 @@ use runtime_parachains::{ configuration::{self, HostConfiguration}, dmp, }; +use sp_runtime::{FixedPointNumber, FixedU128}; use sp_std::{marker::PhantomData, prelude::*}; use xcm::prelude::*; use SendError::*; @@ -54,13 +55,13 @@ impl> PriceForParachainDelivery for ConstantPrice { /// The formula for the fee is based on the sum of a base fee plus a message length fee, multiplied /// by a specified factor. In mathematical form, it is `F * (B + msg_len * M)`. pub struct ExponentialPrice(sp_std::marker::PhantomData<(A, B, M, F)>); -impl, B: Get, M: Get, F: Get> PriceForParachainDelivery +impl, B: Get, M: Get, F: Get> PriceForParachainDelivery for ExponentialPrice { fn price_for_parachain_delivery(_: ParaId, msg: &Xcm<()>) -> MultiAssets { let msg_fee = (msg.encoded_size() as u128).saturating_mul(M::get()); let fee_sum = B::get().saturating_add(msg_fee); - let amount = F::get().saturating_mul(fee_sum); + let amount = F::get().saturating_mul_int(fee_sum); (A::get(), amount).into() } } diff --git a/runtime/kusama/src/xcm_config.rs b/runtime/kusama/src/xcm_config.rs index 57d85d0fca5b..e8e6b5a4215b 100644 --- a/runtime/kusama/src/xcm_config.rs +++ b/runtime/kusama/src/xcm_config.rs @@ -27,13 +27,11 @@ use frame_support::{ weights::Weight, }; use kusama_runtime_constants::currency::CENTS; -use parity_scale_codec::Encode; use runtime_common::{ paras_registrar, - xcm_sender::{ChildParachainRouter, ExponentialPrice, PriceForParachainDelivery}, + xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; -use sp_arithmetic::FixedPointNumber; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ diff --git a/runtime/polkadot/src/xcm_config.rs b/runtime/polkadot/src/xcm_config.rs index 6a831b204728..b2e169bb8c19 100644 --- a/runtime/polkadot/src/xcm_config.rs +++ b/runtime/polkadot/src/xcm_config.rs @@ -25,14 +25,12 @@ use frame_support::{ traits::{Contains, Everything, Nothing}, weights::Weight, }; -use parity_scale_codec::Encode; use polkadot_runtime_constants::currency::CENTS; use runtime_common::{ paras_registrar, - xcm_sender::{ChildParachainRouter, ExponentialPrice, PriceForParachainDelivery}, + xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; -use sp_arithmetic::FixedPointNumber; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ diff --git a/runtime/rococo/src/xcm_config.rs b/runtime/rococo/src/xcm_config.rs index 480923bb2aa5..0de388ec3989 100644 --- a/runtime/rococo/src/xcm_config.rs +++ b/runtime/rococo/src/xcm_config.rs @@ -25,14 +25,12 @@ use frame_support::{ traits::{Contains, Everything, Nothing}, weights::Weight, }; -use parity_scale_codec::Encode; use rococo_runtime_constants::currency::CENTS; use runtime_common::{ paras_registrar, - xcm_sender::{ChildParachainRouter, ExponentialPrice, PriceForParachainDelivery}, + xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; -use sp_arithmetic::FixedPointNumber; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index ebb7f860c49c..fbfcbbeb665f 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -24,13 +24,11 @@ use frame_support::{ parameter_types, traits::{Contains, Everything, Nothing}, }; -use parity_scale_codec::Encode; use runtime_common::{ paras_registrar, - xcm_sender::{ChildParachainRouter, ExponentialPrice, PriceForParachainDelivery}, + xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; -use sp_arithmetic::FixedPointNumber; use sp_core::ConstU32; use westend_runtime_constants::currency::CENTS; use xcm::latest::prelude::*; From 8c7c9f97cf27e41f68c923aa0dd14ba35168e063 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Wed, 15 Mar 2023 13:26:45 +0000 Subject: [PATCH 17/40] Fixes --- runtime/kusama/src/xcm_config.rs | 3 ++- runtime/polkadot/src/xcm_config.rs | 3 ++- runtime/rococo/src/xcm_config.rs | 3 ++- runtime/westend/src/xcm_config.rs | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/runtime/kusama/src/xcm_config.rs b/runtime/kusama/src/xcm_config.rs index e8e6b5a4215b..bf1d8e31b146 100644 --- a/runtime/kusama/src/xcm_config.rs +++ b/runtime/kusama/src/xcm_config.rs @@ -32,6 +32,7 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; +use sp_arithmetic::FixedU128; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ @@ -111,7 +112,7 @@ parameter_types! { /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); /// The factor to multiply by for the message delivery fees. - pub FeeFactor: u128 = Dmp::delivery_fee_factor(); + pub FeeFactor: FixedU128 = Dmp::delivery_fee_factor(); } /// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our diff --git a/runtime/polkadot/src/xcm_config.rs b/runtime/polkadot/src/xcm_config.rs index b2e169bb8c19..4865ec9fd9b7 100644 --- a/runtime/polkadot/src/xcm_config.rs +++ b/runtime/polkadot/src/xcm_config.rs @@ -31,6 +31,7 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; +use sp_arithmetic::FixedU128; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ @@ -109,7 +110,7 @@ parameter_types! { /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); /// The factor to multiply by for the message delivery fees. - pub FeeFactor: u128 = Dmp::delivery_fee_factor(); + pub FeeFactor: FixedU128 = Dmp::delivery_fee_factor(); } /// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our diff --git a/runtime/rococo/src/xcm_config.rs b/runtime/rococo/src/xcm_config.rs index 0de388ec3989..3bb372aa6b7b 100644 --- a/runtime/rococo/src/xcm_config.rs +++ b/runtime/rococo/src/xcm_config.rs @@ -31,6 +31,7 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; +use sp_arithmetic::FixedU128; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ @@ -91,7 +92,7 @@ parameter_types! { /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); /// The factor to multiply by for the message delivery fees. - pub FeeFactor: u128 = Dmp::delivery_fee_factor(); + pub FeeFactor: FixedU128 = Dmp::delivery_fee_factor(); } /// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index fbfcbbeb665f..7a18fa504f68 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -29,6 +29,7 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; +use sp_arithmetic::FixedU128; use sp_core::ConstU32; use westend_runtime_constants::currency::CENTS; use xcm::latest::prelude::*; @@ -53,7 +54,7 @@ parameter_types! { /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); /// The factor to multiply by for the message delivery fees. - pub FeeFactor: u128 = Dmp::delivery_fee_factor(); + pub FeeFactor: FixedU128 = Dmp::delivery_fee_factor(); } pub type LocationConverter = From 395a70b4fca9f38d1a3216d7dd7b8edd10637e81 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Thu, 16 Mar 2023 11:55:03 +0000 Subject: [PATCH 18/40] Update runtime/parachains/src/dmp.rs Co-authored-by: Squirrel --- runtime/parachains/src/dmp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index d166ca8f7bde..2f5cc25e59e7 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -284,7 +284,7 @@ impl Pallet { /// Returns the new delivery fee factor after the decrement. pub(crate) fn decrement_fee_factor() -> FixedU128 { >::mutate(|f| { - *f = InitialFactor::get().min(*f / MULTIPLICATIVE_FEE_FACTOR); + *f = InitialFactor::get().max(*f / MULTIPLICATIVE_FEE_FACTOR); *f }) } From a938c9c5a27b61b95a7da73a5269cb026bb4c5bf Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Tue, 21 Mar 2023 23:55:15 +0800 Subject: [PATCH 19/40] Make DeliveryFeeFactor be a StorageMap keyed on ParaIds --- runtime/parachains/src/dmp.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index 2f5cc25e59e7..72303c40eeb2 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -114,7 +114,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn delivery_fee_factor)] pub(crate) type DeliveryFeeFactor = - StorageValue<_, FixedU128, ValueQuery, InitialFactor>; + StorageMap<_, Twox64Concat, ParaId, FixedU128, ValueQuery, InitialFactor>; } /// Routines and getters related to downward message passing. @@ -199,7 +199,7 @@ impl Pallet { }); if q_len > MAX_MESSAGE_QUEUE_SIZE { - Self::increment_fee_factor(); + Self::increment_fee_factor(para); } Ok(()) @@ -239,7 +239,7 @@ impl Pallet { q.len() }); if q_len <= MAX_MESSAGE_QUEUE_SIZE { - Self::decrement_fee_factor(); + Self::decrement_fee_factor(para); } T::DbWeight::get().reads_writes(1, 1) } @@ -270,8 +270,8 @@ impl Pallet { /// Raise the delivery fee factor by a multiplicative factor and stores the resulting value. /// /// Returns the new delivery fee factor after the increment. - pub(crate) fn increment_fee_factor() -> FixedU128 { - >::mutate(|f| { + pub(crate) fn increment_fee_factor(para: ParaId) -> FixedU128 { + >::mutate(para, |f| { *f = f.saturating_mul(MULTIPLICATIVE_FEE_FACTOR); *f }) @@ -282,8 +282,8 @@ impl Pallet { /// Does not reduce the fee factor below the initial value, which is currently set as 1. /// /// Returns the new delivery fee factor after the decrement. - pub(crate) fn decrement_fee_factor() -> FixedU128 { - >::mutate(|f| { + pub(crate) fn decrement_fee_factor(para: ParaId) -> FixedU128 { + >::mutate(para, |f| { *f = InitialFactor::get().max(*f / MULTIPLICATIVE_FEE_FACTOR); *f }) From 56a018d2fa722ea6b3233720fafe02008ab21f57 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Wed, 22 Mar 2023 06:28:16 +0800 Subject: [PATCH 20/40] Fixes --- runtime/common/src/xcm_sender.rs | 12 ++++++------ runtime/kusama/src/xcm_config.rs | 5 +---- runtime/parachains/src/dmp.rs | 8 +++++++- runtime/parachains/src/lib.rs | 7 ++++++- runtime/polkadot/src/xcm_config.rs | 5 +---- runtime/rococo/src/xcm_config.rs | 5 +---- runtime/westend/src/xcm_config.rs | 5 +---- 7 files changed, 23 insertions(+), 24 deletions(-) diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs index 0d5db7ae1a8c..b6c8e76be151 100644 --- a/runtime/common/src/xcm_sender.rs +++ b/runtime/common/src/xcm_sender.rs @@ -21,9 +21,9 @@ use parity_scale_codec::Encode; use primitives::Id as ParaId; use runtime_parachains::{ configuration::{self, HostConfiguration}, - dmp, + dmp, FeeTracker, }; -use sp_runtime::{FixedPointNumber, FixedU128}; +use sp_runtime::FixedPointNumber; use sp_std::{marker::PhantomData, prelude::*}; use xcm::prelude::*; use SendError::*; @@ -53,15 +53,15 @@ impl> PriceForParachainDelivery for ConstantPrice { /// fee. /// /// The formula for the fee is based on the sum of a base fee plus a message length fee, multiplied -/// by a specified factor. In mathematical form, it is `F * (B + msg_len * M)`. +/// by a specified factor. In mathematical form, it is `F * (B + encoded_msg_len * M)`. pub struct ExponentialPrice(sp_std::marker::PhantomData<(A, B, M, F)>); -impl, B: Get, M: Get, F: Get> PriceForParachainDelivery +impl, B: Get, M: Get, F: FeeTracker> PriceForParachainDelivery for ExponentialPrice { - fn price_for_parachain_delivery(_: ParaId, msg: &Xcm<()>) -> MultiAssets { + fn price_for_parachain_delivery(para: ParaId, msg: &Xcm<()>) -> MultiAssets { let msg_fee = (msg.encoded_size() as u128).saturating_mul(M::get()); let fee_sum = B::get().saturating_add(msg_fee); - let amount = F::get().saturating_mul_int(fee_sum); + let amount = F::get_fee_factor(para).saturating_mul_int(fee_sum); (A::get(), amount).into() } } diff --git a/runtime/kusama/src/xcm_config.rs b/runtime/kusama/src/xcm_config.rs index bf1d8e31b146..5bcaa38e7407 100644 --- a/runtime/kusama/src/xcm_config.rs +++ b/runtime/kusama/src/xcm_config.rs @@ -32,7 +32,6 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; -use sp_arithmetic::FixedU128; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ @@ -111,8 +110,6 @@ parameter_types! { pub FeeAssetId: AssetId = Concrete(Here.into()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); - /// The factor to multiply by for the message delivery fees. - pub FeeFactor: FixedU128 = Dmp::delivery_fee_factor(); } /// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our @@ -122,7 +119,7 @@ pub type XcmRouter = ( ChildParachainRouter< Runtime, XcmPallet, - ExponentialPrice, + ExponentialPrice, >, ); diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index 72303c40eeb2..b095ce01182d 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -16,7 +16,7 @@ use crate::{ configuration::{self, HostConfiguration}, - initializer, + initializer, FeeTracker, }; use frame_support::pallet_prelude::*; use primitives::{DownwardMessage, Hash, Id as ParaId, InboundDownwardMessage}; @@ -289,3 +289,9 @@ impl Pallet { }) } } + +impl FeeTracker for Pallet { + fn get_fee_factor(para: ParaId) -> FixedU128 { + Pallet::::delivery_fee_factor(para) + } +} diff --git a/runtime/parachains/src/lib.rs b/runtime/parachains/src/lib.rs index c45f0d446015..c57c5aac9b7d 100644 --- a/runtime/parachains/src/lib.rs +++ b/runtime/parachains/src/lib.rs @@ -51,7 +51,12 @@ mod mock; pub use origin::{ensure_parachain, Origin}; pub use paras::ParaLifecycle; use primitives::{HeadData, Id as ParaId, ValidationCode}; -use sp_runtime::DispatchResult; +use sp_runtime::{DispatchResult, FixedU128}; + +/// Trait for tracking message delivery fees on a transport protocol. +pub trait FeeTracker { + fn get_fee_factor(para: ParaId) -> FixedU128; +} /// Schedule a para to be initialized at the start of the next session with the given genesis data. /// diff --git a/runtime/polkadot/src/xcm_config.rs b/runtime/polkadot/src/xcm_config.rs index 4865ec9fd9b7..c60c94e8f4b5 100644 --- a/runtime/polkadot/src/xcm_config.rs +++ b/runtime/polkadot/src/xcm_config.rs @@ -31,7 +31,6 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; -use sp_arithmetic::FixedU128; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ @@ -109,8 +108,6 @@ parameter_types! { pub FeeAssetId: AssetId = Concrete(Here.into()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); - /// The factor to multiply by for the message delivery fees. - pub FeeFactor: FixedU128 = Dmp::delivery_fee_factor(); } /// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our @@ -120,7 +117,7 @@ pub type XcmRouter = ( ChildParachainRouter< Runtime, XcmPallet, - ExponentialPrice, + ExponentialPrice, >, ); diff --git a/runtime/rococo/src/xcm_config.rs b/runtime/rococo/src/xcm_config.rs index 3bb372aa6b7b..dfc6b89e2395 100644 --- a/runtime/rococo/src/xcm_config.rs +++ b/runtime/rococo/src/xcm_config.rs @@ -31,7 +31,6 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; -use sp_arithmetic::FixedU128; use sp_core::ConstU32; use xcm::latest::prelude::*; use xcm_builder::{ @@ -91,8 +90,6 @@ parameter_types! { pub FeeAssetId: AssetId = Concrete(Here.into()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); - /// The factor to multiply by for the message delivery fees. - pub FeeFactor: FixedU128 = Dmp::delivery_fee_factor(); } /// The XCM router. When we want to send an XCM message, we use this type. It amalgamates all of our @@ -102,7 +99,7 @@ pub type XcmRouter = ( ChildParachainRouter< Runtime, XcmPallet, - ExponentialPrice, + ExponentialPrice, >, ); diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index 7a18fa504f68..5a2ff32b6d1a 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -29,7 +29,6 @@ use runtime_common::{ xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; -use sp_arithmetic::FixedU128; use sp_core::ConstU32; use westend_runtime_constants::currency::CENTS; use xcm::latest::prelude::*; @@ -53,8 +52,6 @@ parameter_types! { pub FeeAssetId: AssetId = Concrete(Here.into()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); - /// The factor to multiply by for the message delivery fees. - pub FeeFactor: FixedU128 = Dmp::delivery_fee_factor(); } pub type LocationConverter = @@ -87,7 +84,7 @@ pub type XcmRouter = ( ChildParachainRouter< Runtime, XcmPallet, - ExponentialPrice, + ExponentialPrice, >, ); From 838b9b59b68afd8fc287cc3210cf127e0e6edacc Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Wed, 22 Mar 2023 19:16:48 +0100 Subject: [PATCH 21/40] introduce limit for fee increase on dmp queue --- runtime/parachains/src/dmp.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index b095ce01182d..89fda0241ab7 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -20,6 +20,7 @@ use crate::{ }; use frame_support::pallet_prelude::*; use primitives::{DownwardMessage, Hash, Id as ParaId, InboundDownwardMessage}; +use sp_core::MAX_POSSIBLE_ALLOCATION; use sp_runtime::{ traits::{BlakeTwo256, Hash as HashT, SaturatedConversion}, FixedU128, Saturating, @@ -198,7 +199,11 @@ impl Pallet { v.len() }); - if q_len > MAX_MESSAGE_QUEUE_SIZE { + if q_len > + (MAX_POSSIBLE_ALLOCATION + .saturating_div(config.max_downward_message_size) + .saturating_div(2u32)) as usize + { Self::increment_fee_factor(para); } @@ -238,7 +243,13 @@ impl Pallet { } q.len() }); - if q_len <= MAX_MESSAGE_QUEUE_SIZE { + + let config = configuration::ActiveConfig::::get(); + if q_len <= + (MAX_POSSIBLE_ALLOCATION + .saturating_div(config.max_downward_message_size) + .saturating_div(2u32)) as usize + { Self::decrement_fee_factor(para); } T::DbWeight::get().reads_writes(1, 1) From 1a2bcd63711b8b1bc6e0e302ded430efb4045298 Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Thu, 23 Mar 2023 10:32:52 +0100 Subject: [PATCH 22/40] add message_size based fee factor to increment_fee_factor --- runtime/parachains/src/dmp.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index 89fda0241ab7..f6462c02ba66 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -34,7 +34,8 @@ pub use pallet::*; mod tests; pub const MAX_MESSAGE_QUEUE_SIZE: usize = 1024; -pub const MULTIPLICATIVE_FEE_FACTOR: FixedU128 = FixedU128::from_rational(101, 100); // 1.01 +pub const EXPONENTIAL_FEE_BASE: FixedU128 = FixedU128::from_rational(101, 100); // 1.01 +pub const MESSAGE_SIZE_FEE_BASE: FixedU128 = FixedU128::from_rational(1001, 1000); //1.001 /// An error sending a downward message. #[cfg_attr(test, derive(Debug))] @@ -204,7 +205,10 @@ impl Pallet { .saturating_div(config.max_downward_message_size) .saturating_div(2u32)) as usize { - Self::increment_fee_factor(para); + let message_size_factor = + FixedU128::from_inner(serialized_len.saturating_div(1024) as u128) + .saturating_mul(MESSAGE_SIZE_FEE_BASE); + Self::increment_fee_factor(para, message_size_factor); } Ok(()) @@ -281,9 +285,9 @@ impl Pallet { /// Raise the delivery fee factor by a multiplicative factor and stores the resulting value. /// /// Returns the new delivery fee factor after the increment. - pub(crate) fn increment_fee_factor(para: ParaId) -> FixedU128 { + pub(crate) fn increment_fee_factor(para: ParaId, message_size_factor: FixedU128) -> FixedU128 { >::mutate(para, |f| { - *f = f.saturating_mul(MULTIPLICATIVE_FEE_FACTOR); + *f = f.saturating_mul(EXPONENTIAL_FEE_BASE + message_size_factor); *f }) } @@ -295,7 +299,7 @@ impl Pallet { /// Returns the new delivery fee factor after the decrement. pub(crate) fn decrement_fee_factor(para: ParaId) -> FixedU128 { >::mutate(para, |f| { - *f = InitialFactor::get().max(*f / MULTIPLICATIVE_FEE_FACTOR); + *f = InitialFactor::get().max(*f / EXPONENTIAL_FEE_BASE); *f }) } From 35466987b6a12ba2106870d1f24c5c93fce52188 Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Thu, 23 Mar 2023 10:44:31 +0100 Subject: [PATCH 23/40] change message_size fee rate to correct value --- runtime/parachains/src/dmp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index f6462c02ba66..43a66960c251 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -35,7 +35,7 @@ mod tests; pub const MAX_MESSAGE_QUEUE_SIZE: usize = 1024; pub const EXPONENTIAL_FEE_BASE: FixedU128 = FixedU128::from_rational(101, 100); // 1.01 -pub const MESSAGE_SIZE_FEE_BASE: FixedU128 = FixedU128::from_rational(1001, 1000); //1.001 +pub const MESSAGE_SIZE_FEE_BASE: FixedU128 = FixedU128::from_rational(1, 1000); //0.001 /// An error sending a downward message. #[cfg_attr(test, derive(Debug))] From da90e3510eb486225b76ea0c302e8b56b366cf01 Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Thu, 23 Mar 2023 11:51:27 +0100 Subject: [PATCH 24/40] fix div by 0 error --- runtime/parachains/src/dmp.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index 43a66960c251..badc9d434d96 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -35,7 +35,7 @@ mod tests; pub const MAX_MESSAGE_QUEUE_SIZE: usize = 1024; pub const EXPONENTIAL_FEE_BASE: FixedU128 = FixedU128::from_rational(101, 100); // 1.01 -pub const MESSAGE_SIZE_FEE_BASE: FixedU128 = FixedU128::from_rational(1, 1000); //0.001 +pub const MESSAGE_SIZE_FEE_BASE: FixedU128 = FixedU128::from_rational(1, 1000); // 0.001 /// An error sending a downward message. #[cfg_attr(test, derive(Debug))] @@ -202,7 +202,8 @@ impl Pallet { if q_len > (MAX_POSSIBLE_ALLOCATION - .saturating_div(config.max_downward_message_size) + .checked_div(config.max_downward_message_size) + .unwrap_or(51200u32) .saturating_div(2u32)) as usize { let message_size_factor = @@ -251,7 +252,8 @@ impl Pallet { let config = configuration::ActiveConfig::::get(); if q_len <= (MAX_POSSIBLE_ALLOCATION - .saturating_div(config.max_downward_message_size) + .checked_div(config.max_downward_message_size) + .unwrap_or(51200u32) .saturating_div(2u32)) as usize { Self::decrement_fee_factor(para); From 9eefb518a9d4e63bc313253ebfa4bcfdb87de16c Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Thu, 23 Mar 2023 12:02:57 +0100 Subject: [PATCH 25/40] bind limit to variable --- runtime/parachains/src/dmp.rs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index badc9d434d96..d891af924943 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -199,13 +199,11 @@ impl Pallet { v.push(inbound); v.len() }); - - if q_len > - (MAX_POSSIBLE_ALLOCATION - .checked_div(config.max_downward_message_size) - .unwrap_or(51200u32) - .saturating_div(2u32)) as usize - { + let delivery_fee_limit = (MAX_POSSIBLE_ALLOCATION + .checked_div(config.max_downward_message_size) + .unwrap_or(51200u32) + .saturating_div(2u32)) as usize; + if q_len > delivery_fee_limit { let message_size_factor = FixedU128::from_inner(serialized_len.saturating_div(1024) as u128) .saturating_mul(MESSAGE_SIZE_FEE_BASE); @@ -250,12 +248,11 @@ impl Pallet { }); let config = configuration::ActiveConfig::::get(); - if q_len <= - (MAX_POSSIBLE_ALLOCATION - .checked_div(config.max_downward_message_size) - .unwrap_or(51200u32) - .saturating_div(2u32)) as usize - { + let delivery_fee_limit = (MAX_POSSIBLE_ALLOCATION + .checked_div(config.max_downward_message_size) + .unwrap_or(51200u32) + .saturating_div(2u32)) as usize; + if q_len <= delivery_fee_limit { Self::decrement_fee_factor(para); } T::DbWeight::get().reads_writes(1, 1) From 7086ec19e078489639f944f043087c4a156eb09d Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Fri, 24 Mar 2023 16:40:27 +0100 Subject: [PATCH 26/40] fix message_size_factor and add DeliveryFeeFactor test --- runtime/parachains/src/dmp.rs | 7 ++--- runtime/parachains/src/dmp/tests.rs | 42 +++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index d891af924943..68678ba2239b 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -108,8 +108,9 @@ pub mod pallet { pub(crate) type DownwardMessageQueueHeads = StorageMap<_, Twox64Concat, ParaId, Hash, ValueQuery>; - frame_support::parameter_types! { - pub InitialFactor: FixedU128 = FixedU128::from_u32(1); + #[pallet::type_value] + pub fn InitialFactor() -> FixedU128 { + FixedU128::from_u32(1) } /// The number to multiply the base delivery fee by. @@ -205,7 +206,7 @@ impl Pallet { .saturating_div(2u32)) as usize; if q_len > delivery_fee_limit { let message_size_factor = - FixedU128::from_inner(serialized_len.saturating_div(1024) as u128) + FixedU128::from_u32(serialized_len.saturating_div(1024) as u32) .saturating_mul(MESSAGE_SIZE_FEE_BASE); Self::increment_fee_factor(para, message_size_factor); } diff --git a/runtime/parachains/src/dmp/tests.rs b/runtime/parachains/src/dmp/tests.rs index a3d9b6e3ac85..50a1fe9f3982 100644 --- a/runtime/parachains/src/dmp/tests.rs +++ b/runtime/parachains/src/dmp/tests.rs @@ -205,3 +205,45 @@ fn verify_dmq_mqc_head_is_externally_accessible() { ); }); } + +#[test] +fn verify_fee_increment_and_decrement() { + let a = ParaId::from(123); + + let mut genesis = default_genesis_config(); + // Sets `delivery_fee_limit` to 1 message + genesis.configuration.config.max_downward_message_size = 16_777_216; + + new_test_ext(genesis).execute_with(|| { + assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_u32(1)); + + // Under fee limit + queue_downward_message(a, vec![1]).unwrap(); + assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_u32(1)); + + // Limit reached so fee is increased + queue_downward_message(a, vec![1]).unwrap(); + assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_float(1.01)); + + Dmp::prune_dmq(a, 1); + assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_u32(1)); + + // 10 Kb message adds additional 0.001 per KB fee factor + let big_message = [0; 10240].to_vec(); + queue_downward_message(a, big_message).unwrap(); + assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_float(1.02)); + + queue_downward_message(a, vec![1]).unwrap(); + assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_float(1.0302)); + Dmp::prune_dmq(a, 3); + assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_float(1.02)); + assert_eq!(Dmp::dmq_length(a), 0); + + // Messages under limit will keep decreasing fee factor until base fee factor is reached + queue_downward_message(a, vec![1]).unwrap(); + Dmp::prune_dmq(a, 1); + queue_downward_message(a, vec![1]).unwrap(); + Dmp::prune_dmq(a, 1); + assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_u32(1)); + }); +} From f2f042749093e07023c03f70707f2bd84502996d Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Mon, 27 Mar 2023 12:39:26 +0200 Subject: [PATCH 27/40] add test for ExponentialPrice implementation --- runtime/common/src/xcm_sender.rs | 46 ++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs index b6c8e76be151..fd18e02cea40 100644 --- a/runtime/common/src/xcm_sender.rs +++ b/runtime/common/src/xcm_sender.rs @@ -107,3 +107,49 @@ impl FixedU128 { + FixedU128::from_rational(101, 100) + } + } + + type TestExponentialPrice = + ExponentialPrice; + + #[test] + fn exponential_price_correct_price_calculation() { + // message size = 1 + assert_eq!( + TestExponentialPrice::price_for_parachain_delivery(123.into(), &Xcm(vec![])), + (FeeAssetId::get(), 304_010_000).into() + ); + // message size = 2 + assert_eq!( + TestExponentialPrice::price_for_parachain_delivery(123.into(), &Xcm(vec![ClearOrigin])), + (FeeAssetId::get(), 305_020_000).into() + ); + // message size = 4 + assert_eq!( + TestExponentialPrice::price_for_parachain_delivery( + 123.into(), + &Xcm(vec![SetAppendix(Xcm(vec![ClearOrigin]))]) + ), + (FeeAssetId::get(), 307_040_000).into() + ); + } +} From e1fa3380f74291c95bd5edf837461276f03a0b5d Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Mon, 27 Mar 2023 14:01:02 +0200 Subject: [PATCH 28/40] make test formula based --- runtime/common/src/xcm_sender.rs | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs index fd18e02cea40..d0557039d5b0 100644 --- a/runtime/common/src/xcm_sender.rs +++ b/runtime/common/src/xcm_sender.rs @@ -133,23 +133,35 @@ mod tests { #[test] fn exponential_price_correct_price_calculation() { - // message size = 1 + let id: ParaId = 123.into(); + let b: u128 = BaseDeliveryFee::get(); + let m: u128 = TransactionByteFee::get(); + + // F * (B + msg_length * M) + // message_length = 1 + let result: u128 = TestFeeTracker::get_fee_factor(id.clone()).saturating_mul_int(b + m); assert_eq!( - TestExponentialPrice::price_for_parachain_delivery(123.into(), &Xcm(vec![])), - (FeeAssetId::get(), 304_010_000).into() + TestExponentialPrice::price_for_parachain_delivery(id.clone(), &Xcm(vec![])), + (FeeAssetId::get(), result).into() ); + // message size = 2 + let result: u128 = + TestFeeTracker::get_fee_factor(id.clone()).saturating_mul_int(b + (2 * m)); assert_eq!( - TestExponentialPrice::price_for_parachain_delivery(123.into(), &Xcm(vec![ClearOrigin])), - (FeeAssetId::get(), 305_020_000).into() + TestExponentialPrice::price_for_parachain_delivery(id.clone(), &Xcm(vec![ClearOrigin])), + (FeeAssetId::get(), result).into() ); + // message size = 4 + let result: u128 = + TestFeeTracker::get_fee_factor(id.clone()).saturating_mul_int(b + (4 * m)); assert_eq!( TestExponentialPrice::price_for_parachain_delivery( - 123.into(), + id.clone(), &Xcm(vec![SetAppendix(Xcm(vec![ClearOrigin]))]) ), - (FeeAssetId::get(), 307_040_000).into() + (FeeAssetId::get(), result).into() ); } } From 303d7d5bc825cdaa2235ff20473ac77672526c7e Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Mon, 27 Mar 2023 14:45:44 +0200 Subject: [PATCH 29/40] make delivery fee factor test formula based --- runtime/parachains/src/dmp/tests.rs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/runtime/parachains/src/dmp/tests.rs b/runtime/parachains/src/dmp/tests.rs index 50a1fe9f3982..ec07a2094137 100644 --- a/runtime/parachains/src/dmp/tests.rs +++ b/runtime/parachains/src/dmp/tests.rs @@ -215,28 +215,38 @@ fn verify_fee_increment_and_decrement() { genesis.configuration.config.max_downward_message_size = 16_777_216; new_test_ext(genesis).execute_with(|| { - assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_u32(1)); + let default = InitialFactor::get(); + assert_eq!(DeliveryFeeFactor::::get(a), default); // Under fee limit queue_downward_message(a, vec![1]).unwrap(); - assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_u32(1)); + assert_eq!(DeliveryFeeFactor::::get(a), default); // Limit reached so fee is increased queue_downward_message(a, vec![1]).unwrap(); - assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_float(1.01)); + let result = InitialFactor::get().saturating_mul(EXPONENTIAL_FEE_BASE); + assert_eq!(DeliveryFeeFactor::::get(a), result); Dmp::prune_dmq(a, 1); - assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_u32(1)); + assert_eq!(DeliveryFeeFactor::::get(a), default); // 10 Kb message adds additional 0.001 per KB fee factor let big_message = [0; 10240].to_vec(); + let msg_len_in_kb = big_message.len().saturating_div(1024) as u32; + let result = default.saturating_mul( + EXPONENTIAL_FEE_BASE + + MESSAGE_SIZE_FEE_BASE.saturating_mul(FixedU128::from_u32(msg_len_in_kb)), + ); queue_downward_message(a, big_message).unwrap(); - assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_float(1.02)); + assert_eq!(DeliveryFeeFactor::::get(a), result); queue_downward_message(a, vec![1]).unwrap(); - assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_float(1.0302)); + let result = result.saturating_mul(EXPONENTIAL_FEE_BASE); + assert_eq!(DeliveryFeeFactor::::get(a), result); + Dmp::prune_dmq(a, 3); - assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_float(1.02)); + let result = result / EXPONENTIAL_FEE_BASE; + assert_eq!(DeliveryFeeFactor::::get(a), result); assert_eq!(Dmp::dmq_length(a), 0); // Messages under limit will keep decreasing fee factor until base fee factor is reached @@ -244,6 +254,6 @@ fn verify_fee_increment_and_decrement() { Dmp::prune_dmq(a, 1); queue_downward_message(a, vec![1]).unwrap(); Dmp::prune_dmq(a, 1); - assert_eq!(DeliveryFeeFactor::::get(a), FixedU128::from_u32(1)); + assert_eq!(DeliveryFeeFactor::::get(a), default); }); } From 8588ce915d8e08ccca0bec17228b98c917ad9067 Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Tue, 28 Mar 2023 12:49:31 +0200 Subject: [PATCH 30/40] add max value test for DeliveryFeeFactor and move limit to config --- runtime/kusama/src/lib.rs | 8 +++++- runtime/parachains/src/dmp.rs | 44 ++++++++++++++++++++--------- runtime/parachains/src/dmp/tests.rs | 20 ++++++++++--- runtime/parachains/src/mock.rs | 8 +++++- runtime/polkadot/src/lib.rs | 8 +++++- runtime/rococo/src/lib.rs | 8 +++++- runtime/test-runtime/src/lib.rs | 8 +++++- runtime/westend/src/lib.rs | 8 +++++- 8 files changed, 88 insertions(+), 24 deletions(-) diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index 482d52e75c49..9fd32ab12d09 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -1110,7 +1110,13 @@ impl parachains_ump::Config for Runtime { type WeightInfo = weights::runtime_parachains_ump::WeightInfo; } -impl parachains_dmp::Config for Runtime {} +parameter_types! { + pub const MessageQueueFeeLimit: u32 = 320; +} + +impl parachains_dmp::Config for Runtime { + type MessageQueueFeeLimit = MessageQueueFeeLimit; +} impl parachains_hrmp::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index 68678ba2239b..cd3d6e17d1dc 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -19,6 +19,7 @@ use crate::{ initializer, FeeTracker, }; use frame_support::pallet_prelude::*; +use frame_system::pallet_prelude::*; use primitives::{DownwardMessage, Hash, Id as ParaId, InboundDownwardMessage}; use sp_core::MAX_POSSIBLE_ALLOCATION; use sp_runtime::{ @@ -34,8 +35,8 @@ pub use pallet::*; mod tests; pub const MAX_MESSAGE_QUEUE_SIZE: usize = 1024; -pub const EXPONENTIAL_FEE_BASE: FixedU128 = FixedU128::from_rational(101, 100); // 1.01 -pub const MESSAGE_SIZE_FEE_BASE: FixedU128 = FixedU128::from_rational(1, 1000); // 0.001 +const EXPONENTIAL_FEE_BASE: FixedU128 = FixedU128::from_rational(101, 100); // 1.01 +const MESSAGE_SIZE_FEE_BASE: FixedU128 = FixedU128::from_rational(1, 1000); // 0.001 /// An error sending a downward message. #[cfg_attr(test, derive(Debug))] @@ -85,7 +86,12 @@ pub mod pallet { pub struct Pallet(_); #[pallet::config] - pub trait Config: frame_system::Config + configuration::Config {} + pub trait Config: frame_system::Config + configuration::Config { + /// A limit on the number of messages in any `DownwardMessageQueue`. + /// When the limit is reached the `DeliveryFeeFactor` will increase. + #[pallet::constant] + type MessageQueueFeeLimit: Get; + } /// The downward messages addressed for a certain para. #[pallet::storage] @@ -108,6 +114,7 @@ pub mod pallet { pub(crate) type DownwardMessageQueueHeads = StorageMap<_, Twox64Concat, ParaId, Hash, ValueQuery>; + /// Initialization value for the DeliveryFee factor. #[pallet::type_value] pub fn InitialFactor() -> FixedU128 { FixedU128::from_u32(1) @@ -118,6 +125,24 @@ pub mod pallet { #[pallet::getter(fn delivery_fee_factor)] pub(crate) type DeliveryFeeFactor = StorageMap<_, Twox64Concat, ParaId, FixedU128, ValueQuery, InitialFactor>; + + #[pallet::hooks] + impl Hooks> for Pallet { + #[cfg(feature = "std")] + fn integrity_test() { + sp_io::TestExternalities::default().execute_with(|| { + let max_msg_size = + configuration::ActiveConfig::::get().max_downward_message_size; + assert!( + T::MessageQueueFeeLimit::get() <= + MAX_POSSIBLE_ALLOCATION + .checked_div(max_msg_size) + .unwrap_or(640u32) + .saturating_div(2u32) + ); + }); + } + } } /// Routines and getters related to downward message passing. @@ -200,11 +225,7 @@ impl Pallet { v.push(inbound); v.len() }); - let delivery_fee_limit = (MAX_POSSIBLE_ALLOCATION - .checked_div(config.max_downward_message_size) - .unwrap_or(51200u32) - .saturating_div(2u32)) as usize; - if q_len > delivery_fee_limit { + if q_len > T::MessageQueueFeeLimit::get() as usize { let message_size_factor = FixedU128::from_u32(serialized_len.saturating_div(1024) as u32) .saturating_mul(MESSAGE_SIZE_FEE_BASE); @@ -248,12 +269,7 @@ impl Pallet { q.len() }); - let config = configuration::ActiveConfig::::get(); - let delivery_fee_limit = (MAX_POSSIBLE_ALLOCATION - .checked_div(config.max_downward_message_size) - .unwrap_or(51200u32) - .saturating_div(2u32)) as usize; - if q_len <= delivery_fee_limit { + if q_len <= T::MessageQueueFeeLimit::get() as usize { Self::decrement_fee_factor(para); } T::DbWeight::get().reads_writes(1, 1) diff --git a/runtime/parachains/src/dmp/tests.rs b/runtime/parachains/src/dmp/tests.rs index ec07a2094137..7ae8da7ae307 100644 --- a/runtime/parachains/src/dmp/tests.rs +++ b/runtime/parachains/src/dmp/tests.rs @@ -209,11 +209,8 @@ fn verify_dmq_mqc_head_is_externally_accessible() { #[test] fn verify_fee_increment_and_decrement() { let a = ParaId::from(123); - let mut genesis = default_genesis_config(); - // Sets `delivery_fee_limit` to 1 message - genesis.configuration.config.max_downward_message_size = 16_777_216; - + genesis.configuration.config.max_downward_message_size = 51200; new_test_ext(genesis).execute_with(|| { let default = InitialFactor::get(); assert_eq!(DeliveryFeeFactor::::get(a), default); @@ -257,3 +254,18 @@ fn verify_fee_increment_and_decrement() { assert_eq!(DeliveryFeeFactor::::get(a), default); }); } + +#[test] +#[should_panic] +fn verify_fee_reaches_high_value() { + let a = ParaId::from(123); + let mut genesis = default_genesis_config(); + genesis.configuration.config.max_downward_message_size = 51200; + new_test_ext(genesis).execute_with(|| { + let big_message = [0; 51000].to_vec(); + loop { + queue_downward_message(a, big_message.clone()).unwrap(); + assert!(DeliveryFeeFactor::::get(a) < FixedU128::from_u32(u32::MAX)); + } + }); +} diff --git a/runtime/parachains/src/mock.rs b/runtime/parachains/src/mock.rs index fb6946a0161d..3de6fba2ae4c 100644 --- a/runtime/parachains/src/mock.rs +++ b/runtime/parachains/src/mock.rs @@ -215,7 +215,13 @@ impl crate::paras::Config for Test { type NextSessionRotation = TestNextSessionRotation; } -impl crate::dmp::Config for Test {} +parameter_types! { + pub const MessageQueueFeeLimit: u32 = 1; +} + +impl crate::dmp::Config for Test { + type MessageQueueFeeLimit = MessageQueueFeeLimit; +} parameter_types! { pub const FirstMessageFactorPercent: u64 = 100; diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index 9a44f5e26681..f053f2355881 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -1119,7 +1119,13 @@ impl parachains_ump::Config for Runtime { type WeightInfo = weights::runtime_parachains_ump::WeightInfo; } -impl parachains_dmp::Config for Runtime {} +parameter_types! { + pub const MessageQueueFeeLimit: u32 = 320; +} + +impl parachains_dmp::Config for Runtime { + type MessageQueueFeeLimit = MessageQueueFeeLimit; +} impl parachains_hrmp::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index d3e816e1c73e..969408e995d7 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -1048,7 +1048,13 @@ impl parachains_ump::Config for Runtime { type WeightInfo = weights::runtime_parachains_ump::WeightInfo; } -impl parachains_dmp::Config for Runtime {} +parameter_types! { + pub const MessageQueueFeeLimit: u32 = 320; +} + +impl parachains_dmp::Config for Runtime { + type MessageQueueFeeLimit = MessageQueueFeeLimit; +} impl parachains_hrmp::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; diff --git a/runtime/test-runtime/src/lib.rs b/runtime/test-runtime/src/lib.rs index ae436353ec43..cc1216d68319 100644 --- a/runtime/test-runtime/src/lib.rs +++ b/runtime/test-runtime/src/lib.rs @@ -509,7 +509,13 @@ impl parachains_paras::Config for Runtime { type NextSessionRotation = Babe; } -impl parachains_dmp::Config for Runtime {} +parameter_types! { + pub const MessageQueueFeeLimit: u32 = 320; +} + +impl parachains_dmp::Config for Runtime { + type MessageQueueFeeLimit = MessageQueueFeeLimit; +} parameter_types! { pub const FirstMessageFactorPercent: u64 = 100; diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs index f04ae63926f7..bb2cf9aba99b 100644 --- a/runtime/westend/src/lib.rs +++ b/runtime/westend/src/lib.rs @@ -916,7 +916,13 @@ impl parachains_ump::Config for Runtime { type WeightInfo = weights::runtime_parachains_ump::WeightInfo; } -impl parachains_dmp::Config for Runtime {} +parameter_types! { + pub const MessageQueueFeeLimit: u32 = 320; +} + +impl parachains_dmp::Config for Runtime { + type MessageQueueFeeLimit = MessageQueueFeeLimit; +} impl parachains_hrmp::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; From 7f6cfdf3e7833d7c4f57842c37df9aba6370c550 Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Thu, 30 Mar 2023 16:30:49 +0200 Subject: [PATCH 31/40] change threshold back to dynamic value and fix tests --- runtime/kusama/src/lib.rs | 8 +--- runtime/parachains/src/dmp.rs | 72 ++++++++++++++++------------- runtime/parachains/src/dmp/tests.rs | 17 ++++--- runtime/parachains/src/mock.rs | 8 +--- runtime/polkadot/src/lib.rs | 8 +--- runtime/rococo/src/lib.rs | 8 +--- runtime/test-runtime/src/lib.rs | 8 +--- runtime/westend/src/lib.rs | 8 +--- 8 files changed, 57 insertions(+), 80 deletions(-) diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index 9fd32ab12d09..482d52e75c49 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -1110,13 +1110,7 @@ impl parachains_ump::Config for Runtime { type WeightInfo = weights::runtime_parachains_ump::WeightInfo; } -parameter_types! { - pub const MessageQueueFeeLimit: u32 = 320; -} - -impl parachains_dmp::Config for Runtime { - type MessageQueueFeeLimit = MessageQueueFeeLimit; -} +impl parachains_dmp::Config for Runtime {} impl parachains_hrmp::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index cd3d6e17d1dc..6410f52251a1 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -14,12 +14,26 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . +//! To prevent Out of Memory errors on the `DownwardMessageQueue`, +//! an exponential fee factor (`DeliveryFeeFactor`) is set +//! The fee factor increments exponentially after the number of messages in the `DownwardMessageQueue` +//! pass a threshold. This threshold is set as: +//! //Maximum max sized messages that can be send to the DownwardMessageQueue before it runs out of memory +//! `max_messsages = MAX_POSSIBLE_ALLOCATION / max_downward_message_size` +//! `threshold = max_messages / THRESHOLD_FACTOR` +//! Based on the THRESHOLD_FACTOR, the threshold is set as a fraction of the total messages. +//! The DeliveryFeeFactor increases for a message over the threshold by: +//! `DeliveryFeeFactor = DeliveryFeeFactor * (EXPONENTIAL_FEE_BASE + MESSAGE_SIZE_FEE_BASE * message_size_in_KB) +//! And Decreases when the number of messages in the `DownwardMessageQueue` fall below the threshold by: +//! `DeliveryFeeFactor = DeliveryFeeFactor / EXPONENTIAL_FEE_BASE` +//! As an extra defensive measure, a `max_messages` hard limit is set to the number of messages in the DownwardMessageQueue. +//! Messages that would increase the number of messages in the queue above this hard limit are dropped. + use crate::{ configuration::{self, HostConfiguration}, initializer, FeeTracker, }; use frame_support::pallet_prelude::*; -use frame_system::pallet_prelude::*; use primitives::{DownwardMessage, Hash, Id as ParaId, InboundDownwardMessage}; use sp_core::MAX_POSSIBLE_ALLOCATION; use sp_runtime::{ @@ -34,8 +48,8 @@ pub use pallet::*; #[cfg(test)] mod tests; -pub const MAX_MESSAGE_QUEUE_SIZE: usize = 1024; -const EXPONENTIAL_FEE_BASE: FixedU128 = FixedU128::from_rational(101, 100); // 1.01 +const THRESHOLD_FACTOR: u32 = 2; +const EXPONENTIAL_FEE_BASE: FixedU128 = FixedU128::from_rational(105, 100); // 1.05 const MESSAGE_SIZE_FEE_BASE: FixedU128 = FixedU128::from_rational(1, 1000); // 0.001 /// An error sending a downward message. @@ -86,12 +100,7 @@ pub mod pallet { pub struct Pallet(_); #[pallet::config] - pub trait Config: frame_system::Config + configuration::Config { - /// A limit on the number of messages in any `DownwardMessageQueue`. - /// When the limit is reached the `DeliveryFeeFactor` will increase. - #[pallet::constant] - type MessageQueueFeeLimit: Get; - } + pub trait Config: frame_system::Config + configuration::Config {} /// The downward messages addressed for a certain para. #[pallet::storage] @@ -125,26 +134,7 @@ pub mod pallet { #[pallet::getter(fn delivery_fee_factor)] pub(crate) type DeliveryFeeFactor = StorageMap<_, Twox64Concat, ParaId, FixedU128, ValueQuery, InitialFactor>; - - #[pallet::hooks] - impl Hooks> for Pallet { - #[cfg(feature = "std")] - fn integrity_test() { - sp_io::TestExternalities::default().execute_with(|| { - let max_msg_size = - configuration::ActiveConfig::::get().max_downward_message_size; - assert!( - T::MessageQueueFeeLimit::get() <= - MAX_POSSIBLE_ALLOCATION - .checked_div(max_msg_size) - .unwrap_or(640u32) - .saturating_div(2u32) - ); - }); - } - } } - /// Routines and getters related to downward message passing. impl Pallet { /// Block initialization logic, called by initializer. @@ -182,7 +172,7 @@ impl Pallet { /// `queue_downward_message` with the same parameters will be successful. pub fn can_queue_downward_message( config: &HostConfiguration, - _: &ParaId, + para: &ParaId, msg: &DownwardMessage, ) -> Result<(), QueueDownwardMessageError> { let serialized_len = msg.len() as u32; @@ -190,6 +180,11 @@ impl Pallet { return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) } + // Hard limit on Queue size + if Self::dmq_length(*para) > Self::dmq_max_length(config.max_downward_message_size) { + return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) + } + Ok(()) } @@ -211,6 +206,11 @@ impl Pallet { return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) } + // Hard limit on Queue size + if Self::dmq_length(para) > Self::dmq_max_length(config.max_downward_message_size) { + return Err(QueueDownwardMessageError::ExceedsMaxMessageSize) + } + let inbound = InboundDownwardMessage { msg, sent_at: >::block_number() }; @@ -225,7 +225,10 @@ impl Pallet { v.push(inbound); v.len() }); - if q_len > T::MessageQueueFeeLimit::get() as usize { + + let threshold = + Self::dmq_max_length(config.max_downward_message_size).saturating_div(THRESHOLD_FACTOR); + if q_len > (threshold as usize) { let message_size_factor = FixedU128::from_u32(serialized_len.saturating_div(1024) as u32) .saturating_mul(MESSAGE_SIZE_FEE_BASE); @@ -269,7 +272,10 @@ impl Pallet { q.len() }); - if q_len <= T::MessageQueueFeeLimit::get() as usize { + let config = configuration::ActiveConfig::::get(); + let threshold = + Self::dmq_max_length(config.max_downward_message_size).saturating_div(THRESHOLD_FACTOR); + if q_len <= (threshold as usize) { Self::decrement_fee_factor(para); } T::DbWeight::get().reads_writes(1, 1) @@ -291,6 +297,10 @@ impl Pallet { .saturated_into::() } + fn dmq_max_length(max_downward_message_size: u32) -> u32 { + MAX_POSSIBLE_ALLOCATION.checked_div(max_downward_message_size).unwrap_or(0) + } + /// Returns the downward message queue contents for the given para. /// /// The most recent messages are the latest in the vector. diff --git a/runtime/parachains/src/dmp/tests.rs b/runtime/parachains/src/dmp/tests.rs index 7ae8da7ae307..90eb67be92c1 100644 --- a/runtime/parachains/src/dmp/tests.rs +++ b/runtime/parachains/src/dmp/tests.rs @@ -16,6 +16,8 @@ use super::*; use crate::mock::{new_test_ext, Configuration, Dmp, MockGenesisConfig, Paras, System, Test}; +use crate::configuration::ActiveConfig; +use frame_support::assert_ok; use hex_literal::hex; use parity_scale_codec::Encode; use primitives::BlockNumber; @@ -210,7 +212,7 @@ fn verify_dmq_mqc_head_is_externally_accessible() { fn verify_fee_increment_and_decrement() { let a = ParaId::from(123); let mut genesis = default_genesis_config(); - genesis.configuration.config.max_downward_message_size = 51200; + genesis.configuration.config.max_downward_message_size = 16777216; new_test_ext(genesis).execute_with(|| { let default = InitialFactor::get(); assert_eq!(DeliveryFeeFactor::::get(a), default); @@ -256,16 +258,17 @@ fn verify_fee_increment_and_decrement() { } #[test] -#[should_panic] -fn verify_fee_reaches_high_value() { +fn verify_fee_factor_reaches_high_value() { let a = ParaId::from(123); let mut genesis = default_genesis_config(); genesis.configuration.config.max_downward_message_size = 51200; new_test_ext(genesis).execute_with(|| { - let big_message = [0; 51000].to_vec(); - loop { - queue_downward_message(a, big_message.clone()).unwrap(); - assert!(DeliveryFeeFactor::::get(a) < FixedU128::from_u32(u32::MAX)); + let max_messages = Dmp::dmq_max_length(ActiveConfig::::get().max_downward_message_size); + let mut total_fee_factor = FixedU128::from_float(1.0); + for _ in 1..max_messages { + assert_ok!(queue_downward_message(a, vec![])); + total_fee_factor = total_fee_factor + (DeliveryFeeFactor::::get(a)); } + assert!(total_fee_factor > FixedU128::from_u32(100_000_000)); }); } diff --git a/runtime/parachains/src/mock.rs b/runtime/parachains/src/mock.rs index 3de6fba2ae4c..fb6946a0161d 100644 --- a/runtime/parachains/src/mock.rs +++ b/runtime/parachains/src/mock.rs @@ -215,13 +215,7 @@ impl crate::paras::Config for Test { type NextSessionRotation = TestNextSessionRotation; } -parameter_types! { - pub const MessageQueueFeeLimit: u32 = 1; -} - -impl crate::dmp::Config for Test { - type MessageQueueFeeLimit = MessageQueueFeeLimit; -} +impl crate::dmp::Config for Test {} parameter_types! { pub const FirstMessageFactorPercent: u64 = 100; diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index f053f2355881..9a44f5e26681 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -1119,13 +1119,7 @@ impl parachains_ump::Config for Runtime { type WeightInfo = weights::runtime_parachains_ump::WeightInfo; } -parameter_types! { - pub const MessageQueueFeeLimit: u32 = 320; -} - -impl parachains_dmp::Config for Runtime { - type MessageQueueFeeLimit = MessageQueueFeeLimit; -} +impl parachains_dmp::Config for Runtime {} impl parachains_hrmp::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index 969408e995d7..d3e816e1c73e 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -1048,13 +1048,7 @@ impl parachains_ump::Config for Runtime { type WeightInfo = weights::runtime_parachains_ump::WeightInfo; } -parameter_types! { - pub const MessageQueueFeeLimit: u32 = 320; -} - -impl parachains_dmp::Config for Runtime { - type MessageQueueFeeLimit = MessageQueueFeeLimit; -} +impl parachains_dmp::Config for Runtime {} impl parachains_hrmp::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; diff --git a/runtime/test-runtime/src/lib.rs b/runtime/test-runtime/src/lib.rs index cc1216d68319..ae436353ec43 100644 --- a/runtime/test-runtime/src/lib.rs +++ b/runtime/test-runtime/src/lib.rs @@ -509,13 +509,7 @@ impl parachains_paras::Config for Runtime { type NextSessionRotation = Babe; } -parameter_types! { - pub const MessageQueueFeeLimit: u32 = 320; -} - -impl parachains_dmp::Config for Runtime { - type MessageQueueFeeLimit = MessageQueueFeeLimit; -} +impl parachains_dmp::Config for Runtime {} parameter_types! { pub const FirstMessageFactorPercent: u64 = 100; diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs index bb2cf9aba99b..f04ae63926f7 100644 --- a/runtime/westend/src/lib.rs +++ b/runtime/westend/src/lib.rs @@ -916,13 +916,7 @@ impl parachains_ump::Config for Runtime { type WeightInfo = weights::runtime_parachains_ump::WeightInfo; } -parameter_types! { - pub const MessageQueueFeeLimit: u32 = 320; -} - -impl parachains_dmp::Config for Runtime { - type MessageQueueFeeLimit = MessageQueueFeeLimit; -} +impl parachains_dmp::Config for Runtime {} impl parachains_hrmp::Config for Runtime { type RuntimeOrigin = RuntimeOrigin; From 759277c1ec2efd0ff3f39f461cab0128aa73b537 Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Thu, 30 Mar 2023 16:33:10 +0200 Subject: [PATCH 32/40] fmt --- runtime/parachains/src/dmp/tests.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/runtime/parachains/src/dmp/tests.rs b/runtime/parachains/src/dmp/tests.rs index 90eb67be92c1..a7614ddd5cd2 100644 --- a/runtime/parachains/src/dmp/tests.rs +++ b/runtime/parachains/src/dmp/tests.rs @@ -15,8 +15,10 @@ // along with Polkadot. If not, see . use super::*; -use crate::mock::{new_test_ext, Configuration, Dmp, MockGenesisConfig, Paras, System, Test}; -use crate::configuration::ActiveConfig; +use crate::{ + configuration::ActiveConfig, + mock::{new_test_ext, Configuration, Dmp, MockGenesisConfig, Paras, System, Test}, +}; use frame_support::assert_ok; use hex_literal::hex; use parity_scale_codec::Encode; @@ -263,11 +265,12 @@ fn verify_fee_factor_reaches_high_value() { let mut genesis = default_genesis_config(); genesis.configuration.config.max_downward_message_size = 51200; new_test_ext(genesis).execute_with(|| { - let max_messages = Dmp::dmq_max_length(ActiveConfig::::get().max_downward_message_size); + let max_messages = + Dmp::dmq_max_length(ActiveConfig::::get().max_downward_message_size); let mut total_fee_factor = FixedU128::from_float(1.0); for _ in 1..max_messages { assert_ok!(queue_downward_message(a, vec![])); - total_fee_factor = total_fee_factor + (DeliveryFeeFactor::::get(a)); + total_fee_factor = total_fee_factor + (DeliveryFeeFactor::::get(a)); } assert!(total_fee_factor > FixedU128::from_u32(100_000_000)); }); From a6a7fd9832f883705e40b313f2f9e18615cd748a Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Fri, 31 Mar 2023 11:12:40 +0200 Subject: [PATCH 33/40] suggested changes and fmt --- runtime/parachains/src/dmp.rs | 10 ++++++---- runtime/parachains/src/dmp/tests.rs | 12 ++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index 6410f52251a1..fbbffe25c6ec 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -18,13 +18,15 @@ //! an exponential fee factor (`DeliveryFeeFactor`) is set //! The fee factor increments exponentially after the number of messages in the `DownwardMessageQueue` //! pass a threshold. This threshold is set as: +//! ```ignore //! //Maximum max sized messages that can be send to the DownwardMessageQueue before it runs out of memory -//! `max_messsages = MAX_POSSIBLE_ALLOCATION / max_downward_message_size` -//! `threshold = max_messages / THRESHOLD_FACTOR` +//! max_messsages = MAX_POSSIBLE_ALLOCATION / max_downward_message_size +//! threshold = max_messages / THRESHOLD_FACTOR +//! ``` //! Based on the THRESHOLD_FACTOR, the threshold is set as a fraction of the total messages. //! The DeliveryFeeFactor increases for a message over the threshold by: -//! `DeliveryFeeFactor = DeliveryFeeFactor * (EXPONENTIAL_FEE_BASE + MESSAGE_SIZE_FEE_BASE * message_size_in_KB) -//! And Decreases when the number of messages in the `DownwardMessageQueue` fall below the threshold by: +//! `DeliveryFeeFactor = DeliveryFeeFactor * (EXPONENTIAL_FEE_BASE + MESSAGE_SIZE_FEE_BASE * encoded_message_size_in_KB) +//! And decreases when the number of messages in the `DownwardMessageQueue` fall below the threshold by: //! `DeliveryFeeFactor = DeliveryFeeFactor / EXPONENTIAL_FEE_BASE` //! As an extra defensive measure, a `max_messages` hard limit is set to the number of messages in the DownwardMessageQueue. //! Messages that would increase the number of messages in the queue above this hard limit are dropped. diff --git a/runtime/parachains/src/dmp/tests.rs b/runtime/parachains/src/dmp/tests.rs index a7614ddd5cd2..e3eab813211a 100644 --- a/runtime/parachains/src/dmp/tests.rs +++ b/runtime/parachains/src/dmp/tests.rs @@ -216,12 +216,12 @@ fn verify_fee_increment_and_decrement() { let mut genesis = default_genesis_config(); genesis.configuration.config.max_downward_message_size = 16777216; new_test_ext(genesis).execute_with(|| { - let default = InitialFactor::get(); - assert_eq!(DeliveryFeeFactor::::get(a), default); + let initial = InitialFactor::get(); + assert_eq!(DeliveryFeeFactor::::get(a), initial); // Under fee limit queue_downward_message(a, vec![1]).unwrap(); - assert_eq!(DeliveryFeeFactor::::get(a), default); + assert_eq!(DeliveryFeeFactor::::get(a), initial); // Limit reached so fee is increased queue_downward_message(a, vec![1]).unwrap(); @@ -229,12 +229,12 @@ fn verify_fee_increment_and_decrement() { assert_eq!(DeliveryFeeFactor::::get(a), result); Dmp::prune_dmq(a, 1); - assert_eq!(DeliveryFeeFactor::::get(a), default); + assert_eq!(DeliveryFeeFactor::::get(a), initial); // 10 Kb message adds additional 0.001 per KB fee factor let big_message = [0; 10240].to_vec(); let msg_len_in_kb = big_message.len().saturating_div(1024) as u32; - let result = default.saturating_mul( + let result = initial.saturating_mul( EXPONENTIAL_FEE_BASE + MESSAGE_SIZE_FEE_BASE.saturating_mul(FixedU128::from_u32(msg_len_in_kb)), ); @@ -255,7 +255,7 @@ fn verify_fee_increment_and_decrement() { Dmp::prune_dmq(a, 1); queue_downward_message(a, vec![1]).unwrap(); Dmp::prune_dmq(a, 1); - assert_eq!(DeliveryFeeFactor::::get(a), default); + assert_eq!(DeliveryFeeFactor::::get(a), initial); }); } From d92d99034e86bfa5b1f5c8ee6a7b8f5bda160c65 Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Mon, 3 Apr 2023 12:17:41 +0200 Subject: [PATCH 34/40] small stylistic change --- runtime/parachains/src/dmp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index fbbffe25c6ec..5602d8123182 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -15,7 +15,7 @@ // along with Polkadot. If not, see . //! To prevent Out of Memory errors on the `DownwardMessageQueue`, -//! an exponential fee factor (`DeliveryFeeFactor`) is set +//! an exponential fee factor (`DeliveryFeeFactor`) is set. //! The fee factor increments exponentially after the number of messages in the `DownwardMessageQueue` //! pass a threshold. This threshold is set as: //! ```ignore From d0c5de19ec51f035c407e9456f4236fa6f19c741 Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Mon, 3 Apr 2023 12:53:58 +0200 Subject: [PATCH 35/40] fmt --- runtime/kusama/src/xcm_config.rs | 3 +-- runtime/polkadot/src/xcm_config.rs | 3 +-- runtime/rococo/src/xcm_config.rs | 3 +-- runtime/westend/src/xcm_config.rs | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/runtime/kusama/src/xcm_config.rs b/runtime/kusama/src/xcm_config.rs index e8004fd06177..d7f437b8966c 100644 --- a/runtime/kusama/src/xcm_config.rs +++ b/runtime/kusama/src/xcm_config.rs @@ -29,8 +29,7 @@ use frame_support::{ use frame_system::EnsureRoot; use kusama_runtime_constants::currency::CENTS; use runtime_common::{ - crowdloan, - paras_registrar, + crowdloan, paras_registrar, xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; diff --git a/runtime/polkadot/src/xcm_config.rs b/runtime/polkadot/src/xcm_config.rs index 40c50f02a6f8..b736fc50273e 100644 --- a/runtime/polkadot/src/xcm_config.rs +++ b/runtime/polkadot/src/xcm_config.rs @@ -32,8 +32,7 @@ use polkadot_runtime_constants::{ currency::CENTS, system_parachain::*, xcm::body::FELLOWSHIP_ADMIN_INDEX, }; use runtime_common::{ - crowdloan, - paras_registrar, + crowdloan, paras_registrar, xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; diff --git a/runtime/rococo/src/xcm_config.rs b/runtime/rococo/src/xcm_config.rs index 7e3712f10a39..6aa1303a3f30 100644 --- a/runtime/rococo/src/xcm_config.rs +++ b/runtime/rococo/src/xcm_config.rs @@ -28,8 +28,7 @@ use frame_support::{ use frame_system::EnsureRoot; use rococo_runtime_constants::currency::CENTS; use runtime_common::{ - crowdloan, - paras_registrar, + crowdloan, paras_registrar, xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index 0e247726ddfd..665047119eec 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -26,8 +26,7 @@ use frame_support::{ }; use frame_system::EnsureRoot; use runtime_common::{ - crowdloan, - paras_registrar, + crowdloan, paras_registrar, xcm_sender::{ChildParachainRouter, ExponentialPrice}, ToAuthor, }; From ea42774ef64362bfabf8d924d06249091e016473 Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Tue, 4 Apr 2023 10:32:30 +0200 Subject: [PATCH 36/40] change to tokenlocation --- runtime/kusama/src/xcm_config.rs | 2 +- runtime/polkadot/src/xcm_config.rs | 2 +- runtime/rococo/src/xcm_config.rs | 2 +- runtime/westend/src/xcm_config.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime/kusama/src/xcm_config.rs b/runtime/kusama/src/xcm_config.rs index d7f437b8966c..17dbb624b8aa 100644 --- a/runtime/kusama/src/xcm_config.rs +++ b/runtime/kusama/src/xcm_config.rs @@ -108,7 +108,7 @@ parameter_types! { /// calculations getting too crazy. pub const MaxInstructions: u32 = 100; /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(Here.into()); + pub FeeAssetId: AssetId = Concrete(TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } diff --git a/runtime/polkadot/src/xcm_config.rs b/runtime/polkadot/src/xcm_config.rs index b736fc50273e..afcf0cd2dd0a 100644 --- a/runtime/polkadot/src/xcm_config.rs +++ b/runtime/polkadot/src/xcm_config.rs @@ -113,7 +113,7 @@ parameter_types! { /// calculations getting too crazy. pub const MaxInstructions: u32 = 100; /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(Here.into()); + pub FeeAssetId: AssetId = Concrete(TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } diff --git a/runtime/rococo/src/xcm_config.rs b/runtime/rococo/src/xcm_config.rs index 6aa1303a3f30..c389c10c0db1 100644 --- a/runtime/rococo/src/xcm_config.rs +++ b/runtime/rococo/src/xcm_config.rs @@ -88,7 +88,7 @@ parameter_types! { /// The amount of weight an XCM operation takes. This is a safe overestimate. pub const BaseXcmWeight: Weight = Weight::from_parts(1_000_000_000, 64 * 1024); /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(Here.into()); + pub FeeAssetId: AssetId = Concrete(TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } diff --git a/runtime/westend/src/xcm_config.rs b/runtime/westend/src/xcm_config.rs index 665047119eec..ff9e67a7b162 100644 --- a/runtime/westend/src/xcm_config.rs +++ b/runtime/westend/src/xcm_config.rs @@ -50,7 +50,7 @@ parameter_types! { pub CheckAccount: AccountId = XcmPallet::check_account(); pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local); /// The asset ID for the asset that we use to pay for message delivery fees. - pub FeeAssetId: AssetId = Concrete(Here.into()); + pub FeeAssetId: AssetId = Concrete(TokenLocation::get()); /// The base fee for the message delivery fees. pub const BaseDeliveryFee: u128 = CENTS.saturating_mul(3); } From 173284632d760ed00114b986e3356c03b1961041 Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Tue, 11 Apr 2023 13:35:28 +0200 Subject: [PATCH 37/40] small fixes --- runtime/parachains/src/dmp.rs | 38 ++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index 5602d8123182..6d2a4f5142c5 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -14,22 +14,33 @@ // You should have received a copy of the GNU General Public License // along with Polkadot. If not, see . -//! To prevent Out of Memory errors on the `DownwardMessageQueue`, -//! an exponential fee factor (`DeliveryFeeFactor`) is set. -//! The fee factor increments exponentially after the number of messages in the `DownwardMessageQueue` -//! pass a threshold. This threshold is set as: +//! To prevent Out of Memory errors on the `DownwardMessageQueue`, an +//! exponential fee factor (`DeliveryFeeFactor`) is set. The fee factor +//! increments exponentially after the number of messages in the +//! `DownwardMessageQueue` pass a threshold. This threshold is set as: +//! //! ```ignore -//! //Maximum max sized messages that can be send to the DownwardMessageQueue before it runs out of memory +//! // Maximum max sized messages that can be send to +//! // the DownwardMessageQueue before it runs out of memory //! max_messsages = MAX_POSSIBLE_ALLOCATION / max_downward_message_size //! threshold = max_messages / THRESHOLD_FACTOR //! ``` -//! Based on the THRESHOLD_FACTOR, the threshold is set as a fraction of the total messages. -//! The DeliveryFeeFactor increases for a message over the threshold by: -//! `DeliveryFeeFactor = DeliveryFeeFactor * (EXPONENTIAL_FEE_BASE + MESSAGE_SIZE_FEE_BASE * encoded_message_size_in_KB) -//! And decreases when the number of messages in the `DownwardMessageQueue` fall below the threshold by: -//! `DeliveryFeeFactor = DeliveryFeeFactor / EXPONENTIAL_FEE_BASE` -//! As an extra defensive measure, a `max_messages` hard limit is set to the number of messages in the DownwardMessageQueue. -//! Messages that would increase the number of messages in the queue above this hard limit are dropped. +//! Based on the THRESHOLD_FACTOR, the threshold is set as a fraction of the +//! total messages. The DeliveryFeeFactor increases for a message over the +//! threshold by: +//! +//! `DeliveryFeeFactor = DeliveryFeeFactor * +//! (EXPONENTIAL_FEE_BASE + MESSAGE_SIZE_FEE_BASE * encoded_message_size_in_KB)` +//! +//! And decreases when the number of messages in the `DownwardMessageQueue` fall +//! below the threshold by: +//! +//! `DeliveryFeeFactor = DeliveryFeeFactor / EXPONENTIAL_FEE_BASE` +//! +//! As an extra defensive measure, a `max_messages` hard +//! limit is set to the number of messages in the DownwardMessageQueue. Messages +//! that would increase the number of messages in the queue above this hard +//! limit are dropped. use crate::{ configuration::{self, HostConfiguration}, @@ -133,7 +144,6 @@ pub mod pallet { /// The number to multiply the base delivery fee by. #[pallet::storage] - #[pallet::getter(fn delivery_fee_factor)] pub(crate) type DeliveryFeeFactor = StorageMap<_, Twox64Concat, ParaId, FixedU128, ValueQuery, InitialFactor>; } @@ -335,6 +345,6 @@ impl Pallet { impl FeeTracker for Pallet { fn get_fee_factor(para: ParaId) -> FixedU128 { - Pallet::::delivery_fee_factor(para) + DeliveryFeeFactor::::get(para) } } From 56fe04d03123cb56089e2ceeb11e83f4cef2faad Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Tue, 11 Apr 2023 13:59:49 +0200 Subject: [PATCH 38/40] fmt --- runtime/parachains/src/dmp.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index 6d2a4f5142c5..8c7a167a6f68 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -18,25 +18,25 @@ //! exponential fee factor (`DeliveryFeeFactor`) is set. The fee factor //! increments exponentially after the number of messages in the //! `DownwardMessageQueue` pass a threshold. This threshold is set as: -//! +//! //! ```ignore -//! // Maximum max sized messages that can be send to +//! // Maximum max sized messages that can be send to //! // the DownwardMessageQueue before it runs out of memory //! max_messsages = MAX_POSSIBLE_ALLOCATION / max_downward_message_size //! threshold = max_messages / THRESHOLD_FACTOR //! ``` //! Based on the THRESHOLD_FACTOR, the threshold is set as a fraction of the //! total messages. The DeliveryFeeFactor increases for a message over the -//! threshold by: -//! -//! `DeliveryFeeFactor = DeliveryFeeFactor * +//! threshold by: +//! +//! `DeliveryFeeFactor = DeliveryFeeFactor * //! (EXPONENTIAL_FEE_BASE + MESSAGE_SIZE_FEE_BASE * encoded_message_size_in_KB)` -//! +//! //! And decreases when the number of messages in the `DownwardMessageQueue` fall -//! below the threshold by: -//! -//! `DeliveryFeeFactor = DeliveryFeeFactor / EXPONENTIAL_FEE_BASE` -//! +//! below the threshold by: +//! +//! `DeliveryFeeFactor = DeliveryFeeFactor / EXPONENTIAL_FEE_BASE` +//! //! As an extra defensive measure, a `max_messages` hard //! limit is set to the number of messages in the DownwardMessageQueue. Messages //! that would increase the number of messages in the queue above this hard From 2f7acd19ec6954971f4f9b9ec3f9f6778d54ed5e Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Fri, 14 Apr 2023 11:31:25 +0200 Subject: [PATCH 39/40] remove sp_arithmetic dependency --- Cargo.lock | 2 -- runtime/rococo/Cargo.toml | 2 -- runtime/westend/Cargo.toml | 2 -- 3 files changed, 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1eaea8179706..92b6c18c0c49 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8893,7 +8893,6 @@ dependencies = [ "serde_json", "smallvec", "sp-api", - "sp-arithmetic", "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", @@ -13652,7 +13651,6 @@ dependencies = [ "serde_json", "smallvec", "sp-api", - "sp-arithmetic", "sp-authority-discovery", "sp-block-builder", "sp-consensus-babe", diff --git a/runtime/rococo/Cargo.toml b/runtime/rococo/Cargo.toml index 6b3d1c6e1e6f..25bd679d4d35 100644 --- a/runtime/rococo/Cargo.toml +++ b/runtime/rococo/Cargo.toml @@ -27,7 +27,6 @@ sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", de sp-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } -sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } @@ -113,7 +112,6 @@ std = [ "parity-scale-codec/std", "scale-info/std", "inherents/std", - "sp-arithmetic/std", "sp-core/std", "sp-api/std", "tx-pool-api/std", diff --git a/runtime/westend/Cargo.toml b/runtime/westend/Cargo.toml index 2aea8c070a18..58b79e3889ec 100644 --- a/runtime/westend/Cargo.toml +++ b/runtime/westend/Cargo.toml @@ -26,7 +26,6 @@ sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", de sp-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } -sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false } @@ -121,7 +120,6 @@ std = [ "parity-scale-codec/std", "scale-info/std", "inherents/std", - "sp-arithmetic/std", "sp-core/std", "polkadot-parachain/std", "sp-api/std", From a7e5deddf193a99488a8b717a4660bbcc4f93861 Mon Sep 17 00:00:00 2001 From: Just van Stam Date: Thu, 20 Apr 2023 11:03:45 +0200 Subject: [PATCH 40/40] Update runtime/parachains/src/dmp.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- runtime/parachains/src/dmp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs index c6a165e66967..5244406fcce4 100644 --- a/runtime/parachains/src/dmp.rs +++ b/runtime/parachains/src/dmp.rs @@ -26,7 +26,7 @@ //! threshold = max_messages / THRESHOLD_FACTOR //! ``` //! Based on the THRESHOLD_FACTOR, the threshold is set as a fraction of the -//! total messages. The DeliveryFeeFactor increases for a message over the +//! total messages. The `DeliveryFeeFactor` increases for a message over the //! threshold by: //! //! `DeliveryFeeFactor = DeliveryFeeFactor *