1use bp_header_chain::SubmitFinalityProofInfo;
21use bp_messages::MessagesCallInfo;
22use bp_parachains::SubmitParachainHeadsInfo;
23use bp_runtime::StaticStrProvider;
24use codec::{Decode, Encode};
25use core::fmt::Debug;
26use frame_support::{dispatch::CallableCallFor, traits::IsSubType, weights::Weight, DebugNoBound};
27use frame_system::Config as SystemConfig;
28use pallet_utility::{Call as UtilityCall, Pallet as UtilityPallet};
29use sp_runtime::{
30 traits::Get,
31 transaction_validity::{TransactionPriority, TransactionValidityError},
32};
33use sp_std::{marker::PhantomData, vec, vec::Vec};
34
35#[derive(PartialEq, DebugNoBound)]
37pub enum ExtensionCallInfo<RemoteGrandpaChainBlockNumber: Debug, LaneId: Clone + Copy + Debug> {
38 AllFinalityAndMsgs(
40 SubmitFinalityProofInfo<RemoteGrandpaChainBlockNumber>,
41 SubmitParachainHeadsInfo,
42 MessagesCallInfo<LaneId>,
43 ),
44 RelayFinalityAndMsgs(
46 SubmitFinalityProofInfo<RemoteGrandpaChainBlockNumber>,
47 MessagesCallInfo<LaneId>,
48 ),
49 ParachainFinalityAndMsgs(SubmitParachainHeadsInfo, MessagesCallInfo<LaneId>),
53 Msgs(MessagesCallInfo<LaneId>),
55}
56
57impl<RemoteGrandpaChainBlockNumber: Clone + Copy + Debug, LaneId: Clone + Copy + Debug>
58 ExtensionCallInfo<RemoteGrandpaChainBlockNumber, LaneId>
59{
60 pub fn is_receive_messages_proof_call(&self) -> bool {
62 match self.messages_call_info() {
63 MessagesCallInfo::ReceiveMessagesProof(_) => true,
64 MessagesCallInfo::ReceiveMessagesDeliveryProof(_) => false,
65 }
66 }
67
68 pub fn submit_finality_proof_info(
70 &self,
71 ) -> Option<SubmitFinalityProofInfo<RemoteGrandpaChainBlockNumber>> {
72 match *self {
73 Self::AllFinalityAndMsgs(info, _, _) => Some(info),
74 Self::RelayFinalityAndMsgs(info, _) => Some(info),
75 _ => None,
76 }
77 }
78
79 pub fn submit_parachain_heads_info(&self) -> Option<&SubmitParachainHeadsInfo> {
81 match self {
82 Self::AllFinalityAndMsgs(_, info, _) => Some(info),
83 Self::ParachainFinalityAndMsgs(info, _) => Some(info),
84 _ => None,
85 }
86 }
87
88 pub fn messages_call_info(&self) -> &MessagesCallInfo<LaneId> {
90 match self {
91 Self::AllFinalityAndMsgs(_, _, info) => info,
92 Self::RelayFinalityAndMsgs(_, info) => info,
93 Self::ParachainFinalityAndMsgs(_, info) => info,
94 Self::Msgs(info) => info,
95 }
96 }
97}
98
99#[derive(Default, Debug)]
101pub struct ExtensionCallData {
102 pub extra_weight: Weight,
106 pub extra_size: u32,
110}
111
112pub trait ExtensionConfig {
119 type IdProvider: StaticStrProvider;
121 type Runtime: frame_system::Config;
124 type BridgeRelayersPalletInstance: 'static;
126 type BridgeMessagesPalletInstance: 'static;
128 type PriorityBoostPerMessage: Get<TransactionPriority>;
131 type RemoteGrandpaChainBlockNumber: Clone + Copy + Debug;
136 type LaneId: Clone + Copy + Decode + Encode + Debug;
138
139 fn parse_and_check_for_obsolete_call(
142 call: &<Self::Runtime as SystemConfig>::RuntimeCall,
143 ) -> Result<
144 Option<ExtensionCallInfo<Self::RemoteGrandpaChainBlockNumber, Self::LaneId>>,
145 TransactionValidityError,
146 >;
147
148 fn check_obsolete_parsed_call(
150 call: &<Self::Runtime as SystemConfig>::RuntimeCall,
151 ) -> Result<&<Self::Runtime as SystemConfig>::RuntimeCall, TransactionValidityError>;
152
153 fn check_call_result(
156 call_info: &ExtensionCallInfo<Self::RemoteGrandpaChainBlockNumber, Self::LaneId>,
157 call_data: &mut ExtensionCallData,
158 relayer: &<Self::Runtime as SystemConfig>::AccountId,
159 ) -> bool;
160}
161
162pub trait BatchCallUnpacker<Runtime: frame_system::Config> {
164 fn unpack(call: &Runtime::RuntimeCall, max_packed_calls: u32) -> Vec<&Runtime::RuntimeCall>;
166}
167
168pub struct RuntimeWithUtilityPallet<Runtime>(PhantomData<Runtime>);
170
171impl<Runtime> BatchCallUnpacker<Runtime> for RuntimeWithUtilityPallet<Runtime>
172where
173 Runtime: pallet_utility::Config<RuntimeCall = <Runtime as SystemConfig>::RuntimeCall>,
174 <Runtime as SystemConfig>::RuntimeCall:
175 IsSubType<CallableCallFor<UtilityPallet<Runtime>, Runtime>>,
176{
177 fn unpack(
178 call: &<Runtime as frame_system::Config>::RuntimeCall,
179 max_packed_calls: u32,
180 ) -> Vec<&<Runtime as frame_system::Config>::RuntimeCall> {
181 match call.is_sub_type() {
182 Some(UtilityCall::<Runtime>::batch_all { ref calls })
183 if calls.len() <= max_packed_calls as usize =>
184 {
185 calls.iter().collect()
186 },
187 Some(_) => vec![],
188 None => vec![call],
189 }
190 }
191}
192
193impl<Runtime: frame_system::Config> BatchCallUnpacker<Runtime> for () {
194 fn unpack(call: &Runtime::RuntimeCall, _max_packed_calls: u32) -> Vec<&Runtime::RuntimeCall> {
195 vec![call]
196 }
197}