bridge_hub_common/
message_queue.rs1use codec::{Decode, Encode, MaxEncodedLen};
17use core::marker::PhantomData;
18use cumulus_primitives_core::{AggregateMessageOrigin as CumulusAggregateMessageOrigin, ParaId};
19use frame_support::{
20 traits::{ProcessMessage, ProcessMessageError, QueueFootprint, QueuePausedQuery},
21 weights::WeightMeter,
22};
23use pallet_message_queue::OnQueueChanged;
24use scale_info::TypeInfo;
25use snowbridge_core::ChannelId;
26use xcm::latest::prelude::{Junction, Location};
27
28#[derive(Encode, Decode, Copy, MaxEncodedLen, Clone, Eq, PartialEq, TypeInfo, Debug)]
32pub enum AggregateMessageOrigin {
33 Here,
35 Parent,
39 Sibling(ParaId),
43 Snowbridge(ChannelId),
47}
48
49impl From<AggregateMessageOrigin> for Location {
50 fn from(origin: AggregateMessageOrigin) -> Self {
51 use AggregateMessageOrigin::*;
52 match origin {
53 Here => Location::here(),
54 Parent => Location::parent(),
55 Sibling(id) => Location::new(1, Junction::Parachain(id.into())),
56 Snowbridge(_) => Location::default(),
59 }
60 }
61}
62
63impl From<CumulusAggregateMessageOrigin> for AggregateMessageOrigin {
64 fn from(origin: CumulusAggregateMessageOrigin) -> Self {
65 match origin {
66 CumulusAggregateMessageOrigin::Here => Self::Here,
67 CumulusAggregateMessageOrigin::Parent => Self::Parent,
68 CumulusAggregateMessageOrigin::Sibling(id) => Self::Sibling(id),
69 }
70 }
71}
72
73#[cfg(feature = "runtime-benchmarks")]
74impl From<u32> for AggregateMessageOrigin {
75 fn from(x: u32) -> Self {
76 match x {
77 0 => Self::Here,
78 1 => Self::Parent,
79 p => Self::Sibling(ParaId::from(p)),
80 }
81 }
82}
83
84pub struct BridgeHubMessageRouter<XcmpProcessor, SnowbridgeProcessor>(
86 PhantomData<(XcmpProcessor, SnowbridgeProcessor)>,
87)
88where
89 XcmpProcessor: ProcessMessage<Origin = AggregateMessageOrigin>,
90 SnowbridgeProcessor: ProcessMessage<Origin = AggregateMessageOrigin>;
91
92impl<XcmpProcessor, SnowbridgeProcessor> ProcessMessage
93 for BridgeHubMessageRouter<XcmpProcessor, SnowbridgeProcessor>
94where
95 XcmpProcessor: ProcessMessage<Origin = AggregateMessageOrigin>,
96 SnowbridgeProcessor: ProcessMessage<Origin = AggregateMessageOrigin>,
97{
98 type Origin = AggregateMessageOrigin;
99
100 fn process_message(
101 message: &[u8],
102 origin: Self::Origin,
103 meter: &mut WeightMeter,
104 id: &mut [u8; 32],
105 ) -> Result<bool, ProcessMessageError> {
106 use AggregateMessageOrigin::*;
107 match origin {
108 Here | Parent | Sibling(_) =>
109 XcmpProcessor::process_message(message, origin, meter, id),
110 Snowbridge(_) => SnowbridgeProcessor::process_message(message, origin, meter, id),
111 }
112 }
113}
114
115pub struct NarrowOriginToSibling<Inner>(PhantomData<Inner>);
119impl<Inner: QueuePausedQuery<ParaId>> QueuePausedQuery<AggregateMessageOrigin>
120 for NarrowOriginToSibling<Inner>
121{
122 fn is_paused(origin: &AggregateMessageOrigin) -> bool {
123 match origin {
124 AggregateMessageOrigin::Sibling(id) => Inner::is_paused(id),
125 _ => false,
126 }
127 }
128}
129
130impl<Inner: OnQueueChanged<ParaId>> OnQueueChanged<AggregateMessageOrigin>
131 for NarrowOriginToSibling<Inner>
132{
133 fn on_queue_changed(origin: AggregateMessageOrigin, fp: QueueFootprint) {
134 if let AggregateMessageOrigin::Sibling(id) = origin {
135 Inner::on_queue_changed(id, fp)
136 }
137 }
138}
139
140pub struct ParaIdToSibling;
142impl sp_runtime::traits::Convert<ParaId, AggregateMessageOrigin> for ParaIdToSibling {
143 fn convert(para_id: ParaId) -> AggregateMessageOrigin {
144 AggregateMessageOrigin::Sibling(para_id)
145 }
146}