Skip to content
Permalink
Browse files Browse the repository at this point in the history
Limit number of iterations in genesis nonce building (#753)
  • Loading branch information
sorpaas committed Jun 29, 2022
1 parent f6fff7f commit fed5e0a
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 25 deletions.
4 changes: 2 additions & 2 deletions frame/ethereum/src/lib.rs
Expand Up @@ -687,7 +687,7 @@ impl<T: Config> Pallet<T> {
target,
input,
value,
gas_limit.low_u64(),
gas_limit.unique_saturated_into(),
max_fee_per_gas,
max_priority_fee_per_gas,
nonce,
Expand Down Expand Up @@ -715,7 +715,7 @@ impl<T: Config> Pallet<T> {
from,
input,
value,
gas_limit.low_u64(),
gas_limit.unique_saturated_into(),
max_fee_per_gas,
max_priority_fee_per_gas,
nonce,
Expand Down
31 changes: 20 additions & 11 deletions frame/evm/src/lib.rs
Expand Up @@ -77,7 +77,7 @@ use sp_runtime::{
traits::{BadOrigin, Saturating, UniqueSaturatedInto, Zero},
AccountId32, DispatchErrorWithPostInfo,
};
use sp_std::vec::Vec;
use sp_std::{cmp::min, vec::Vec};

pub use evm::{
Config as EvmConfig, Context, ExitError, ExitFatal, ExitReason, ExitRevert, ExitSucceed,
Expand Down Expand Up @@ -438,21 +438,26 @@ pub mod pallet {
}

#[pallet::genesis_build]
impl<T: Config> GenesisBuild<T> for GenesisConfig {
impl<T: Config> GenesisBuild<T> for GenesisConfig
where
U256: UniqueSaturatedInto<BalanceOf<T>>,
{
fn build(&self) {
const MAX_ACCOUNT_NONCE: usize = 100;

for (address, account) in &self.accounts {
let account_id = T::AddressMapping::into_account_id(*address);

// ASSUME: in one single EVM transaction, the nonce will not increase more than
// `u128::max_value()`.
for _ in 0..account.nonce.low_u128() {
for _ in 0..min(
MAX_ACCOUNT_NONCE,
UniqueSaturatedInto::<usize>::unique_saturated_into(account.nonce),
) {
frame_system::Pallet::<T>::inc_account_nonce(&account_id);
}

T::Currency::deposit_creating(
&account_id,
account.balance.low_u128().unique_saturated_into(),
);
T::Currency::deposit_creating(&account_id, account.balance.unique_saturated_into());

Pallet::<T>::create_account(*address, account.code.clone());

Expand Down Expand Up @@ -735,6 +740,7 @@ where
Opposite = C::PositiveImbalance,
>,
OU: OnUnbalanced<NegativeImbalanceOf<C, T>>,
U256: UniqueSaturatedInto<<C as Currency<<T as frame_system::Config>::AccountId>>::Balance>,
{
// Kept type as Option to satisfy bound of Default
type LiquidityInfo = Option<NegativeImbalanceOf<C, T>>;
Expand All @@ -746,7 +752,7 @@ where
let account_id = T::AddressMapping::into_account_id(*who);
let imbalance = C::withdraw(
&account_id,
fee.low_u128().unique_saturated_into(),
fee.unique_saturated_into(),
WithdrawReasons::FEE,
ExistenceRequirement::AllowDeath,
)
Expand All @@ -766,7 +772,7 @@ where
// Calculate how much refund we should return
let refund_amount = paid
.peek()
.saturating_sub(corrected_fee.low_u128().unique_saturated_into());
.saturating_sub(corrected_fee.unique_saturated_into());
// 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.
Expand Down Expand Up @@ -797,7 +803,7 @@ where
.same()
.unwrap_or_else(|_| C::NegativeImbalance::zero());

let (base_fee, tip) = adjusted_paid.split(base_fee.low_u128().unique_saturated_into());
let (base_fee, tip) = adjusted_paid.split(base_fee.unique_saturated_into());
// Handle base fee. Can be either burned, rationed, etc ...
OU::on_unbalanced(base_fee);
return Some(tip);
Expand All @@ -821,7 +827,10 @@ impl<T> OnChargeEVMTransaction<T> for ()
<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::PositiveImbalance:
Imbalance<<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance, Opposite = <T::Currency as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance>,
<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance:
Imbalance<<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance, Opposite = <T::Currency as Currency<<T as frame_system::Config>::AccountId>>::PositiveImbalance>, {
Imbalance<<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance, Opposite = <T::Currency as Currency<<T as frame_system::Config>::AccountId>>::PositiveImbalance>,
U256: UniqueSaturatedInto<BalanceOf<T>>,

{
// Kept type as Option to satisfy bound of Default
type LiquidityInfo = Option<NegativeImbalanceOf<T::Currency, T>>;

Expand Down
22 changes: 17 additions & 5 deletions frame/evm/src/runner/stack.rs
Expand Up @@ -18,8 +18,9 @@
//! EVM stack-based runner.

use crate::{
runner::Runner as RunnerT, AccountCodes, AccountStorages, AddressMapping, BlockHashMapping,
Config, Error, Event, FeeCalculator, OnChargeEVMTransaction, Pallet, RunnerError,
runner::Runner as RunnerT, AccountCodes, AccountStorages, AddressMapping, BalanceOf,
BlockHashMapping, Config, Error, Event, FeeCalculator, OnChargeEVMTransaction, Pallet,
RunnerError,
};
use evm::{
backend::Backend as BackendT,
Expand All @@ -37,7 +38,10 @@ pub struct Runner<T: Config> {
_marker: PhantomData<T>,
}

impl<T: Config> Runner<T> {
impl<T: Config> Runner<T>
where
BalanceOf<T>: TryFrom<U256> + Into<U256>,
{
/// Execute an already validated EVM operation.
fn execute<'config, 'precompiles, F, R>(
source: H160,
Expand Down Expand Up @@ -192,7 +196,10 @@ impl<T: Config> Runner<T> {
}
}

impl<T: Config> RunnerT<T> for Runner<T> {
impl<T: Config> RunnerT<T> for Runner<T>
where
BalanceOf<T>: TryFrom<U256> + Into<U256>,
{
type Error = Error<T>;

fn validate(
Expand Down Expand Up @@ -579,6 +586,8 @@ impl<'vicinity, 'config, T: Config> BackendT for SubstrateStackState<'vicinity,

impl<'vicinity, 'config, T: Config> StackStateT<'config>
for SubstrateStackState<'vicinity, 'config, T>
where
BalanceOf<T>: TryFrom<U256> + Into<U256>,
{
fn metadata(&self) -> &StackSubstateMetadata<'config> {
self.substate.metadata()
Expand Down Expand Up @@ -667,7 +676,10 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config>
T::Currency::transfer(
&source,
&target,
transfer.value.low_u128().unique_saturated_into(),
transfer
.value
.try_into()
.map_err(|_| ExitError::OutOfFund)?,
ExistenceRequirement::AllowDeath,
)
.map_err(|_| ExitError::OutOfFund)
Expand Down
8 changes: 5 additions & 3 deletions frame/evm/src/tests.rs
Expand Up @@ -268,8 +268,10 @@ fn issuance_after_tip() {
result.expect("EVM can be called");
let after_tip = <Test as Config>::Currency::total_issuance();
// Only base fee is burned
let (base_fee, _) = <Test as Config>::FeeCalculator::min_gas_price();
assert_eq!(after_tip, (before_tip - (base_fee.low_u64() * 21_000)));
let base_fee: u64 = <Test as Config>::FeeCalculator::min_gas_price()
.0
.unique_saturated_into();
assert_eq!(after_tip, (before_tip - (base_fee * 21_000)));
});
}

Expand Down Expand Up @@ -355,7 +357,7 @@ fn refunds_and_priority_should_work() {
assert_eq!(after_call, before_call - total_cost);

let after_tip = EVM::account_basic(&author).0.balance;
assert_eq!(after_tip, (before_tip + actual_tip.low_u128()));
assert_eq!(after_tip, (before_tip + actual_tip));
});
}

Expand Down
3 changes: 2 additions & 1 deletion primitives/evm/src/validation.rs
Expand Up @@ -17,6 +17,7 @@
#![allow(clippy::comparison_chain)]

pub use evm::backend::Basic as Account;
use frame_support::sp_runtime::traits::UniqueSaturatedInto;
use sp_core::{H160, H256, U256};
use sp_std::vec::Vec;

Expand Down Expand Up @@ -181,7 +182,7 @@ impl<'config, E: From<InvalidEvmTransactionError>> CheckEvmTransaction<'config,
// We must ensure a transaction can pay the cost of its data bytes.
// If it can't it should not be included in a block.
let mut gasometer = evm::gasometer::Gasometer::new(
self.transaction.gas_limit.low_u64(),
self.transaction.gas_limit.unique_saturated_into(),
self.config.evm_config,
);
let transaction_cost = if self.transaction.to.is_some() {
Expand Down
6 changes: 3 additions & 3 deletions template/runtime/src/lib.rs
Expand Up @@ -24,7 +24,7 @@ use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys,
traits::{
AccountIdLookup, BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable,
IdentifyAccount, NumberFor, PostDispatchInfoOf, Verify,
IdentifyAccount, NumberFor, PostDispatchInfoOf, UniqueSaturatedInto, Verify,
},
transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},
ApplyExtrinsicResult, MultiSignature,
Expand Down Expand Up @@ -664,7 +664,7 @@ impl_runtime_apis! {
to,
data,
value,
gas_limit.low_u64(),
gas_limit.unique_saturated_into(),
max_fee_per_gas,
max_priority_fee_per_gas,
nonce,
Expand Down Expand Up @@ -701,7 +701,7 @@ impl_runtime_apis! {
from,
data,
value,
gas_limit.low_u64(),
gas_limit.unique_saturated_into(),
max_fee_per_gas,
max_priority_fee_per_gas,
nonce,
Expand Down

0 comments on commit fed5e0a

Please sign in to comment.