mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 13:27:57 +00:00
[FRAME] Short-circuit fungible self transfer (#2118)
Changes: - Change the fungible(s) logic to treat a self-transfer as No-OP (as long as all pre-checks pass). Note that the self-transfer case will not emit an event since no state was changed. --------- Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
This commit is contained in:
committed by
GitHub
parent
4f05f9a686
commit
c66ae375e6
@@ -219,7 +219,7 @@ impl<
|
||||
impl<
|
||||
F: fungibles::Mutate<AccountId>,
|
||||
A: Get<<F as fungibles::Inspect<AccountId>>::AssetId>,
|
||||
AccountId,
|
||||
AccountId: Eq,
|
||||
> Mutate<AccountId> for ItemOf<F, A, AccountId>
|
||||
{
|
||||
fn mint_into(who: &AccountId, amount: Self::Balance) -> Result<Self::Balance, DispatchError> {
|
||||
|
||||
@@ -235,7 +235,10 @@ pub trait Unbalanced<AccountId>: Inspect<AccountId> {
|
||||
}
|
||||
|
||||
/// Trait for providing a basic fungible asset.
|
||||
pub trait Mutate<AccountId>: Inspect<AccountId> + Unbalanced<AccountId> {
|
||||
pub trait Mutate<AccountId>: Inspect<AccountId> + Unbalanced<AccountId>
|
||||
where
|
||||
AccountId: Eq,
|
||||
{
|
||||
/// Increase the balance of `who` by exactly `amount`, minting new tokens. If that isn't
|
||||
/// possible then an `Err` is returned and nothing is changed.
|
||||
fn mint_into(who: &AccountId, amount: Self::Balance) -> Result<Self::Balance, DispatchError> {
|
||||
@@ -303,6 +306,9 @@ pub trait Mutate<AccountId>: Inspect<AccountId> + Unbalanced<AccountId> {
|
||||
}
|
||||
|
||||
/// Transfer funds from one account into another.
|
||||
///
|
||||
/// A transfer where the source and destination account are identical is treated as No-OP after
|
||||
/// checking the preconditions.
|
||||
fn transfer(
|
||||
source: &AccountId,
|
||||
dest: &AccountId,
|
||||
@@ -311,6 +317,10 @@ pub trait Mutate<AccountId>: Inspect<AccountId> + Unbalanced<AccountId> {
|
||||
) -> Result<Self::Balance, DispatchError> {
|
||||
let _extra = Self::can_withdraw(source, amount).into_result(preservation != Expendable)?;
|
||||
Self::can_deposit(dest, amount, Extant).into_result()?;
|
||||
if source == dest {
|
||||
return Ok(amount)
|
||||
}
|
||||
|
||||
Self::decrease_balance(source, amount, BestEffort, preservation, Polite)?;
|
||||
// This should never fail as we checked `can_deposit` earlier. But we do a best-effort
|
||||
// anyway.
|
||||
|
||||
@@ -250,7 +250,10 @@ pub trait Unbalanced<AccountId>: Inspect<AccountId> {
|
||||
}
|
||||
|
||||
/// Trait for providing a basic fungible asset.
|
||||
pub trait Mutate<AccountId>: Inspect<AccountId> + Unbalanced<AccountId> {
|
||||
pub trait Mutate<AccountId>: Inspect<AccountId> + Unbalanced<AccountId>
|
||||
where
|
||||
AccountId: Eq,
|
||||
{
|
||||
/// Increase the balance of `who` by exactly `amount`, minting new tokens. If that isn't
|
||||
/// possible then an `Err` is returned and nothing is changed.
|
||||
fn mint_into(
|
||||
@@ -353,6 +356,9 @@ pub trait Mutate<AccountId>: Inspect<AccountId> + Unbalanced<AccountId> {
|
||||
}
|
||||
|
||||
/// Transfer funds from one account into another.
|
||||
///
|
||||
/// A transfer where the source and destination account are identical is treated as No-OP after
|
||||
/// checking the preconditions.
|
||||
fn transfer(
|
||||
asset: Self::AssetId,
|
||||
source: &AccountId,
|
||||
@@ -363,6 +369,10 @@ pub trait Mutate<AccountId>: Inspect<AccountId> + Unbalanced<AccountId> {
|
||||
let _extra = Self::can_withdraw(asset.clone(), source, amount)
|
||||
.into_result(preservation != Expendable)?;
|
||||
Self::can_deposit(asset.clone(), dest, amount, Extant).into_result()?;
|
||||
if source == dest {
|
||||
return Ok(amount)
|
||||
}
|
||||
|
||||
Self::decrease_balance(asset.clone(), source, amount, BestEffort, preservation, Polite)?;
|
||||
// This should never fail as we checked `can_deposit` earlier. But we do a best-effort
|
||||
// anyway.
|
||||
|
||||
@@ -82,8 +82,13 @@ pub enum PaymentStatus {
|
||||
}
|
||||
|
||||
/// Simple implementation of `Pay` which makes a payment from a "pot" - i.e. a single account.
|
||||
pub struct PayFromAccount<F, A>(sp_std::marker::PhantomData<(F, A)>);
|
||||
impl<A: TypedGet, F: fungible::Mutate<A::Type>> Pay for PayFromAccount<F, A> {
|
||||
pub struct PayFromAccount<F, A>(core::marker::PhantomData<(F, A)>);
|
||||
impl<A, F> Pay for PayFromAccount<F, A>
|
||||
where
|
||||
A: TypedGet,
|
||||
F: fungible::Mutate<A::Type>,
|
||||
A::Type: Eq,
|
||||
{
|
||||
type Balance = F::Balance;
|
||||
type Beneficiary = A::Type;
|
||||
type AssetKind = ();
|
||||
@@ -110,11 +115,12 @@ impl<A: TypedGet, F: fungible::Mutate<A::Type>> Pay for PayFromAccount<F, A> {
|
||||
|
||||
/// Simple implementation of `Pay` for assets which makes a payment from a "pot" - i.e. a single
|
||||
/// account.
|
||||
pub struct PayAssetFromAccount<F, A>(sp_std::marker::PhantomData<(F, A)>);
|
||||
pub struct PayAssetFromAccount<F, A>(core::marker::PhantomData<(F, A)>);
|
||||
impl<A, F> frame_support::traits::tokens::Pay for PayAssetFromAccount<F, A>
|
||||
where
|
||||
A: TypedGet,
|
||||
F: fungibles::Mutate<A::Type> + fungibles::Create<A::Type>,
|
||||
A::Type: Eq,
|
||||
{
|
||||
type Balance = F::Balance;
|
||||
type Beneficiary = A::Type;
|
||||
|
||||
Reference in New Issue
Block a user