Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Add xcm context to weight trader #7561

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion runtime/test-runtime/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,12 @@ impl WeightTrader for DummyWeightTrader {
DummyWeightTrader
}

fn buy_weight(&mut self, _weight: Weight, _payment: Assets) -> Result<Assets, XcmError> {
fn buy_weight(
&mut self,
_ctx: Option<&XcmContext>,
_weight: Weight,
_payment: Assets,
) -> Result<Assets, XcmError> {
Ok(Assets::default())
}
}
Expand Down
43 changes: 32 additions & 11 deletions xcm/xcm-builder/src/tests/weight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,42 @@ fn fixed_rate_of_fungible_should_work() {
}

let mut trader = FixedRateOfFungible::<WeightPrice, ()>::new();
let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None };

// supplies 100 unit of asset, 80 still remains after purchasing weight
assert_eq!(
trader
.buy_weight(Weight::from_parts(10, 10), fungible_multi_asset(Here.into(), 100).into()),
trader.buy_weight(
Some(&ctx),
Weight::from_parts(10, 10),
fungible_multi_asset(Here.into(), 100).into()
),
Ok(fungible_multi_asset(Here.into(), 80).into()),
);
// should have nothing left, as 5 + 5 = 10, and we supplied 10 units of asset.
assert_eq!(
trader.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(Here.into(), 10).into()),
trader.buy_weight(
Some(&ctx),
Weight::from_parts(5, 5),
fungible_multi_asset(Here.into(), 10).into()
),
Ok(vec![].into()),
);
// should have 5 left, as there are no proof size components
assert_eq!(
trader.buy_weight(Weight::from_parts(5, 0), fungible_multi_asset(Here.into(), 10).into()),
trader.buy_weight(
Some(&ctx),
Weight::from_parts(5, 0),
fungible_multi_asset(Here.into(), 10).into()
),
Ok(fungible_multi_asset(Here.into(), 5).into()),
);
// not enough to purchase the combined weights
assert_err!(
trader.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(Here.into(), 5).into()),
trader.buy_weight(
Some(&ctx),
Weight::from_parts(5, 5),
fungible_multi_asset(Here.into(), 5).into()
),
XcmError::TooExpensive,
);
}
Expand Down Expand Up @@ -151,33 +168,37 @@ fn weight_trader_tuple_should_work() {
let mut traders = Traders::new();
// trader one buys weight
assert_eq!(
traders.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(Here.into(), 10).into()),
traders.buy_weight(
None,
Weight::from_parts(5, 5),
fungible_multi_asset(Here.into(), 10).into()
),
Ok(vec![].into()),
);
// trader one refunds
assert_eq!(
traders.refund_weight(Weight::from_parts(2, 2)),
traders.refund_weight(None, Weight::from_parts(2, 2)),
Some(fungible_multi_asset(Here.into(), 4))
);

let mut traders = Traders::new();
// trader one failed; trader two buys weight
assert_eq!(
traders.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(para_1, 10).into()),
traders.buy_weight(None, Weight::from_parts(5, 5), fungible_multi_asset(para_1, 10).into()),
Ok(vec![].into()),
);
// trader two refunds
assert_eq!(
traders.refund_weight(Weight::from_parts(2, 2)),
traders.refund_weight(None, Weight::from_parts(2, 2)),
Some(fungible_multi_asset(para_1, 4))
);

let mut traders = Traders::new();
// all traders fails
assert_err!(
traders.buy_weight(Weight::from_parts(5, 5), fungible_multi_asset(para_2, 10).into()),
traders.buy_weight(None, Weight::from_parts(5, 5), fungible_multi_asset(para_2, 10).into()),
XcmError::TooExpensive,
);
// and no refund
assert_eq!(traders.refund_weight(Weight::from_parts(2, 2)), None);
assert_eq!(traders.refund_weight(None, Weight::from_parts(2, 2)), None);
}
18 changes: 14 additions & 4 deletions xcm/xcm-builder/src/weight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,12 @@ impl<T: Get<(AssetId, u128, u128)>, R: TakeRevenue> WeightTrader for FixedRateOf
Self(Weight::zero(), 0, PhantomData)
}

fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
fn buy_weight(
&mut self,
_ctx: Option<&XcmContext>,
weight: Weight,
payment: Assets,
) -> Result<Assets, XcmError> {
log::trace!(
target: "xcm::weight",
"FixedRateOfFungible::buy_weight weight: {:?}, payment: {:?}",
Expand All @@ -160,7 +165,7 @@ impl<T: Get<(AssetId, u128, u128)>, R: TakeRevenue> WeightTrader for FixedRateOf
Ok(unused)
}

fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
fn refund_weight(&mut self, _ctx: Option<&XcmContext>, weight: Weight) -> Option<MultiAsset> {
log::trace!(target: "xcm::weight", "FixedRateOfFungible::refund_weight weight: {:?}", weight);
let (id, units_per_second, units_per_mb) = T::get();
let weight = weight.min(self.0);
Expand Down Expand Up @@ -210,7 +215,12 @@ impl<
Self(Weight::zero(), Zero::zero(), PhantomData)
}

fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
fn buy_weight(
&mut self,
_ctx: Option<&XcmContext>,
weight: Weight,
payment: Assets,
) -> Result<Assets, XcmError> {
log::trace!(target: "xcm::weight", "UsingComponents::buy_weight weight: {:?}, payment: {:?}", weight, payment);
let amount = WeightToFee::weight_to_fee(&weight);
let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;
Expand All @@ -221,7 +231,7 @@ impl<
Ok(unused)
}

fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
fn refund_weight(&mut self, _ctx: Option<&XcmContext>, weight: Weight) -> Option<MultiAsset> {
log::trace!(target: "xcm::weight", "UsingComponents::refund_weight weight: {:?}", weight);
let weight = weight.min(self.0);
let amount = WeightToFee::weight_to_fee(&weight);
Expand Down
4 changes: 2 additions & 2 deletions xcm/xcm-executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
let current_surplus = self.total_surplus.saturating_sub(self.total_refunded);
if current_surplus.any_gt(Weight::zero()) {
self.total_refunded.saturating_accrue(current_surplus);
if let Some(w) = self.trader.refund_weight(current_surplus) {
if let Some(w) = self.trader.refund_weight(Some(&self.context), current_surplus) {
self.subsume_asset(w)?;
}
}
Expand Down Expand Up @@ -689,7 +689,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
// pay for `weight` using up to `fees` of the holding register.
let max_fee =
self.holding.try_take(fees.into()).map_err(|_| XcmError::NotHoldingFees)?;
let unspent = self.trader.buy_weight(weight, max_fee)?;
let unspent = self.trader.buy_weight(Some(&self.context), weight, max_fee)?;
self.subsume_assets(unspent)?;
}
Ok(())
Expand Down
22 changes: 16 additions & 6 deletions xcm/xcm-executor/src/traits/weight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,18 @@ pub trait WeightTrader: Sized {
/// Purchase execution weight credit in return for up to a given `payment`. If less of the
/// payment is required then the surplus is returned. If the `payment` cannot be used to pay
/// for the `weight`, then an error is returned.
fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError>;
fn buy_weight(
&mut self,
ctx: Option<&XcmContext>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why as first arg? since we extending more logical to see it a last arg. Also in other contracts it appears to be the last arg.
Also we do not have ctx naming for context so far.

weight: Weight,
payment: Assets,
) -> Result<Assets, XcmError>;

/// Attempt a refund of `weight` into some asset. The caller does not guarantee that the weight was
/// purchased using `buy_weight`.
///
/// Default implementation refunds nothing.
fn refund_weight(&mut self, _weight: Weight) -> Option<MultiAsset> {
fn refund_weight(&mut self, _ctx: Option<&XcmContext>, _weight: Weight) -> Option<MultiAsset> {
None
}
}
Expand All @@ -66,11 +71,16 @@ impl WeightTrader for Tuple {
for_tuples!( ( #( Tuple::new() ),* ) )
}

fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
fn buy_weight(
&mut self,
ctx: Option<&XcmContext>,
weight: Weight,
payment: Assets,
) -> Result<Assets, XcmError> {
let mut too_expensive_error_found = false;
let mut last_error = None;
for_tuples!( #(
match Tuple.buy_weight(weight, payment.clone()) {
match Tuple.buy_weight(ctx, weight, payment.clone()) {
Ok(assets) => return Ok(assets),
Err(e) => {
if let XcmError::TooExpensive = e {
Expand All @@ -92,9 +102,9 @@ impl WeightTrader for Tuple {
})
}

fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
fn refund_weight(&mut self, ctx: Option<&XcmContext>, weight: Weight) -> Option<MultiAsset> {
for_tuples!( #(
if let Some(asset) = Tuple.refund_weight(weight) {
if let Some(asset) = Tuple.refund_weight(ctx, weight) {
return Some(asset);
}
)* );
Expand Down