use codec::{Compact, Decode, DecodeWithMemTracking, Encode};
use impl_trait_for_tuples::impl_for_tuples;
use pezsp_runtime::{
impl_tx_ext_default,
traits::{Dispatchable, TransactionExtension},
transaction_validity::TransactionValidityError,
};
use pezsp_std::{fmt::Debug, marker::PhantomData};
use scale_info::{StaticTypeInfo, TypeInfo};
pub trait TransactionExtensionSchema:
Encode + Decode + DecodeWithMemTracking + Debug + Eq + Clone + StaticTypeInfo
{
type Payload: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo;
type Implicit: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo;
}
impl TransactionExtensionSchema for () {
type Payload = ();
type Implicit = ();
}
#[derive(Encode, Decode, DecodeWithMemTracking, Clone, Debug, PartialEq, Eq, TypeInfo)]
pub struct GenericTransactionExtensionSchema<P, S>(PhantomData<(P, S)>);
impl<P, S> TransactionExtensionSchema for GenericTransactionExtensionSchema<P, S>
where
P: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo,
S: Encode + Decode + Debug + Eq + Clone + StaticTypeInfo,
{
type Payload = P;
type Implicit = S;
}
pub type CheckNonZeroSender = GenericTransactionExtensionSchema<(), ()>;
pub type CheckSpecVersion = GenericTransactionExtensionSchema<(), u32>;
pub type CheckTxVersion = GenericTransactionExtensionSchema<(), u32>;
pub type CheckGenesis<Hash> = GenericTransactionExtensionSchema<(), Hash>;
pub type CheckEra<Hash> = GenericTransactionExtensionSchema<pezsp_runtime::generic::Era, Hash>;
pub type CheckNonce<TxNonce> = GenericTransactionExtensionSchema<Compact<TxNonce>, ()>;
pub type CheckWeight = GenericTransactionExtensionSchema<(), ()>;
pub type ChargeTransactionPayment<Balance> =
GenericTransactionExtensionSchema<Compact<Balance>, ()>;
pub type PrevalidateAttests = GenericTransactionExtensionSchema<(), ()>;
pub type BridgeRejectObsoleteHeadersAndMessages = GenericTransactionExtensionSchema<(), ()>;
pub type RefundBridgedTeyrchainMessagesSchema = GenericTransactionExtensionSchema<(), ()>;
#[impl_for_tuples(1, 12)]
impl TransactionExtensionSchema for Tuple {
for_tuples!( type Payload = ( #( Tuple::Payload ),* ); );
for_tuples!( type Implicit = ( #( Tuple::Implicit ),* ); );
}
#[derive(Encode, Decode, DecodeWithMemTracking, Debug, PartialEq, Eq, Clone, TypeInfo)]
pub struct GenericTransactionExtension<S: TransactionExtensionSchema> {
pub payload: S::Payload,
#[codec(skip)]
implicit: Option<S::Implicit>,
}
impl<S: TransactionExtensionSchema> GenericTransactionExtension<S> {
pub fn new(payload: S::Payload, implicit: Option<S::Implicit>) -> Self {
Self { payload, implicit }
}
}
impl<S, C> TransactionExtension<C> for GenericTransactionExtension<S>
where
C: Dispatchable,
S: TransactionExtensionSchema,
S::Payload: DecodeWithMemTracking + Send + Sync,
S::Implicit: Send + Sync,
{
const IDENTIFIER: &'static str = "Not needed.";
type Implicit = S::Implicit;
fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
self.implicit
.clone()
.ok_or(pezframe_support::unsigned::TransactionValidityError::Unknown(
pezframe_support::unsigned::UnknownTransaction::Custom(0xFF),
))
}
type Pre = ();
type Val = ();
impl_tx_ext_default!(C; weight validate prepare);
}