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

XCM: Deny barrier checks for nested XCMs with specific instructions to be executed on the local chain #7200

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

bkontur
Copy link
Contributor

@bkontur bkontur commented Jan 16, 2025

Resolves (partially): #7148
Depends on: #7169

Description

For context and additional information, please refer to Problem 2 - Barrier vs nested XCM validation.

TODO

  • Evaluate PoC, more details at poc(XCM): Deny Nested XCM Barriers #7351:
    • DenyInstructionsWithXcm: Keep it as it is and be explicit:
      1. Name the Deny barriers for the top level.
      2. Name the Deny barrier for nested with DenyInstructionsWithXcm.
    • RecursiveDenyThenTry: Alternatively, hard-code those three instructions in DenyThenTry, so we wouldn’t need DenyInstructionsWithXcm. However, this approach wouldn’t be as general.
    • DenyFirstInstructionsWithXcm: Another possibility is to check DenyInstructionsWithXcm::Inner for the actual message, so we don’t need duplication for top-level and nested (not sure, maybe be explicit is good thing) - see Problem2 - example. Instead of this:
    DenyThenTry<
                 (
                                // Deny for top level XCM program 
                                DenyReserveTransferToRelayChain,
                                // Dedicated barrier for nested XCM programs
                                DenyInstructionsWithXcmFor<
                                                 // Repeat all Deny filters here 
                                                 DenyReserveTransferToRelayChain,
                                 >
                 ),
    
    we could just use:
    DenyThenTry<
                 (
                                // Dedicated barrier for XCM programs
                                DenyInstructionsWithXcmFor<
                                                 // Add all `Deny` filters here 
                                                 DenyReserveTransferToRelayChain,
                                                 ...
                                 >
                 ),
    
  • POC Evaluation
  • Consider better name DenyInstructionsWithXcm
  • Clean-up and docs
  • Merge xcm: fix for DenyThenTry Barrier #7169 or rebase this branch on the top of yrong:fix-for-deny-then-try
  • Set for the runtimes where we use DenyThenTry
  • Schedule sec.audit

@bkontur bkontur added T6-XCM This PR/Issue is related to XCM. C1-mentor A task where a mentor is available. Please indicate in the issue who the mentor could be. labels Jan 16, 2025
@bkontur bkontur force-pushed the bko-deny-nested-xcm-barrier branch from 2c6325f to 9c80770 Compare January 22, 2025 09:31
@bkontur bkontur added the C2-good-first-issue A task for a first time contributor to become familiar with the Polkadot-SDK. label Jan 22, 2025
@bkontur bkontur assigned bkontur and unassigned bkontur Jan 22, 2025
@raymondkfcheung raymondkfcheung self-assigned this Jan 23, 2025
/// Applies the `Inner` filter to the nested XCM for the `SetAppendix`, `SetErrorHandler`, and `ExecuteWithOrigin` instructions.
///
/// Note: The nested XCM is checked recursively!
pub struct DenyInstructionsWithXcm<Inner>(PhantomData<Inner>);
Copy link

@raymondkfcheung raymondkfcheung Jan 29, 2025

Choose a reason for hiding this comment

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

Regarding the naming, maybe we can use DenyNestedXcmInstructions, which may be better to state clearly with nested XCMs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think DenyNestedXcmInstructions is a better name, but we still need to ensure it's explicitly used only for the following instructions: SetAppendix, SetErrorHandler, and ExecuteWithOrigin—which are meant to be executed on the local chain.

This is important because there are other instructions with nested XCM, such as DepositReserveAsset { xcm: Xcm<()>, ... } and InitiateReserveWithdraw { xcm: Xcm<()>, ... }, where the inner xcm is executed on a remote chain.

Choose a reason for hiding this comment

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

Good point! If we want to check all nested XCM instructions recursively (including those executed remotely), we could rename it to DenyNestedXcmInstructions and adjust the logic accordingly.

However, since this implementation currently applies only to instructions executed on the local chain (SetAppendix, SetErrorHandler, and ExecuteWithOrigin), we could instead introduce two separate types for clarity:

  • DenyNestedLocalInstructions: Covers only local execution cases (current behavior).
  • DenyNestedRemoteInstructions: Specifically targets instructions like DepositReserveAsset and InitiateReserveWithdraw, ensuring remote execution filtering.

Would this separation make sense, or do you think a more unified approach is preferable?

Copy link
Contributor

Choose a reason for hiding this comment

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

DenyNestedRemoteInstructions: Specifically targets instructions like DepositReserveAsset and InitiateReserveWithdraw, ensuring remote execution filtering.

Generally, a local chain should not assume rules about other chains' rules/barriers.

The design is that each chain only enforces its own local rules.

