Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
58 changes: 58 additions & 0 deletions runtime/common/src/impl_on_charge_evm_transaction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2019-2022 PureStake Inc.
// This file is part of Moonbeam.

// Moonbeam is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Moonbeam is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Moonbeam. If not, see <http://www.gnu.org/licenses/>.

#[macro_export]
macro_rules! impl_on_charge_evm_transaction {
{} => {
type CurrencyAccountId<T> = <T as frame_system::Config>::AccountId;

type BalanceFor<T> =
<<T as pallet_evm::Config>::Currency as CurrencyT<CurrencyAccountId<T>>>::Balance;

type PositiveImbalanceFor<T> =
<<T as pallet_evm::Config>::Currency as CurrencyT<CurrencyAccountId<T>>>::PositiveImbalance;

type NegativeImbalanceFor<T> =
<<T as pallet_evm::Config>::Currency as CurrencyT<CurrencyAccountId<T>>>::NegativeImbalance;

pub struct OnChargeEVMTransaction<OU>(sp_std::marker::PhantomData<OU>);
impl<T, OU> OnChargeEVMTransactionT<T> for OnChargeEVMTransaction<OU>
where
T: pallet_evm::Config,
PositiveImbalanceFor<T>: Imbalance<BalanceFor<T>, Opposite = NegativeImbalanceFor<T>>,
NegativeImbalanceFor<T>: Imbalance<BalanceFor<T>, Opposite = PositiveImbalanceFor<T>>,
OU: OnUnbalanced<NegativeImbalanceFor<T>>,
{
type LiquidityInfo = Option<NegativeImbalanceFor<T>>;

fn withdraw_fee(who: &H160, fee: U256) -> Result<Self::LiquidityInfo, pallet_evm::Error<T>> {
EVMCurrencyAdapter::<<T as pallet_evm::Config>::Currency, ()>::withdraw_fee(who, fee)
}

fn correct_and_deposit_fee(
who: &H160,
corrected_fee: U256,
already_withdrawn: Self::LiquidityInfo,
) {
<EVMCurrencyAdapter<<T as pallet_evm::Config>::Currency, OU> as OnChargeEVMTransactionT<
T,
>>::correct_and_deposit_fee(who, corrected_fee, already_withdrawn)
}

fn pay_priority_fee(_tip: U256) {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It amuses me how subtle this is in code...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it necessary to add some docs about this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@AsceticBear PTAL to polkadot-evm/frontier#700

I thought about it this past days, and decided to slightly modify the approach in Frontier. I think splitting both base fee and priority fee handling offers the most flexibility in terms of how each chain wants to deals with them.

}
}
}
1 change: 1 addition & 0 deletions runtime/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use sp_core::H160;

mod apis;
mod impl_on_charge_evm_transaction;
mod impl_self_contained_call;
pub mod migrations;

Expand Down
38 changes: 1 addition & 37 deletions runtime/moonbase/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,43 +417,7 @@ where
}
}

type CurrencyAccountId<T> = <T as frame_system::Config>::AccountId;

type BalanceFor<T> =
<<T as pallet_evm::Config>::Currency as CurrencyT<CurrencyAccountId<T>>>::Balance;

type PositiveImbalanceFor<T> =
<<T as pallet_evm::Config>::Currency as CurrencyT<CurrencyAccountId<T>>>::PositiveImbalance;

type NegativeImbalanceFor<T> =
<<T as pallet_evm::Config>::Currency as CurrencyT<CurrencyAccountId<T>>>::NegativeImbalance;

