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

Open
wants to merge 63 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
9c80770
PoC: DenyInstructionsWithXcm for validating nested XCM instructions
bkontur Jan 15, 2025
6c79a06
PoC: DenyInstructionsWithXcm for validating nested XCM instructions
bkontur Jan 15, 2025
a98fc0d
Merge branch 'bko-deny-nested-xcm-barrier' of https://github.com/pari…
raymondkfcheung Jan 28, 2025
a70881e
Merge branch 'master' into bko-deny-nested-xcm-barrier
raymondkfcheung Jan 28, 2025
72bec5b
Fix merge conflicts
raymondkfcheung Jan 28, 2025
7aec7fe
Merge branch 'master' into bko-deny-nested-xcm-barrier
raymondkfcheung Jan 29, 2025
6f60579
Update from raymondkfcheung running command 'fmt'
github-actions[bot] Jan 29, 2025
06c7e65
Fix merge conflicts
raymondkfcheung Jan 29, 2025
7bd8e10
Merge branch 'master' into bko-deny-nested-xcm-barrier
raymondkfcheung Jan 29, 2025
2d3d33d
Update from raymondkfcheung running command 'fmt'
github-actions[bot] Jan 29, 2025
df64f5f
poc(XCM): Deny Nested XCM Barriers (#7351)
raymondkfcheung Jan 31, 2025
797f868
Merge branch 'master' into bko-deny-nested-xcm-barrier
raymondkfcheung Jan 31, 2025
72f8fe4
Refactor DenyInstructionsWithXcm with new NestedXcmType
raymondkfcheung Jan 31, 2025
5fe41bc
Rename to DenyNestedLocalInstructions
raymondkfcheung Feb 3, 2025
95ce08d
Remove NestedXcmType
raymondkfcheung Feb 3, 2025
914ba61
Refactor DenyNestedXcmInstructions
raymondkfcheung Feb 3, 2025
97f50a6
Refactor DenyNestedLocalInstructionsThenTry
raymondkfcheung Feb 3, 2025
91d9541
Make DenyNestedXcmInstructions privately
raymondkfcheung Feb 3, 2025
0866f2a
Update comments
raymondkfcheung Feb 3, 2025
b58f7a3
Update tests
raymondkfcheung Feb 3, 2025
255a23a
Fix imports
raymondkfcheung Feb 3, 2025
b5d2777
Merge branch 'master' into bko-deny-nested-xcm-barrier
raymondkfcheung Feb 3, 2025
4f8d0af
Update from raymondkfcheung running command 'prdoc --audience runtime…
github-actions[bot] Feb 3, 2025
2a48a71
Move deny_execution logic to DenyNestedLocalInstructions
raymondkfcheung Feb 3, 2025
c6a363d
Merge branch 'master' into bko-deny-nested-xcm-barrier
raymondkfcheung Feb 3, 2025
9ca64e7
Update config
raymondkfcheung Feb 3, 2025
9601ee0
Update from raymondkfcheung running command 'fmt'
github-actions[bot] Feb 3, 2025
f2ff48d
Remove for regenerating
raymondkfcheung Feb 3, 2025
b75c40f
Update from raymondkfcheung running command 'prdoc --audience runtime…
github-actions[bot] Feb 3, 2025
a663b43
Update prdoc
raymondkfcheung Feb 3, 2025
19e0b6f
Update prdoc
raymondkfcheung Feb 3, 2025
9f4048d
Update prdoc
raymondkfcheung Feb 3, 2025
211c0d8
Update prdoc
raymondkfcheung Feb 3, 2025
f4662da
Update from raymondkfcheung running command 'prdoc --audience runtime…
github-actions[bot] Feb 3, 2025
1951b39
Update prdoc
raymondkfcheung Feb 3, 2025
f8009f1
Merge branch 'master' into bko-deny-nested-xcm-barrier
raymondkfcheung Feb 3, 2025
c69d6c5
Update prdoc
raymondkfcheung Feb 3, 2025
fb948e4
Refactor DenyNestedXcmInstructions
raymondkfcheung Feb 4, 2025
f84b50a
Add more tests
raymondkfcheung Feb 4, 2025
936e56e
Remove `mut`
raymondkfcheung Feb 4, 2025
2994fe2
Update comment for DenyNestedXcmInstructions
raymondkfcheung Feb 4, 2025
85a36a2
Merge branch 'master' into bko-deny-nested-xcm-barrier
raymondkfcheung Feb 4, 2025
5443750
Merge branch 'master' into bko-deny-nested-xcm-barrier
raymondkfcheung Feb 4, 2025
f3bf860
Merge branch 'master' into bko-deny-nested-xcm-barrier
raymondkfcheung Feb 5, 2025
f2f8449
Add comment for RECURSION_LIMIT
raymondkfcheung Feb 5, 2025
3f51889
Rename to DenyLocalInstructions
raymondkfcheung Feb 5, 2025
7329db8
Move dummy filters to tests/barriers.rs
raymondkfcheung Feb 5, 2025
c518c59
Clean up tests
raymondkfcheung Feb 5, 2025
632430e
Merge branch 'master' into bko-deny-nested-xcm-barrier
raymondkfcheung Feb 5, 2025
c5ca5e7
Update prdoc
raymondkfcheung Feb 5, 2025
24dd3e3
Remove DenyNestedLocalInstructionsThenTry
raymondkfcheung Feb 5, 2025
a1b3454
Merge branch 'master' into bko-deny-nested-xcm-barrier
raymondkfcheung Feb 5, 2025
4c4b9ec
Rename to xcm
raymondkfcheung Feb 5, 2025
63b0df1
Remove DenyNestedLocalInstructionsThenTry
raymondkfcheung Feb 5, 2025
632f2b6
Remove DenyNestedXcmInstructions
raymondkfcheung Feb 5, 2025
66af360
Apply fmt
raymondkfcheung Feb 5, 2025
758e871
Simplify the recursion
raymondkfcheung Feb 5, 2025
5a817a8
Update polkadot/xcm/xcm-builder/src/barriers.rs
bkontur Feb 5, 2025
c03412e
Merge branch 'master' into bko-deny-nested-xcm-barrier
bkontur Feb 5, 2025
ede0da7
Update prdoc/pr_7200.prdoc
bkontur Feb 5, 2025
b625ecc
Update prdoc/pr_7200.prdoc
bkontur Feb 6, 2025
30d7688
Add scenario test
raymondkfcheung Feb 6, 2025
cc50283
Merge branch 'master' into bko-deny-nested-xcm-barrier
raymondkfcheung Feb 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion polkadot/xcm/xcm-builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ workspace = true

[dependencies]
codec = { features = ["derive"], workspace = true }
environmental = { workspace = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
impl-trait-for-tuples = { workspace = true }
Expand All @@ -21,6 +22,7 @@ pallet-asset-conversion = { workspace = true }
pallet-transaction-payment = { workspace = true }
scale-info = { features = ["derive"], workspace = true }
sp-arithmetic = { workspace = true }
sp-core = { workspace = true }
sp-io = { workspace = true }
sp-runtime = { workspace = true }
sp-weights = { workspace = true }
Expand All @@ -39,7 +41,6 @@ polkadot-primitives = { workspace = true, default-features = true }
polkadot-runtime-parachains = { workspace = true, default-features = true }
polkadot-test-runtime = { workspace = true }
primitive-types = { features = ["codec", "num-traits", "scale-info"], workspace = true }
sp-core = { workspace = true, default-features = true }

[features]
default = ["std"]
Expand All @@ -62,6 +63,7 @@ runtime-benchmarks = [
]
std = [
"codec/std",
"environmental/std",
"frame-support/std",
"frame-system/std",
"log/std",
Expand All @@ -71,6 +73,7 @@ std = [
"primitive-types/std",
"scale-info/std",
"sp-arithmetic/std",
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
"sp-weights/std",
Expand Down
103 changes: 87 additions & 16 deletions polkadot/xcm/xcm-builder/src/barriers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,21 +82,22 @@ impl<T: Contains<Location>> ShouldExecute for AllowTopLevelPaidExecutionFrom<T>
instructions[..end]
.matcher()
.match_next_inst(|inst| match inst {
WithdrawAsset(ref assets) |
ReceiveTeleportedAsset(ref assets) |
ReserveAssetDeposited(ref assets) |
ClaimAsset { ref assets, .. } =>
WithdrawAsset(ref assets)
| ReceiveTeleportedAsset(ref assets)
| ReserveAssetDeposited(ref assets)
| ClaimAsset { ref assets, .. } => {
if assets.len() <= MAX_ASSETS_FOR_BUY_EXECUTION {
Ok(())
} else {
Err(ProcessMessageError::BadFormat)
},
}
},
_ => Err(ProcessMessageError::BadFormat),
})?
.skip_inst_while(|inst| {
matches!(inst, ClearOrigin | AliasOrigin(..)) ||
matches!(inst, DescendOrigin(child) if child != &Here) ||
matches!(inst, SetHints { .. })
matches!(inst, ClearOrigin | AliasOrigin(..))
|| matches!(inst, DescendOrigin(child) if child != &Here)
|| matches!(inst, SetHints { .. })
})?
.match_next_inst(|inst| match inst {
BuyExecution { weight_limit: Limited(ref mut weight), .. }
Expand Down Expand Up @@ -198,7 +199,7 @@ impl<InnerBarrier: ShouldExecute, LocalUniversal: Get<InteriorLocation>, MaxPref
},
DescendOrigin(j) => {
let Ok(_) = actual_origin.append_with(j.clone()) else {
return Err(ProcessMessageError::Unsupported)
return Err(ProcessMessageError::Unsupported);
};
},
_ => return Ok(ControlFlow::Break(())),
Expand Down Expand Up @@ -371,7 +372,9 @@ impl<ResponseHandler: OnResponse> ShouldExecute for AllowKnownQueryResponses<Res
.match_next_inst(|inst| match inst {
QueryResponse { query_id, querier, .. }
if ResponseHandler::expecting_response(origin, *query_id, querier.as_ref()) =>
Ok(()),
{
Ok(())
},
_ => Err(ProcessMessageError::BadFormat),
})?;
Ok(())
Expand Down Expand Up @@ -431,9 +434,9 @@ impl ShouldExecute for AllowHrmpNotificationsFromRelayChain {
.matcher()
.assert_remaining_insts(1)?
.match_next_inst(|inst| match inst {
HrmpNewChannelOpenRequest { .. } |
HrmpChannelAccepted { .. } |
HrmpChannelClosing { .. } => Ok(()),
HrmpNewChannelOpenRequest { .. }
| HrmpChannelAccepted { .. }
| HrmpChannelClosing { .. } => Ok(()),
_ => Err(ProcessMessageError::BadFormat),
})?;
Ok(())
Expand Down Expand Up @@ -478,9 +481,9 @@ impl DenyExecution for DenyReserveTransferToRelayChain {
InitiateReserveWithdraw {
reserve: Location { parents: 1, interior: Here },
..
} |
DepositReserveAsset { dest: Location { parents: 1, interior: Here }, .. } |
TransferReserveAsset { dest: Location { parents: 1, interior: Here }, .. } => {
}
| DepositReserveAsset { dest: Location { parents: 1, interior: Here }, .. }
| TransferReserveAsset { dest: Location { parents: 1, interior: Here }, .. } => {
Err(ProcessMessageError::Unsupported) // Deny
},

Expand All @@ -502,3 +505,71 @@ impl DenyExecution for DenyReserveTransferToRelayChain {
Ok(())
}
}

environmental::environmental!(recursion_count: u8);

// TBD:
/// 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>);
raymondkfcheung marked this conversation as resolved.
Show resolved Hide resolved
impl<Inner: ShouldExecute> ShouldExecute for DenyInstructionsWithXcm<Inner> {
fn should_execute<RuntimeCall>(
origin: &Location,
message: &mut [Instruction<RuntimeCall>],
max_weight: Weight,
properties: &mut Properties,
) -> Result<(), ProcessMessageError> {
message.matcher().match_next_inst_while(
|_| true,
|inst| match inst {
SetAppendix(nested_xcm) |
SetErrorHandler(nested_xcm) |
ExecuteWithOrigin { xcm: nested_xcm, .. } => {
// check xcm instructions with `Inner` filter
let _ = Inner::should_execute(origin, nested_xcm.inner_mut(), max_weight, properties)
.inspect_err(|e| {
log::warn!(
target: "xcm::barriers",
"`DenyInstructionsWithXcm`'s `Inner::should_execute` did not pass for origin: {:?} and nested_xcm: {:?} with error: {:?}",
origin,
nested_xcm,
e
);
})?;

// Initialize the recursion count only the first time we hit this code in our
// potential recursive execution.
let _ = recursion_count::using_once(&mut 1, || {
recursion_count::with(|count| {
if *count > xcm_executor::RECURSION_LIMIT {
return Err(ProcessMessageError::StackLimitReached)
}
*count = count.saturating_add(1);
Ok(())
})
// This should always return `Some`, but let's play it safe.
.unwrap_or(Ok(()))?;

// Ensure that we always decrement the counter whenever we finish processing
// the `DenyInstructionsWithXcm`.
sp_core::defer! {
recursion_count::with(|count| {
*count = count.saturating_sub(1);
});
}

// check recursively with `DenyInstructionsWithXcm`
Self::should_execute(origin, nested_xcm.inner_mut(), max_weight, properties)
})?;

Ok(ControlFlow::Continue(()))
},
_ => Ok(ControlFlow::Continue(())),
},
)?;

// Permit everything else
Ok(())
}
}
4 changes: 2 additions & 2 deletions polkadot/xcm/xcm-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ mod barriers;
pub use barriers::{
AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain,
AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom,
AllowUnpaidExecutionFrom, DenyReserveTransferToRelayChain, DenyThenTry, IsChildSystemParachain,
IsParentsOnly, IsSiblingSystemParachain, RespectSuspension, TakeWeightCredit,
AllowUnpaidExecutionFrom, DenyReserveTransferToRelayChain, DenyInstructionsWithXcm, DenyThenTry,
IsChildSystemParachain, IsParentsOnly, IsSiblingSystemParachain, RespectSuspension, TakeWeightCredit,
TrailingSetTopicAsId, WithComputedOrigin,
};

Expand Down
Loading
Loading