-
Notifications
You must be signed in to change notification settings - Fork 690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pallet-xcm: add extrinsic to allow withdrawal of reserve-based assets #1430
pallet-xcm: add extrinsic to allow withdrawal of reserve-based assets #1430
Conversation
pallet-xcm already offers `reserve_transfer_assets()` call for easy reserve-based asset transfer, where original assets are reserved in some reserve location and equivalent assets are minted at destination. This commit adds `reserve_withdraw_assets()` call for users to be able to do the operation reverse too: burn equivalent assets and release original ones from reserve location. Co-authored-by: Aleksandr Krupenkin <mail@akru.me>
bot bench polkadot-pallet --pallet=pallet_xcm |
@acatangiu Command |
a6cf8c2
to
2d4ac96
Compare
So I'm not 100% sure that we should have a separate extrinsic for this. We actually found out that In other words, if the goal for introducing |
No, the goal is not to work around any limitations (none present afaik) of TLDR: Long-winded explanation of abovereserve_transfer_assetMy understanding of the purpose of Where
So (at least afaik) it can only be used for the original reserve asset, not for derivatives (assets based on original reserve). It clearly "reserves" an asset by placing in local SA of So the point of it is to turn an/any asset into a reserve asset, reserve it locally in the ownership of dest, and let dest know about it (which usually means dest mints some dest-local derivative equivalent asset). (Let chain A be the local use of reserve_withdraw_assetTo do the reversed operation (reversed as in "undo", not as in mirrored), user would call
A (poorish) analogy I can think of on the spot is a
I guess we could build a more complex extrinsic that could do both "push" and "pop" and figure out the intention of its user based on parameters or built-in (opaque) logic, but ultimately it still has to run different XCM instructions ( Maybe I'm missing something, WDYT? |
That's what it isn't supposed to do -- we fully intended it to be a function that allows you to burn a derivative, send an onwards message to the reserve, transfer the reserve asset underlying the derivative to the SA of the destination, and finally notifying the destination chain. The extrinsic as it stands now doesn't burn anything via This would then solve your other issue as well, since there is no "reverse direction" anymore -- it's all just the same function that you call. What I also imagine it to be doing is to be smart and know that if e.g. the destination and the reserve location are the same, it'll just know not to forward a |
Sorry I'm a bit confused so I will answer to both interpretations to your comment:
"The extrinsic" you refer to is
|
let assets = Self::reanchored( | |
self.holding.saturating_take(assets), | |
&reserve, | |
Some(&mut self.holding), | |
); | |
let mut message = vec![WithdrawAsset(assets), ClearOrigin]; |
It
saturating_take
s it out of holding
and does nothing else with it - by reanchoring its multilocation we end up referring to the reserve asset. The WithdrawAssets(assets)
then happens on destination chain to release the reserve asset from the SA of this chain then later deposit it to final beneficiary
.It does the "burning" same as
BurnAsset
:polkadot-sdk/polkadot/xcm/xcm-executor/src/lib.rs
Lines 747 to 750 in 342d720
BurnAsset(assets) => { | |
self.holding.saturating_take(assets.into()); | |
Ok(()) | |
}, |
"The extrinsic" you refer to is reserve_transfer_asset
Or by "The extrinsic" you mean reserve_transfer_asset
and that it should do either ReserveAssetDeposited
or InitiateReserveWithdraw
(or both) based on inner logic?
If this is the case, can you please provide a scenario/user-story for a user with accounts on both chain A and chain B that wants to move a reserve-based asset between his/her accounts using reserve_transfer_asset
in both ways?
What should the extrinsic do in each case? Also behavior would be different I think and should also be described when reserve is chain A (or B) or third chain C.
If reserve_transfer_asset
extrinsic redesign is required, we can also move this discussion to a https://github.com/polkadot-fellows/RFCs to properly redesign before we attempt code changes?
I still think the way xtokens handles it is significantly better. i.e. a |
This isn't necessary -- that was an oversight, and |
This pull request has been mentioned on Polkadot Forum. There might be relevant details there: https://forum.polkadot.network/t/polkadot-kusama-bridge/2971/5 |
Opened #1584 to detail the proposed solution - will close this PR on behalf of alternative described there. |
I'll look at the |
closing in favor of #1672 |
…tTargetChain is used) (paritytech#1430) * reintroduce From<SourceChain>InboundLaneApi * impl From<Chain>InboundLaneApi for testnet runtimes * use inboundlaneapi in relay * remove unused OutboundXcmWeigher * spelling * added the only test to messages pallet * fmt
…tTargetChain is used) (paritytech#1430) * reintroduce From<SourceChain>InboundLaneApi * impl From<Chain>InboundLaneApi for testnet runtimes * use inboundlaneapi in relay * remove unused OutboundXcmWeigher * spelling * added the only test to messages pallet * fmt
…tTargetChain is used) (paritytech#1430) * reintroduce From<SourceChain>InboundLaneApi * impl From<Chain>InboundLaneApi for testnet runtimes * use inboundlaneapi in relay * remove unused OutboundXcmWeigher * spelling * added the only test to messages pallet * fmt
…tTargetChain is used) (paritytech#1430) * reintroduce From<SourceChain>InboundLaneApi * impl From<Chain>InboundLaneApi for testnet runtimes * use inboundlaneapi in relay * remove unused OutboundXcmWeigher * spelling * added the only test to messages pallet * fmt
…tTargetChain is used) (paritytech#1430) * reintroduce From<SourceChain>InboundLaneApi * impl From<Chain>InboundLaneApi for testnet runtimes * use inboundlaneapi in relay * remove unused OutboundXcmWeigher * spelling * added the only test to messages pallet * fmt
…tTargetChain is used) (paritytech#1430) * reintroduce From<SourceChain>InboundLaneApi * impl From<Chain>InboundLaneApi for testnet runtimes * use inboundlaneapi in relay * remove unused OutboundXcmWeigher * spelling * added the only test to messages pallet * fmt
…tTargetChain is used) (paritytech#1430) * reintroduce From<SourceChain>InboundLaneApi * impl From<Chain>InboundLaneApi for testnet runtimes * use inboundlaneapi in relay * remove unused OutboundXcmWeigher * spelling * added the only test to messages pallet * fmt
…tTargetChain is used) (paritytech#1430) * reintroduce From<SourceChain>InboundLaneApi * impl From<Chain>InboundLaneApi for testnet runtimes * use inboundlaneapi in relay * remove unused OutboundXcmWeigher * spelling * added the only test to messages pallet * fmt
…tTargetChain is used) (paritytech#1430) * reintroduce From<SourceChain>InboundLaneApi * impl From<Chain>InboundLaneApi for testnet runtimes * use inboundlaneapi in relay * remove unused OutboundXcmWeigher * spelling * added the only test to messages pallet * fmt
…tTargetChain is used) (paritytech#1430) * reintroduce From<SourceChain>InboundLaneApi * impl From<Chain>InboundLaneApi for testnet runtimes * use inboundlaneapi in relay * remove unused OutboundXcmWeigher * spelling * added the only test to messages pallet * fmt
…tTargetChain is used) (paritytech#1430) * reintroduce From<SourceChain>InboundLaneApi * impl From<Chain>InboundLaneApi for testnet runtimes * use inboundlaneapi in relay * remove unused OutboundXcmWeigher * spelling * added the only test to messages pallet * fmt
…tTargetChain is used) (paritytech#1430) * reintroduce From<SourceChain>InboundLaneApi * impl From<Chain>InboundLaneApi for testnet runtimes * use inboundlaneapi in relay * remove unused OutboundXcmWeigher * spelling * added the only test to messages pallet * fmt
…tTargetChain is used) (#1430) * reintroduce From<SourceChain>InboundLaneApi * impl From<Chain>InboundLaneApi for testnet runtimes * use inboundlaneapi in relay * remove unused OutboundXcmWeigher * spelling * added the only test to messages pallet * fmt
Description
Motivation
pallet-xcm
is the main user-facing interface for XCM functionality, including assets manipulation functions liketeleportAssets()
andreserve_transfer_assets()
calls.While
teleportAsset()
works both ways,reserve_transfer_assets()
works only for sending reserve-based assets to a remote destination and beneficiary, but there is no user-facing extrinsic for burning reserved-based assets and getting back the original reserved assets.Solution
This PR adds
(limited_)reserve_withdraw_assets()
extrinsics that builds and locally executes XCM program containingInitiateReserveWithdraw
XCVM instruction to burn synthetic asset on (local) chain and send notification to destination (reserve chain) for releasing locked asset.Testing
Added synthetic
pallet-xcm
unit-test for testing extrinsic when used with native asset, andAssetHub
s runtime unit-tests that test extrinsic when used with foreign asset.Partially fixes paritytech/parity-bridges-common#2405
Checklist
T
required)
If this PR alters any external APIs or interfaces used by Polkadot, the corresponding Polkadot PR is ready as wellas the corresponding Cumulus PR (optional)