-
Notifications
You must be signed in to change notification settings - Fork 370
Increase xcm fees when busy #2342
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -53,6 +53,7 @@ use sp_runtime::{ | |
| InvalidTransaction, TransactionLongevity, TransactionSource, TransactionValidity, | ||
| ValidTransaction, | ||
| }, | ||
| FixedU128, Saturating, | ||
| }; | ||
| use sp_std::{cmp, collections::btree_map::BTreeMap, prelude::*}; | ||
| use xcm::latest::XcmHash; | ||
|
|
@@ -91,6 +92,8 @@ pub use relay_state_snapshot::{MessagingStateSnapshot, RelayChainStateProof}; | |
|
|
||
| pub use pallet::*; | ||
|
|
||
| pub const MULTIPLICATIVE_FEE_FACTOR_UMP: FixedU128 = FixedU128::from_rational(101, 100); // 1.01 | ||
|
|
||
| /// Something that can check the associated relay block number. | ||
| /// | ||
| /// Each Parachain block is built in the context of a relay chain block, this trait allows us | ||
|
|
@@ -261,6 +264,9 @@ pub mod pallet { | |
|
|
||
| UpwardMessages::<T>::put(&up[..num]); | ||
| *up = up.split_off(num); | ||
| if num > 0 { | ||
| Self::decrement_ump_fee_factor(); | ||
| } | ||
| }); | ||
|
|
||
| // Sending HRMP messages is a little bit more involved. There are the following | ||
|
|
@@ -691,6 +697,16 @@ pub mod pallet { | |
| #[pallet::storage] | ||
| pub(super) type CustomValidationHeadData<T: Config> = StorageValue<_, Vec<u8>, OptionQuery>; | ||
|
|
||
| frame_support::parameter_types! { | ||
| pub InitialFactor: FixedU128 = FixedU128::from_u32(1); | ||
| } | ||
|
|
||
| /// The number to multiply the base delivery fee by. | ||
| #[pallet::storage] | ||
| #[pallet::getter(fn delivery_fee_factor_ump)] | ||
| pub(crate) type DeliveryFeeFactorUmp<T: Config> = | ||
| StorageValue<_, FixedU128, ValueQuery, InitialFactor>; | ||
|
|
||
| #[pallet::inherent] | ||
| impl<T: Config> ProvideInherent for Pallet<T> { | ||
| type Call = Call<T>; | ||
|
|
@@ -1069,7 +1085,7 @@ impl<T: Config> Pallet<T> { | |
| match Self::host_configuration() { | ||
| Some(cfg) => | ||
| if message.len() > cfg.max_upward_message_size as usize { | ||
| return Err(MessageSendError::TooBig) | ||
| Self::increment_ump_fee_factor(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the wrong place to put the increment. The condition here checks whether the individual message size is greater than the limit, and does not check for the queue size. |
||
| }, | ||
| None => { | ||
| // This storage field should carry over from the previous block. So if it's None | ||
|
|
@@ -1091,6 +1107,28 @@ impl<T: Config> Pallet<T> { | |
| Self::deposit_event(Event::UpwardMessageSent { message_hash: Some(hash) }); | ||
| Ok((0, hash)) | ||
| } | ||
|
|
||
| /// 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_ump_fee_factor() -> FixedU128 { | ||
| <DeliveryFeeFactorUMP<T>>::mutate(|f| { | ||
| *f = f.saturating_mul(MULTIPLICATIVE_FEE_FACTOR_UMP); | ||
| *f | ||
| }) | ||
| } | ||
|
|
||
| /// 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 decrement. | ||
| pub(crate) fn decrement_ump_fee_factor() -> FixedU128 { | ||
| <DeliveryFeeFactorUMP<T>>::mutate(|f| { | ||
| *f = InitialFactor::get().max(*f / MULTIPLICATIVE_FEE_FACTOR_UMP); | ||
| *f | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| impl<T: Config> UpwardMessageSender for Pallet<T> { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -53,7 +53,7 @@ use rand_chacha::{ | |
| ChaChaRng, | ||
| }; | ||
| use scale_info::TypeInfo; | ||
| use sp_runtime::RuntimeDebug; | ||
| use sp_runtime::{FixedPointNumber, FixedU128, RuntimeDebug, Saturating}; | ||
| use sp_std::{convert::TryFrom, prelude::*}; | ||
| use xcm::{latest::prelude::*, VersionedXcm, WrapVersion, MAX_XCM_DECODE_DEPTH}; | ||
| use xcm_executor::traits::ConvertOrigin; | ||
|
|
@@ -72,6 +72,8 @@ const MAX_MESSAGES_PER_BLOCK: u8 = 10; | |
| // Maximum amount of messages that can exist in the overweight queue at any given time. | ||
| const MAX_OVERWEIGHT_MESSAGES: u32 = 1000; | ||
|
|
||
| pub const MULTIPLICATIVE_FEE_FACTOR_XCMP: FixedU128 = FixedU128::from_rational(101, 100); // 1.01 | ||
|
|
||
| #[frame_support::pallet] | ||
| pub mod pallet { | ||
| use super::*; | ||
|
|
@@ -374,6 +376,16 @@ pub mod pallet { | |
| /// Whether or not the XCMP queue is suspended from executing incoming XCMs or not. | ||
| #[pallet::storage] | ||
| pub(super) type QueueSuspended<T: Config> = StorageValue<_, bool, ValueQuery>; | ||
|
|
||
| frame_support::parameter_types! { | ||
| pub InitialFactor: FixedU128 = FixedU128::from_u32(1); | ||
| } | ||
|
|
||
| /// The number to multiply the base delivery fee by. | ||
| #[pallet::storage] | ||
| #[pallet::getter(fn delivery_fee_factor_xcmp)] | ||
| pub(crate) type DeliveryFeeFactor<T: Config> = | ||
| StorageValue<_, FixedU128, ValueQuery, InitialFactor>; | ||
| } | ||
|
|
||
| #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, TypeInfo)] | ||
|
|
@@ -516,7 +528,7 @@ impl<T: Config> Pallet<T> { | |
| let max_message_size = | ||
| T::ChannelInfo::get_channel_max(recipient).ok_or(MessageSendError::NoChannel)?; | ||
| if data.len() > max_message_size { | ||
| return Err(MessageSendError::TooBig) | ||
| Self::increment_xcmp_fee_factor(); | ||
| } | ||
|
|
||
| let mut s = <OutboundXcmpStatus<T>>::get(); | ||
|
|
@@ -943,6 +955,28 @@ impl<T: Config> Pallet<T> { | |
| } | ||
| }); | ||
| } | ||
|
|
||
| /// 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_xcmp_fee_factor() -> FixedU128 { | ||
| <DeliveryFeeFactorXCMP<T>>::mutate(|f| { | ||
| *f = f.saturating_mul(MULTIPLICATIVE_FEE_FACTOR_XCMP); | ||
| *f | ||
| }) | ||
| } | ||
|
|
||
| /// 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 decrement. | ||
| pub(crate) fn decrement_xcmp_fee_factor() -> FixedU128 { | ||
| <DeliveryFeeFactorXCMP<T>>::mutate(|f| { | ||
| *f = InitialFactor::get().max(*f / MULTIPLICATIVE_FEE_FACTOR_XCMP); | ||
| *f | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| impl<T: Config> XcmpMessageHandler for Pallet<T> { | ||
|
|
@@ -1129,6 +1163,9 @@ impl<T: Config> XcmpMessageSource for Pallet<T> { | |
|
|
||
| <OutboundXcmpStatus<T>>::put(statuses); | ||
|
|
||
| if !result.is_empty() { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should check whether the number of messages in queue is less than the maximum limit. |
||
| Self::decrement_xcmp_fee_factor(); | ||
| } | ||
| result | ||
| } | ||
| } | ||
|
|
@@ -1190,3 +1227,21 @@ impl<T: Config> SendXcm for Pallet<T> { | |
| } | ||
| } | ||
| } | ||
|
|
||
| /// Implementation of `PriceForSiblingDelivery` 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 SiblingExponentialPrice<A, B, M, F>(sp_std::marker::PhantomData<(A, B, M, F)>); | ||
| impl<A: Get<AssetId>, B: Get<u128>, M: Get<u128>, F: Get<FixedU128>> PriceForSiblingDelivery | ||
| for SiblingExponentialPrice<A, B, M, F> | ||
| { | ||
| fn price_for_sibling_delivery(_para_id: 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); | ||
| (A::get(), amount).into() | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,7 +28,9 @@ pub mod constants; | |
| mod weights; | ||
| pub mod xcm_config; | ||
|
|
||
| use crate::xcm_config::{BaseDeliveryFee, FeeAssetId, XcmpFeeFactor}; | ||
| use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; | ||
| use cumulus_pallet_xcmp_queue::SiblingExponentialPrice; | ||
| use sp_api::impl_runtime_apis; | ||
| use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; | ||
| use sp_runtime::{ | ||
|
|
@@ -475,7 +477,8 @@ impl cumulus_pallet_xcmp_queue::Config for Runtime { | |
| >; | ||
| type ControllerOriginConverter = xcm_config::XcmOriginToTransactDispatchOrigin; | ||
| type WeightInfo = weights::cumulus_pallet_xcmp_queue::WeightInfo<Runtime>; | ||
| type PriceForSiblingDelivery = (); | ||
| type PriceForSiblingDelivery = | ||
| SiblingExponentialPrice<FeeAssetId, BaseDeliveryFee, TransactionByteFee, XcmpFeeFactor>; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when paritytech/polkadot#7005 and paritytech/polkadot#7585, |
||
| } | ||
|
|
||
| impl cumulus_pallet_dmp_queue::Config for Runtime { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should check whether the UMP queue is less than then max limit.