use bp_header_chain::SubmitFinalityProofInfo;
use bp_messages::MessagesCallInfo;
use bp_parachains::SubmitParachainHeadsInfo;
use bp_runtime::StaticStrProvider;
use codec::{Decode, Encode};
use core::fmt::Debug;
use frame_support::{dispatch::CallableCallFor, traits::IsSubType, weights::Weight, DebugNoBound};
use frame_system::Config as SystemConfig;
use pallet_utility::{Call as UtilityCall, Pallet as UtilityPallet};
use sp_runtime::{
traits::Get,
transaction_validity::{TransactionPriority, TransactionValidityError},
};
use sp_std::{marker::PhantomData, vec, vec::Vec};
#[derive(PartialEq, DebugNoBound)]
pub enum ExtensionCallInfo<RemoteGrandpaChainBlockNumber: Debug, LaneId: Clone + Copy + Debug> {
AllFinalityAndMsgs(
SubmitFinalityProofInfo<RemoteGrandpaChainBlockNumber>,
SubmitParachainHeadsInfo,
MessagesCallInfo<LaneId>,
),
RelayFinalityAndMsgs(
SubmitFinalityProofInfo<RemoteGrandpaChainBlockNumber>,
MessagesCallInfo<LaneId>,
),
ParachainFinalityAndMsgs(SubmitParachainHeadsInfo, MessagesCallInfo<LaneId>),
Msgs(MessagesCallInfo<LaneId>),
}
impl<RemoteGrandpaChainBlockNumber: Clone + Copy + Debug, LaneId: Clone + Copy + Debug>
ExtensionCallInfo<RemoteGrandpaChainBlockNumber, LaneId>
{
pub fn is_receive_messages_proof_call(&self) -> bool {
match self.messages_call_info() {
MessagesCallInfo::ReceiveMessagesProof(_) => true,
MessagesCallInfo::ReceiveMessagesDeliveryProof(_) => false,
}
}
pub fn submit_finality_proof_info(
&self,
) -> Option<SubmitFinalityProofInfo<RemoteGrandpaChainBlockNumber>> {
match *self {
Self::AllFinalityAndMsgs(info, _, _) => Some(info),
Self::RelayFinalityAndMsgs(info, _) => Some(info),
_ => None,
}
}
pub fn submit_parachain_heads_info(&self) -> Option<&SubmitParachainHeadsInfo> {
match self {
Self::AllFinalityAndMsgs(_, info, _) => Some(info),
Self::ParachainFinalityAndMsgs(info, _) => Some(info),
_ => None,
}
}
pub fn messages_call_info(&self) -> &MessagesCallInfo<LaneId> {
match self {
Self::AllFinalityAndMsgs(_, _, info) => info,
Self::RelayFinalityAndMsgs(_, info) => info,
Self::ParachainFinalityAndMsgs(_, info) => info,
Self::Msgs(info) => info,
}
}
}
#[derive(Default, Debug)]
pub struct ExtensionCallData {
pub extra_weight: Weight,
pub extra_size: u32,
}
pub trait ExtensionConfig {
type IdProvider: StaticStrProvider;
type Runtime: frame_system::Config;
type BridgeRelayersPalletInstance: 'static;
type BridgeMessagesPalletInstance: 'static;
type PriorityBoostPerMessage: Get<TransactionPriority>;
type RemoteGrandpaChainBlockNumber: Clone + Copy + Debug;
type LaneId: Clone + Copy + Decode + Encode + Debug;
fn parse_and_check_for_obsolete_call(
call: &<Self::Runtime as SystemConfig>::RuntimeCall,
) -> Result<
Option<ExtensionCallInfo<Self::RemoteGrandpaChainBlockNumber, Self::LaneId>>,
TransactionValidityError,
>;
fn check_obsolete_parsed_call(
call: &<Self::Runtime as SystemConfig>::RuntimeCall,
) -> Result<&<Self::Runtime as SystemConfig>::RuntimeCall, TransactionValidityError>;
fn check_call_result(
call_info: &ExtensionCallInfo<Self::RemoteGrandpaChainBlockNumber, Self::LaneId>,
call_data: &mut ExtensionCallData,
relayer: &<Self::Runtime as SystemConfig>::AccountId,
) -> bool;
}
pub trait BatchCallUnpacker<Runtime: frame_system::Config> {
fn unpack(call: &Runtime::RuntimeCall, max_packed_calls: u32) -> Vec<&Runtime::RuntimeCall>;
}
pub struct RuntimeWithUtilityPallet<Runtime>(PhantomData<Runtime>);
impl<Runtime> BatchCallUnpacker<Runtime> for RuntimeWithUtilityPallet<Runtime>
where
Runtime: pallet_utility::Config<RuntimeCall = <Runtime as SystemConfig>::RuntimeCall>,
<Runtime as SystemConfig>::RuntimeCall:
IsSubType<CallableCallFor<UtilityPallet<Runtime>, Runtime>>,
{
fn unpack(
call: &<Runtime as frame_system::Config>::RuntimeCall,
max_packed_calls: u32,
) -> Vec<&<Runtime as frame_system::Config>::RuntimeCall> {
match call.is_sub_type() {
Some(UtilityCall::<Runtime>::batch_all { ref calls })
if calls.len() <= max_packed_calls as usize =>
{
calls.iter().collect()
},
Some(_) => vec![],
None => vec![call],
}
}
}
impl<Runtime: frame_system::Config> BatchCallUnpacker<Runtime> for () {
fn unpack(call: &Runtime::RuntimeCall, _max_packed_calls: u32) -> Vec<&Runtime::RuntimeCall> {
vec![call]
}
}