From 793d9765e46433a05ad1117ac53f0c48df0da711 Mon Sep 17 00:00:00 2001 From: gorka Date: Thu, 16 Dec 2021 13:12:14 +0100 Subject: [PATCH 1/2] Use fungigbles adapter to withdraw (burn) assets and not get trapped --- pallets/xcm-transactor/src/lib.rs | 31 +++++--------------- pallets/xcm-transactor/src/mock.rs | 1 + precompiles/xcm_transactor/src/mock.rs | 1 + runtime/moonbase/src/lib.rs | 1 + runtime/moonbase/tests/xcm_mock/parachain.rs | 1 + runtime/moonbase/tests/xcm_tests.rs | 11 +++++++ 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/pallets/xcm-transactor/src/lib.rs b/pallets/xcm-transactor/src/lib.rs index 94f2bb380a..cb914350e2 100644 --- a/pallets/xcm-transactor/src/lib.rs +++ b/pallets/xcm-transactor/src/lib.rs @@ -66,7 +66,7 @@ pub mod pallet { use sp_std::convert::TryFrom; use sp_std::prelude::*; use xcm::{latest::prelude::*, VersionedMultiLocation}; - use xcm_executor::traits::{InvertLocation, WeightBounds}; + use xcm_executor::traits::{InvertLocation, TransactAsset, WeightBounds}; use xcm_primitives::{UtilityAvailableCalls, UtilityEncodeCall, XcmTransact}; #[pallet::pallet] @@ -94,6 +94,10 @@ pub mod pallet { // utility call encoding and multilocation gathering type Transactor: Parameter + Member + Clone + XcmTransact; + /// AssetTransactor allows us to withdraw asset without being trapped + /// This should change in xcm v3, which allows us to burn assets + type AssetTransactor: TransactAsset; + // The origin that is allowed to register derivative address indices type DerivativeAddressRegistrationOrigin: EnsureOrigin; @@ -179,6 +183,7 @@ pub mod pallet { NotCrossChainTransferableCurrency, XcmExecuteError, BadVersion, + UnableToWithdrawAsset, } #[pallet::event] @@ -443,28 +448,8 @@ pub mod pallet { // Construct the local withdraw message with the previous calculated amount // This message deducts and burns "amount" from the caller when executed - let mut withdraw_message = Xcm(vec![WithdrawAsset(fee.clone().into())]); - - // Calculate weight of message - let weight = T::Weigher::weight(&mut withdraw_message) - .map_err(|()| Error::::UnweighableMessage)?; - - // This execution ensures we withdraw assets from the calling account - let outcome = T::XcmExecutor::execute_xcm_in_credit( - origin_as_mult, - withdraw_message, - weight, - weight, - ); - - // Let's check if the execution was succesful - let maybe_xcm_err: Option = match outcome { - Outcome::Complete(_w) => Option::None, - Outcome::Incomplete(_w, err) => Some(err), - Outcome::Error(err) => Some(err), - }; - - ensure!(maybe_xcm_err.is_none(), Error::::XcmExecuteError); + T::AssetTransactor::withdraw_asset(&fee.clone().into(), &origin_as_mult) + .map_err(|_| Error::::UnableToWithdrawAsset)?; // Construct the transact message. This is composed of WithdrawAsset||BuyExecution|| // Transact. diff --git a/pallets/xcm-transactor/src/mock.rs b/pallets/xcm-transactor/src/mock.rs index 05ad305efc..3899142f37 100644 --- a/pallets/xcm-transactor/src/mock.rs +++ b/pallets/xcm-transactor/src/mock.rs @@ -320,6 +320,7 @@ impl Config for Test { type Transactor = Transactors; type DerivativeAddressRegistrationOrigin = EnsureRoot; type SovereignAccountDispatcherOrigin = EnsureRoot; + type LocalAssetTransactor = DummyAssetTransactor; type CurrencyId = CurrencyId; type CurrencyIdToMultiLocation = CurrencyIdToMultiLocation; type AccountIdToMultiLocation = AccountIdToMultiLocation; diff --git a/precompiles/xcm_transactor/src/mock.rs b/precompiles/xcm_transactor/src/mock.rs index 3f18b94c7b..0e338c174e 100644 --- a/precompiles/xcm_transactor/src/mock.rs +++ b/precompiles/xcm_transactor/src/mock.rs @@ -424,6 +424,7 @@ impl xcm_transactor::Config for Test { type LocationInverter = InvertNothing; type BaseXcmWeight = BaseXcmWeight; type XcmSender = DoNothingRouter; + type AssetTransactor = DummyAssetTransactor; } // We need to use the encoding from the relay mock runtime diff --git a/runtime/moonbase/src/lib.rs b/runtime/moonbase/src/lib.rs index fe3af4c275..ddcdd5a8e9 100644 --- a/runtime/moonbase/src/lib.rs +++ b/runtime/moonbase/src/lib.rs @@ -1410,6 +1410,7 @@ impl xcm_transactor::Config for Runtime { type Weigher = xcm_builder::FixedWeightBounds; type LocationInverter = LocationInverter; type BaseXcmWeight = BaseXcmWeight; + type AssetTransactor = AssetTransactors; } /// Call filter used during Phase 3 of the Moonriver rollout diff --git a/runtime/moonbase/tests/xcm_mock/parachain.rs b/runtime/moonbase/tests/xcm_mock/parachain.rs index 86d485323e..9bf97f9ece 100644 --- a/runtime/moonbase/tests/xcm_mock/parachain.rs +++ b/runtime/moonbase/tests/xcm_mock/parachain.rs @@ -676,6 +676,7 @@ impl xcm_transactor::Config for Runtime { type LocationInverter = LocationInverter; type XcmSender = XcmRouter; type BaseXcmWeight = BaseXcmWeight; + type AssetTransactor = AssetTransactors; } pub struct NormalFilter; diff --git a/runtime/moonbase/tests/xcm_tests.rs b/runtime/moonbase/tests/xcm_tests.rs index a9532844bc..f4e8813493 100644 --- a/runtime/moonbase/tests/xcm_tests.rs +++ b/runtime/moonbase/tests/xcm_tests.rs @@ -839,6 +839,17 @@ fn transact_through_derivative_multilocation() { 4000000000, encoded, )); + let event_found: Option = + parachain::para_events() + .iter() + .find_map(|event| match event.clone() { + parachain::Event::PolkadotXcm(pallet_xcm::Event::AssetsTrapped(_, _, _)) => { + Some(event.clone()) + } + _ => None, + }); + // Assert that the events do not contain the assets being trapped + assert!(event_found.is_none()); }); Relay::execute_with(|| { From e04da331de57524e6de8b301eac620ad9794917d Mon Sep 17 00:00:00 2001 From: gorka Date: Thu, 16 Dec 2021 13:35:36 +0100 Subject: [PATCH 2/2] Change name --- pallets/xcm-transactor/src/mock.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/xcm-transactor/src/mock.rs b/pallets/xcm-transactor/src/mock.rs index 3899142f37..1fbedc9583 100644 --- a/pallets/xcm-transactor/src/mock.rs +++ b/pallets/xcm-transactor/src/mock.rs @@ -320,7 +320,7 @@ impl Config for Test { type Transactor = Transactors; type DerivativeAddressRegistrationOrigin = EnsureRoot; type SovereignAccountDispatcherOrigin = EnsureRoot; - type LocalAssetTransactor = DummyAssetTransactor; + type AssetTransactor = DummyAssetTransactor; type CurrencyId = CurrencyId; type CurrencyIdToMultiLocation = CurrencyIdToMultiLocation; type AccountIdToMultiLocation = AccountIdToMultiLocation;