mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-20 18:35:41 +00:00
XCM: Properly set the pricing for the DMP router (#6843)
* Properly set the pricing for the DMP router * Publicize price types * Use FixedU128 instead of Percent * Add sp-arithmetic as a dependency for rococo runtime * Add sp-arithmetic as a dependency to all runtimes * Remove duplicate import * Add missing import * Fix tests * Create an appropriate QueueDownwardMessageError variant * Recalculate delivery fee factor based on past queue sizes * Remove unused error variant * Fixes * Fixes * Remove unused imports * Rewrite fee factor update mechanism * Remove unused imports * Fixes * Update runtime/parachains/src/dmp.rs Co-authored-by: Squirrel <gilescope@gmail.com> * Make DeliveryFeeFactor be a StorageMap keyed on ParaIds * Fixes * introduce limit for fee increase on dmp queue * add message_size based fee factor to increment_fee_factor * change message_size fee rate to correct value * fix div by 0 error * bind limit to variable * fix message_size_factor and add DeliveryFeeFactor test * add test for ExponentialPrice implementation * make test formula based * make delivery fee factor test formula based * add max value test for DeliveryFeeFactor and move limit to config * change threshold back to dynamic value and fix tests * fmt * suggested changes and fmt * small stylistic change * fmt * change to tokenlocation * small fixes * fmt * remove sp_arithmetic dependency * Update runtime/parachains/src/dmp.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --------- Co-authored-by: Squirrel <gilescope@gmail.com> Co-authored-by: Just van Stam <just.van.stam@gmail.com> Co-authored-by: Just van Stam <vstam1@users.noreply.github.com> Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
@@ -21,8 +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;
|
||||
use sp_std::{marker::PhantomData, prelude::*};
|
||||
use xcm::prelude::*;
|
||||
use SendError::*;
|
||||
@@ -47,6 +48,24 @@ impl<T: Get<MultiAssets>> PriceForParachainDelivery for ConstantPrice<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 + encoded_msg_len * M)`.
|
||||
pub struct ExponentialPrice<A, B, M, F>(sp_std::marker::PhantomData<(A, B, M, F)>);
|
||||
impl<A: Get<AssetId>, B: Get<u128>, M: Get<u128>, F: FeeTracker> PriceForParachainDelivery
|
||||
for ExponentialPrice<A, B, M, F>
|
||||
{
|
||||
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_fee_factor(para).saturating_mul_int(fee_sum);
|
||||
(A::get(), amount).into()
|
||||
}
|
||||
}
|
||||
|
||||
/// XCM sender for relay chain. It only sends downward message.
|
||||
pub struct ChildParachainRouter<T, W, P>(PhantomData<(T, W, P)>);
|
||||
|
||||
@@ -88,3 +107,61 @@ impl<T: configuration::Config + dmp::Config, W: xcm::WrapVersion, P: PriceForPar
|
||||
.map_err(|_| SendError::Transport(&"Error placing into DMP queue"))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use frame_support::parameter_types;
|
||||
use runtime_parachains::FeeTracker;
|
||||
use sp_runtime::FixedU128;
|
||||
|
||||
parameter_types! {
|
||||
pub const BaseDeliveryFee: u128 = 300_000_000;
|
||||
pub const TransactionByteFee: u128 = 1_000_000;
|
||||
pub FeeAssetId: AssetId = Concrete(Here.into());
|
||||
}
|
||||
|
||||
struct TestFeeTracker;
|
||||
impl FeeTracker for TestFeeTracker {
|
||||
fn get_fee_factor(_: ParaId) -> FixedU128 {
|
||||
FixedU128::from_rational(101, 100)
|
||||
}
|
||||
}
|
||||
|
||||
type TestExponentialPrice =
|
||||
ExponentialPrice<FeeAssetId, BaseDeliveryFee, TransactionByteFee, TestFeeTracker>;
|
||||
|
||||
#[test]
|
||||
fn exponential_price_correct_price_calculation() {
|
||||
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(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(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(
|
||||
id.clone(),
|
||||
&Xcm(vec![SetAppendix(Xcm(vec![ClearOrigin]))])
|
||||
),
|
||||
(FeeAssetId::get(), result).into()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user