1use bp_header_chain::SubmitFinalityProofInfo;
21use bp_messages::MessagesCallInfo;
22use bp_parachains::SubmitParachainHeadsInfo;
23use bp_runtime::StaticStrProvider;
24use codec::{Decode, Encode};
25use frame_support::{
26 dispatch::CallableCallFor, traits::IsSubType, weights::Weight, RuntimeDebugNoBound,
27};
28use frame_system::Config as SystemConfig;
29use pallet_utility::{Call as UtilityCall, Pallet as UtilityPallet};
30use sp_runtime::{
31 traits::Get,
32 transaction_validity::{TransactionPriority, TransactionValidityError},
33 RuntimeDebug,
34};
35use sp_std::{fmt::Debug, marker::PhantomData, vec, vec::Vec};
36
37#[derive(PartialEq, RuntimeDebugNoBound)]
39pub enum ExtensionCallInfo<RemoteGrandpaChainBlockNumber: Debug, LaneId: Clone + Copy + Debug> {
40 AllFinalityAndMsgs(
42 SubmitFinalityProofInfo<RemoteGrandpaChainBlockNumber>,
43 SubmitParachainHeadsInfo,
44 MessagesCallInfo<LaneId>,
45 ),
46 RelayFinalityAndMsgs(
48 SubmitFinalityProofInfo<RemoteGrandpaChainBlockNumber>,
49 MessagesCallInfo<LaneId>,
50 ),
51 ParachainFinalityAndMsgs(SubmitParachainHeadsInfo, MessagesCallInfo<LaneId>),
55 Msgs(MessagesCallInfo<LaneId>),
57}
58
59impl<RemoteGrandpaChainBlockNumber: Clone + Copy + Debug, LaneId: Clone + Copy + Debug>
60 ExtensionCallInfo<RemoteGrandpaChainBlockNumber, LaneId>
61{
62 pub fn is_receive_messages_proof_call(&self) -> bool {
64 match self.messages_call_info() {
65 MessagesCallInfo::ReceiveMessagesProof(_) => true,
66 MessagesCallInfo::ReceiveMessagesDeliveryProof(_) => false,
67 }
68 }
69
70 pub fn submit_finality_proof_info(
72 &self,
73 ) -> Option<SubmitFinalityProofInfo<RemoteGrandpaChainBlockNumber>> {
74 match *self {
75 Self::AllFinalityAndMsgs(info, _, _) => Some(info),
76 Self::RelayFinalityAndMsgs(info, _) => Some(info),
77 _ => None,
78 }
79 }
80
81 pub fn submit_parachain_heads_info(&self) -> Option<&SubmitParachainHeadsInfo> {
83 match self {
84 Self::AllFinalityAndMsgs(_, info, _) => Some(info),
85 Self::ParachainFinalityAndMsgs(info, _) => Some(info),
86 _ => None,
87 }
88 }
89
90 pub fn messages_call_info(&self) -> &MessagesCallInfo<LaneId> {
92 match self {
93 Self::AllFinalityAndMsgs(_, _, info) => info,
94 Self::RelayFinalityAndMsgs(_, info) => info,
95 Self::ParachainFinalityAndMsgs(_, info) => info,
96 Self::Msgs(info) => info,
97 }
98 }
99}
100
101#[derive(Default, RuntimeDebug)]
103pub struct ExtensionCallData {
104 pub extra_weight: Weight,
108 pub extra_size: u32,
112}
113
114pub trait ExtensionConfig {
121 type IdProvider: StaticStrProvider;
123 type Runtime: frame_system::Config;
126 type BridgeRelayersPalletInstance: 'static;
128 type BridgeMessagesPalletInstance: 'static;
130 type PriorityBoostPerMessage: Get<TransactionPriority>;
133 type RemoteGrandpaChainBlockNumber: Clone + Copy + Debug;
138 type LaneId: Clone + Copy + Decode + Encode + Debug;
140
141 fn parse_and_check_for_obsolete_call(
144 call: &<Self::Runtime as SystemConfig>::RuntimeCall,
145 ) -> Result<
146 Option<ExtensionCallInfo<Self::RemoteGrandpaChainBlockNumber, Self::LaneId>>,
147 TransactionValidityError,
148 >;
149
150 fn check_obsolete_parsed_call(
152 call: &<Self::Runtime as SystemConfig>::RuntimeCall,
153 ) -> Result<&<Self::Runtime as SystemConfig>::RuntimeCall, TransactionValidityError>;
154
155 fn check_call_result(
158 call_info: &ExtensionCallInfo<Self::RemoteGrandpaChainBlockNumber, Self::LaneId>,
159 call_data: &mut ExtensionCallData,
160 relayer: &<Self::Runtime as SystemConfig>::AccountId,
161 ) -> bool;
162}
163
164pub trait BatchCallUnpacker<Runtime: frame_system::Config> {
166 fn unpack(call: &Runtime::RuntimeCall, max_packed_calls: u32) -> Vec<&Runtime::RuntimeCall>;
168}
169
170pub struct RuntimeWithUtilityPallet<Runtime>(PhantomData<Runtime>);
172
173impl<Runtime> BatchCallUnpacker<Runtime> for RuntimeWithUtilityPallet<Runtime>
174where
175 Runtime: pallet_utility::Config<RuntimeCall = <Runtime as SystemConfig>::RuntimeCall>,
176 <Runtime as SystemConfig>::RuntimeCall:
177 IsSubType<CallableCallFor<UtilityPallet<Runtime>, Runtime>>,
178{
179 fn unpack(
180 call: &<Runtime as frame_system::Config>::RuntimeCall,
181 max_packed_calls: u32,
182 ) -> Vec<&<Runtime as frame_system::Config>::RuntimeCall> {
183 match call.is_sub_type() {
184 Some(UtilityCall::<Runtime>::batch_all { ref calls })
185 if calls.len() <= max_packed_calls as usize =>
186 calls.iter().collect(),
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}