Skip to content

Commit

Permalink
Withdraw Assets Before Checking Out in OnReapIdentity impl (#2552)
Browse files Browse the repository at this point in the history
Follow up to fix a bug from #1814 discovered in XCM emulator testing.

I mistakenly thought that checking out an asset would withdraw it from
the sender. This actually withdraws the asset before checking out.

---------

Co-authored-by: Adrian Catangiu <[email protected]>
Co-authored-by: Liam Aharon <[email protected]>
  • Loading branch information
3 people authored Nov 30, 2023
1 parent eaf1bc5 commit 64361ac
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
24 changes: 23 additions & 1 deletion polkadot/runtime/rococo/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ impl<Runtime, AccountId> ToParachainIdentityReaper<Runtime, AccountId> {
}
}

// Note / Warning: This implementation should only be used in a transactional context. If not, then
// an error could result in assets being burned.
impl<Runtime, AccountId> OnReapIdentity<AccountId> for ToParachainIdentityReaper<Runtime, AccountId>
where
Runtime: frame_system::Config + pallet_xcm::Config,
Expand All @@ -100,14 +102,34 @@ where
// Do `check_out` accounting since the XCM Executor's `InitiateTeleport` doesn't support
// unpaid teleports.

// withdraw the asset from `who`
let who_origin =
Junction::AccountId32 { network: None, id: who.clone().into() }.into_location();
let _withdrawn = xcm_config::LocalAssetTransactor::withdraw_asset(&roc, &who_origin, None)
.map_err(|err| {
log::error!(
target: "runtime::on_reap_identity",
"withdraw_asset(what: {:?}, who_origin: {:?}) error: {:?}",
roc, who_origin, err
);
pallet_xcm::Error::<Runtime>::LowBalance
})?;

// check out
xcm_config::LocalAssetTransactor::can_check_out(
&destination,
&roc,
// not used in AssetTransactor
&XcmContext { origin: None, message_id: [0; 32], topic: None },
)
.map_err(|_| pallet_xcm::Error::<Runtime>::CannotCheckOutTeleport)?;
.map_err(|err| {
log::error!(
target: "runtime::on_reap_identity",
"can_check_out(destination: {:?}, asset: {:?}, _) error: {:?}",
destination, roc, err
);
pallet_xcm::Error::<Runtime>::CannotCheckOutTeleport
})?;
xcm_config::LocalAssetTransactor::check_out(
&destination,
&roc,
Expand Down
24 changes: 23 additions & 1 deletion polkadot/runtime/westend/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ impl<Runtime, AccountId> ToParachainIdentityReaper<Runtime, AccountId> {
}
}

// Note / Warning: This implementation should only be used in a transactional context. If not, then
// an error could result in assets being burned.
impl<Runtime, AccountId> OnReapIdentity<AccountId> for ToParachainIdentityReaper<Runtime, AccountId>
where
Runtime: frame_system::Config + pallet_xcm::Config,
Expand All @@ -100,14 +102,34 @@ where
// Do `check_out` accounting since the XCM Executor's `InitiateTeleport` doesn't support
// unpaid teleports.

// withdraw the asset from `who`
let who_origin =
Junction::AccountId32 { network: None, id: who.clone().into() }.into_location();
let _withdrawn = xcm_config::LocalAssetTransactor::withdraw_asset(&wnd, &who_origin, None)
.map_err(|err| {
log::error!(
target: "runtime::on_reap_identity",
"withdraw_asset(what: {:?}, who_origin: {:?}) error: {:?}",
wnd, who_origin, err
);
pallet_xcm::Error::<Runtime>::LowBalance
})?;

// check out
xcm_config::LocalAssetTransactor::can_check_out(
&destination,
&wnd,
// not used in AssetTransactor
&XcmContext { origin: None, message_id: [0; 32], topic: None },
)
.map_err(|_| pallet_xcm::Error::<Runtime>::CannotCheckOutTeleport)?;
.map_err(|err| {
log::error!(
target: "runtime::on_reap_identity",
"can_check_out(destination: {:?}, asset: {:?}, _) error: {:?}",
destination, wnd, err
);
pallet_xcm::Error::<Runtime>::CannotCheckOutTeleport
})?;
xcm_config::LocalAssetTransactor::check_out(
&destination,
&wnd,
Expand Down

0 comments on commit 64361ac

Please sign in to comment.