-
Notifications
You must be signed in to change notification settings - Fork 803
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
base: master
Are you sure you want to change the base?
Conversation
2c6325f
to
9c80770
Compare
…tytech/polkadot-sdk into bko-deny-nested-xcm-barrier
/// 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>); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 likeDepositReserveAsset
andInitiateReserveWithdraw
, ensuring remote execution filtering.
Would this separation make sense, or do you think a more unified approach is preferable?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
/cmd fmt |
/cmd fmt |
// ok | ||
assert_should_execute(vec![ClearTransactStatus], Location::parent(), Ok(())); | ||
// ok top-level contains `ClearOrigin` | ||
assert_should_execute(vec![ClearOrigin], Location::parent(), Ok(())); |
There was a problem hiding this comment.
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.
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>
// `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), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
POC Evaluation
- Redefine
DenyThenTry
asRecursiveDenyThenTry
: 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.
All GitHub workflows were cancelled due to failure one of the required jobs. |
Resolves (partially): #7148
Depends on: #7169
Description
For context and additional information, please refer to Problem 2 - Barrier vs nested XCM validation.
TODO
DenyInstructionsWithXcm
.DenyThenTry
, so we wouldn’t needDenyInstructionsWithXcm
. However, this approach wouldn’t be as general.DenyInstructionsWithXcm::Inner
for the actualmessage
, 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:DenyInstructionsWithXcm
yrong:fix-for-deny-then-try
DenyThenTry