pub struct OnChargeEVMTransaction<OU>(sp_std::marker::PhantomData<OU>);
impl<T, OU> OnChargeEVMTransactionT<T> for OnChargeEVMTransaction<OU>
where
T: pallet_evm::Config,
PositiveImbalanceFor<T>: Imbalance<BalanceFor<T>, Opposite = NegativeImbalanceFor<T>>,
NegativeImbalanceFor<T>: Imbalance<BalanceFor<T>, Opposite = PositiveImbalanceFor<T>>,
OU: OnUnbalanced<NegativeImbalanceFor<T>>,
{
type LiquidityInfo = Option<NegativeImbalanceFor<T>>;

fn withdraw_fee(who: &H160, fee: U256) -> Result<Self::LiquidityInfo, pallet_evm::Error<T>> {
EVMCurrencyAdapter::<<T as pallet_evm::Config>::Currency, ()>::withdraw_fee(who, fee)
}

fn correct_and_deposit_fee(
who: &H160,
corrected_fee: U256,
already_withdrawn: Self::LiquidityInfo,
) {
<EVMCurrencyAdapter<<T as pallet_evm::Config>::Currency, OU> as OnChargeEVMTransactionT<
T,
>>::correct_and_deposit_fee(who, corrected_fee, already_withdrawn)
}

fn pay_priority_fee(_tip: U256) {}
}
runtime_common::impl_on_charge_evm_transaction!();

impl pallet_evm::Config for Runtime {
type FeeCalculator = FixedGasPrice;
Expand Down
38 changes: 36 additions & 2 deletions runtime/moonbase/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ use frame_support::{
assert_noop, assert_ok,
dispatch::Dispatchable,
traits::{
fungible::Inspect, fungibles::Inspect as FungiblesInspect, EnsureOrigin, PalletInfo,
StorageInfo, StorageInfoTrait,
fungible::Inspect, fungibles::Inspect as FungiblesInspect, Currency as CurrencyT,
EnsureOrigin, PalletInfo, StorageInfo, StorageInfoTrait,
},
weights::{DispatchClass, Weight},
StorageHasher, Twox128,
Expand Down Expand Up @@ -2444,6 +2444,40 @@ fn refund_ed_0_evm() {
});
}

#[test]
fn author_does_not_receive_priority_fee() {
ExtBuilder::default()
.with_balances(vec![(
AccountId::from(BOB),
(1 * UNIT) + (21_000 * (500 * GIGAWEI)),
)])
.build()
.execute_with(|| {
// Some block author as seen by pallet-evm.
let author = AccountId::from(<pallet_evm::Pallet<Runtime>>::find_author());
// Currently the default impl of the evm uses `deposit_into_existing`.
// If we were to use this implementation, and for an author to receive eventual tips,
// the account needs to be somehow initialized, otherwise the deposit would fail.
Balances::make_free_balance_be(&author, 100 * UNIT);

// EVM transfer.
assert_ok!(Call::EVM(pallet_evm::Call::<Runtime>::call {
source: H160::from(BOB),
target: H160::from(ALICE),
input: Vec::new(),
value: (1 * UNIT).into(),
gas_limit: 21_000u64,
max_fee_per_gas: U256::from(300 * GIGAWEI),
max_priority_fee_per_gas: Some(U256::from(200 * GIGAWEI)),
nonce: Some(U256::from(0)),
access_list: Vec::new(),
})
.dispatch(<Runtime as frame_system::Config>::Origin::root()));
// Author free balance didn't change.
assert_eq!(Balances::free_balance(author), 100 * UNIT,);
Comment thread
tgmichel marked this conversation as resolved.
});
}

