mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 21:01:02 +00:00
xcm-executor: DepositReserveAsset charges delivery fees from inner assets (#3142)
This fix aims to solve an issue in Kusama that resulted in failed reserve asset transfers. During multi-hop XCMs, like reserve asset transfers where the reserve is not the sender nor the destination, but a third remote chain, the origin is not available to pay for delivery fees out of their account directly, so delivery fees should be paid out of transferred assets. This commit also adds an xcm-emulator regression test that validates this scenario is now working. Signed-off-by: Adrian Catangiu <adrian@parity.io> Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>
This commit is contained in:
Generated
+1
@@ -823,6 +823,7 @@ dependencies = [
|
|||||||
"assert_matches",
|
"assert_matches",
|
||||||
"asset-hub-rococo-runtime",
|
"asset-hub-rococo-runtime",
|
||||||
"asset-test-utils",
|
"asset-test-utils",
|
||||||
|
"cumulus-pallet-parachain-system",
|
||||||
"emulated-integration-tests-common",
|
"emulated-integration-tests-common",
|
||||||
"frame-support",
|
"frame-support",
|
||||||
"pallet-asset-conversion",
|
"pallet-asset-conversion",
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ rococo-runtime = { path = "../../../../../../../polkadot/runtime/rococo" }
|
|||||||
# Cumulus
|
# Cumulus
|
||||||
asset-test-utils = { path = "../../../../../runtimes/assets/test-utils" }
|
asset-test-utils = { path = "../../../../../runtimes/assets/test-utils" }
|
||||||
parachains-common = { path = "../../../../../../parachains/common" }
|
parachains-common = { path = "../../../../../../parachains/common" }
|
||||||
|
cumulus-pallet-parachain-system = { path = "../../../../../../pallets/parachain-system", default-features = false }
|
||||||
testnet-parachains-constants = { path = "../../../../../runtimes/constants", features = ["rococo"] }
|
testnet-parachains-constants = { path = "../../../../../runtimes/constants", features = ["rococo"] }
|
||||||
asset-hub-rococo-runtime = { path = "../../../../../runtimes/assets/asset-hub-rococo" }
|
asset-hub-rococo-runtime = { path = "../../../../../runtimes/assets/asset-hub-rococo" }
|
||||||
emulated-integration-tests-common = { path = "../../../common", default-features = false }
|
emulated-integration-tests-common = { path = "../../../common", default-features = false }
|
||||||
|
|||||||
+3
-2
@@ -51,8 +51,8 @@ pub use rococo_system_emulated_network::{
|
|||||||
AssetHubRococoParaSender as AssetHubRococoSender, BridgeHubRococoPara as BridgeHubRococo,
|
AssetHubRococoParaSender as AssetHubRococoSender, BridgeHubRococoPara as BridgeHubRococo,
|
||||||
BridgeHubRococoParaReceiver as BridgeHubRococoReceiver, PenpalAPara as PenpalA,
|
BridgeHubRococoParaReceiver as BridgeHubRococoReceiver, PenpalAPara as PenpalA,
|
||||||
PenpalAParaReceiver as PenpalAReceiver, PenpalAParaSender as PenpalASender,
|
PenpalAParaReceiver as PenpalAReceiver, PenpalAParaSender as PenpalASender,
|
||||||
RococoRelay as Rococo, RococoRelayReceiver as RococoReceiver,
|
PenpalBPara as PenpalB, PenpalBParaReceiver as PenpalBReceiver, RococoRelay as Rococo,
|
||||||
RococoRelaySender as RococoSender,
|
RococoRelayReceiver as RococoReceiver, RococoRelaySender as RococoSender,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ASSET_ID: u32 = 1;
|
pub const ASSET_ID: u32 = 1;
|
||||||
@@ -65,6 +65,7 @@ pub type RelayToParaTest = Test<Rococo, PenpalA>;
|
|||||||
pub type SystemParaToRelayTest = Test<AssetHubRococo, Rococo>;
|
pub type SystemParaToRelayTest = Test<AssetHubRococo, Rococo>;
|
||||||
pub type SystemParaToParaTest = Test<AssetHubRococo, PenpalA>;
|
pub type SystemParaToParaTest = Test<AssetHubRococo, PenpalA>;
|
||||||
pub type ParaToSystemParaTest = Test<PenpalA, AssetHubRococo>;
|
pub type ParaToSystemParaTest = Test<PenpalA, AssetHubRococo>;
|
||||||
|
pub type ParaToParaTest = Test<PenpalA, PenpalB, Rococo>;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
+122
@@ -152,6 +152,69 @@ fn system_para_to_para_assets_receiver_assertions<Test>(_: Test) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn para_to_para_sender_assertions(t: ParaToParaTest) {
|
||||||
|
type RuntimeEvent = <PenpalA as Chain>::RuntimeEvent;
|
||||||
|
PenpalA::assert_xcm_pallet_attempted_complete(None);
|
||||||
|
assert_expected_events!(
|
||||||
|
PenpalA,
|
||||||
|
vec![
|
||||||
|
// Amount to reserve transfer is transferred to Parachain's Sovereign account
|
||||||
|
RuntimeEvent::Balances(
|
||||||
|
pallet_balances::Event::Withdraw { who, amount }
|
||||||
|
) => {
|
||||||
|
who: *who == t.sender.account_id,
|
||||||
|
amount: *amount == t.args.amount,
|
||||||
|
},
|
||||||
|
// XCM sent to relay reserve
|
||||||
|
RuntimeEvent::ParachainSystem(
|
||||||
|
cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }
|
||||||
|
) => {},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn para_to_para_relay_hop_assertions(t: ParaToParaTest) {
|
||||||
|
type RuntimeEvent = <Rococo as Chain>::RuntimeEvent;
|
||||||
|
let sov_penpal_a_on_rococo =
|
||||||
|
Rococo::sovereign_account_id_of(Rococo::child_location_of(PenpalA::para_id()));
|
||||||
|
let sov_penpal_b_on_rococo =
|
||||||
|
Rococo::sovereign_account_id_of(Rococo::child_location_of(PenpalB::para_id()));
|
||||||
|
assert_expected_events!(
|
||||||
|
Rococo,
|
||||||
|
vec![
|
||||||
|
// Withdrawn from sender parachain SA
|
||||||
|
RuntimeEvent::Balances(
|
||||||
|
pallet_balances::Event::Withdraw { who, amount }
|
||||||
|
) => {
|
||||||
|
who: *who == sov_penpal_a_on_rococo,
|
||||||
|
amount: *amount == t.args.amount,
|
||||||
|
},
|
||||||
|
// Deposited to receiver parachain SA
|
||||||
|
RuntimeEvent::Balances(
|
||||||
|
pallet_balances::Event::Deposit { who, .. }
|
||||||
|
) => {
|
||||||
|
who: *who == sov_penpal_b_on_rococo,
|
||||||
|
},
|
||||||
|
RuntimeEvent::MessageQueue(
|
||||||
|
pallet_message_queue::Event::Processed { success: true, .. }
|
||||||
|
) => {},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn para_to_para_receiver_assertions(_: ParaToParaTest) {
|
||||||
|
type RuntimeEvent = <PenpalB as Chain>::RuntimeEvent;
|
||||||
|
assert_expected_events!(
|
||||||
|
PenpalB,
|
||||||
|
vec![
|
||||||
|
RuntimeEvent::Balances(pallet_balances::Event::Deposit { .. }) => {},
|
||||||
|
RuntimeEvent::MessageQueue(
|
||||||
|
pallet_message_queue::Event::Processed { success: true, .. }
|
||||||
|
) => {},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn relay_to_para_reserve_transfer_assets(t: RelayToParaTest) -> DispatchResult {
|
fn relay_to_para_reserve_transfer_assets(t: RelayToParaTest) -> DispatchResult {
|
||||||
<Rococo as RococoPallet>::XcmPallet::limited_reserve_transfer_assets(
|
<Rococo as RococoPallet>::XcmPallet::limited_reserve_transfer_assets(
|
||||||
t.signed_origin,
|
t.signed_origin,
|
||||||
@@ -185,6 +248,17 @@ fn para_to_system_para_reserve_transfer_assets(t: ParaToSystemParaTest) -> Dispa
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn para_to_para_limited_reserve_transfer_assets(t: ParaToParaTest) -> DispatchResult {
|
||||||
|
<PenpalA as PenpalAPallet>::PolkadotXcm::limited_reserve_transfer_assets(
|
||||||
|
t.signed_origin,
|
||||||
|
bx!(t.args.dest.into()),
|
||||||
|
bx!(t.args.beneficiary.into()),
|
||||||
|
bx!(t.args.assets.into()),
|
||||||
|
t.args.fee_asset_item,
|
||||||
|
t.args.weight_limit,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't work
|
/// Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't work
|
||||||
#[test]
|
#[test]
|
||||||
fn reserve_transfer_native_asset_from_relay_to_system_para_fails() {
|
fn reserve_transfer_native_asset_from_relay_to_system_para_fails() {
|
||||||
@@ -493,3 +567,51 @@ fn reserve_transfer_assets_from_system_para_to_para() {
|
|||||||
// Receiver's balance is increased by exact amount
|
// Receiver's balance is increased by exact amount
|
||||||
assert_eq!(receiver_assets_after, receiver_assets_before + asset_amount_to_send);
|
assert_eq!(receiver_assets_after, receiver_assets_before + asset_amount_to_send);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reserve Transfers of native asset from Parachain to Parachain (through Relay reserve) should
|
||||||
|
/// work
|
||||||
|
#[test]
|
||||||
|
fn reserve_transfer_native_asset_from_para_to_para() {
|
||||||
|
// Init values for Penpal Parachain
|
||||||
|
let destination = PenpalA::sibling_location_of(PenpalB::para_id());
|
||||||
|
let beneficiary_id = PenpalBReceiver::get();
|
||||||
|
let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 10000;
|
||||||
|
let assets = (Parent, amount_to_send).into();
|
||||||
|
|
||||||
|
let test_args = TestContext {
|
||||||
|
sender: PenpalASender::get(),
|
||||||
|
receiver: PenpalBReceiver::get(),
|
||||||
|
args: TestArgs::new_para(destination, beneficiary_id, amount_to_send, assets, None, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut test = ParaToParaTest::new(test_args);
|
||||||
|
|
||||||
|
let sender_balance_before = test.sender.balance;
|
||||||
|
let receiver_balance_before = test.receiver.balance;
|
||||||
|
|
||||||
|
let sender_as_seen_by_relay = Rococo::child_location_of(PenpalA::para_id());
|
||||||
|
let sov_of_sender_on_relay = Rococo::sovereign_account_id_of(sender_as_seen_by_relay);
|
||||||
|
|
||||||
|
// fund the PenpalA's SA on Rococo with the native tokens held in reserve
|
||||||
|
Rococo::fund_accounts(vec![(sov_of_sender_on_relay.into(), amount_to_send * 2)]);
|
||||||
|
|
||||||
|
test.set_assertion::<PenpalA>(para_to_para_sender_assertions);
|
||||||
|
test.set_assertion::<Rococo>(para_to_para_relay_hop_assertions);
|
||||||
|
test.set_assertion::<PenpalB>(para_to_para_receiver_assertions);
|
||||||
|
test.set_dispatchable::<PenpalA>(para_to_para_limited_reserve_transfer_assets);
|
||||||
|
test.assert();
|
||||||
|
|
||||||
|
let sender_balance_after = test.sender.balance;
|
||||||
|
let receiver_balance_after = test.receiver.balance;
|
||||||
|
|
||||||
|
let delivery_fees = PenpalA::execute_with(|| {
|
||||||
|
xcm_helpers::transfer_assets_delivery_fees::<
|
||||||
|
<PenpalRococoXcmConfig as xcm_executor::Config>::XcmSender,
|
||||||
|
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sender's balance is reduced
|
||||||
|
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
||||||
|
// Receiver's balance is increased
|
||||||
|
assert!(receiver_balance_after > receiver_balance_before);
|
||||||
|
}
|
||||||
|
|||||||
+3
-1
@@ -56,7 +56,8 @@ pub use westend_system_emulated_network::{
|
|||||||
AssetHubWestendPara as AssetHubWestend, AssetHubWestendParaReceiver as AssetHubWestendReceiver,
|
AssetHubWestendPara as AssetHubWestend, AssetHubWestendParaReceiver as AssetHubWestendReceiver,
|
||||||
AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubWestendPara as BridgeHubWestend,
|
AssetHubWestendParaSender as AssetHubWestendSender, BridgeHubWestendPara as BridgeHubWestend,
|
||||||
BridgeHubWestendParaReceiver as BridgeHubWestendReceiver,
|
BridgeHubWestendParaReceiver as BridgeHubWestendReceiver,
|
||||||
CollectivesWestendPara as CollectivesWestend, PenpalBPara as PenpalB,
|
CollectivesWestendPara as CollectivesWestend, PenpalAPara as PenpalA,
|
||||||
|
PenpalAParaReceiver as PenpalAReceiver, PenpalBPara as PenpalB,
|
||||||
PenpalBParaReceiver as PenpalBReceiver, PenpalBParaSender as PenpalBSender,
|
PenpalBParaReceiver as PenpalBReceiver, PenpalBParaSender as PenpalBSender,
|
||||||
WestendRelay as Westend, WestendRelayReceiver as WestendReceiver,
|
WestendRelay as Westend, WestendRelayReceiver as WestendReceiver,
|
||||||
WestendRelaySender as WestendSender,
|
WestendRelaySender as WestendSender,
|
||||||
@@ -72,6 +73,7 @@ pub type RelayToParaTest = Test<Westend, PenpalB>;
|
|||||||
pub type SystemParaToRelayTest = Test<AssetHubWestend, Westend>;
|
pub type SystemParaToRelayTest = Test<AssetHubWestend, Westend>;
|
||||||
pub type SystemParaToParaTest = Test<AssetHubWestend, PenpalB>;
|
pub type SystemParaToParaTest = Test<AssetHubWestend, PenpalB>;
|
||||||
pub type ParaToSystemParaTest = Test<PenpalB, AssetHubWestend>;
|
pub type ParaToSystemParaTest = Test<PenpalB, AssetHubWestend>;
|
||||||
|
pub type ParaToParaTest = Test<PenpalB, PenpalA, Westend>;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
+122
@@ -162,6 +162,69 @@ fn system_para_to_para_assets_receiver_assertions<Test>(_: Test) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn para_to_para_sender_assertions(t: ParaToParaTest) {
|
||||||
|
type RuntimeEvent = <PenpalB as Chain>::RuntimeEvent;
|
||||||
|
PenpalB::assert_xcm_pallet_attempted_complete(None);
|
||||||
|
assert_expected_events!(
|
||||||
|
PenpalB,
|
||||||
|
vec![
|
||||||
|
// Amount to reserve transfer is transferred to Parachain's Sovereign account
|
||||||
|
RuntimeEvent::Balances(
|
||||||
|
pallet_balances::Event::Withdraw { who, amount }
|
||||||
|
) => {
|
||||||
|
who: *who == t.sender.account_id,
|
||||||
|
amount: *amount == t.args.amount,
|
||||||
|
},
|
||||||
|
// XCM sent to relay reserve
|
||||||
|
RuntimeEvent::ParachainSystem(
|
||||||
|
cumulus_pallet_parachain_system::Event::UpwardMessageSent { .. }
|
||||||
|
) => {},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn para_to_para_relay_hop_assertions(t: ParaToParaTest) {
|
||||||
|
type RuntimeEvent = <Westend as Chain>::RuntimeEvent;
|
||||||
|
let sov_penpal_b_on_westend =
|
||||||
|
Westend::sovereign_account_id_of(Westend::child_location_of(PenpalB::para_id()));
|
||||||
|
let sov_penpal_a_on_westend =
|
||||||
|
Westend::sovereign_account_id_of(Westend::child_location_of(PenpalA::para_id()));
|
||||||
|
assert_expected_events!(
|
||||||
|
Westend,
|
||||||
|
vec![
|
||||||
|
// Withdrawn from sender parachain SA
|
||||||
|
RuntimeEvent::Balances(
|
||||||
|
pallet_balances::Event::Withdraw { who, amount }
|
||||||
|
) => {
|
||||||
|
who: *who == sov_penpal_b_on_westend,
|
||||||
|
amount: *amount == t.args.amount,
|
||||||
|
},
|
||||||
|
// Deposited to receiver parachain SA
|
||||||
|
RuntimeEvent::Balances(
|
||||||
|
pallet_balances::Event::Deposit { who, .. }
|
||||||
|
) => {
|
||||||
|
who: *who == sov_penpal_a_on_westend,
|
||||||
|
},
|
||||||
|
RuntimeEvent::MessageQueue(
|
||||||
|
pallet_message_queue::Event::Processed { success: true, .. }
|
||||||
|
) => {},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn para_to_para_receiver_assertions(_: ParaToParaTest) {
|
||||||
|
type RuntimeEvent = <PenpalA as Chain>::RuntimeEvent;
|
||||||
|
assert_expected_events!(
|
||||||
|
PenpalA,
|
||||||
|
vec![
|
||||||
|
RuntimeEvent::Balances(pallet_balances::Event::Deposit { .. }) => {},
|
||||||
|
RuntimeEvent::MessageQueue(
|
||||||
|
pallet_message_queue::Event::Processed { success: true, .. }
|
||||||
|
) => {},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn relay_to_para_reserve_transfer_assets(t: RelayToParaTest) -> DispatchResult {
|
fn relay_to_para_reserve_transfer_assets(t: RelayToParaTest) -> DispatchResult {
|
||||||
<Westend as WestendPallet>::XcmPallet::limited_reserve_transfer_assets(
|
<Westend as WestendPallet>::XcmPallet::limited_reserve_transfer_assets(
|
||||||
t.signed_origin,
|
t.signed_origin,
|
||||||
@@ -195,6 +258,17 @@ fn para_to_system_para_reserve_transfer_assets(t: ParaToSystemParaTest) -> Dispa
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn para_to_para_limited_reserve_transfer_assets(t: ParaToParaTest) -> DispatchResult {
|
||||||
|
<PenpalB as PenpalBPallet>::PolkadotXcm::limited_reserve_transfer_assets(
|
||||||
|
t.signed_origin,
|
||||||
|
bx!(t.args.dest.into()),
|
||||||
|
bx!(t.args.beneficiary.into()),
|
||||||
|
bx!(t.args.assets.into()),
|
||||||
|
t.args.fee_asset_item,
|
||||||
|
t.args.weight_limit,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't work
|
/// Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't work
|
||||||
#[test]
|
#[test]
|
||||||
fn reserve_transfer_native_asset_from_relay_to_system_para_fails() {
|
fn reserve_transfer_native_asset_from_relay_to_system_para_fails() {
|
||||||
@@ -503,3 +577,51 @@ fn reserve_transfer_assets_from_system_para_to_para() {
|
|||||||
// Receiver's balance is increased by exact amount
|
// Receiver's balance is increased by exact amount
|
||||||
assert_eq!(receiver_assets_after, receiver_assets_before + asset_amount_to_send);
|
assert_eq!(receiver_assets_after, receiver_assets_before + asset_amount_to_send);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reserve Transfers of native asset from Parachain to Parachain (through Relay reserve) should
|
||||||
|
/// work
|
||||||
|
#[test]
|
||||||
|
fn reserve_transfer_native_asset_from_para_to_para() {
|
||||||
|
// Init values for Penpal Parachain
|
||||||
|
let destination = PenpalB::sibling_location_of(PenpalA::para_id());
|
||||||
|
let beneficiary_id = PenpalAReceiver::get();
|
||||||
|
let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 1000;
|
||||||
|
let assets = (Parent, amount_to_send).into();
|
||||||
|
|
||||||
|
let test_args = TestContext {
|
||||||
|
sender: PenpalBSender::get(),
|
||||||
|
receiver: PenpalAReceiver::get(),
|
||||||
|
args: TestArgs::new_para(destination, beneficiary_id, amount_to_send, assets, None, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut test = ParaToParaTest::new(test_args);
|
||||||
|
|
||||||
|
let sender_balance_before = test.sender.balance;
|
||||||
|
let receiver_balance_before = test.receiver.balance;
|
||||||
|
|
||||||
|
let sender_as_seen_by_relay = Westend::child_location_of(PenpalB::para_id());
|
||||||
|
let sov_of_sender_on_relay = Westend::sovereign_account_id_of(sender_as_seen_by_relay);
|
||||||
|
|
||||||
|
// fund the PenpalB's SA on Westend with the native tokens held in reserve
|
||||||
|
Westend::fund_accounts(vec![(sov_of_sender_on_relay.into(), amount_to_send * 2)]);
|
||||||
|
|
||||||
|
test.set_assertion::<PenpalB>(para_to_para_sender_assertions);
|
||||||
|
test.set_assertion::<Westend>(para_to_para_relay_hop_assertions);
|
||||||
|
test.set_assertion::<PenpalA>(para_to_para_receiver_assertions);
|
||||||
|
test.set_dispatchable::<PenpalB>(para_to_para_limited_reserve_transfer_assets);
|
||||||
|
test.assert();
|
||||||
|
|
||||||
|
let sender_balance_after = test.sender.balance;
|
||||||
|
let receiver_balance_after = test.receiver.balance;
|
||||||
|
|
||||||
|
let delivery_fees = PenpalB::execute_with(|| {
|
||||||
|
xcm_helpers::transfer_assets_delivery_fees::<
|
||||||
|
<PenpalWestendXcmConfig as xcm_executor::Config>::XcmSender,
|
||||||
|
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sender's balance is reduced
|
||||||
|
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
||||||
|
// Receiver's balance is increased
|
||||||
|
assert!(receiver_balance_after > receiver_balance_before);
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,12 +49,12 @@ use xcm::latest::prelude::*;
|
|||||||
use xcm_builder::{
|
use xcm_builder::{
|
||||||
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
|
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
|
||||||
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, AsPrefixedGeneralIndex,
|
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, AsPrefixedGeneralIndex,
|
||||||
ConvertedConcreteId, CurrencyAdapter, DenyReserveTransferToRelayChain, DenyThenTry,
|
ConvertedConcreteId, CurrencyAdapter, EnsureXcmOrigin, FixedWeightBounds,
|
||||||
EnsureXcmOrigin, FixedWeightBounds, FrameTransactionalProcessor, FungiblesAdapter, IsConcrete,
|
FrameTransactionalProcessor, FungiblesAdapter, IsConcrete, LocalMint, NativeAsset, NoChecking,
|
||||||
LocalMint, NativeAsset, NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative,
|
ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
|
||||||
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
|
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
|
||||||
SignedToAccountId32, SovereignSignedViaLocation, StartsWith, TakeWeightCredit,
|
SovereignSignedViaLocation, StartsWith, TakeWeightCredit, TrailingSetTopicAsId,
|
||||||
TrailingSetTopicAsId, UsingComponents, WithComputedOrigin, WithUniqueTopic,
|
UsingComponents, WithComputedOrigin, WithUniqueTopic,
|
||||||
};
|
};
|
||||||
use xcm_executor::{traits::JustTry, XcmExecutor};
|
use xcm_executor::{traits::JustTry, XcmExecutor};
|
||||||
|
|
||||||
@@ -194,34 +194,29 @@ impl Contains<Location> for CommonGoodAssetsParachain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Barrier = TrailingSetTopicAsId<
|
pub type Barrier = TrailingSetTopicAsId<(
|
||||||
DenyThenTry<
|
TakeWeightCredit,
|
||||||
DenyReserveTransferToRelayChain,
|
// Expected responses are OK.
|
||||||
|
AllowKnownQueryResponses<PolkadotXcm>,
|
||||||
|
// Allow XCMs with some computed origins to pass through.
|
||||||
|
WithComputedOrigin<
|
||||||
(
|
(
|
||||||
TakeWeightCredit,
|
// If the message is one that immediately attempts to pay for execution, then
|
||||||
// Expected responses are OK.
|
// allow it.
|
||||||
AllowKnownQueryResponses<PolkadotXcm>,
|
AllowTopLevelPaidExecutionFrom<Everything>,
|
||||||
// Allow XCMs with some computed origins to pass through.
|
// System Assets parachain, parent and its exec plurality get free
|
||||||
WithComputedOrigin<
|
// execution
|
||||||
(
|
AllowExplicitUnpaidExecutionFrom<(
|
||||||
// If the message is one that immediately attempts to pay for execution, then
|
CommonGoodAssetsParachain,
|
||||||
// allow it.
|
ParentOrParentsExecutivePlurality,
|
||||||
AllowTopLevelPaidExecutionFrom<Everything>,
|
)>,
|
||||||
// System Assets parachain, parent and its exec plurality get free
|
// Subscriptions for version tracking are OK.
|
||||||
// execution
|
AllowSubscriptionsFrom<Everything>,
|
||||||
AllowExplicitUnpaidExecutionFrom<(
|
|
||||||
CommonGoodAssetsParachain,
|
|
||||||
ParentOrParentsExecutivePlurality,
|
|
||||||
)>,
|
|
||||||
// Subscriptions for version tracking are OK.
|
|
||||||
AllowSubscriptionsFrom<Everything>,
|
|
||||||
),
|
|
||||||
UniversalLocation,
|
|
||||||
ConstU32<8>,
|
|
||||||
>,
|
|
||||||
),
|
),
|
||||||
|
UniversalLocation,
|
||||||
|
ConstU32<8>,
|
||||||
>,
|
>,
|
||||||
>;
|
)>;
|
||||||
|
|
||||||
/// Type alias to conveniently refer to `frame_system`'s `Config::AccountId`.
|
/// Type alias to conveniently refer to `frame_system`'s `Config::AccountId`.
|
||||||
pub type AccountIdOf<R> = <R as frame_system::Config>::AccountId;
|
pub type AccountIdOf<R> = <R as frame_system::Config>::AccountId;
|
||||||
|
|||||||
@@ -822,6 +822,20 @@ impl<Config: config::Config> XcmExecutor<Config> {
|
|||||||
DepositReserveAsset { assets, dest, xcm } => {
|
DepositReserveAsset { assets, dest, xcm } => {
|
||||||
let old_holding = self.holding.clone();
|
let old_holding = self.holding.clone();
|
||||||
let result = Config::TransactionalProcessor::process(|| {
|
let result = Config::TransactionalProcessor::process(|| {
|
||||||
|
// we need to do this take/put cycle to solve wildcards and get exact assets to
|
||||||
|
// be weighed
|
||||||
|
let to_weigh = self.holding.saturating_take(assets.clone());
|
||||||
|
self.holding.subsume_assets(to_weigh.clone());
|
||||||
|
|
||||||
|
let mut message_to_weigh =
|
||||||
|
vec![ReserveAssetDeposited(to_weigh.into()), ClearOrigin];
|
||||||
|
message_to_weigh.extend(xcm.0.clone().into_iter());
|
||||||
|
let (_, fee) =
|
||||||
|
validate_send::<Config::XcmSender>(dest.clone(), Xcm(message_to_weigh))?;
|
||||||
|
// set aside fee to be charged by XcmSender
|
||||||
|
let transport_fee = self.holding.saturating_take(fee.into());
|
||||||
|
|
||||||
|
// now take assets to deposit (excluding transport_fee)
|
||||||
let deposited = self.holding.saturating_take(assets);
|
let deposited = self.holding.saturating_take(assets);
|
||||||
for asset in deposited.assets_iter() {
|
for asset in deposited.assets_iter() {
|
||||||
Config::AssetTransactor::deposit_asset(&asset, &dest, Some(&self.context))?;
|
Config::AssetTransactor::deposit_asset(&asset, &dest, Some(&self.context))?;
|
||||||
@@ -832,6 +846,8 @@ impl<Config: config::Config> XcmExecutor<Config> {
|
|||||||
let assets = Self::reanchored(deposited, &dest, None);
|
let assets = Self::reanchored(deposited, &dest, None);
|
||||||
let mut message = vec![ReserveAssetDeposited(assets), ClearOrigin];
|
let mut message = vec![ReserveAssetDeposited(assets), ClearOrigin];
|
||||||
message.extend(xcm.0.into_iter());
|
message.extend(xcm.0.into_iter());
|
||||||
|
// put back transport_fee in holding register to be charged by XcmSender
|
||||||
|
self.holding.subsume_assets(transport_fee);
|
||||||
self.send(dest, Xcm(message), FeeReason::DepositReserveAsset)?;
|
self.send(dest, Xcm(message), FeeReason::DepositReserveAsset)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user