Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 3ad67d3

Browse files
committed
Squashed 'bridges/' changes from c364846936..f822ebc450
f822ebc450 Dynamic fees v1: report congestion status to sending chain (#2318) add9fb1d53 added/fixed some docs 569a80f233 Rename LocalXcmChannel to XcmChannelStatusProvider (#2319) dc3618a4a5 Clippy e7cab6ab49 (Suggestion) Ability to externalize configuration for `ExporterFor` (#2313) REVERT: c364846936 report congestion status: changes at the bridge hub REVERT: d78f10664a OnMessagesDelivered is back REVERT: ac799a88e3 report congestion status: changes at the sending chain git-subtree-dir: bridges git-subtree-split: f822ebc45081e67217e7395cae7d42c661dc8464
1 parent 9257e21 commit 3ad67d3

File tree

14 files changed

+374
-113
lines changed

14 files changed

+374
-113
lines changed

bin/millau/runtime/src/lib.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ use sp_std::prelude::*;
5555
#[cfg(feature = "std")]
5656
use sp_version::NativeVersion;
5757
use sp_version::RuntimeVersion;
58+
use xcm_builder::NetworkExportTable;
5859

5960
// to be able to use Millau runtime in `bridge-runtime-common` tests
6061
pub use bridge_runtime_common;
@@ -548,18 +549,21 @@ impl pallet_utility::Config for Runtime {
548549

549550
// this config is totally incorrect - the pallet is not actually used at this runtime. We need
550551
// it only to be able to run benchmarks and make required traits (and default weights for tests).
552+
parameter_types! {
553+
pub BridgeTable: Vec<(xcm::prelude::NetworkId, xcm::prelude::MultiLocation, Option<xcm::prelude::MultiAsset>)>
554+
= vec![(xcm_config::RialtoNetwork::get(), xcm_config::TokenLocation::get(), Some((xcm_config::TokenAssetId::get(), 1_000_000_000_u128).into()))];
555+
}
551556
impl pallet_xcm_bridge_hub_router::Config for Runtime {
552557
type WeightInfo = ();
553558

554559
type UniversalLocation = xcm_config::UniversalLocation;
555-
type SiblingBridgeHubLocation = xcm_config::TokenLocation;
556560
type BridgedNetworkId = xcm_config::RialtoNetwork;
561+
type Bridges = NetworkExportTable<BridgeTable>;
557562

558563
type BridgeHubOrigin = frame_system::EnsureRoot<AccountId>;
559564
type ToBridgeHubSender = xcm_config::XcmRouter;
560565
type WithBridgeHubChannel = xcm_config::EmulatedSiblingXcmpChannel;
561566

562-
type BaseFee = ConstU128<1_000_000_000>;
563567
type ByteFee = ConstU128<1_000>;
564568
type FeeAsset = xcm_config::TokenAssetId;
565569
}

bin/millau/runtime/src/rialto_messages.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl XcmBlobHauler for ToRialtoXcmBlobHauler {
133133
type MessagesInstance = WithRialtoMessagesInstance;
134134
type SenderAndLane = RialtoSenderAndLane;
135135

136-
type ToSendingChainSender = crate::xcm_config::XcmRouter;
136+
type ToSourceChainSender = crate::xcm_config::XcmRouter;
137137
type CongestedMessage = DummyXcmMessage;
138138
type UncongestedMessage = DummyXcmMessage;
139139

bin/millau/runtime/src/rialto_parachain_messages.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl XcmBlobHauler for ToRialtoParachainXcmBlobHauler {
133133
type MessagesInstance = WithRialtoParachainMessagesInstance;
134134
type SenderAndLane = RialtoParachainSenderAndLane;
135135

136-
type ToSendingChainSender = crate::xcm_config::XcmRouter;
136+
type ToSourceChainSender = crate::xcm_config::XcmRouter;
137137
type CongestedMessage = DummyXcmMessage;
138138
type UncongestedMessage = DummyXcmMessage;
139139

bin/millau/runtime/src/xcm_config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ impl EmulatedSiblingXcmpChannel {
263263
}
264264
}
265265

266-
impl bp_xcm_bridge_hub_router::LocalXcmChannel for EmulatedSiblingXcmpChannel {
266+
impl bp_xcm_bridge_hub_router::XcmChannelStatusProvider for EmulatedSiblingXcmpChannel {
267267
fn is_congested() -> bool {
268268
frame_support::storage::unhashed::get_or_default(b"EmulatedSiblingXcmpChannel.Congested")
269269
}

bin/rialto-parachain/runtime/src/millau_messages.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl XcmBlobHauler for ToMillauXcmBlobHauler {
133133
type MessagesInstance = WithMillauMessagesInstance;
134134
type SenderAndLane = MullauSenderAndLane;
135135

136-
type ToSendingChainSender = crate::XcmRouter;
136+
type ToSourceChainSender = crate::XcmRouter;
137137
type CongestedMessage = DummyXcmMessage;
138138
type UncongestedMessage = DummyXcmMessage;
139139

bin/rialto/runtime/src/millau_messages.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl XcmBlobHauler for ToMillauXcmBlobHauler {
132132
type MessagesInstance = WithMillauMessagesInstance;
133133
type SenderAndLane = MullauSenderAndLane;
134134

135-
type ToSendingChainSender = crate::xcm_config::XcmRouter;
135+
type ToSourceChainSender = crate::xcm_config::XcmRouter;
136136
type CongestedMessage = DummyXcmMessage;
137137
type UncongestedMessage = DummyXcmMessage;
138138

bin/runtime-common/src/messages_xcm_extension.rs

Lines changed: 177 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use bp_messages::{
2727
LaneId, MessageNonce,
2828
};
2929
use bp_runtime::messages::MessageDispatchResult;
30-
use bp_xcm_bridge_hub_router::LocalXcmChannel;
30+
use bp_xcm_bridge_hub_router::XcmChannelStatusProvider;
3131
use codec::{Decode, Encode};
3232
use frame_support::{dispatch::Weight, traits::Get, CloneNoBound, EqNoBound, PartialEqNoBound};
3333
use frame_system::Config as SystemConfig;
@@ -59,8 +59,11 @@ pub struct XcmBlobMessageDispatch<DispatchBlob, Weights, Channel> {
5959
_marker: sp_std::marker::PhantomData<(DispatchBlob, Weights, Channel)>,
6060
}
6161

62-
impl<BlobDispatcher: DispatchBlob, Weights: MessagesPalletWeights, Channel: LocalXcmChannel>
63-
MessageDispatch for XcmBlobMessageDispatch<BlobDispatcher, Weights, Channel>
62+
impl<
63+
BlobDispatcher: DispatchBlob,
64+
Weights: MessagesPalletWeights,
65+
Channel: XcmChannelStatusProvider,
66+
> MessageDispatch for XcmBlobMessageDispatch<BlobDispatcher, Weights, Channel>
6467
{
6568
type DispatchPayload = XcmAsPlainPayload;
6669
type DispatchLevelResult = XcmBlobMessageDispatchResult;
@@ -145,22 +148,23 @@ pub trait XcmBlobHauler {
145148
/// Returns lane used by this hauler.
146149
type SenderAndLane: Get<SenderAndLane>;
147150

148-
/// Actual XCM message sender (`HRMP` or `UMP`) to the sending chain
151+
/// Actual XCM message sender (`HRMP` or `UMP`) to the source chain
149152
/// location (`Self::SenderAndLane::get().location`).
150-
type ToSendingChainSender: SendXcm;
153+
type ToSourceChainSender: SendXcm;
151154
/// An XCM message that is sent to the sending chain when the bridge queue becomes congested.
152155
type CongestedMessage: Get<Xcm<()>>;
153-
/// An XCM message that is sent to the sending chain when the bridge queue becomes uncongested.
156+
/// An XCM message that is sent to the sending chain when the bridge queue becomes not
157+
/// congested.
154158
type UncongestedMessage: Get<Xcm<()>>;
155159

156-
/// Runtime message sender origin, which is used by [`Self::MessageSender`].
160+
/// Runtime message sender origin, which is used by the associated messages pallet.
157161
type MessageSenderOrigin;
158162
/// Runtime origin for our (i.e. this bridge hub) location within the Consensus Universe.
159163
fn message_sender_origin() -> Self::MessageSenderOrigin;
160164
}
161165

162-
/// XCM bridge adapter which connects [`XcmBlobHauler`] with [`XcmBlobHauler::MessageSender`] and
163-
/// makes sure that XCM blob is sent to the [`pallet_bridge_messages`] queue to be relayed.
166+
/// XCM bridge adapter which connects [`XcmBlobHauler`] with [`pallet_bridge_messages`] and
167+
/// makes sure that XCM blob is sent to the outbound lane to be relayed.
164168
///
165169
/// It needs to be used at the source bridge hub.
166170
pub struct XcmBlobHaulerAdapter<XcmBlobHauler>(sp_std::marker::PhantomData<XcmBlobHauler>);
@@ -233,7 +237,7 @@ pub struct LocalXcmQueueManager<H>(PhantomData<H>);
233237
const OUTBOUND_LANE_CONGESTED_THRESHOLD: MessageNonce = 8_192;
234238

235239
/// After we have sent "congestion" XCM message to the sending chain, we wait until number
236-
/// of messages in the outbound bridge queue drops to this count, before sending "uncongestion"
240+
/// of messages in the outbound bridge queue drops to this count, before sending `uncongestion`
237241
/// XCM message.
238242
const OUTBOUND_LANE_UNCONGESTED_THRESHOLD: MessageNonce = 1_024;
239243

@@ -243,8 +247,7 @@ impl<H: XcmBlobHauler> LocalXcmQueueManager<H> {
243247
sender_and_lane: &SenderAndLane,
244248
enqueued_messages: MessageNonce,
245249
) {
246-
// if we have alsender_and_laneready sent the congestion signal, we don't want to do
247-
// anything
250+
// if we have already sent the congestion signal, we don't want to do anything
248251
if Self::is_congested_signal_sent(sender_and_lane.lane) {
249252
return
250253
}
@@ -311,28 +314,182 @@ impl<H: XcmBlobHauler> LocalXcmQueueManager<H> {
311314

312315
/// Returns true if we have sent "congested" signal to the `sending_chain_location`.
313316
fn is_congested_signal_sent(lane: LaneId) -> bool {
314-
OutboundLanesCongestedSignals::<H::Runtime, H::MessagesInstance>::get(&lane)
317+
OutboundLanesCongestedSignals::<H::Runtime, H::MessagesInstance>::get(lane)
315318
}
316319

317320
/// Send congested signal to the `sending_chain_location`.
318321
fn send_congested_signal(sender_and_lane: &SenderAndLane) -> Result<(), SendError> {
319-
send_xcm::<H::ToSendingChainSender>(sender_and_lane.location, H::CongestedMessage::get())?;
322+
send_xcm::<H::ToSourceChainSender>(sender_and_lane.location, H::CongestedMessage::get())?;
320323
OutboundLanesCongestedSignals::<H::Runtime, H::MessagesInstance>::insert(
321324
sender_and_lane.lane,
322325
true,
323326
);
324327
Ok(())
325328
}
326329

327-
/// Send uncongested signal to the `sending_chain_location`.
330+
/// Send `uncongested` signal to the `sending_chain_location`.
328331
fn send_uncongested_signal(sender_and_lane: &SenderAndLane) -> Result<(), SendError> {
329-
send_xcm::<H::ToSendingChainSender>(
330-
sender_and_lane.location,
331-
H::UncongestedMessage::get(),
332-
)?;
332+
send_xcm::<H::ToSourceChainSender>(sender_and_lane.location, H::UncongestedMessage::get())?;
333333
OutboundLanesCongestedSignals::<H::Runtime, H::MessagesInstance>::remove(
334-
&sender_and_lane.lane,
334+
sender_and_lane.lane,
335335
);
336336
Ok(())
337337
}
338338
}
339+
340+
#[cfg(test)]
341+
mod tests {
342+
use super::*;
343+
use crate::mock::*;
344+
345+
use bp_messages::OutboundLaneData;
346+
use frame_support::parameter_types;
347+
use pallet_bridge_messages::OutboundLanes;
348+
349+
parameter_types! {
350+
pub TestSenderAndLane: SenderAndLane = SenderAndLane {
351+
location: MultiLocation::new(1, X1(Parachain(1000))),
352+
lane: TEST_LANE_ID,
353+
};
354+
pub DummyXcmMessage: Xcm<()> = Xcm::new();
355+
}
356+
357+
struct DummySendXcm;
358+
359+
impl DummySendXcm {
360+
fn messages_sent() -> u32 {
361+
frame_support::storage::unhashed::get(b"DummySendXcm").unwrap_or(0)
362+
}
363+
}
364+
365+
impl SendXcm for DummySendXcm {
366+
type Ticket = ();
367+
368+
fn validate(
369+
_destination: &mut Option<MultiLocation>,
370+
_message: &mut Option<Xcm<()>>,
371+
) -> SendResult<Self::Ticket> {
372+
Ok(((), Default::default()))
373+
}
374+
375+
fn deliver(_ticket: Self::Ticket) -> Result<XcmHash, SendError> {
376+
let messages_sent: u32 = Self::messages_sent();
377+
frame_support::storage::unhashed::put(b"DummySendXcm", &(messages_sent + 1));
378+
Ok(XcmHash::default())
379+
}
380+
}
381+
382+
struct TestBlobHauler;
383+
384+
impl XcmBlobHauler for TestBlobHauler {
385+
type Runtime = TestRuntime;
386+
type MessagesInstance = ();
387+
type SenderAndLane = TestSenderAndLane;
388+
389+
type ToSourceChainSender = DummySendXcm;
390+
type CongestedMessage = DummyXcmMessage;
391+
type UncongestedMessage = DummyXcmMessage;
392+
393+
type MessageSenderOrigin = RuntimeOrigin;
394+
395+
fn message_sender_origin() -> Self::MessageSenderOrigin {
396+
RuntimeOrigin::root()
397+
}
398+
}
399+
400+
type TestBlobHaulerAdapter = XcmBlobHaulerAdapter<TestBlobHauler>;
401+
402+
fn fill_up_lane_to_congestion() {
403+
OutboundLanes::<TestRuntime, ()>::insert(
404+
TEST_LANE_ID,
405+
OutboundLaneData {
406+
oldest_unpruned_nonce: 0,
407+
latest_received_nonce: 0,
408+
latest_generated_nonce: OUTBOUND_LANE_CONGESTED_THRESHOLD,
409+
},
410+
);
411+
}
412+
413+
#[test]
414+
fn congested_signal_is_not_sent_twice() {
415+
run_test(|| {
416+
fill_up_lane_to_congestion();
417+
418+
// next sent message leads to congested signal
419+
TestBlobHaulerAdapter::haul_blob(vec![42]).unwrap();
420+
assert_eq!(DummySendXcm::messages_sent(), 1);
421+
422+
// next sent message => we don't sent another congested signal
423+
TestBlobHaulerAdapter::haul_blob(vec![42]).unwrap();
424+
assert_eq!(DummySendXcm::messages_sent(), 1);
425+
});
426+
}
427+
428+
#[test]
429+
fn congested_signal_is_not_sent_when_outbound_lane_is_not_congested() {
430+
run_test(|| {
431+
TestBlobHaulerAdapter::haul_blob(vec![42]).unwrap();
432+
assert_eq!(DummySendXcm::messages_sent(), 0);
433+
});
434+
}
435+
436+
#[test]
437+
fn congested_signal_is_sent_when_outbound_lane_is_congested() {
438+
run_test(|| {
439+
fill_up_lane_to_congestion();
440+
441+
// next sent message leads to congested signal
442+
TestBlobHaulerAdapter::haul_blob(vec![42]).unwrap();
443+
assert_eq!(DummySendXcm::messages_sent(), 1);
444+
assert!(LocalXcmQueueManager::<TestBlobHauler>::is_congested_signal_sent(TEST_LANE_ID));
445+
});
446+
}
447+
448+
#[test]
449+
fn uncongested_signal_is_not_sent_when_messages_are_delivered_at_other_lane() {
450+
run_test(|| {
451+
LocalXcmQueueManager::<TestBlobHauler>::send_congested_signal(&TestSenderAndLane::get()).unwrap();
452+
assert_eq!(DummySendXcm::messages_sent(), 1);
453+
454+
// when we receive a delivery report for other lane, we don't send an uncongested signal
455+
TestBlobHaulerAdapter::on_messages_delivered(LaneId([42, 42, 42, 42]), 0);
456+
assert_eq!(DummySendXcm::messages_sent(), 1);
457+
});
458+
}
459+
460+
#[test]
461+
fn uncongested_signal_is_not_sent_when_we_havent_send_congested_signal_before() {
462+
run_test(|| {
463+
TestBlobHaulerAdapter::on_messages_delivered(TEST_LANE_ID, 0);
464+
assert_eq!(DummySendXcm::messages_sent(), 0);
465+
});
466+
}
467+
468+
#[test]
469+
fn uncongested_signal_is_not_sent_if_outbound_lane_is_still_congested() {
470+
run_test(|| {
471+
LocalXcmQueueManager::<TestBlobHauler>::send_congested_signal(&TestSenderAndLane::get()).unwrap();
472+
assert_eq!(DummySendXcm::messages_sent(), 1);
473+
474+
TestBlobHaulerAdapter::on_messages_delivered(
475+
TEST_LANE_ID,
476+
OUTBOUND_LANE_UNCONGESTED_THRESHOLD + 1,
477+
);
478+
assert_eq!(DummySendXcm::messages_sent(), 1);
479+
});
480+
}
481+
482+
#[test]
483+
fn uncongested_signal_is_sent_if_outbound_lane_is_uncongested() {
484+
run_test(|| {
485+
LocalXcmQueueManager::<TestBlobHauler>::send_congested_signal(&TestSenderAndLane::get()).unwrap();
486+
assert_eq!(DummySendXcm::messages_sent(), 1);
487+
488+
TestBlobHaulerAdapter::on_messages_delivered(
489+
TEST_LANE_ID,
490+
OUTBOUND_LANE_UNCONGESTED_THRESHOLD,
491+
);
492+
assert_eq!(DummySendXcm::messages_sent(), 2);
493+
});
494+
}
495+
}

modules/messages/src/lib.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ pub mod pallet {
498498
// notify others about messages delivery
499499
T::OnMessagesDelivered::on_messages_delivered(
500500
lane_id,
501-
lane.data().queued_messages().checked_len().unwrap_or(0),
501+
lane.data().queued_messages().saturating_len(),
502502
);
503503

504504
// because of lags, the inbound lane state (`lane_data`) may have entries for
@@ -599,10 +599,12 @@ pub mod pallet {
599599
/// Map of lane id => is congested signal sent. It is managed by the
600600
/// `bridge_runtime_common::LocalXcmQueueManager`.
601601
///
602-
/// **bridges-v1**: this map is temporary and will be dropped in the v2. We can emulate
603-
/// a storage map using unhashed storage functions, but then benchmarks are not accounting
604-
/// its `proof_size`, so it is missing from the final weights. So we need to make it a map
605-
/// inside some pallet.
602+
/// **bridges-v1**: this map is a temporary hack and will be dropped in the `v2`. We can emulate
603+
/// a storage map using `sp_io::unhashed` storage functions, but then benchmarks are not
604+
/// accounting its `proof_size`, so it is missing from the final weights. So we need to make it
605+
/// a map inside some pallet. We could use a simply value instead of map here, because
606+
/// in `v1` we'll only have a single lane. But in the case of adding another lane before `v2`,
607+
/// it'll be easier to deal with the isolated storage map instead.
606608
#[pallet::storage]
607609
pub type OutboundLanesCongestedSignals<T: Config<I>, I: 'static = ()> = StorageMap<
608610
Hasher = Blake2_128Concat,
@@ -928,9 +930,10 @@ mod tests {
928930
inbound_unrewarded_relayers_state, message, message_payload, run_test,
929931
unrewarded_relayer, AccountId, DbWeight, RuntimeEvent as TestEvent, RuntimeOrigin,
930932
TestDeliveryConfirmationPayments, TestDeliveryPayments, TestMessageDispatch,
931-
TestMessagesDeliveryProof, TestMessagesProof, TestRelayer, TestRuntime, TestWeightInfo,
932-
MAX_OUTBOUND_PAYLOAD_SIZE, PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD,
933-
TEST_LANE_ID, TEST_LANE_ID_2, TEST_LANE_ID_3, TEST_RELAYER_A, TEST_RELAYER_B,
933+
TestMessagesDeliveryProof, TestMessagesProof, TestOnMessagesDelivered, TestRelayer,
934+
TestRuntime, TestWeightInfo, MAX_OUTBOUND_PAYLOAD_SIZE,
935+
PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_LANE_ID_2,
936+
TEST_LANE_ID_3, TEST_RELAYER_A, TEST_RELAYER_B,
934937
},
935938
outbound_lane::ReceivalConfirmationError,
936939
};
@@ -1401,6 +1404,7 @@ mod tests {
14011404
);
14021405
assert!(TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_A, 1));
14031406
assert!(!TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_B, 1));
1407+
assert_eq!(TestOnMessagesDelivered::call_arguments(), Some((TEST_LANE_ID, 1)));
14041408

14051409
// this reports delivery of both message 1 and message 2 => reward is paid only to
14061410
// TEST_RELAYER_B
@@ -1443,6 +1447,7 @@ mod tests {
14431447
);
14441448
assert!(!TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_A, 1));
14451449
assert!(TestDeliveryConfirmationPayments::is_reward_paid(TEST_RELAYER_B, 1));
1450+
assert_eq!(TestOnMessagesDelivered::call_arguments(), Some((TEST_LANE_ID, 0)));
14461451
});
14471452
}
14481453

0 commit comments

Comments
 (0)