Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Fee and tip represented as asset ID inside AssetTxFeePaid #13083

Merged
merged 7 commits into from
Feb 2, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ impl pallet_asset_tx_payment::Config for Runtime {
pallet_assets::BalanceToAssetBalance<Balances, Runtime, ConvertInto>,
CreditToBlockAuthor,
>;
type BalanceToAsset = pallet_assets::BalanceToAssetBalance<Balances, Runtime, ConvertInto>;
}

parameter_types! {
Expand Down
39 changes: 31 additions & 8 deletions frame/transaction-payment/asset-tx-payment/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use frame_support::{
traits::{
tokens::{
fungibles::{Balanced, CreditOf, Inspect},
WithdrawConsequence,
BalanceConversion, WithdrawConsequence,
},
IsType,
},
Expand All @@ -52,7 +52,7 @@ use frame_support::{
use pallet_transaction_payment::OnChargeTransaction;
use scale_info::TypeInfo;
use sp_runtime::{
traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf, SignedExtension, Zero},
traits::{DispatchInfoOf, Dispatchable, One, PostDispatchInfoOf, SignedExtension, Zero},
transaction_validity::{
InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransaction,
},
Expand Down Expand Up @@ -119,6 +119,12 @@ pub mod pallet {
type Fungibles: Balanced<Self::AccountId>;
/// The actual transaction charging logic that charges the fees.
type OnChargeAssetTransaction: OnChargeAssetTransaction<Self>;
/// Type that implements the `BalanceConversion` trait.
type BalanceToAsset: BalanceConversion<
BalanceOf<Self>,
AssetIdOf<Self>,
AssetBalanceOf<Self>,
>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to look into this a bit more. Not saying it's wrong, but need to look at this whole pallet.

With the DEX pallet, I want this Asset Tx Payment pallet to be more configurable. We want to be able to configure it like,

  • "Convert the native fee balance to an asset amount, using ratio of minimum balances (AssetBalanceOf), and make the payment in the AssetId"
  • "Calculate the fee in the native asset, and then swap AssetId in the Dex, paying the collator in BalanceOf".

Perhaps should log this as a separate issue and do a refactor of this pallet that could have breaking changes to this interface.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is a separate issue.

"Convert the native fee balance to an asset amount, using ratio of minimum balances (AssetBalanceOf), and make the payment in the AssetId"

Especially this would require a new signed extension, because it works in a quite different way than the current implementation. Currently you pay in an asset and you want to start swapping assets before. I'm not even sure if this needs to be part of asset-tx-payment and isn't more its own logic/signed extension in the dex. But yeah, new issue! :D

}

#[pallet::pallet]
Expand All @@ -132,8 +138,8 @@ pub mod pallet {
/// has been paid by `who` in an asset `asset_id`.
AssetTxFeePaid {
who: T::AccountId,
actual_fee: BalanceOf<T>,
tip: BalanceOf<T>,
actual_fee: AssetBalanceOf<T>,
tip: AssetBalanceOf<T>,
asset_id: Option<ChargeAssetIdOf<T>>,
},
}
Expand Down Expand Up @@ -282,18 +288,35 @@ where
let actual_fee = pallet_transaction_payment::Pallet::<T>::compute_actual_fee(
len as u32, info, post_info, tip,
);

let min_converted_fee =
if actual_fee.is_zero() { Zero::zero() } else { One::one() };
Szegoo marked this conversation as resolved.
Show resolved Hide resolved
// Convert the actual fee into the asset used for payment.
let converted_actual_fee =
T::BalanceToAsset::to_asset_balance(actual_fee, already_withdrawn.asset())
.map_err(|_| -> TransactionValidityError {
InvalidTransaction::Payment.into()
})?
.max(min_converted_fee);
// Also convert the tip into the asset used for payment.
let converted_tip =
T::BalanceToAsset::to_asset_balance(tip, already_withdrawn.asset())
.map_err(|_| -> TransactionValidityError {
InvalidTransaction::Payment.into()
})?;

T::OnChargeAssetTransaction::correct_and_deposit_fee(
&who,
info,
post_info,
actual_fee.into(),
tip.into(),
converted_actual_fee,
converted_tip,
already_withdrawn.into(),
)?;
Pallet::<T>::deposit_event(Event::<T>::AssetTxFeePaid {
who,
actual_fee,
tip,
actual_fee: converted_actual_fee,
tip: converted_tip,
asset_id,
});
},
Expand Down
15 changes: 5 additions & 10 deletions frame/transaction-payment/asset-tx-payment/src/payment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ pub trait OnChargeAssetTransaction<T: Config> {
who: &T::AccountId,
dispatch_info: &DispatchInfoOf<T::RuntimeCall>,
post_info: &PostDispatchInfoOf<T::RuntimeCall>,
corrected_fee: Self::Balance,
tip: Self::Balance,
corrected_fee: AssetBalanceOf<T>,
tip: AssetBalanceOf<T>,
already_withdrawn: Self::LiquidityInfo,
) -> Result<(), TransactionValidityError>;
}
Expand Down Expand Up @@ -144,17 +144,12 @@ where
who: &T::AccountId,
_dispatch_info: &DispatchInfoOf<T::RuntimeCall>,
_post_info: &PostDispatchInfoOf<T::RuntimeCall>,
corrected_fee: Self::Balance,
_tip: Self::Balance,
corrected_fee: AssetBalanceOf<T>,
_tip: AssetBalanceOf<T>,
paid: Self::LiquidityInfo,
) -> Result<(), TransactionValidityError> {
let min_converted_fee = if corrected_fee.is_zero() { Zero::zero() } else { One::one() };
// Convert the corrected fee into the asset used for payment.
let converted_fee = CON::to_asset_balance(corrected_fee, paid.asset())
.map_err(|_| -> TransactionValidityError { InvalidTransaction::Payment.into() })?
Szegoo marked this conversation as resolved.
Show resolved Hide resolved
.max(min_converted_fee);
// Calculate how much refund we should return.
let (final_fee, refund) = paid.split(converted_fee);
let (final_fee, refund) = paid.split(corrected_fee);
// Refund to the account that paid the fees. If this fails, the account might have dropped
// below the existential balance. In that case we don't refund anything.
let _ = <T::Fungibles as Balanced<T::AccountId>>::resolve(who, refund);
Expand Down
1 change: 1 addition & 0 deletions frame/transaction-payment/asset-tx-payment/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ impl Config for Runtime {
pallet_assets::BalanceToAssetBalance<Balances, Runtime, ConvertInto>,
CreditToBlockAuthor,
>;
type BalanceToAsset = pallet_assets::BalanceToAssetBalance<Balances, Runtime, ConvertInto>;
}

pub struct ExtBuilder {
Expand Down