#[test]
fn root_can_change_default_xcm_vers() {
ExtBuilder::default()
Expand Down
14 changes: 8 additions & 6 deletions runtime/moonbeam/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ use frame_support::{
pallet_prelude::DispatchResult,
parameter_types,
traits::{
ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, Contains, EnsureOneOf,
EqualPrivilegeOnly, Imbalance, InstanceFilter, OffchainWorker, OnFinalize, OnIdle,
OnInitialize, OnRuntimeUpgrade, OnUnbalanced,
ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, Contains,
Currency as CurrencyT, EnsureOneOf, EqualPrivilegeOnly, Imbalance, InstanceFilter,
OffchainWorker, OnFinalize, OnIdle, OnInitialize, OnRuntimeUpgrade, OnUnbalanced,
},
weights::{
constants::{RocksDbWeight, WEIGHT_PER_SECOND},
Expand All @@ -61,8 +61,8 @@ use pallet_balances::NegativeImbalance;
use pallet_ethereum::Call::transact;
use pallet_ethereum::Transaction as EthereumTransaction;
use pallet_evm::{
Account as EVMAccount, EnsureAddressNever, EnsureAddressRoot, FeeCalculator, GasWeightMapping,
Runner,
Account as EVMAccount, EVMCurrencyAdapter, EnsureAddressNever, EnsureAddressRoot,
FeeCalculator, GasWeightMapping, OnChargeEVMTransaction as OnChargeEVMTransactionT, Runner,
};
use pallet_transaction_payment::{CurrencyAdapter, Multiplier, TargetedFeeAdjustment};
pub use parachain_staking::{InflationInfo, Range};
Expand Down Expand Up @@ -387,6 +387,8 @@ where
}
}

runtime_common::impl_on_charge_evm_transaction!();

impl pallet_evm::Config for Runtime {
type FeeCalculator = FixedGasPrice;
type GasWeightMapping = MoonbeamGasWeightMapping;
Expand All @@ -400,7 +402,7 @@ impl pallet_evm::Config for Runtime {
type PrecompilesType = MoonbeamPrecompiles<Self>;
type PrecompilesValue = PrecompilesValue;
type ChainId = EthereumChainId;
type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees<Runtime>>;
type OnChargeTransaction = OnChargeEVMTransaction<DealWithFees<Runtime>>;
type BlockGasLimit = BlockGasLimit;
type FindAuthor = FindAuthorAdapter<AuthorInherent>;
type WeightInfo = pallet_evm::weights::SubstrateWeight<Self>;
Expand Down
38 changes: 36 additions & 2 deletions runtime/moonbeam/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ use frame_support::{
assert_noop, assert_ok,
dispatch::Dispatchable,
traits::{
fungible::Inspect, fungibles::Inspect as FungiblesInspect, EnsureOrigin, PalletInfo,
StorageInfo, StorageInfoTrait,
fungible::Inspect, fungibles::Inspect as FungiblesInspect, Currency as CurrencyT,
EnsureOrigin, PalletInfo, StorageInfo, StorageInfoTrait,
},
weights::{DispatchClass, Weight},
StorageHasher, Twox128,
Expand Down Expand Up @@ -1255,6 +1255,40 @@ fn refund_ed_0_evm() {
});
}

#[test]
fn author_does_not_receive_priority_fee() {
ExtBuilder::default()
.with_balances(vec![(
AccountId::from(BOB),
(1 * GLMR) + (21_000 * (500 * GIGAWEI)),
)])
.build()
.execute_with(|| {
// Some block author as seen by pallet-evm.
let author = AccountId::from(<pallet_evm::Pallet<Runtime>>::find_author());
// Currently the default impl of the evm uses `deposit_into_existing`.
// If we were to use this implementation, and for an author to receive eventual tips,
// the account needs to be somehow initialized, otherwise the deposit would fail.
Balances::make_free_balance_be(&author, 100 * GLMR);

// EVM transfer.
assert_ok!(Call::EVM(pallet_evm::Call::<Runtime>::call {
source: H160::from(BOB),
target: H160::from(ALICE),
input: Vec::new(),
value: (1 * GLMR).into(),
gas_limit: 21_000u64,
max_fee_per_gas: U256::from(300 * GIGAWEI),
max_priority_fee_per_gas: Some(U256::from(200 * GIGAWEI)),
nonce: Some(U256::from(0)),
access_list: Vec::new(),
})
.dispatch(<Runtime as frame_system::Config>::Origin::root()));
// Author free balance didn't change.
assert_eq!(Balances::free_balance(author), 100 * GLMR,);
});
}

#[test]
fn root_can_change_default_xcm_vers() {
ExtBuilder::default()
Expand Down
14 changes: 8 additions & 6 deletions runtime/moonriver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ use frame_support::{
pallet_prelude::DispatchResult,
parameter_types,
traits::{
ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, Contains, EnsureOneOf,
EqualPrivilegeOnly, Imbalance, InstanceFilter, OffchainWorker, OnFinalize, OnIdle,
OnInitialize, OnRuntimeUpgrade, OnUnbalanced,
ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, ConstU8, Contains,
Currency as CurrencyT, EnsureOneOf, EqualPrivilegeOnly, Imbalance, InstanceFilter,
OffchainWorker, OnFinalize, OnIdle, OnInitialize, OnRuntimeUpgrade, OnUnbalanced,
},
weights::{
constants::{RocksDbWeight, WEIGHT_PER_SECOND},
Expand All @@ -62,8 +62,8 @@ use pallet_balances::NegativeImbalance;
use pallet_ethereum::Call::transact;
use pallet_ethereum::Transaction as EthereumTransaction;
use pallet_evm::{
Account as EVMAccount, EnsureAddressNever, EnsureAddressRoot, FeeCalculator, GasWeightMapping,
Runner,
Account as EVMAccount, EVMCurrencyAdapter, EnsureAddressNever, EnsureAddressRoot,
FeeCalculator, GasWeightMapping, OnChargeEVMTransaction as OnChargeEVMTransactionT, Runner,
};
use pallet_transaction_payment::{CurrencyAdapter, Multiplier, TargetedFeeAdjustment};
pub use parachain_staking::{InflationInfo, Range};
Expand Down Expand Up @@ -409,6 +409,8 @@ where
}
}

runtime_common::impl_on_charge_evm_transaction!();

impl pallet_evm::Config for Runtime {
type FeeCalculator = FixedGasPrice;
type GasWeightMapping = MoonbeamGasWeightMapping;
Expand All @@ -422,7 +424,7 @@ impl pallet_evm::Config for Runtime {
type PrecompilesType = MoonriverPrecompiles<Self>;
type PrecompilesValue = PrecompilesValue;
type ChainId = EthereumChainId;
type OnChargeTransaction = pallet_evm::EVMCurrencyAdapter<Balances, DealWithFees<Runtime>>;
type OnChargeTransaction = OnChargeEVMTransaction<DealWithFees<Runtime>>;
type BlockGasLimit = BlockGasLimit;
type FindAuthor = FindAuthorAdapter<AuthorInherent>;
type WeightInfo = pallet_evm::weights::SubstrateWeight<Self>;
Expand Down
38 changes: 36 additions & 2 deletions runtime/moonriver/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ use frame_support::{
assert_noop, assert_ok,
dispatch::Dispatchable,
traits::{
fungible::Inspect, fungibles::Inspect as FungiblesInspect, EnsureOrigin, PalletInfo,
StorageInfo, StorageInfoTrait,
fungible::Inspect, fungibles::Inspect as FungiblesInspect, Currency as CurrencyT,
EnsureOrigin, PalletInfo, StorageInfo, StorageInfoTrait,
},
weights::{DispatchClass, Weight},
StorageHasher, Twox128,
Expand Down Expand Up @@ -1243,6 +1243,40 @@ fn refund_ed_0_evm() {
});
}

#[test]
fn author_does_not_receive_priority_fee() {
ExtBuilder::default()
.with_balances(vec![(
AccountId::from(BOB),
(1 * MOVR) + (21_000 * (500 * GIGAWEI)),
)])
.build()
.execute_with(|| {
// Some block author as seen by pallet-evm.
let author = AccountId::from(<pallet_evm::Pallet<Runtime>>::find_author());
// Currently the default impl of the evm uses `deposit_into_existing`.
// If we were to use this implementation, and for an author to receive eventual tips,
// the account needs to be somehow initialized, otherwise the deposit would fail.
Balances::make_free_balance_be(&author, 100 * MOVR);

// EVM transfer.
assert_ok!(Call::EVM(pallet_evm::Call::<Runtime>::call {
source: H160::from(BOB),
target: H160::from(ALICE),
input: Vec::new(),
value: (1 * MOVR).into(),
gas_limit: 21_000u64,
max_fee_per_gas: U256::from(300 * GIGAWEI),
max_priority_fee_per_gas: Some(U256::from(200 * GIGAWEI)),
nonce: Some(U256::from(0)),
access_list: Vec::new(),
})
.dispatch(<Runtime as frame_system::Config>::Origin::root()));
// Author free balance didn't change.
assert_eq!(Balances::free_balance(author), 100 * MOVR,);
});
}

#[test]
fn root_can_change_default_xcm_vers() {
ExtBuilder::default()
Expand Down