Unverified Commit 67fd660f authored by Gavin Wood's avatar Gavin Wood Committed by GitHub
Browse files

Avoid bad pattern of wildcard fees (#3578)

* Avoid bad pattern of wildcard fees

* spelling

* fmt

* Fix runtimes

* spelling
parent 5d462ca2
Pipeline #151370 passed with stages
in 39 minutes and 21 seconds
......@@ -1380,6 +1380,7 @@ impl pallet_xcm::Config for Runtime {
type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
type LocationInverter = LocationInverter<Ancestry>;
}
parameter_types! {
......
......@@ -755,6 +755,7 @@ impl pallet_xcm::Config for Runtime {
type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
type LocationInverter = LocationInverter<Ancestry>;
}
impl parachains_session_info::Config for Runtime {}
......
......@@ -1012,6 +1012,7 @@ impl pallet_xcm::Config for Runtime {
type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
type LocationInverter = LocationInverter<Ancestry>;
}
construct_runtime! {
......
......@@ -38,7 +38,7 @@ pub mod pallet {
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
use sp_runtime::traits::AccountIdConversion;
use xcm_executor::traits::WeightBounds;
use xcm_executor::traits::{InvertLocation, WeightBounds};
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
......@@ -76,6 +76,9 @@ pub mod pallet {
/// Means of measuring the weight consumed by an XCM message locally.
type Weigher: WeightBounds<Self::Call>;
/// Means of inverting a location.
type LocationInverter: InvertLocation;
}
#[pallet::event]
......@@ -93,6 +96,10 @@ pub mod pallet {
Filtered,
/// The message's weight could not be determined.
UnweighableMessage,
/// The assets to be sent are empty.
Empty,
/// Could not reanchor the assets to declare the fees for the destination chain.
CannotReanchor,
}
#[pallet::hooks]
......@@ -115,6 +122,8 @@ pub mod pallet {
/// Teleport some assets from the local chain to some destination chain.
///
/// Fee payment on the destination side is made from the first asset listed in the `assets` vector.
///
/// - `origin`: Must be capable of withdrawing the `assets` and executing XCM.
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send
/// from parachain to parachain, or `X1(Parachain(..))` to send from relay to parachain.
......@@ -146,6 +155,9 @@ pub mod pallet {
let value = (origin_location, assets);
ensure!(T::XcmTeleportFilter::contains(&value), Error::<T>::Filtered);
let (origin_location, assets) = value;
let inv_dest = T::LocationInverter::invert_location(&dest);
let mut fees = assets.first().ok_or(Error::<T>::Empty)?.clone();
fees.reanchor(&inv_dest).map_err(|_| Error::<T>::CannotReanchor)?;
let mut message = Xcm::WithdrawAsset {
assets,
effects: vec![InitiateTeleport {
......@@ -153,7 +165,7 @@ pub mod pallet {
dest,
effects: vec![
BuyExecution {
fees: All,
fees,
// Zero weight for additional XCM (since there are none to execute)
weight: 0,
debt: dest_weight,
......@@ -175,6 +187,8 @@ pub mod pallet {
/// Transfer some assets from the local chain to the sovereign account of a destination chain and forward
/// a notification XCM.
///
/// Fee payment on the destination side is made from the first asset listed in the `assets` vector.
///
/// - `origin`: Must be capable of withdrawing the `assets` and executing XCM.
/// - `dest`: Destination context for the assets. Will typically be `X2(Parent, Parachain(..))` to send
/// from parachain to parachain, or `X1(Parachain(..))` to send from relay to parachain.
......@@ -203,12 +217,15 @@ pub mod pallet {
let value = (origin_location, assets);
ensure!(T::XcmReserveTransferFilter::contains(&value), Error::<T>::Filtered);
let (origin_location, assets) = value;
let inv_dest = T::LocationInverter::invert_location(&dest);
let mut fees = assets.first().ok_or(Error::<T>::Empty)?.clone();
fees.reanchor(&inv_dest).map_err(|_| Error::<T>::CannotReanchor)?;
let mut message = Xcm::TransferReserveAsset {
assets,
dest,
effects: vec![
BuyExecution {
fees: All,
fees,
// Zero weight for additional XCM (since there are none to execute)
weight: 0,
debt: dest_weight,
......
......@@ -186,6 +186,7 @@ impl pallet_xcm::Config for Test {
type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
type LocationInverter = LocationInverter<Ancestry>;
}
impl origin::Config for Test {}
......@@ -194,9 +195,9 @@ pub(crate) fn last_event() -> Event {
System::events().pop().expect("Event expected").event
}
pub(crate) fn buy_execution<C>(debt: Weight) -> Order<C> {
pub(crate) fn buy_execution<C>(debt: Weight, fees: MultiAsset) -> Order<C> {
use xcm::opaque::v0::prelude::*;
Order::BuyExecution { fees: All, weight: 0, debt, halt_on_error: false, xcm: vec![] }
Order::BuyExecution { fees, weight: 0, debt, halt_on_error: false, xcm: vec![] }
}
pub(crate) fn new_test_ext_with_balances(
......
......@@ -42,7 +42,10 @@ fn send_works() {
let message = Xcm::ReserveAssetDeposit {
assets: vec![ConcreteFungible { id: Parent.into(), amount: SEND_AMOUNT }],
effects: vec![
buy_execution(weight),
buy_execution(
weight,
ConcreteFungible { id: MultiLocation::Null, amount: SEND_AMOUNT },
),
DepositAsset { assets: vec![All], dest: sender.clone() },
],
};
......@@ -76,7 +79,10 @@ fn send_fails_when_xcm_router_blocks() {
let message = Xcm::ReserveAssetDeposit {
assets: vec![ConcreteFungible { id: Parent.into(), amount: SEND_AMOUNT }],
effects: vec![
buy_execution(weight),
buy_execution(
weight,
ConcreteFungible { id: MultiLocation::Null, amount: SEND_AMOUNT },
),
DepositAsset { assets: vec![All], dest: sender.clone() },
],
};
......@@ -157,7 +163,13 @@ fn reserve_transfer_assets_works() {
Parachain(PARA_ID).into(),
Xcm::ReserveAssetDeposit {
assets: vec![ConcreteFungible { id: Parent.into(), amount: SEND_AMOUNT }],
effects: vec![buy_execution(weight), DepositAsset { assets: vec![All], dest },]
effects: vec![
buy_execution(
weight,
ConcreteFungible { id: Parent.into(), amount: SEND_AMOUNT }
),
DepositAsset { assets: vec![All], dest },
]
}
)]
);
......@@ -185,7 +197,13 @@ fn execute_withdraw_to_deposit_works() {
Origin::signed(ALICE),
Box::new(Xcm::WithdrawAsset {
assets: vec![ConcreteFungible { id: MultiLocation::Null, amount: SEND_AMOUNT }],
effects: vec![buy_execution(weight), DepositAsset { assets: vec![All], dest }],
effects: vec![
buy_execution(
weight,
ConcreteFungible { id: MultiLocation::Null, amount: SEND_AMOUNT }
),
DepositAsset { assets: vec![All], dest },
],
}),
weight
));
......
......@@ -187,7 +187,7 @@ pub mod mock_msg_queue {
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
// XCMP
/// Some XCM was executed ok.
/// Some XCM was executed OK.
Success(Option<T::Hash>),
/// Some XCM failed.
Fail(Option<T::Hash>, XcmError),
......@@ -302,6 +302,7 @@ impl pallet_xcm::Config for Runtime {
type XcmTeleportFilter = ();
type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
type LocationInverter = LocationInverter<Ancestry>;
}
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
......
......@@ -148,6 +148,7 @@ impl pallet_xcm::Config for Runtime {
type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
type LocationInverter = LocationInverter<Ancestry>;
}
parameter_types! {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment