Skip to content

Commit fed5e0a

Browse files
authored
Limit number of iterations in genesis nonce building (#753)
1 parent f6fff7f commit fed5e0a

File tree

6 files changed

+49
-25
lines changed

6 files changed

+49
-25
lines changed

frame/ethereum/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ impl<T: Config> Pallet<T> {
687687
target,
688688
input,
689689
value,
690-
gas_limit.low_u64(),
690+
gas_limit.unique_saturated_into(),
691691
max_fee_per_gas,
692692
max_priority_fee_per_gas,
693693
nonce,
@@ -715,7 +715,7 @@ impl<T: Config> Pallet<T> {
715715
from,
716716
input,
717717
value,
718-
gas_limit.low_u64(),
718+
gas_limit.unique_saturated_into(),
719719
max_fee_per_gas,
720720
max_priority_fee_per_gas,
721721
nonce,

frame/evm/src/lib.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ use sp_runtime::{
7777
traits::{BadOrigin, Saturating, UniqueSaturatedInto, Zero},
7878
AccountId32, DispatchErrorWithPostInfo,
7979
};
80-
use sp_std::vec::Vec;
80+
use sp_std::{cmp::min, vec::Vec};
8181

8282
pub use evm::{
8383
Config as EvmConfig, Context, ExitError, ExitFatal, ExitReason, ExitRevert, ExitSucceed,
@@ -438,21 +438,26 @@ pub mod pallet {
438438
}
439439

440440
#[pallet::genesis_build]
441-
impl<T: Config> GenesisBuild<T> for GenesisConfig {
441+
impl<T: Config> GenesisBuild<T> for GenesisConfig
442+
where
443+
U256: UniqueSaturatedInto<BalanceOf<T>>,
444+
{
442445
fn build(&self) {
446+
const MAX_ACCOUNT_NONCE: usize = 100;
447+
443448
for (address, account) in &self.accounts {
444449
let account_id = T::AddressMapping::into_account_id(*address);
445450

446451
// ASSUME: in one single EVM transaction, the nonce will not increase more than
447452
// `u128::max_value()`.
448-
for _ in 0..account.nonce.low_u128() {
453+
for _ in 0..min(
454+
MAX_ACCOUNT_NONCE,
455+
UniqueSaturatedInto::<usize>::unique_saturated_into(account.nonce),
456+
) {
449457
frame_system::Pallet::<T>::inc_account_nonce(&account_id);
450458
}
451459

452-
T::Currency::deposit_creating(
453-
&account_id,
454-
account.balance.low_u128().unique_saturated_into(),
455-
);
460+
T::Currency::deposit_creating(&account_id, account.balance.unique_saturated_into());
456461

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

@@ -735,6 +740,7 @@ where
735740
Opposite = C::PositiveImbalance,
736741
>,
737742
OU: OnUnbalanced<NegativeImbalanceOf<C, T>>,
743+
U256: UniqueSaturatedInto<<C as Currency<<T as frame_system::Config>::AccountId>>::Balance>,
738744
{
739745
// Kept type as Option to satisfy bound of Default
740746
type LiquidityInfo = Option<NegativeImbalanceOf<C, T>>;
@@ -746,7 +752,7 @@ where
746752
let account_id = T::AddressMapping::into_account_id(*who);
747753
let imbalance = C::withdraw(
748754
&account_id,
749-
fee.low_u128().unique_saturated_into(),
755+
fee.unique_saturated_into(),
750756
WithdrawReasons::FEE,
751757
ExistenceRequirement::AllowDeath,
752758
)
@@ -766,7 +772,7 @@ where
766772
// Calculate how much refund we should return
767773
let refund_amount = paid
768774
.peek()
769-
.saturating_sub(corrected_fee.low_u128().unique_saturated_into());
775+
.saturating_sub(corrected_fee.unique_saturated_into());
770776
// refund to the account that paid the fees. If this fails, the
771777
// account might have dropped below the existential balance. In
772778
// that case we don't refund anything.
@@ -797,7 +803,7 @@ where
797803
.same()
798804
.unwrap_or_else(|_| C::NegativeImbalance::zero());
799805

800-
let (base_fee, tip) = adjusted_paid.split(base_fee.low_u128().unique_saturated_into());
806+
let (base_fee, tip) = adjusted_paid.split(base_fee.unique_saturated_into());
801807
// Handle base fee. Can be either burned, rationed, etc ...
802808
OU::on_unbalanced(base_fee);
803809
return Some(tip);
@@ -821,7 +827,10 @@ impl<T> OnChargeEVMTransaction<T> for ()
821827
<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::PositiveImbalance:
822828
Imbalance<<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance, Opposite = <T::Currency as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance>,
823829
<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance:
824-
Imbalance<<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance, Opposite = <T::Currency as Currency<<T as frame_system::Config>::AccountId>>::PositiveImbalance>, {
830+
Imbalance<<T::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance, Opposite = <T::Currency as Currency<<T as frame_system::Config>::AccountId>>::PositiveImbalance>,
831+
U256: UniqueSaturatedInto<BalanceOf<T>>,
832+
833+
{
825834
// Kept type as Option to satisfy bound of Default
826835
type LiquidityInfo = Option<NegativeImbalanceOf<T::Currency, T>>;
827836

frame/evm/src/runner/stack.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818
//! EVM stack-based runner.
1919
2020
use crate::{
21-
runner::Runner as RunnerT, AccountCodes, AccountStorages, AddressMapping, BlockHashMapping,
22-
Config, Error, Event, FeeCalculator, OnChargeEVMTransaction, Pallet, RunnerError,
21+
runner::Runner as RunnerT, AccountCodes, AccountStorages, AddressMapping, BalanceOf,
22+
BlockHashMapping, Config, Error, Event, FeeCalculator, OnChargeEVMTransaction, Pallet,
23+
RunnerError,
2324
};
2425
use evm::{
2526
backend::Backend as BackendT,
@@ -37,7 +38,10 @@ pub struct Runner<T: Config> {
3738
_marker: PhantomData<T>,
3839
}
3940

40-
impl<T: Config> Runner<T> {
41+
impl<T: Config> Runner<T>
42+
where
43+
BalanceOf<T>: TryFrom<U256> + Into<U256>,
44+
{
4145
/// Execute an already validated EVM operation.
4246
fn execute<'config, 'precompiles, F, R>(
4347
source: H160,
@@ -192,7 +196,10 @@ impl<T: Config> Runner<T> {
192196
}
193197
}
194198

195-
impl<T: Config> RunnerT<T> for Runner<T> {
199+
impl<T: Config> RunnerT<T> for Runner<T>
200+
where
201+
BalanceOf<T>: TryFrom<U256> + Into<U256>,
202+
{
196203
type Error = Error<T>;
197204

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

580587
impl<'vicinity, 'config, T: Config> StackStateT<'config>
581588
for SubstrateStackState<'vicinity, 'config, T>
589+
where
590+
BalanceOf<T>: TryFrom<U256> + Into<U256>,
582591
{
583592
fn metadata(&self) -> &StackSubstateMetadata<'config> {
584593
self.substate.metadata()
@@ -667,7 +676,10 @@ impl<'vicinity, 'config, T: Config> StackStateT<'config>
667676
T::Currency::transfer(
668677
&source,
669678
&target,
670-
transfer.value.low_u128().unique_saturated_into(),
679+
transfer
680+
.value
681+
.try_into()
682+
.map_err(|_| ExitError::OutOfFund)?,
671683
ExistenceRequirement::AllowDeath,
672684
)
673685
.map_err(|_| ExitError::OutOfFund)

frame/evm/src/tests.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,10 @@ fn issuance_after_tip() {
268268
result.expect("EVM can be called");
269269
let after_tip = <Test as Config>::Currency::total_issuance();
270270
// Only base fee is burned
271-
let (base_fee, _) = <Test as Config>::FeeCalculator::min_gas_price();
272-
assert_eq!(after_tip, (before_tip - (base_fee.low_u64() * 21_000)));
271+
let base_fee: u64 = <Test as Config>::FeeCalculator::min_gas_price()
272+
.0
273+
.unique_saturated_into();
274+
assert_eq!(after_tip, (before_tip - (base_fee * 21_000)));
273275
});
274276
}
275277

@@ -355,7 +357,7 @@ fn refunds_and_priority_should_work() {
355357
assert_eq!(after_call, before_call - total_cost);
356358

357359
let after_tip = EVM::account_basic(&author).0.balance;
358-
assert_eq!(after_tip, (before_tip + actual_tip.low_u128()));
360+
assert_eq!(after_tip, (before_tip + actual_tip));
359361
});
360362
}
361363

primitives/evm/src/validation.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#![allow(clippy::comparison_chain)]
1818

1919
pub use evm::backend::Basic as Account;
20+
use frame_support::sp_runtime::traits::UniqueSaturatedInto;
2021
use sp_core::{H160, H256, U256};
2122
use sp_std::vec::Vec;
2223

@@ -181,7 +182,7 @@ impl<'config, E: From<InvalidEvmTransactionError>> CheckEvmTransaction<'config,
181182
// We must ensure a transaction can pay the cost of its data bytes.
182183
// If it can't it should not be included in a block.
183184
let mut gasometer = evm::gasometer::Gasometer::new(
184-
self.transaction.gas_limit.low_u64(),
185+
self.transaction.gas_limit.unique_saturated_into(),
185186
self.config.evm_config,
186187
);
187188
let transaction_cost = if self.transaction.to.is_some() {

template/runtime/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use sp_runtime::{
2424
create_runtime_str, generic, impl_opaque_keys,
2525
traits::{
2626
AccountIdLookup, BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable,
27-
IdentifyAccount, NumberFor, PostDispatchInfoOf, Verify,
27+
IdentifyAccount, NumberFor, PostDispatchInfoOf, UniqueSaturatedInto, Verify,
2828
},
2929
transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},
3030
ApplyExtrinsicResult, MultiSignature,
@@ -664,7 +664,7 @@ impl_runtime_apis! {
664664
to,
665665
data,
666666
value,
667-
gas_limit.low_u64(),
667+
gas_limit.unique_saturated_into(),
668668
max_fee_per_gas,
669669
max_priority_fee_per_gas,
670670
nonce,
@@ -701,7 +701,7 @@ impl_runtime_apis! {
701701
from,
702702
data,
703703
value,
704-
gas_limit.low_u64(),
704+
gas_limit.unique_saturated_into(),
705705
max_fee_per_gas,
706706
max_priority_fee_per_gas,
707707
nonce,

0 commit comments

Comments
 (0)