-
Notifications
You must be signed in to change notification settings - Fork 298
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
Transfer with Transact Design Discussion #766
Comments
If |
Right, the |
I'm a bit hesitant to add an API that allows any signed account to simply provide an encoded call and then have it be executed on a foreign chain. It just sounds to me that there's a high chance that it could be exploited in ways that we don't quite yet understand, the one that I could think of is via a bad runtime upgrade that accidentally added a new dispatchable to modify important state info without having proper access controls. Further, since work is underway to provide an upper limit to all I also feel like there's a significant overhead for sending 2 XCMs instead of one, and indeed from the changes linked in the description, it requires adding an XcmSender as a configurable on the ORML XCM pallet, which did not exist before. I hear that the reason was because of the In general though, I don't feel like a transfer with a |
Hi @KiChjang, Thanks for the feedback, this is really helpful. Thanks for the
Motivation
Our motivating application is to streamline the privatization of parachain assets. For example, using You can argue that we can always compose these transactions at the front-end/dApp level. However, composing at runtime level has the great advantage of latency and reducing complexity for dApp development. Since these operations are streamlined. dApp developers doesn't need to handle the complexity of composing and waiting for the first extrinsic finish and then sending the second one. Here, we would like to at least to provide a choice to compose at runtime level. Security
This is a very good point, in @ghzlatarev 's original post, he didn't elaborate on the security aspect of the design. The key security guarantees of the design are as follows (BTW, these points are precisely why we want to implement in ORML and get the code potentially audited):
Transact { origin_type, require_weight_at_most, mut call } => {
// We assume that the Relay-chain is allowed to use transact on this parachain.
let origin = self.origin.clone().ok_or(XcmError::BadOrigin)?;
// TODO: paritytech/polkadot#2841 #TRANSACTFILTER allow the trait to issue filters for the relay-chain
let message_call = call.take_decoded().map_err(|_| XcmError::FailedToDecode)?;
let dispatch_origin = Config::OriginConverter::convert_origin(origin, origin_type)
.map_err(|_| XcmError::BadOrigin)?;` and in the I think these are kind of strong assumptions that we need to enforce to make sure the current |
What I would argue instead is whether you can think of a way to introduce a new XCM instruction that sidesteps this issue. Remember, any XCM instruction is capable of having different semantics determined by the receiving chain, so if this is something that you feel like it can be generalized, then perhaps it's a really good idea to add such an operation at the XCM instruction level, rather than trying to operate around the current security constraints and instruction set. I don't have a good name for the operation that you are trying to introduce, but I will say that there is already an |
I think the fundamental issue of current XCM design that prevents an elegant solution for something like this is the forcefully |
Hi, hadnt seen this thread before but I would like to share my thoughts on this matter:
|
Just to quickly add, for the user to 1-click transfer assets, I view this as a UX problem rather than an XCM issue. I don't see why XCM interactions should correlate 1-to-1 with user actions. |
Also, I now recall that |
Thanks for the input guys! Some more thoughts from my side:
Indeed this is a UX issue, and our thinking is that it will probably have to be dealt with on different front-ends, so that's why it could be beneficial to have the solution in xtokens directly.
The issue with
This is an example where one wouldn't need the second XCM call, the amount is burned on Moonbeam's side and withdrawn from Moonbeam's sovereign account on the relay chain and used by a derivative of the sovereign account. However this assumes that there already was a reserve transfer from relay to Moonbeam. If I'm doing a
I think the |
While in general I agree with this (and we might move to this in the future), we had some concerns around this, specifically being:
Dont know if these are sufficient concerns, but maybe we can make both cases co-exist (e.g., a extrinsic with transfer_and_transact, and another one with just transact). |
As it turns out, XCMv3 doesn't resolve this issue, as we can't be certain that the reserve is accurately representing the origin when it tries to modify the origin register with |
Indeed, that's another assumption in my initial design, mostly for simplicity of the prototype though. The fee is the same as asset, and must be accepted on the receiver chain, otherwise it won't work. The design can probably also be extended to support transfers where the asset and fee are different.
Yeah the cost of all the deposits and withdrawals into the buffer accounts might become non-negligible at some point. But again that's due to the generality of
All right so I'm just going to try and do a proper implementation of this 2 message design to see what you guys think. With a bounded input and xcm-sender, as well as a second If you feel strongly for dropping this idea, please let me know so I can try and focus on an alternative approach like paritytech/polkadot-sdk#801 |
Ok guys thanks for the attention, so here is a much cleaner draft PR against my own fork. If it has potential I can reopen against orml master: How this code can be used:
How the code change from first iteration:
Current stage of code is that the sender sends 2 xcm messages:
TODOs: -todo: This code is also similar to this idea https://gist.github.com/xlc/ebc2476afb7ecacdaa5ce95ae3b991c8#xcm-builder and similarly could use a more comprehensive solution to calculate weights on the sender side. Please let me know what you think. |
Hi guys, we would like to propose a new feature for xtokens and want to start a discussion to see if it is reasonable and can be worked on.
Given that users can privatize any asset on our chain, we want to enable them to move cross-chain assets to our chain and privatize them in one call. Our idea is to allow users to send, along with token transfers, a Transact instruction that includes the encoded privatization extrinsic. Moving some assets and using them in an extrinsic with one call seems like something that can be useful for other use-cases as well.
The design that we've come up with so far is the following:
transfer_with_transact
extrinsic that will use existing token transfer logic and sends a message to move some assets:a. for the encoded call in the Transact instruction (our case to be privatized)
b. to pay for execution fees
MultiLocation
of the sender user account on the sender chain (from the viewpoint of the receiver chain) withAccount32Hash
or whatever converter is implemented on the receiver chain.a. first descend the origin to the account from step 2
b. withdraw the fee assets from 1.b. to holding
c. buy execution with the assets in holding
d. Transact the encoded manta-pay extrinsic to privatize the assets from 1.a.
e. Change can be deposited back to the same account or a different account
Here's a very rough shot implementation of the idea for reference https://github.com/Manta-Network/open-runtime-module-library/pull/4/files
Also some impl details:
a.
asset
is a CurrencyId andfee
is the same CurrencyId.b.
asset
andfee
are withdrawn separately from sender.a.
self_location.append_with(sender_account_origin).reanchor(destination_chain, ancestry)
b. the above destination won't be valid according to the
dest != self_location
checkc. to work around 2.b. we need to construct a "fake" destination to pass the check
d. then use the
maybe_recipient_override
argument to override with the "real" destination from 2.a.a. it would be easier to do a refund to the destination from 2.a.
b. we can start off without depositing any change
The text was updated successfully, but these errors were encountered: