pallet_frequency_tx_payment/
payment.rs1use common_primitives::msa::MsaValidator;
2use core::marker::PhantomData;
3use frame_support::traits::tokens::{fungible::Inspect as InspectFungible, Balance};
4
5use super::*;
6use crate::Config;
7
8pub trait OnChargeCapacityTransaction<T: Config> {
10 type Balance: Balance;
12
13 fn withdraw_fee(
15 key: &T::AccountId,
16 fee: Self::Balance,
17 ) -> Result<Self::Balance, TransactionValidityError>;
18
19 fn can_withdraw_fee(
21 key: &T::AccountId,
22 fee: Self::Balance,
23 ) -> Result<(), TransactionValidityError>;
24}
25
26pub struct CapacityAdapter<Curr, Msa>(PhantomData<(Curr, Msa)>);
28
29impl<T, Curr, Msa> OnChargeCapacityTransaction<T> for CapacityAdapter<Curr, Msa>
30where
31 T: Config,
32 Curr: InspectFungible<<T as frame_system::Config>::AccountId>,
33 Msa: MsaValidator<AccountId = <T as frame_system::Config>::AccountId>,
34 BalanceOf<T>: Send + Sync + FixedPointOperand + IsType<CapacityBalanceOf<T>> + MaxEncodedLen,
35{
36 type Balance = BalanceOf<T>;
37
38 fn withdraw_fee(
41 key: &T::AccountId,
42 fee: Self::Balance,
43 ) -> Result<Self::Balance, TransactionValidityError> {
44 let msa_id = Msa::ensure_valid_msa_key(key)
45 .map_err(|_| ChargeFrqTransactionPaymentError::InvalidMsaKey.into())?;
46
47 if T::Capacity::can_replenish(msa_id) {
48 ensure!(
49 T::Capacity::replenish_all_for(msa_id).is_ok(),
50 TransactionValidityError::Invalid(InvalidTransaction::Payment)
51 );
52 }
53
54 ensure!(
55 T::Capacity::deduct(msa_id, fee.into()).is_ok(),
56 TransactionValidityError::Invalid(InvalidTransaction::Payment)
57 );
58
59 Ok(fee)
60 }
61
62 fn can_withdraw_fee(
65 key: &T::AccountId,
66 fee: Self::Balance,
67 ) -> Result<(), TransactionValidityError> {
68 let minimum_balance = Curr::minimum_balance();
69 ensure!(
70 Curr::total_balance(key) >= minimum_balance,
71 TransactionValidityError::Invalid(InvalidTransaction::Payment)
72 );
73
74 let msa_id = Msa::ensure_valid_msa_key(key)
75 .map_err(|_| ChargeFrqTransactionPaymentError::InvalidMsaKey.into())?;
76
77 let available_capacity: Self::Balance = if T::Capacity::can_replenish(msa_id) {
78 T::Capacity::replenishable_balance(msa_id).into()
79 } else {
80 T::Capacity::balance(msa_id).into()
81 };
82
83 ensure!(
84 fee <= available_capacity,
85 TransactionValidityError::Invalid(InvalidTransaction::Payment)
86 );
87 Ok(())
88 }
89}