Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
29 changes: 15 additions & 14 deletions frame/evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,14 +641,13 @@ pub trait OnChargeEVMTransaction<T: Config> {
/// After the transaction was executed the actual fee can be calculated.
/// This function should refund any overpaid fees and optionally deposit
/// the corrected amount.
/// `actual_priority_fee`: Introduced in EIP1559 to handle the priority tip payment to the block Author.
fn correct_and_deposit_fee(
who: &H160,
corrected_fee: U256,
actual_priority_fee: Option<U256>,
already_withdrawn: Self::LiquidityInfo,
);

/// Introduced in EIP1559 to handle the priority tip payment to the block Author.
fn pay_priority_fee(tip: U256);
}

/// Implements the transaction payment for a pallet implementing the `Currency`
Expand Down Expand Up @@ -692,6 +691,7 @@ where
fn correct_and_deposit_fee(
who: &H160,
corrected_fee: U256,
actual_priority_fee: Option<U256>,
already_withdrawn: Self::LiquidityInfo,
) {
if let Some(paid) = already_withdrawn {
Expand Down Expand Up @@ -730,13 +730,17 @@ where
.offset(refund_imbalance)
.same()
.unwrap_or_else(|_| C::NegativeImbalance::zero());
OU::on_unbalanced(adjusted_paid);
}
}

fn pay_priority_fee(tip: U256) {
let account_id = T::AddressMapping::into_account_id(<Pallet<T>>::find_author());
let _ = C::deposit_into_existing(&account_id, tip.low_u128().unique_saturated_into());
let tip = if let Some(priority_tip) = actual_priority_fee {
priority_tip.low_u128().unique_saturated_into()
} else {
C::Balance::zero()
};

// Call someone else to handle the imbalance (fee and tip separately)
let (tip, base_fee) = adjusted_paid.split(tip);
OU::on_unbalanceds(Some(base_fee).into_iter().chain(Some(tip)));
}
}
}

Expand All @@ -761,12 +765,9 @@ impl<T> OnChargeEVMTransaction<T> for ()
fn correct_and_deposit_fee(
who: &H160,
corrected_fee: U256,
tip: Option<U256>,
already_withdrawn: Self::LiquidityInfo,
) {
<EVMCurrencyAdapter::<<T as Config>::Currency, ()> as OnChargeEVMTransaction<T>>::correct_and_deposit_fee(who, corrected_fee, already_withdrawn)
}

fn pay_priority_fee(tip: U256) {
<EVMCurrencyAdapter::<<T as Config>::Currency, ()> as OnChargeEVMTransaction<T>>::pay_priority_fee(tip);
<EVMCurrencyAdapter::<<T as Config>::Currency, ()> as OnChargeEVMTransaction<T>>::correct_and_deposit_fee(who, corrected_fee, tip, already_withdrawn)
}
}
33 changes: 30 additions & 3 deletions frame/evm/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

use frame_support::{
parameter_types,
traits::{ConstU32, FindAuthor},
traits::{ConstU32, Currency, FindAuthor, OnUnbalanced},
ConsensusEngineId,
};
use sp_core::{H160, H256, U256};
Expand All @@ -29,7 +29,10 @@ use sp_runtime::{
};
use sp_std::{boxed::Box, prelude::*, str::FromStr};

use crate::{EnsureAddressNever, EnsureAddressRoot, FeeCalculator, IdentityAddressMapping};
use crate::{
AddressMapping, EVMCurrencyAdapter, EnsureAddressNever, EnsureAddressRoot, FeeCalculator,
IdentityAddressMapping,
};

type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
type Block = frame_system::mocking::MockBlock<Test>;
Expand Down Expand Up @@ -122,6 +125,30 @@ impl FindAuthor<H160> for FindAuthorTruncated {
}
}

type NegativeImbalance = <Balances as Currency<H160>>::NegativeImbalance;

impl OnUnbalanced<NegativeImbalance> for FindAuthorTruncated {
fn on_nonzero_unbalanced(amount: NegativeImbalance) {
let author = H160::from_str("1234500000000000000000000000000000000000").unwrap();
let author_substrate = <Test as crate::Config>::AddressMapping::into_account_id(author);
Balances::resolve_creating(&author_substrate, amount);
}
}

pub struct DealWithFees;
impl OnUnbalanced<NegativeImbalance> for DealWithFees {
fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {
if let Some(_fees) = fees_then_tips.next() {
// 1. for fee, default to be burned.

// 2. for tips, if any, 100% to author.
if let Some(tips) = fees_then_tips.next() {
FindAuthorTruncated::on_unbalanced(tips);
}
}
}
}

impl crate::Config for Test {
type FeeCalculator = FixedGasPrice;
type GasWeightMapping = ();
Expand All @@ -138,7 +165,7 @@ impl crate::Config for Test {
type PrecompilesValue = ();
type ChainId = ();
type BlockGasLimit = ();
type OnChargeTransaction = ();
type OnChargeTransaction = EVMCurrencyAdapter<Balances, DealWithFees>;
type BlockHashMapping = crate::SubstrateBlockHashMapping<Self>;
type FindAuthor = FindAuthorTruncated;
}
13 changes: 9 additions & 4 deletions frame/evm/src/runner/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,15 @@ impl<T: Config> Runner<T> {
// Refunded 200 - 40 = 160.
// Tip 5 * 6 = 30.
// Burned 200 - (160 + 30) = 10. Which is equivalent to gas_used * base_fee.
T::OnChargeTransaction::correct_and_deposit_fee(&source, actual_fee, fee);
if let Some(actual_priority_fee) = actual_priority_fee {
T::OnChargeTransaction::pay_priority_fee(actual_priority_fee);
}
//
// The `refund` = `fee` - `actual_fee`, and `actual_fee` = `base` + `tip` will be handled by `OnUnbalanced`
// The `actual_fee` can be burned or reward to block authors.
T::OnChargeTransaction::correct_and_deposit_fee(
&source,
actual_fee,
actual_priority_fee,
fee,
);

let state = executor.into_state();

Expand Down
4 changes: 2 additions & 2 deletions frame/evm/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ fn fee_deduction() {
let imbalance = <<Test as Config>::OnChargeTransaction as OnChargeEVMTransaction<Test>>::withdraw_fee(&evm_addr, U256::from(10)).unwrap();
assert_eq!(Balances::free_balance(&substrate_addr), 90);

// Refund fees as 5 units
<<Test as Config>::OnChargeTransaction as OnChargeEVMTransaction<Test>>::correct_and_deposit_fee(&evm_addr, U256::from(5), imbalance);
// Refund fees as 5 units, priority fees as 0 uints
<<Test as Config>::OnChargeTransaction as OnChargeEVMTransaction<Test>>::correct_and_deposit_fee(&evm_addr, U256::from(5), None,imbalance);
assert_eq!(Balances::free_balance(&substrate_addr), 95);
});
}
Expand Down