mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 02:07:56 +00:00
Refactor the asset-conversion-tx-payment pallet (#14558)
* Code refactoring * Fix imports * Typo * Update frame/asset-conversion/src/types.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Sync docs --------- Co-authored-by: parity-processbot <> Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
This commit is contained in:
@@ -69,6 +69,8 @@ mod mock;
|
||||
mod tests;
|
||||
|
||||
mod payment;
|
||||
use frame_support::traits::tokens::AssetId;
|
||||
use pallet_asset_conversion::MultiAssetIdConverter;
|
||||
pub use payment::*;
|
||||
|
||||
/// Type aliases used for interaction with `OnChargeTransaction`.
|
||||
@@ -116,7 +118,9 @@ pub mod pallet {
|
||||
use super::*;
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config: frame_system::Config + pallet_transaction_payment::Config {
|
||||
pub trait Config:
|
||||
frame_system::Config + pallet_transaction_payment::Config + pallet_asset_conversion::Config
|
||||
{
|
||||
/// The overarching event type.
|
||||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
|
||||
/// The fungibles instance used to pay for transactions in assets.
|
||||
@@ -187,12 +191,12 @@ where
|
||||
debug_assert!(self.tip <= fee, "tip should be included in the computed fee");
|
||||
if fee.is_zero() {
|
||||
Ok((fee, InitialPayment::Nothing))
|
||||
} else if let Some(asset_id) = self.asset_id {
|
||||
} else if let Some(asset_id) = &self.asset_id {
|
||||
T::OnChargeAssetTransaction::withdraw_fee(
|
||||
who,
|
||||
call,
|
||||
info,
|
||||
asset_id,
|
||||
asset_id.clone(),
|
||||
fee.into(),
|
||||
self.tip.into(),
|
||||
)
|
||||
@@ -324,7 +328,7 @@ where
|
||||
tip.into(),
|
||||
used_for_fee.into(),
|
||||
received_exchanged.into(),
|
||||
asset_id,
|
||||
asset_id.clone(),
|
||||
asset_consumed.into(),
|
||||
)?;
|
||||
|
||||
|
||||
@@ -17,26 +17,25 @@
|
||||
use super::*;
|
||||
use crate::Config;
|
||||
|
||||
use codec::FullCodec;
|
||||
use frame_support::{
|
||||
ensure,
|
||||
traits::{fungible::Inspect, fungibles::SwapNative, tokens::Balance},
|
||||
traits::{fungible::Inspect, tokens::Balance},
|
||||
unsigned::TransactionValidityError,
|
||||
};
|
||||
use scale_info::TypeInfo;
|
||||
use pallet_asset_conversion::Swap;
|
||||
use sp_runtime::{
|
||||
traits::{DispatchInfoOf, MaybeSerializeDeserialize, PostDispatchInfoOf, Zero},
|
||||
traits::{DispatchInfoOf, PostDispatchInfoOf, Zero},
|
||||
transaction_validity::InvalidTransaction,
|
||||
Saturating,
|
||||
};
|
||||
use sp_std::{fmt::Debug, marker::PhantomData};
|
||||
use sp_std::marker::PhantomData;
|
||||
|
||||
/// Handle withdrawing, refunding and depositing of transaction fees.
|
||||
pub trait OnChargeAssetTransaction<T: Config> {
|
||||
/// The underlying integer type in which fees are calculated.
|
||||
type Balance: Balance;
|
||||
/// The type used to identify the assets used for transaction payment.
|
||||
type AssetId: FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default + Eq + TypeInfo;
|
||||
type AssetId: AssetId;
|
||||
/// The type used to store the intermediate values between pre- and post-dispatch.
|
||||
type LiquidityInfo;
|
||||
|
||||
@@ -74,8 +73,7 @@ pub trait OnChargeAssetTransaction<T: Config> {
|
||||
) -> Result<AssetBalanceOf<T>, TransactionValidityError>;
|
||||
}
|
||||
|
||||
/// Implements the asset transaction for a balance to asset converter (implementing
|
||||
/// [`SwapNative`]).
|
||||
/// Implements the asset transaction for a balance to asset converter (implementing [`Swap`]).
|
||||
///
|
||||
/// The converter is given the complete fee in terms of the asset used for the transaction.
|
||||
pub struct AssetConversionAdapter<C, CON>(PhantomData<(C, CON)>);
|
||||
@@ -85,8 +83,9 @@ impl<T, C, CON> OnChargeAssetTransaction<T> for AssetConversionAdapter<C, CON>
|
||||
where
|
||||
T: Config,
|
||||
C: Inspect<<T as frame_system::Config>::AccountId>,
|
||||
CON: SwapNative<T::RuntimeOrigin, T::AccountId, BalanceOf<T>, AssetBalanceOf<T>, AssetIdOf<T>>,
|
||||
AssetIdOf<T>: FullCodec + Copy + MaybeSerializeDeserialize + Debug + Default + Eq + TypeInfo,
|
||||
CON: Swap<T::AccountId, T::HigherPrecisionBalance, T::MultiAssetId>,
|
||||
T::HigherPrecisionBalance: From<BalanceOf<T>> + TryInto<AssetBalanceOf<T>>,
|
||||
T::MultiAssetId: From<AssetIdOf<T>>,
|
||||
BalanceOf<T>: IsType<<C as Inspect<<T as frame_system::Config>::AccountId>>::Balance>,
|
||||
{
|
||||
type Balance = BalanceOf<T>;
|
||||
@@ -115,16 +114,20 @@ where
|
||||
let native_asset_required =
|
||||
if C::balance(&who) >= ed.saturating_add(fee.into()) { fee } else { fee + ed.into() };
|
||||
|
||||
let asset_consumed = CON::swap_tokens_for_exact_native(
|
||||
let asset_consumed = CON::swap_tokens_for_exact_tokens(
|
||||
who.clone(),
|
||||
asset_id,
|
||||
native_asset_required,
|
||||
vec![asset_id.into(), T::MultiAssetIdConverter::get_native()],
|
||||
T::HigherPrecisionBalance::from(native_asset_required),
|
||||
None,
|
||||
who.clone(),
|
||||
true,
|
||||
)
|
||||
.map_err(|_| TransactionValidityError::from(InvalidTransaction::Payment))?;
|
||||
|
||||
let asset_consumed = asset_consumed
|
||||
.try_into()
|
||||
.map_err(|_| TransactionValidityError::from(InvalidTransaction::Payment))?;
|
||||
|
||||
ensure!(asset_consumed > Zero::zero(), InvalidTransaction::Payment);
|
||||
|
||||
// charge the fee in native currency
|
||||
@@ -166,17 +169,25 @@ where
|
||||
// If this fails, the account might have dropped below the existential balance or there
|
||||
// is not enough liquidity left in the pool. In that case we don't throw an error and
|
||||
// the account will keep the native currency.
|
||||
match CON::swap_exact_native_for_tokens(
|
||||
match CON::swap_exact_tokens_for_tokens(
|
||||
who.clone(), // we already deposited the native to `who`
|
||||
asset_id, // we want asset_id back
|
||||
swap_back, // amount of the native asset to convert to `asset_id`
|
||||
vec![
|
||||
T::MultiAssetIdConverter::get_native(), // we provide the native
|
||||
asset_id.into(), // we want asset_id back
|
||||
],
|
||||
T::HigherPrecisionBalance::from(swap_back), /* amount of the native asset to
|
||||
* convert to `asset_id` */
|
||||
None, // no minimum amount back
|
||||
who.clone(), // we will refund to `who`
|
||||
false, // no need to keep alive
|
||||
)
|
||||
.ok()
|
||||
{
|
||||
Some(acquired) => asset_refund = acquired,
|
||||
Some(acquired) => {
|
||||
asset_refund = acquired
|
||||
.try_into()
|
||||
.map_err(|_| TransactionValidityError::from(InvalidTransaction::Payment))?;
|
||||
},
|
||||
None => {
|
||||
Pallet::<T>::deposit_event(Event::<T>::AssetRefundFailed {
|
||||
native_amount_kept: swap_back,
|
||||
|
||||
Reference in New Issue
Block a user