It is the job of the offchain component (wallet/ui/app) building the XCM to validate (e.g. through XCM dry-run APIs) that the XCM they build will pass barriers on all involved chains.

Choose a reason for hiding this comment

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

I've defined a new NestedXcmType when performing the deny execution. This categorises nested XCM calls as either Local or Remote, ensuring we handle them separately.

Right now, both types go through deny_recursively, but I can implement two different denial strategies (DenyNestedLocalInstructions and DenyNestedRemoteInstructions) if needed. Let me know if you see any difference in behavior, or if you'd prefer keeping a single DenyNestedXcmInstructions that applies to both.

Or shall I use origin: &Location to determine whether it's Local or Remote? If it's Remote, then I could deny all location-based instructions.

@raymondkfcheung
Copy link

/cmd fmt

@raymondkfcheung
Copy link

/cmd fmt

// ok
assert_should_execute(vec![ClearTransactStatus], Location::parent(), Ok(()));
// ok top-level contains `ClearOrigin`
assert_should_execute(vec![ClearOrigin], Location::parent(), Ok(()));
Copy link

@raymondkfcheung raymondkfcheung Jan 29, 2025

Choose a reason for hiding this comment

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

DenyInstructionsWithXcm can't reject the top level Deny barrier. Other two approaches (#7351) can deny earlier.

raymondkfcheung and others added 2 commits January 31, 2025 13:41
Resolves (partially): #7148
Depends on: #7169, #7200

# Description

For context and additional information, please refer to #7148 and #7200.

# TODOs

* [x] Rebase #7169 and #7200
* [x] Evaluate PoC described on #7200 

| POC | Top-Level Denial | Nested Denial | Try `Allow` | Remark |

|--------------------------------|--------------------|--------------------|--------------------|----------------------------------------------------------------------------------|
| `DenyThenTry` | ✅ | ❌ | ✅ | Blocks
top-level instructions only. |
| `RecursiveDenyThenTry` | ✅ | ✅ |
✅ | Blocks both top-level and nested instructions. |
| `DenyInstructionsWithXcm` | ❌ | ✅ | ❌ | Focuses
on nested instructions, requires additional checks for top-level denial.
|
| `DenyFirstInstructionsWithXcm` | ✅ |
✅ | ❌ | Prioritises top-level denial before recursive
checks. |

---------

Co-authored-by: ron <[email protected]>
Co-authored-by: Branislav Kontur <[email protected]>
Co-authored-by: Francisco Aguirre <[email protected]>
Co-authored-by: command-bot <>
Co-authored-by: Clara van Staden <[email protected]>
Co-authored-by: Adrian Catangiu <[email protected]>
Co-authored-by: cmd[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Comment on lines +887 to +906
// `DenyThenTry`: Top-level=Deny, Nested=Allow, TryAllow=Yes
assert_barrier::<DenyThenTry<Denies, AllowAll>>(Err(ProcessMessageError::Unsupported), Ok(()));

// `RecursiveDenyThenTry`: Top-level=Deny, Nested=Deny, TryAllow=Yes
assert_barrier::<RecursiveDenyThenTry<Denies, AllowAll>>(
Err(ProcessMessageError::Unsupported),
Err(ProcessMessageError::Unsupported),
);

// `DenyInstructionsWithXcm`: Top-level=Allow, Nested=Deny, TryAllow=No
assert_deny_barrier::<DenyInstructionsWithXcm<Denies>>(
Ok(()),
Err(ProcessMessageError::Unsupported),
);

// `DenyFirstInstructionsWithXcm`: Top-level=Deny, Nested=Deny, TryAllow=No
assert_deny_barrier::<DenyFirstInstructionsWithXcm<Denies>>(
Err(ProcessMessageError::Unsupported),
Err(ProcessMessageError::Unsupported),
);

Choose a reason for hiding this comment

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

POC Evaluation

  • Redefine DenyThenTry as RecursiveDenyThenTry: blocks both top-level and nested instructions, before trying to allow execution.
  • Create a new DenyFirstInstructionsWithXcm: blocks both top-level and nested instructions.
  • Establish a helper DenyInstructionsWithXcm, handles nested denies.

@paritytech-workflow-stopper
Copy link

All GitHub workflows were cancelled due to failure one of the required jobs.
Failed workflow url: https://github.com/paritytech/polkadot-sdk/actions/runs/13077258725
Failed job name: build-rustdoc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C1-mentor A task where a mentor is available. Please indicate in the issue who the mentor could be. C2-good-first-issue A task for a first time contributor to become familiar with the Polkadot-SDK. T6-XCM This PR/Issue is related to XCM.
Projects
Status: Todo
Development

Successfully merging this pull request may close these issues.

[XCM] Investigate better support for filtering XCM programs with Barrier
3 participants