git.delta.rocks / unique-network / refs/commits / 90fcef986d5a

difftreelog

source

pallets/nft-charge-transaction/src/lib.rs6.1 KiBsourcehistory
1//2// This file is subject to the terms and conditions defined in3// file 'LICENSE', which is part of this source code package.4//56#![cfg_attr(not(feature = "std"), no_std)]78#[cfg(feature = "std")]9pub use std::*;1011#[cfg(feature = "std")]12pub use serde::*;1314#[cfg(feature = "runtime-benchmarks")]15mod benchmarking;1617use codec::{Decode, Encode};18use frame_support::traits::Get;19use frame_support::{20	decl_module, decl_storage,21	weights::{22		DispatchInfo, PostDispatchInfo, DispatchClass23	}24};25use sp_runtime::{26	traits::{ 27		DispatchInfoOf, Dispatchable, PostDispatchInfoOf, Saturating, SaturatedConversion, SignedExtension, Zero,28	},29	transaction_validity::{ 30		TransactionPriority, TransactionValidity, TransactionValidityError, ValidTransaction,31	},32	FixedPointOperand, DispatchResult33};34use pallet_transaction_payment::OnChargeTransaction;35use sp_std::prelude::*;363738pub trait Config: frame_system::Config + 39    pallet_nft_transaction_payment::Config40{4142}4344decl_storage! {45    trait Store for Module<T: Config> as NftTransactionPayment46    {}47}4849decl_module! {5051	pub struct Module<T: Config> for enum Call 52    where 53		origin: T::Origin,54    {}55}5657type BalanceOf<T> = <<T as pallet_transaction_payment::Config>::OnChargeTransaction as pallet_transaction_payment::OnChargeTransaction<T>>::Balance;5859/// Require the transactor pay for themselves and maybe include a tip to gain additional priority60/// in the queue.61#[derive(Encode, Decode, Clone, Eq, PartialEq)]62pub struct ChargeTransactionPayment<T: Config>(#[codec(compact)] BalanceOf<T>);6364impl<T: Config + Send + Sync> sp_std::fmt::Debug 65    for ChargeTransactionPayment<T>66{67	#[cfg(feature = "std")]68	fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {69		write!(f, "ChargeTransactionPayment<{:?}>", self.0)70	}71	#[cfg(not(feature = "std"))]72	fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {73		Ok(())74	}75}7677impl<T: Config> ChargeTransactionPayment<T>78where79	T::Call: Dispatchable<Info=DispatchInfo, PostInfo=PostDispatchInfo>,80    BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,81{82    fn traditional_fee(83        len: usize,84        info: &DispatchInfoOf<T::Call>,85        tip: BalanceOf<T>,86    ) -> BalanceOf<T>87    where88        T::Call: Dispatchable<Info = DispatchInfo>,89    {90        <pallet_transaction_payment::Module<T>>::compute_fee(len as u32, info, tip)91    }9293	fn get_priority(len: usize, info: &DispatchInfoOf<T::Call>, final_fee: BalanceOf<T>) -> TransactionPriority {94        let weight_saturation = T::BlockWeights::get().max_block / info.weight.max(1);95        let max_block_length = *T::BlockLength::get().max.get(DispatchClass::Normal);96        let len_saturation = max_block_length as u64 / (len as u64).max(1);97        let coefficient: BalanceOf<T> = weight_saturation98            .min(len_saturation)99            .saturated_into::<BalanceOf<T>>();100        final_fee101            .saturating_mul(coefficient)102            .saturated_into::<TransactionPriority>()103    }104105    fn withdraw_fee(106        &self,107        who: &T::AccountId,108        call: &T::Call,109        info: &DispatchInfoOf<T::Call>,110        len: usize,111	) -> Result<112		(113			BalanceOf<T>,114			<<T as pallet_transaction_payment::Config>::OnChargeTransaction as pallet_transaction_payment::OnChargeTransaction<T>>::LiquidityInfo,115		),116		TransactionValidityError,117	> {118        let tip = self.0;119120        let fee = Self::traditional_fee(len, info, tip);121122        // Only mess with balances if fee is not zero.123        if fee.is_zero() {124            return <<T as pallet_transaction_payment::Config>::OnChargeTransaction as pallet_transaction_payment::OnChargeTransaction<T>>::withdraw_fee(who, call, info, fee, tip)125			.map(|i| (fee, i));126        }127128        // Determine who is paying transaction fee based on ecnomic model129		// Parse call to extract collection ID and access collection sponsor	130		let sponsor = <pallet_nft_transaction_payment::Module<T>>::withdraw_type(who, call);131132        let who_pays_fee = sponsor.unwrap_or_else(|| who.clone());133134		<<T as pallet_transaction_payment::Config>::OnChargeTransaction as pallet_transaction_payment::OnChargeTransaction<T>>::withdraw_fee(&who_pays_fee, call, info, fee, tip)135			.map(|i| (fee, i))136    }137}138139impl<T: Config + Send + Sync> SignedExtension140    for ChargeTransactionPayment<T>141where142    BalanceOf<T>: Send + Sync + From<u64> + FixedPointOperand,143	T::Call: Dispatchable<Info=DispatchInfo, PostInfo=PostDispatchInfo>,144{145    const IDENTIFIER: &'static str = "ChargeTransactionPayment";146    type AccountId = T::AccountId;147    type Call = T::Call;148    type AdditionalSigned = ();149    type Pre = (150        // tip151        BalanceOf<T>,152        // who pays fee153        Self::AccountId,154		// imbalance resulting from withdrawing the fee155		<<T as pallet_transaction_payment::Config>::OnChargeTransaction as pallet_transaction_payment::OnChargeTransaction<T>>::LiquidityInfo,156    );157    fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> {158        Ok(())159    }160161    fn validate(162        &self,163        who: &Self::AccountId,164        call: &Self::Call,165        info: &DispatchInfoOf<Self::Call>,166        len: usize,167    ) -> TransactionValidity {168		let (fee, _) = self.withdraw_fee(who, call, info, len)?;169		Ok(ValidTransaction {170			priority: Self::get_priority(len, info, fee),171			..Default::default()172		})173    }174175    fn pre_dispatch(176        self,177        who: &Self::AccountId,178        call: &Self::Call,179        info: &DispatchInfoOf<Self::Call>,180        len: usize,181    ) -> Result<Self::Pre, TransactionValidityError> {182        let (_fee, imbalance) = self.withdraw_fee(who, call, info, len)?;183        Ok((self.0, who.clone(), imbalance))184    }185186    fn post_dispatch(187        pre: Self::Pre,188        info: &DispatchInfoOf<Self::Call>,189        post_info: &PostDispatchInfoOf<Self::Call>,190        len: usize,191        _result: &DispatchResult,192    ) -> Result<(), TransactionValidityError> {193		let (tip, who, imbalance) = pre;194		let actual_fee = pallet_transaction_payment::Pallet::<T>::compute_actual_fee(195			len as u32,196			info,197			post_info,198			tip,199		);200		<T as pallet_transaction_payment::Config>::OnChargeTransaction::correct_and_deposit_fee(&who, info, post_info, actual_fee, tip, imbalance)?;201		Ok(())202    }203}