Skip to content

Commit 6a26c27

Browse files
authored
fix: XCM handshake version negotiation (#1578)
* fix: XCM handshake version * remove debug print * Add missing license Added licensing information and test requirements for XCM version negotiation.
1 parent 4d2076f commit 6a26c27

File tree

10 files changed

+302
-64
lines changed

10 files changed

+302
-64
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

runtime/astar/src/xcm_config.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ use sp_runtime::traits::{Convert, MaybeEquivalence};
3434
// Polkadot imports
3535
use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
3636
use frame_support::traits::{Disabled, TransformOrigin};
37-
use parachains_common::message_queue::ParaIdToSibling;
37+
use parachains_common::{
38+
message_queue::ParaIdToSibling, xcm_config::ParentRelayOrSiblingParachains,
39+
};
3840
use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery;
3941
use xcm::latest::prelude::*;
4042
use xcm_builder::{
@@ -43,7 +45,7 @@ use xcm_builder::{
4345
FungibleAdapter, FungiblesAdapter, IsConcrete, NoChecking, ParentAsSuperuser, ParentIsPreset,
4446
RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
4547
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
46-
UsingComponents, WeightInfoBounds,
48+
TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin,
4749
};
4850
use xcm_executor::{
4951
traits::{JustTry, WithOriginFilter},
@@ -225,16 +227,24 @@ impl Contains<RuntimeCall> for SafeCallFilter {
225227
}
226228
}
227229

228-
pub type XcmBarrier = (
230+
pub type XcmBarrier = TrailingSetTopicAsId<(
229231
TakeWeightCredit,
230-
AllowTopLevelPaidExecutionFrom<Everything>,
231-
// Parent and its plurality get free execution
232-
AllowUnpaidExecutionFrom<ParentOrParentsPlurality>,
233232
// Expected responses are OK.
234233
AllowKnownQueryResponses<PolkadotXcm>,
235-
// Subscriptions for version tracking are OK.
236-
AllowSubscriptionsFrom<Everything>,
237-
);
234+
// Allow XCMs with some computed origins to pass through.
235+
WithComputedOrigin<
236+
(
237+
// If the message is one that immediately attempts to pay for execution, then allow it.
238+
AllowTopLevelPaidExecutionFrom<Everything>,
239+
// Subscriptions for version tracking are OK.
240+
AllowSubscriptionsFrom<ParentRelayOrSiblingParachains>,
241+
),
242+
UniversalLocation,
243+
ConstU32<8>,
244+
>,
245+
// Parent and its plurality get free execution
246+
AllowUnpaidExecutionFrom<ParentOrParentsPlurality>,
247+
)>;
238248

239249
// Used to handle XCM fee deposit into treasury account
240250
pub type AstarXcmFungibleFeeHandler = XcmFungibleFeeHandler<

runtime/shibuya/src/xcm_config.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ use sp_runtime::traits::{Convert, MaybeEquivalence};
3434
// Polkadot imports
3535
use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
3636
use frame_support::traits::{Disabled, TransformOrigin};
37-
use parachains_common::message_queue::ParaIdToSibling;
37+
use parachains_common::{
38+
message_queue::ParaIdToSibling, xcm_config::ParentRelayOrSiblingParachains,
39+
};
3840
use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery;
3941
use xcm::{latest::prelude::*, v5::ROCOCO_GENESIS_HASH};
4042
use xcm_builder::{
@@ -43,8 +45,8 @@ use xcm_builder::{
4345
FrameTransactionalProcessor, FungibleAdapter, FungiblesAdapter, HashedDescription, IsConcrete,
4446
NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
4547
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
46-
SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, WeightInfoBounds,
47-
WithComputedOrigin,
48+
SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
49+
WeightInfoBounds, WithComputedOrigin,
4850
};
4951
use xcm_executor::{traits::JustTry, XcmExecutor};
5052

@@ -153,18 +155,24 @@ impl Contains<Location> for ParentOrParentsPlurality {
153155
}
154156
}
155157

156-
pub type XcmBarrier = (
158+
pub type XcmBarrier = TrailingSetTopicAsId<(
157159
TakeWeightCredit,
158-
AllowTopLevelPaidExecutionFrom<Everything>,
159-
// This will first calculate the derived origin, before checking it against the barrier implementation
160-
WithComputedOrigin<AllowTopLevelPaidExecutionFrom<Everything>, UniversalLocation, ConstU32<8>>,
161-
// Parent and its plurality get free execution
162-
AllowUnpaidExecutionFrom<ParentOrParentsPlurality>,
163160
// Expected responses are OK.
164161
AllowKnownQueryResponses<PolkadotXcm>,
165-
// Subscriptions for version tracking are OK.
166-
AllowSubscriptionsFrom<Everything>,
167-
);
162+
// Allow XCMs with some computed origins to pass through.
163+
WithComputedOrigin<
164+
(
165+
// If the message is one that immediately attempts to pay for execution, then allow it.
166+
AllowTopLevelPaidExecutionFrom<Everything>,
167+
// Subscriptions for version tracking are OK.
168+
AllowSubscriptionsFrom<ParentRelayOrSiblingParachains>,
169+
),
170+
UniversalLocation,
171+
ConstU32<8>,
172+
>,
173+
// Parent and its plurality get free execution
174+
AllowUnpaidExecutionFrom<ParentOrParentsPlurality>,
175+
)>;
168176

169177
// Used to handle XCM fee deposit into treasury account
170178
pub type ShibuyaXcmFungibleFeeHandler = XcmFungibleFeeHandler<

runtime/shiden/src/xcm_config.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ use sp_runtime::traits::{Convert, MaybeEquivalence};
3434
// Polkadot imports
3535
use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
3636
use frame_support::traits::{Disabled, TransformOrigin};
37+
use parachains_common::{
38+
message_queue::ParaIdToSibling, xcm_config::ParentRelayOrSiblingParachains,
39+
};
3740
use polkadot_runtime_common::xcm_sender::NoPriceForMessageDelivery;
3841
use xcm::latest::prelude::*;
3942
use xcm_builder::{
@@ -42,8 +45,8 @@ use xcm_builder::{
4245
FrameTransactionalProcessor, FungibleAdapter, FungiblesAdapter, HashedDescription, IsConcrete,
4346
NoChecking, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
4447
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
45-
SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, WeightInfoBounds,
46-
WithComputedOrigin,
48+
SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
49+
WeightInfoBounds, WithComputedOrigin,
4750
};
4851
use xcm_executor::{
4952
traits::{JustTry, WithOriginFilter},
@@ -52,7 +55,6 @@ use xcm_executor::{
5255

5356
// ORML imports
5457
use orml_xcm_support::DisabledParachainFee;
55-
use parachains_common::message_queue::ParaIdToSibling;
5658

5759
// Astar imports
5860
use astar_primitives::xcm::{
@@ -227,18 +229,24 @@ impl Contains<RuntimeCall> for SafeCallFilter {
227229
}
228230
}
229231

230-
pub type XcmBarrier = (
232+
pub type XcmBarrier = TrailingSetTopicAsId<(
231233
TakeWeightCredit,
232-
AllowTopLevelPaidExecutionFrom<Everything>,
233-
// This will first calculate the derived origin, before checking it against the barrier implementation
234-
WithComputedOrigin<AllowTopLevelPaidExecutionFrom<Everything>, UniversalLocation, ConstU32<8>>,
235-
// Parent and its plurality get free execution
236-
AllowUnpaidExecutionFrom<ParentOrParentsPlurality>,
237234
// Expected responses are OK.
238235
AllowKnownQueryResponses<PolkadotXcm>,
239-
// Subscriptions for version tracking are OK.
240-
AllowSubscriptionsFrom<Everything>,
241-
);
236+
// Allow XCMs with some computed origins to pass through.
237+
WithComputedOrigin<
238+
(
239+
// If the message is one that immediately attempts to pay for execution, then allow it.
240+
AllowTopLevelPaidExecutionFrom<Everything>,
241+
// Subscriptions for version tracking are OK.
242+
AllowSubscriptionsFrom<ParentRelayOrSiblingParachains>,
243+
),
244+
UniversalLocation,
245+
ConstU32<8>,
246+
>,
247+
// Parent and its plurality get free execution
248+
AllowUnpaidExecutionFrom<ParentOrParentsPlurality>,
249+
)>;
242250

243251
// Used to handle XCM fee deposit into treasury account
244252
pub type ShidenXcmFungibleFeeHandler = XcmFungibleFeeHandler<

tests/xcm-simulator/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ polkadot-primitives = { workspace = true }
4646
cumulus-pallet-xcm = { workspace = true }
4747
pallet-message-queue = { workspace = true }
4848
pallet-xcm = { workspace = true }
49+
parachains-common = { workspace = true }
4950
polkadot-core-primitives = { workspace = true }
5051
polkadot-parachain = { workspace = true }
5152
polkadot-runtime-parachains = { workspace = true }
@@ -85,6 +86,7 @@ std = [
8586
"orml-traits/std",
8687
"orml-xcm-support/std",
8788
"pallet-dapp-staking/std",
89+
"parachains-common/std",
8890
]
8991
runtime-benchmarks = [
9092
"frame-system/runtime-benchmarks",
@@ -101,4 +103,5 @@ runtime-benchmarks = [
101103
"astar-primitives/runtime-benchmarks",
102104
"pallet-message-queue/runtime-benchmarks",
103105
"pallet-dapp-staking/runtime-benchmarks",
106+
"parachains-common/runtime-benchmarks",
104107
]

tests/xcm-simulator/src/mocks/msg_queue.rs

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
use frame_support::weights::Weight;
2020
use parity_scale_codec::{Decode, Encode};
21-
use sp_runtime::traits::Hash;
2221
use sp_std::prelude::*;
2322

2423
use polkadot_core_primitives::BlockNumber as RelayBlockNumber;
@@ -70,41 +69,53 @@ pub mod mock_msg_queue {
7069
#[pallet::generate_deposit(pub(super) fn deposit_event)]
7170
pub enum Event<T: Config> {
7271
// XCMP
73-
/// Some XCM was executed OK.
74-
Success(Option<T::Hash>),
72+
/// Some XCM was executed OK. message_id is SetTopic value if TrailingSetTopicAsId is used.
73+
Success { message_id: Option<T::Hash> },
7574
/// Some XCM failed.
76-
Fail(Option<T::Hash>, InstructionError),
75+
Fail {
76+
message_id: Option<T::Hash>,
77+
error: InstructionError,
78+
},
7779
/// Bad XCM version used.
78-
BadVersion(Option<T::Hash>),
80+
BadVersion { message_id: Option<T::Hash> },
7981
/// Bad XCM format used.
80-
BadFormat(Option<T::Hash>),
82+
BadFormat { message_id: Option<T::Hash> },
8183

8284
// DMP
8385
/// Downward message is invalid XCM.
84-
InvalidFormat(MessageId),
86+
InvalidFormat { message_id: MessageId },
8587
/// Downward message is unsupported version of XCM.
86-
UnsupportedVersion(MessageId),
88+
UnsupportedVersion { message_id: MessageId },
8789
/// Downward message executed with the given outcome.
88-
ExecutedDownward(MessageId, Outcome),
90+
ExecutedDownward {
91+
message_id: MessageId,
92+
outcome: Outcome,
93+
},
8994
}
9095

9196
impl<T: Config> Pallet<T> {
9297
pub fn set_para_id(para_id: ParaId) {
9398
ParachainId::<T>::put(para_id);
9499
}
95100

101+
/// Convert `[u8; 32]` to `T::Hash`.
102+
fn hash_from_raw(raw: [u8; 32]) -> T::Hash {
103+
Decode::decode(&mut &raw[..]).expect("32 bytes always decodes to H256")
104+
}
105+
96106
fn handle_xcmp_message(
97107
sender: ParaId,
98108
_sent_at: RelayBlockNumber,
99109
xcm: VersionedXcm<T::RuntimeCall>,
100110
max_weight: Weight,
101111
) -> Result<Weight, InstructionError> {
102-
let hash = Encode::using_encoded(&xcm, T::Hashing::hash);
103112
let mut message_hash = Encode::using_encoded(&xcm, sp_io::hashing::blake2_256);
104113
let (result, event) = match Xcm::<T::RuntimeCall>::try_from(xcm) {
105114
Ok(xcm) => {
106115
let location = (Parent, Parachain(sender.into()));
107116
<ReceivedXcmp<T>>::append(xcm.clone());
117+
118+
// TrailingSetTopicAsId MUTATES message_hash to SetTopic value during execution
108119
match T::XcmExecutor::prepare_and_execute(
109120
location,
110121
xcm.clone(),
@@ -114,14 +125,29 @@ pub mod mock_msg_queue {
114125
) {
115126
Outcome::Error(error) => {
116127
println!("Error in XCMP handling: {:?}, sender=Parachain({sender}), xcm={xcm:?}", error);
117-
(Err(error.clone()), Event::Fail(Some(hash), error))
128+
(
129+
Err(error.clone()),
130+
Event::Fail {
131+
message_id: Some(Self::hash_from_raw(message_hash)),
132+
error,
133+
},
134+
)
118135
}
119-
Outcome::Complete { used } => (Ok(used), Event::Success(Some(hash))),
120-
// As far as the caller is concerned, this was dispatched without error, so
121-
// we just report the weight used.
136+
Outcome::Complete { used } => (
137+
Ok(used),
138+
Event::Success {
139+
message_id: Some(Self::hash_from_raw(message_hash)),
140+
},
141+
),
122142
Outcome::Incomplete { used, error } => {
123143
println!("Incomplete XCMP handling: {:?}, {sender}", error);
124-
(Ok(used), Event::Fail(Some(hash), error))
144+
(
145+
Ok(used),
146+
Event::Fail {
147+
message_id: Some(Self::hash_from_raw(message_hash)),
148+
error,
149+
},
150+
)
125151
}
126152
}
127153
}
@@ -130,7 +156,9 @@ pub mod mock_msg_queue {
130156
error: XcmError::UnhandledXcmVersion,
131157
index: 0,
132158
}),
133-
Event::BadVersion(Some(hash)),
159+
Event::BadVersion {
160+
message_id: Some(Self::hash_from_raw(message_hash)),
161+
},
134162
),
135163
};
136164
Self::deposit_event(event);
@@ -173,10 +201,12 @@ pub mod mock_msg_queue {
173201
let maybe_versioned = VersionedXcm::<T::RuntimeCall>::decode(&mut &data[..]);
174202
match maybe_versioned {
175203
Err(_) => {
176-
Self::deposit_event(Event::InvalidFormat(id));
204+
Self::deposit_event(Event::InvalidFormat { message_id: id });
177205
}
178206
Ok(versioned) => match Xcm::try_from(versioned) {
179-
Err(()) => Self::deposit_event(Event::UnsupportedVersion(id)),
207+
Err(()) => {
208+
Self::deposit_event(Event::UnsupportedVersion { message_id: id })
209+
}
180210
Ok(x) => {
181211
let outcome = T::XcmExecutor::prepare_and_execute(
182212
Parent,
@@ -186,7 +216,10 @@ pub mod mock_msg_queue {
186216
Weight::zero(),
187217
);
188218
<ReceivedDmp<T>>::append(x);
189-
Self::deposit_event(Event::ExecutedDownward(id, outcome));
219+
Self::deposit_event(Event::ExecutedDownward {
220+
message_id: id,
221+
outcome,
222+
});
190223
}
191224
},
192225
}

0 commit comments

Comments
 (0)