moonbeam_runtime_common/
bridge.rs1use core::marker::PhantomData;
18use cumulus_primitives_core::AggregateMessageOrigin;
19use frame_support::pallet_prelude::Get;
20use frame_support::traits::{EnqueueMessage, ProcessMessage, QueueFootprintQuery};
21use frame_support::{ensure, BoundedVec};
22use pallet_xcm_bridge::BridgeId;
23use parity_scale_codec::{Decode, Encode};
24use sp_std::vec::Vec;
25use xcm::latest::{InteriorLocation, Location, SendError, SendResult, SendXcm, Xcm, XcmHash};
26use xcm::{VersionedLocation, VersionedXcm};
27use xcm_builder::{BridgeMessage, DispatchBlob, DispatchBlobError, InspectMessageQueues};
28
29const MESSAGE_QUEUE_CONGESTION_THRESHOLD: u32 = 32;
33
34pub const LOG_TARGET: &str = "moonbeam-bridge";
36
37pub struct BridgeXcmRouter<MessageExporter>(PhantomData<MessageExporter>);
38
39impl<MessageExporter: SendXcm> SendXcm for BridgeXcmRouter<MessageExporter> {
42 type Ticket = MessageExporter::Ticket;
43
44 fn validate(
45 dest: &mut Option<Location>,
46 xcm: &mut Option<Xcm<()>>,
47 ) -> SendResult<Self::Ticket> {
48 log::trace!(target: LOG_TARGET, "validate - msg: {xcm:?}, destination: {dest:?}");
49
50 MessageExporter::validate(dest, xcm)
51 }
52
53 fn deliver(ticket: Self::Ticket) -> Result<XcmHash, SendError> {
54 MessageExporter::deliver(ticket)
55 }
56}
57
58impl<MessageExporter> InspectMessageQueues for BridgeXcmRouter<MessageExporter> {
61 fn clear_messages() {}
62
63 fn get_messages() -> Vec<(VersionedLocation, Vec<VersionedXcm<()>>)> {
64 Vec::new()
65 }
66}
67
68pub struct LocalBlobDispatcher<MQ, OurPlace, OurPlaceBridgeInstance>(
69 PhantomData<(MQ, OurPlace, OurPlaceBridgeInstance)>,
70);
71impl<
72 MQ: EnqueueMessage<AggregateMessageOrigin>,
73 OurPlace: Get<InteriorLocation>,
74 OurPlaceBridgeInstance: Get<Option<InteriorLocation>>,
75 > DispatchBlob for LocalBlobDispatcher<MQ, OurPlace, OurPlaceBridgeInstance>
76{
77 fn dispatch_blob(blob: Vec<u8>) -> Result<(), DispatchBlobError> {
78 let our_universal = OurPlace::get();
79 let our_global = our_universal
80 .global_consensus()
81 .map_err(|()| DispatchBlobError::Unbridgable)?;
82 let BridgeMessage {
83 universal_dest,
84 message,
85 } = Decode::decode(&mut &blob[..]).map_err(|_| DispatchBlobError::InvalidEncoding)?;
86 let universal_dest: InteriorLocation = universal_dest
87 .try_into()
88 .map_err(|_| DispatchBlobError::UnsupportedLocationVersion)?;
89 let intended_global = universal_dest
92 .global_consensus()
93 .map_err(|()| DispatchBlobError::NonUniversalDestination)?;
94 ensure!(
95 intended_global == our_global,
96 DispatchBlobError::WrongGlobal
97 );
98 let xcm: Xcm<()> = message
99 .try_into()
100 .map_err(|_| DispatchBlobError::UnsupportedXcmVersion)?;
101
102 let msg: BoundedVec<u8, MQ::MaxMessageLen> = xcm::opaque::VersionedXcm::V5(xcm)
103 .encode()
104 .try_into()
105 .map_err(|_| DispatchBlobError::InvalidEncoding)?;
106
107 MQ::enqueue_message(
108 msg.as_bounded_slice(),
109 AggregateMessageOrigin::Here, );
111
112 Ok(())
113 }
114}
115
116pub struct CongestionManager<Runtime>(PhantomData<Runtime>);
118impl<Runtime: pallet_message_queue::Config> pallet_xcm_bridge::LocalXcmChannelManager
119 for CongestionManager<Runtime>
120where
121 <Runtime as pallet_message_queue::Config>::MessageProcessor:
122 ProcessMessage<Origin = AggregateMessageOrigin>,
123{
124 type Error = SendError;
125
126 fn is_congested(_with: &Location) -> bool {
127 let book_state = <pallet_message_queue::Pallet<Runtime> as QueueFootprintQuery<
128 AggregateMessageOrigin,
129 >>::footprint(AggregateMessageOrigin::Here);
130
131 book_state.ready_pages >= MESSAGE_QUEUE_CONGESTION_THRESHOLD
132 }
133
134 fn suspend_bridge(_local_origin: &Location, _bridge: BridgeId) -> Result<(), Self::Error> {
135 Ok(())
138 }
139
140 fn resume_bridge(_local_origin: &Location, _bridge: BridgeId) -> Result<(), Self::Error> {
141 Ok(())
142 }
143}