Skip to content
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

Add router to split XCM fee and assets #2394

Closed
wants to merge 1 commit into from

Conversation

franciscoaguirre
Copy link
Contributor

This router is meant to be used for being able to send more assets before BuyExecution than the limit specified in the AllowTopLevelPaidExecutionFrom barrier. It works by splitting those assets into the fee first and the other assets afterward.

TODO:

  • More tests

@franciscoaguirre franciscoaguirre requested a review from a team as a code owner November 18, 2023 22:15
@paritytech-cicd-pr
Copy link

The CI pipeline was cancelled due to failure one of the required jobs.
Job name: test-linux-stable-int
Logs: https://gitlab.parity.io/parity/mirrors/polkadot-sdk/-/jobs/4390952

Copy link
Contributor

@acatangiu acatangiu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this approach of mutating in-flight XCMs to "fix" original XCMs unnatural and obfuscating.. Long term this will just add even more issues and corner-cases.
It adds (to) problems like fees/weights, debugability, control over exact XCM being sent and its intended effects, and general obfuscation of what is happening under the hood.

Instead of this approach, I am very much in favor of biting the bullet and fixing the original miss of these corner-cases in the pallets building XCMs and in the xcm-executor.

With a clear limit of max 1 asset allowed for buying execution, it then becomes clear to XCM builders that XCMs sent to be executed on remote chains they need to do explicit:

Xcm(vec![
	ReceiveTeleportedAsset(fee)/ReserveAssetDeposited(fee)/WithdrawAsset(fee)/ClaimAsset(fee),
	BuyExecution(fee),
	<rest of the program here>,
])

This also means we need to do breaking changes to TransferReserveAsset, DepositReserveAsset, InitiateReserveWithdraw, InitiateTeleport to build fully correct onward XCMs in the first place.
Ideas for this ^ :

  • take extra Option<fees> parameter and make the same split your current router does and add BuyExecution before adding ClearOrigin
  • instead of single xcm they take with_origin_xcm and without_origin_xcm specifying which custom instructions to run before ClearOrigin and which to run after ClearOrigin

Comment on lines +175 to +176
#[cfg(test)]
mod tests {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should move this under tests/ - maybe tests/assets.rs or some new tests/routing.rs

@@ -104,3 +104,139 @@ impl<Inner: SendXcm, TopicSource: SourceTopic> SendXcm for WithTopicSource<Inner
Ok(unique_id)
}
}

fn split_message(message: &mut Option<Xcm<()>>) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fn split_message(message: &mut Option<Xcm<()>>) {
fn split_assets_instructions_for_explicit_fees(message: &mut Option<Xcm<()>>) {

or something more explicit

Comment on lines +119 to +122
(n, ClearOrigin) if n > 0 && n <= 4 => {
clear_origin_instructions += 1;
}
(n, BuyExecution { fees, .. }) if n > 0 && n <= 5 && initial_fund => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
(n, ClearOrigin) if n > 0 && n <= 4 => {
clear_origin_instructions += 1;
}
(n, BuyExecution { fees, .. }) if n > 0 && n <= 5 && initial_fund => {
(n, ClearOrigin) if n > 0 => {
clear_origin_instructions += 1;
}
(n, BuyExecution { fees, .. }) if n > 0 && initial_fund => {

I would remove this opinionated n limit here - it's not clear where it comes from (I'm guessing from AllowTopLevelPaidExecutionFrom barrier)

Comment on lines +143 to +148
if clear_origin_instructions > 0 {
instructions.insert(n + 2, ClearOrigin);
for index in 1..1 + clear_origin_instructions {
instructions.remove(index);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would dedup the ClearOrigin instructions in a dedicated router (or at least dedicated function), that gets called before this one, instead of overloading this one.


for item in instructions.iter().enumerate() {
match item {
(0, WithdrawAsset(assets, ..)) if assets.len() > 1 => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also handle ReceiveTeleportedAsset(assets), ReserveAssetDeposited(assets) and ClaimAsset { assets, .. } not just WithdrawAsset(assets)

@KiChjang
Copy link
Contributor

@acatangiu What you're proposing seems to require an XCM version upgrade. I think I agree with the general approach of solving the issue from the roots, however we'd also want to have a solution while we prepare a long-term fix in the next version.

@acatangiu
Copy link
Contributor

@acatangiu What you're proposing seems to require an XCM version upgrade. I think I agree with the general approach of solving the issue from the roots, however we'd also want to have a solution while we prepare a long-term fix in the next version.

Yes, it'd require a new XCM version.

however we'd also want to have a solution while we prepare a long-term fix in the next version

I'm not against this, but I'm wondering if current MAX_ASSETS_FOR_BUY_EXECUTION = 2 is not enough of a "temporary solution" until proper handling of it in a new XCM version.

I do see how some router solution like this would be useful/necessary during transition to the new XCM version (aka the window between when we change MAX_ASSETS_FOR_BUY_EXECUTION back to 1 and chains actually upgrade to new version - unless we can also make MAX_ASSETS_FOR_BUY_EXECUTION version specific..)

@franciscoaguirre
Copy link
Contributor Author

Closing since MAX_ASSETS_FOR_BUY_EXECUTION = 2 was a good temporary solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants