Skip to content

Commit ed72b02

Browse files
bkonturbkchr
authored andcommitted
Improved ExportXcm::validate implementation for BridgeHubs - step 1 (#2727)
* Improved `ExportXcm::validate` implementation for BridgeHubs * spellcheck * Fix try-runtime * Fix try-runtime
1 parent 6c31cdb commit ed72b02

File tree

8 files changed

+794
-63
lines changed

8 files changed

+794
-63
lines changed

bridges/bin/runtime-common/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ bp-parachains = { path = "../../primitives/parachains", default-features = false
2222
bp-polkadot-core = { path = "../../primitives/polkadot-core", default-features = false }
2323
bp-relayers = { path = "../../primitives/relayers", default-features = false }
2424
bp-runtime = { path = "../../primitives/runtime", default-features = false }
25+
bp-xcm-bridge-hub = { path = "../../primitives/xcm-bridge-hub", default-features = false }
2526
bp-xcm-bridge-hub-router = { path = "../../primitives/xcm-bridge-hub-router", default-features = false }
2627
pallet-bridge-grandpa = { path = "../../modules/grandpa", default-features = false }
2728
pallet-bridge-messages = { path = "../../modules/messages", default-features = false }
@@ -58,6 +59,7 @@ std = [
5859
"bp-polkadot-core/std",
5960
"bp-relayers/std",
6061
"bp-runtime/std",
62+
"bp-xcm-bridge-hub/std",
6163
"bp-xcm-bridge-hub-router/std",
6264
"codec/std",
6365
"frame-support/std",

bridges/bin/runtime-common/src/messages_xcm_extension.rs

Lines changed: 46 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,23 @@
2222
//! `XcmRouter` <- `MessageDispatch` <- `InboundMessageQueue`
2323
2424
use bp_messages::{
25-
source_chain::{MessagesBridge, OnMessagesDelivered},
25+
source_chain::OnMessagesDelivered,
2626
target_chain::{DispatchMessage, MessageDispatch},
2727
LaneId, MessageNonce,
2828
};
2929
use bp_runtime::messages::MessageDispatchResult;
30+
pub use bp_xcm_bridge_hub::XcmAsPlainPayload;
3031
use bp_xcm_bridge_hub_router::XcmChannelStatusProvider;
3132
use codec::{Decode, Encode};
3233
use frame_support::{traits::Get, weights::Weight, CloneNoBound, EqNoBound, PartialEqNoBound};
3334
use pallet_bridge_messages::{
34-
Config as MessagesConfig, OutboundLanesCongestedSignals, Pallet as MessagesPallet,
35-
WeightInfoExt as MessagesPalletWeights,
35+
Config as MessagesConfig, OutboundLanesCongestedSignals, WeightInfoExt as MessagesPalletWeights,
3636
};
3737
use scale_info::TypeInfo;
3838
use sp_runtime::SaturatedConversion;
3939
use sp_std::{fmt::Debug, marker::PhantomData};
4040
use xcm::prelude::*;
41-
use xcm_builder::{DispatchBlob, DispatchBlobError, HaulBlob, HaulBlobError};
42-
43-
/// Plain "XCM" payload, which we transfer through bridge
44-
pub type XcmAsPlainPayload = sp_std::prelude::Vec<u8>;
41+
use xcm_builder::{DispatchBlob, DispatchBlobError};
4542

4643
/// Message dispatch result type for single message
4744
#[derive(CloneNoBound, EqNoBound, PartialEqNoBound, Encode, Decode, Debug, TypeInfo)]
@@ -123,6 +120,7 @@ impl<
123120

124121
/// A pair of sending chain location and message lane, used by this chain to send messages
125122
/// over the bridge.
123+
#[cfg_attr(feature = "std", derive(Debug, Eq, PartialEq))]
126124
pub struct SenderAndLane {
127125
/// Sending chain relative location.
128126
pub location: MultiLocation,
@@ -144,8 +142,6 @@ pub trait XcmBlobHauler {
144142
type Runtime: MessagesConfig<Self::MessagesInstance>;
145143
/// Instance of the messages pallet that is used to send messages.
146144
type MessagesInstance: 'static;
147-
/// Returns lane used by this hauler.
148-
type SenderAndLane: Get<SenderAndLane>;
149145

150146
/// Actual XCM message sender (`HRMP` or `UMP`) to the source chain
151147
/// location (`Self::SenderAndLane::get().location`).
@@ -166,54 +162,25 @@ pub trait XcmBlobHauler {
166162
/// makes sure that XCM blob is sent to the outbound lane to be relayed.
167163
///
168164
/// It needs to be used at the source bridge hub.
169-
pub struct XcmBlobHaulerAdapter<XcmBlobHauler>(sp_std::marker::PhantomData<XcmBlobHauler>);
165+
pub struct XcmBlobHaulerAdapter<XcmBlobHauler, Lanes>(
166+
sp_std::marker::PhantomData<(XcmBlobHauler, Lanes)>,
167+
);
170168

171-
impl<H: XcmBlobHauler> HaulBlob for XcmBlobHaulerAdapter<H>
172-
where
173-
H::Runtime: MessagesConfig<H::MessagesInstance, OutboundPayload = XcmAsPlainPayload>,
169+
impl<
170+
H: XcmBlobHauler,
171+
Lanes: Get<sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))>>,
172+
> OnMessagesDelivered for XcmBlobHaulerAdapter<H, Lanes>
174173
{
175-
fn haul_blob(blob: sp_std::prelude::Vec<u8>) -> Result<(), HaulBlobError> {
176-
let sender_and_lane = H::SenderAndLane::get();
177-
MessagesPallet::<H::Runtime, H::MessagesInstance>::send_message(sender_and_lane.lane, blob)
178-
.map(|artifacts| {
179-
log::info!(
180-
target: crate::LOG_TARGET_BRIDGE_DISPATCH,
181-
"haul_blob result - ok: {:?} on lane: {:?}. Enqueued messages: {}",
182-
artifacts.nonce,
183-
sender_and_lane.lane,
184-
artifacts.enqueued_messages,
185-
);
186-
187-
// notify XCM queue manager about updated lane state
188-
LocalXcmQueueManager::<H>::on_bridge_message_enqueued(
189-
&sender_and_lane,
190-
artifacts.enqueued_messages,
191-
);
192-
})
193-
.map_err(|error| {
194-
log::error!(
195-
target: crate::LOG_TARGET_BRIDGE_DISPATCH,
196-
"haul_blob result - error: {:?} on lane: {:?}",
197-
error,
198-
sender_and_lane.lane,
199-
);
200-
HaulBlobError::Transport("MessageSenderError")
201-
})
202-
}
203-
}
204-
205-
impl<H: XcmBlobHauler> OnMessagesDelivered for XcmBlobHaulerAdapter<H> {
206174
fn on_messages_delivered(lane: LaneId, enqueued_messages: MessageNonce) {
207-
let sender_and_lane = H::SenderAndLane::get();
208-
if sender_and_lane.lane != lane {
209-
return
175+
if let Some(sender_and_lane) =
176+
Lanes::get().iter().find(|link| link.0.lane == lane).map(|link| &link.0)
177+
{
178+
// notify XCM queue manager about updated lane state
179+
LocalXcmQueueManager::<H>::on_bridge_messages_delivered(
180+
sender_and_lane,
181+
enqueued_messages,
182+
);
210183
}
211-
212-
// notify XCM queue manager about updated lane state
213-
LocalXcmQueueManager::<H>::on_bridge_messages_delivered(
214-
&sender_and_lane,
215-
enqueued_messages,
216-
);
217184
}
218185
}
219186

@@ -356,6 +323,9 @@ mod tests {
356323
location: MultiLocation::new(1, X1(Parachain(1000))),
357324
lane: TEST_LANE_ID,
358325
};
326+
pub TestLanes: sp_std::vec::Vec<(SenderAndLane, (NetworkId, InteriorMultiLocation))> = sp_std::vec![
327+
(TestSenderAndLane::get(), (NetworkId::ByGenesis([0; 32]), InteriorMultiLocation::Here))
328+
];
359329
pub DummyXcmMessage: Xcm<()> = Xcm::new();
360330
}
361331

@@ -389,56 +359,69 @@ mod tests {
389359
impl XcmBlobHauler for TestBlobHauler {
390360
type Runtime = TestRuntime;
391361
type MessagesInstance = ();
392-
type SenderAndLane = TestSenderAndLane;
393362

394363
type ToSourceChainSender = DummySendXcm;
395364
type CongestedMessage = DummyXcmMessage;
396365
type UncongestedMessage = DummyXcmMessage;
397366
}
398367

399-
type TestBlobHaulerAdapter = XcmBlobHaulerAdapter<TestBlobHauler>;
368+
type TestBlobHaulerAdapter = XcmBlobHaulerAdapter<TestBlobHauler, TestLanes>;
400369

401-
fn fill_up_lane_to_congestion() {
370+
fn fill_up_lane_to_congestion() -> MessageNonce {
371+
let latest_generated_nonce = OUTBOUND_LANE_CONGESTED_THRESHOLD;
402372
OutboundLanes::<TestRuntime, ()>::insert(
403373
TEST_LANE_ID,
404374
OutboundLaneData {
405375
oldest_unpruned_nonce: 0,
406376
latest_received_nonce: 0,
407-
latest_generated_nonce: OUTBOUND_LANE_CONGESTED_THRESHOLD,
377+
latest_generated_nonce,
408378
},
409379
);
380+
latest_generated_nonce
410381
}
411382

412383
#[test]
413384
fn congested_signal_is_not_sent_twice() {
414385
run_test(|| {
415-
fill_up_lane_to_congestion();
386+
let enqueued = fill_up_lane_to_congestion();
416387

417388
// next sent message leads to congested signal
418-
TestBlobHaulerAdapter::haul_blob(vec![42]).unwrap();
389+
LocalXcmQueueManager::<TestBlobHauler>::on_bridge_message_enqueued(
390+
&TestSenderAndLane::get(),
391+
enqueued + 1,
392+
);
419393
assert_eq!(DummySendXcm::messages_sent(), 1);
420394

421395
// next sent message => we don't sent another congested signal
422-
TestBlobHaulerAdapter::haul_blob(vec![42]).unwrap();
396+
LocalXcmQueueManager::<TestBlobHauler>::on_bridge_message_enqueued(
397+
&TestSenderAndLane::get(),
398+
enqueued,
399+
);
423400
assert_eq!(DummySendXcm::messages_sent(), 1);
424401
});
425402
}
426403

427404
#[test]
428405
fn congested_signal_is_not_sent_when_outbound_lane_is_not_congested() {
429406
run_test(|| {
430-
TestBlobHaulerAdapter::haul_blob(vec![42]).unwrap();
407+
LocalXcmQueueManager::<TestBlobHauler>::on_bridge_message_enqueued(
408+
&TestSenderAndLane::get(),
409+
1,
410+
);
431411
assert_eq!(DummySendXcm::messages_sent(), 0);
432412
});
433413
}
434414

435415
#[test]
436416
fn congested_signal_is_sent_when_outbound_lane_is_congested() {
437417
run_test(|| {
438-
fill_up_lane_to_congestion();
418+
let enqueued = fill_up_lane_to_congestion();
439419

440420
// next sent message leads to congested signal
441-
TestBlobHaulerAdapter::haul_blob(vec![42]).unwrap();
421+
LocalXcmQueueManager::<TestBlobHauler>::on_bridge_message_enqueued(
422+
&TestSenderAndLane::get(),
423+
enqueued + 1,
424+
);
442425
assert_eq!(DummySendXcm::messages_sent(), 1);
443426
assert!(LocalXcmQueueManager::<TestBlobHauler>::is_congested_signal_sent(TEST_LANE_ID));
444427
});
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
[package]
2+
name = "pallet-xcm-bridge-hub"
3+
description = "Module that adds dynamic bridges/lanes support to XCM infrastucture at the bridge hub."
4+
version = "0.1.0"
5+
authors.workspace = true
6+
edition.workspace = true
7+
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
8+
9+
[dependencies]
10+
codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false }
11+
log = { version = "0.4.20", default-features = false }
12+
scale-info = { version = "2.10.0", default-features = false, features = ["derive"] }
13+
14+
# Bridge Dependencies
15+
bp-messages = { path = "../../primitives/messages", default-features = false }
16+
bp-runtime = { path = "../../primitives/runtime", default-features = false }
17+
bp-xcm-bridge-hub = { path = "../../primitives/xcm-bridge-hub", default-features = false }
18+
pallet-bridge-messages = { path = "../messages", default-features = false }
19+
bridge-runtime-common = { path = "../../bin/runtime-common", default-features = false }
20+
21+
# Substrate Dependencies
22+
frame-support = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master", default-features = false }
23+
frame-system = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master", default-features = false }
24+
sp-core = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master", default-features = false }
25+
sp-runtime = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master", default-features = false }
26+
sp-std = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master", default-features = false }
27+
28+
# Polkadot Dependencies
29+
xcm = { package = "staging-xcm", git = "https://github.com/paritytech/polkadot-sdk", branch = "master", default-features = false }
30+
xcm-builder = { package = "staging-xcm-builder", git = "https://github.com/paritytech/polkadot-sdk", branch = "master", default-features = false }
31+
xcm-executor = { package = "staging-xcm-executor", git = "https://github.com/paritytech/polkadot-sdk", branch = "master", default-features = false }
32+
33+
[dev-dependencies]
34+
bp-header-chain = { path = "../../primitives/header-chain" }
35+
pallet-balances = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
36+
sp-io = { git = "https://github.com/paritytech/polkadot-sdk", branch = "master" }
37+
38+
[features]
39+
default = ["std"]
40+
std = [
41+
"bp-messages/std",
42+
"bp-runtime/std",
43+
"bp-xcm-bridge-hub/std",
44+
"bridge-runtime-common/std",
45+
"codec/std",
46+
"frame-support/std",
47+
"frame-system/std",
48+
"log/std",
49+
"pallet-bridge-messages/std",
50+
"scale-info/std",
51+
"sp-core/std",
52+
"sp-runtime/std",
53+
"sp-std/std",
54+
"xcm-builder/std",
55+
"xcm-executor/std",
56+
"xcm/std",
57+
]
58+
runtime-benchmarks = [
59+
"bridge-runtime-common/runtime-benchmarks",
60+
"frame-support/runtime-benchmarks",
61+
"frame-system/runtime-benchmarks",
62+
"pallet-balances/runtime-benchmarks",
63+
"pallet-bridge-messages/runtime-benchmarks",
64+
"sp-runtime/runtime-benchmarks",
65+
"xcm-builder/runtime-benchmarks",
66+
"xcm-executor/runtime-benchmarks",
67+
]
68+
try-runtime = [
69+
"frame-support/try-runtime",
70+
"frame-system/try-runtime",
71+
"pallet-balances/try-runtime",
72+
"pallet-bridge-messages/try-runtime",
73+
"sp-runtime/try-runtime",
74+
]

0 commit comments

Comments
 (0)