snowbridge_inbound_queue_primitives/v2/
processor.rs1use super::*;
6use frame_support::traits::Get;
7use sp_runtime::traits::TryConvert;
8use sp_std::marker::PhantomData;
9use xcm::prelude::*;
10
11pub struct XcmMessageProcessor<T, Sender, Executor, Converter, AccountToLocation, TargetLocation>(
15 pub PhantomData<(T, Sender, Executor, Converter, AccountToLocation, TargetLocation)>,
16);
17
18impl<AccountId, T, Sender, Executor, Converter, AccountToLocation, TargetLocation>
19 MessageProcessor<AccountId>
20 for XcmMessageProcessor<T, Sender, Executor, Converter, AccountToLocation, TargetLocation>
21where
22 T: frame_system::Config<AccountId = AccountId>,
23 Sender: SendXcm,
24 Executor: ExecuteXcm<T::RuntimeCall>,
25 Converter: ConvertMessage,
26 AccountToLocation: for<'a> TryConvert<&'a AccountId, Location>,
27 TargetLocation: Get<Location>,
28{
29 fn can_process_message(_relayer: &AccountId, _message: &Message) -> bool {
30 true
31 }
32
33 fn process_message(
34 relayer: AccountId,
35 message: Message,
36 ) -> Result<[u8; 32], MessageProcessorError> {
37 let id = Self::process_xcm(relayer, message)?;
39 Ok(id)
40 }
41}
42
43impl<T, Sender, Executor, Converter, AccountToLocation, TargetLocation>
44 XcmMessageProcessor<T, Sender, Executor, Converter, AccountToLocation, TargetLocation>
45where
46 T: frame_system::Config,
47 Sender: SendXcm,
48 Executor: ExecuteXcm<T::RuntimeCall>,
49 Converter: ConvertMessage,
50 AccountToLocation: for<'a> TryConvert<&'a T::AccountId, Location>,
51 TargetLocation: Get<Location>,
52{
53 pub fn process_xcm(
55 who: T::AccountId,
56 message: Message,
57 ) -> Result<XcmHash, MessageProcessorError> {
58 let xcm = Converter::convert(message).map_err(|error| {
60 tracing::error!(target: LOG_TARGET, ?error, "XCM conversion failed with error");
61 MessageProcessorError::ConvertMessage(error)
62 })?;
63
64 let dest = TargetLocation::get();
66 let message_id = Self::send_xcm(dest.clone(), &who, xcm.clone()).map_err(|error| {
67 tracing::error!(target: LOG_TARGET, ?error, ?dest, ?xcm, "XCM send failed with error");
68 MessageProcessorError::SendMessage(error)
69 })?;
70
71 Ok(message_id)
73 }
74}
75
76impl<T, Sender, Executor, Converter, AccountToLocation, TargetLocation>
77 XcmMessageProcessor<T, Sender, Executor, Converter, AccountToLocation, TargetLocation>
78where
79 T: frame_system::Config,
80 Sender: SendXcm,
81 Executor: ExecuteXcm<T::RuntimeCall>,
82 Converter: ConvertMessage,
83 AccountToLocation: for<'a> TryConvert<&'a T::AccountId, Location>,
84 TargetLocation: Get<Location>,
85{
86 fn send_xcm(
87 dest: Location,
88 fee_payer: &T::AccountId,
89 xcm: Xcm<()>,
90 ) -> Result<XcmHash, SendError> {
91 let fee_payer = AccountToLocation::try_convert(fee_payer).map_err(|err| {
92 tracing::error!(
93 target: LOG_TARGET,
94 ?err,
95 "Failed to convert account to XCM location",
96 );
97 SendError::NotApplicable
98 })?;
99 let (ticket, fee) = validate_send::<Sender>(dest, xcm)?;
100 Executor::charge_fees(fee_payer, fee).map_err(|error| {
101 tracing::error!(
102 target: LOG_TARGET,
103 ?error,
104 "Charging fees failed with error",
105 );
106 SendError::Fees
107 })?;
108 Sender::deliver(ticket)
109 }
110}