Skip to content

Commit e495b6c

Browse files
authoredApr 5, 2024··
test: re-enable evm tests (#5079)
1 parent 368656f commit e495b6c

File tree

15 files changed

+144
-98
lines changed

15 files changed

+144
-98
lines changed
 

‎crates/edr_evm/src/mempool.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{cmp::Ordering, fmt::Debug};
1+
use std::{cmp::Ordering, fmt::Debug, num::NonZeroU64};
22

33
use edr_eth::{Address, B256, U256};
44
use indexmap::{map::Entry, IndexMap};
@@ -84,7 +84,7 @@ pub enum MemPoolAddTransactionError<SE> {
8484
#[error("Transaction gas limit is {transaction_gas_limit} and exceeds block gas limit of {block_gas_limit}")]
8585
ExceedsBlockGasLimit {
8686
/// The block gas limit
87-
block_gas_limit: u64,
87+
block_gas_limit: NonZeroU64,
8888
/// The transaction gas limit
8989
transaction_gas_limit: u64,
9090
},
@@ -166,7 +166,7 @@ impl OrderedTransaction {
166166
#[derive(Clone, Debug)]
167167
pub struct MemPool {
168168
/// The block's gas limit
169-
block_gas_limit: u64,
169+
block_gas_limit: NonZeroU64,
170170
/// Transactions that can be executed now
171171
pending_transactions: IndexMap<Address, Vec<OrderedTransaction>>,
172172
/// Mapping of transaction hashes to transaction
@@ -179,7 +179,7 @@ pub struct MemPool {
179179

180180
impl MemPool {
181181
/// Constructs a new [`MemPool`] with the specified block gas limit.
182-
pub fn new(block_gas_limit: u64) -> Self {
182+
pub fn new(block_gas_limit: NonZeroU64) -> Self {
183183
Self {
184184
block_gas_limit,
185185
pending_transactions: IndexMap::new(),
@@ -190,12 +190,12 @@ impl MemPool {
190190
}
191191

192192
/// Retrieves the instance's block gas limit.
193-
pub fn block_gas_limit(&self) -> u64 {
193+
pub fn block_gas_limit(&self) -> NonZeroU64 {
194194
self.block_gas_limit
195195
}
196196

197197
/// Sets the instance's block gas limit.
198-
pub fn set_block_gas_limit<S>(&mut self, state: &S, limit: u64) -> Result<(), S::Error>
198+
pub fn set_block_gas_limit<S>(&mut self, state: &S, limit: NonZeroU64) -> Result<(), S::Error>
199199
where
200200
S: StateRef + ?Sized,
201201
S::Error: Debug,
@@ -270,7 +270,7 @@ impl MemPool {
270270
transaction: ExecutableTransaction,
271271
) -> Result<(), MemPoolAddTransactionError<S::Error>> {
272272
let transaction_gas_limit = transaction.gas_limit();
273-
if transaction_gas_limit > self.block_gas_limit {
273+
if transaction_gas_limit > self.block_gas_limit.get() {
274274
return Err(MemPoolAddTransactionError::ExceedsBlockGasLimit {
275275
block_gas_limit: self.block_gas_limit,
276276
transaction_gas_limit,
@@ -380,10 +380,10 @@ impl MemPool {
380380
{
381381
fn is_valid_tx(
382382
transaction: &ExecutableTransaction,
383-
block_gas_limit: u64,
383+
block_gas_limit: NonZeroU64,
384384
sender: &AccountInfo,
385385
) -> bool {
386-
transaction.gas_limit() <= block_gas_limit
386+
transaction.gas_limit() <= block_gas_limit.get()
387387
&& transaction.upfront_cost() <= sender.balance
388388
// Remove all mined transactions
389389
&& transaction.nonce() >= sender.nonce

‎crates/edr_evm/src/test_utils.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::num::NonZeroU64;
2+
13
use edr_eth::{
24
transaction::{Eip1559TransactionRequest, Eip155TransactionRequest, TransactionKind},
35
AccountInfo, Address, Bytes, HashMap, SpecId, U256,
@@ -23,7 +25,8 @@ impl MemPoolTestFixture {
2325
let trie = AccountTrie::with_accounts(&accounts);
2426

2527
MemPoolTestFixture {
26-
mem_pool: MemPool::new(10_000_000u64),
28+
// SAFETY: literal is non-zero
29+
mem_pool: MemPool::new(unsafe { NonZeroU64::new_unchecked(10_000_000u64) }),
2730
state: TrieState::with_accounts(trie),
2831
}
2932
}
@@ -37,7 +40,7 @@ impl MemPoolTestFixture {
3740
}
3841

3942
/// Sets the block gas limit.
40-
pub fn set_block_gas_limit(&mut self, block_gas_limit: u64) -> Result<(), StateError> {
43+
pub fn set_block_gas_limit(&mut self, block_gas_limit: NonZeroU64) -> Result<(), StateError> {
4144
self.mem_pool
4245
.set_block_gas_limit(&self.state, block_gas_limit)
4346
}

‎crates/edr_evm/tests/mem_pool.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#![cfg(feature = "test-utils")]
22

3+
use std::num::NonZeroU64;
4+
35
use edr_eth::{AccountInfo, Address, U256};
46
use edr_evm::{
57
state::{AccountModifierFn, StateDebug},
@@ -318,7 +320,7 @@ fn add_transaction_exceeds_block_limit() -> anyhow::Result<()> {
318320

319321
let mut fixture = MemPoolTestFixture::with_accounts(&[(sender, AccountInfo::default())]);
320322

321-
let exceeds_block_limit = fixture.mem_pool.block_gas_limit() + 1;
323+
let exceeds_block_limit = fixture.mem_pool.block_gas_limit().get() + 1;
322324
let transaction = dummy_eip155_transaction_with_limit(sender, 5, exceeds_block_limit)?;
323325
let result = fixture.add_transaction(transaction);
324326

@@ -625,23 +627,24 @@ fn last_pending_nonce_some_future_to_pending_queue() -> anyhow::Result<()> {
625627

626628
#[test]
627629
fn set_block_gas_limit() -> anyhow::Result<()> {
628-
const NEW_GAS_LIMIT: u64 = 15_000_000;
630+
// SAFETY: literal is non-zero
631+
const NEW_GAS_LIMIT: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(15_000_000) };
629632

630633
let sender = Address::random();
631634

632635
let mut fixture = MemPoolTestFixture::with_accounts(&[(sender, AccountInfo::default())]);
633-
assert_eq!(fixture.mem_pool.block_gas_limit(), 10_000_000);
636+
assert_eq!(fixture.mem_pool.block_gas_limit().get(), 10_000_000);
634637

635638
fixture.set_block_gas_limit(NEW_GAS_LIMIT)?;
636639
assert_eq!(fixture.mem_pool.block_gas_limit(), NEW_GAS_LIMIT);
637640

638-
let transaction = dummy_eip155_transaction_with_limit(sender, 0, NEW_GAS_LIMIT + 1)?;
641+
let transaction = dummy_eip155_transaction_with_limit(sender, 0, NEW_GAS_LIMIT.get() + 1)?;
639642
let result = fixture.add_transaction(transaction);
640643

641644
assert!(matches!(
642645
result,
643646
Err(MemPoolAddTransactionError::ExceedsBlockGasLimit { block_gas_limit, transaction_gas_limit })
644-
if block_gas_limit == NEW_GAS_LIMIT && transaction_gas_limit == NEW_GAS_LIMIT + 1
647+
if block_gas_limit == NEW_GAS_LIMIT && transaction_gas_limit == NEW_GAS_LIMIT.get() + 1
645648
));
646649

647650
Ok(())
@@ -665,7 +668,8 @@ fn set_block_gas_limit_removes_invalid_transactions() -> anyhow::Result<()> {
665668
let future_transactions = fixture.mem_pool.future_transactions().collect::<Vec<_>>();
666669
assert_eq!(future_transactions.len(), 1);
667670

668-
fixture.set_block_gas_limit(5_000_000)?;
671+
// SAFETY: literal is non-zero
672+
fixture.set_block_gas_limit(unsafe { NonZeroU64::new_unchecked(5_000_000) })?;
669673

670674
let pending_transactions = fixture.mem_pool.pending_transactions().collect::<Vec<_>>();
671675
assert_eq!(pending_transactions.len(), 0);
@@ -708,7 +712,8 @@ fn set_block_gas_limit_moves_future_to_pending_queue() -> anyhow::Result<()> {
708712
assert_eq!(*future_transactions[0].pending(), transaction4);
709713
assert_eq!(*future_transactions[1].pending(), transaction5);
710714

711-
fixture.set_block_gas_limit(150_000)?;
715+
// SAFETY: literal is non-zero
716+
fixture.set_block_gas_limit(unsafe { NonZeroU64::new_unchecked(150_000) })?;
712717

713718
let pending_transactions = fixture.mem_pool.pending_transactions().collect::<Vec<_>>();
714719
assert_eq!(pending_transactions.len(), 1);

‎crates/edr_napi/src/provider/config.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::{
2+
num::NonZeroU64,
23
path::PathBuf,
34
time::{Duration, SystemTime},
45
};
@@ -172,7 +173,15 @@ impl TryFrom<MiningConfig> for edr_provider::MiningConfig {
172173
.map(|interval| {
173174
let interval = match interval {
174175
Either::A(interval) => {
175-
edr_provider::IntervalConfig::Fixed(interval.try_cast()?)
176+
let interval = interval.try_cast()?;
177+
let interval = NonZeroU64::new(interval).ok_or_else(|| {
178+
napi::Error::new(
179+
napi::Status::GenericFailure,
180+
"Interval must be greater than 0",
181+
)
182+
})?;
183+
184+
edr_provider::IntervalConfig::Fixed(interval)
176185
}
177186
Either::B(IntervalRange { min, max }) => edr_provider::IntervalConfig::Range {
178187
min: min.try_cast()?,
@@ -225,6 +234,14 @@ impl TryFrom<ProviderConfig> for edr_provider::ProviderConfig {
225234
)
226235
.collect::<napi::Result<_>>()?;
227236

237+
let block_gas_limit =
238+
NonZeroU64::new(value.block_gas_limit.try_cast()?).ok_or_else(|| {
239+
napi::Error::new(
240+
napi::Status::GenericFailure,
241+
"Block gas limit must be greater than 0",
242+
)
243+
})?;
244+
228245
Ok(Self {
229246
accounts: value
230247
.genesis_accounts
@@ -235,7 +252,7 @@ impl TryFrom<ProviderConfig> for edr_provider::ProviderConfig {
235252
allow_unlimited_contract_size: value.allow_unlimited_contract_size,
236253
bail_on_call_failure: value.bail_on_call_failure,
237254
bail_on_transaction_failure: value.bail_on_transaction_failure,
238-
block_gas_limit: value.block_gas_limit.try_cast()?,
255+
block_gas_limit,
239256
cache_dir: PathBuf::from(
240257
value
241258
.cache_dir

‎crates/edr_provider/src/config.rs

+31-16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{path::PathBuf, time::SystemTime};
1+
use std::{num::NonZeroU64, path::PathBuf, time::SystemTime};
22

33
use edr_eth::{
44
block::BlobGas, spec::HardforkActivations, AccountInfo, Address, HashMap, SpecId, B256, U256,
@@ -7,36 +7,51 @@ use edr_evm::{alloy_primitives::ChainId, MineOrdering};
77
use rand::Rng;
88
use serde::{Deserialize, Serialize};
99

10-
use crate::{requests::hardhat::rpc_types::ForkConfig, OneUsizeOrTwo};
10+
use crate::requests::{hardhat::rpc_types::ForkConfig, IntervalConfig as IntervalConfigRequest};
1111

1212
/// Configuration for interval mining.
1313
#[derive(Clone, Debug, Deserialize, Serialize)]
1414
pub enum IntervalConfig {
15-
Fixed(u64),
15+
Fixed(NonZeroU64),
1616
Range { min: u64, max: u64 },
1717
}
1818

1919
impl IntervalConfig {
2020
/// Generates a (random) interval based on the configuration.
2121
pub fn generate_interval(&self) -> u64 {
2222
match self {
23-
IntervalConfig::Fixed(interval) => *interval,
23+
IntervalConfig::Fixed(interval) => interval.get(),
2424
IntervalConfig::Range { min, max } => rand::thread_rng().gen_range(*min..=*max),
2525
}
2626
}
2727
}
2828

29-
impl TryFrom<OneUsizeOrTwo> for IntervalConfig {
30-
type Error = ();
31-
32-
fn try_from(value: OneUsizeOrTwo) -> Result<Self, Self::Error> {
33-
match value {
34-
OneUsizeOrTwo::One(0) => Err(()),
35-
OneUsizeOrTwo::One(value) => Ok(Self::Fixed(value as u64)),
36-
OneUsizeOrTwo::Two([min, max]) => Ok(Self::Range {
37-
min: min as u64,
38-
max: max as u64,
39-
}),
29+
/// An error that occurs when trying to convert [`IntervalConfigRequest`] to an
30+
/// `Option<IntervalConfig>`.
31+
#[derive(Debug, thiserror::Error)]
32+
pub enum IntervalConfigConversionError {
33+
/// The minimum value in the range is greater than the maximum value.
34+
#[error("Minimum value in range is greater than maximum value")]
35+
MinGreaterThanMax,
36+
}
37+
38+
impl TryInto<Option<IntervalConfig>> for IntervalConfigRequest {
39+
type Error = IntervalConfigConversionError;
40+
41+
fn try_into(self) -> Result<Option<IntervalConfig>, Self::Error> {
42+
match self {
43+
Self::FixedOrDisabled(0) => Ok(None),
44+
Self::FixedOrDisabled(value) => {
45+
// Zero implies disabled
46+
Ok(NonZeroU64::new(value).map(IntervalConfig::Fixed))
47+
}
48+
Self::Range([min, max]) => {
49+
if max >= min {
50+
Ok(Some(IntervalConfig::Range { min, max }))
51+
} else {
52+
Err(IntervalConfigConversionError::MinGreaterThanMax)
53+
}
54+
}
4055
}
4156
}
4257
}
@@ -65,7 +80,7 @@ pub struct ProviderConfig {
6580
pub bail_on_call_failure: bool,
6681
/// Whether to return an `Err` when a `eth_sendTransaction` fails
6782
pub bail_on_transaction_failure: bool,
68-
pub block_gas_limit: u64,
83+
pub block_gas_limit: NonZeroU64,
6984
pub cache_dir: PathBuf,
7085
pub chain_id: ChainId,
7186
pub chains: HashMap<ChainId, HardforkActivations>,

‎crates/edr_provider/src/data.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@ mod call;
33
mod gas;
44

55
use std::{
6-
cmp,
7-
cmp::Ordering,
6+
cmp::{self, Ordering},
87
collections::BTreeMap,
98
ffi::OsString,
109
fmt::Debug,
11-
num::NonZeroUsize,
10+
num::{NonZeroU64, NonZeroUsize},
1211
sync::Arc,
1312
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
1413
};
@@ -319,7 +318,7 @@ impl<LoggerErrorT: Debug> ProviderData<LoggerErrorT> {
319318

320319
/// Retrieves the gas limit of the next block.
321320
pub fn block_gas_limit(&self) -> u64 {
322-
self.mem_pool.block_gas_limit()
321+
self.mem_pool.block_gas_limit().get()
323322
}
324323

325324
/// Returns the default caller.
@@ -1527,7 +1526,7 @@ impl<LoggerErrorT: Debug> ProviderData<LoggerErrorT> {
15271526
/// Sets the gas limit used for mining new blocks.
15281527
pub fn set_block_gas_limit(
15291528
&mut self,
1530-
gas_limit: u64,
1529+
gas_limit: NonZeroU64,
15311530
) -> Result<(), ProviderError<LoggerErrorT>> {
15321531
let state = self.current_state()?;
15331532
self.mem_pool
@@ -1892,11 +1891,7 @@ impl<LoggerErrorT: Debug> ProviderData<LoggerErrorT> {
18921891
) -> Result<DebugMineBlockResultAndState<StateError>, ProviderError<LoggerErrorT>> {
18931892
options.base_fee = options.base_fee.or(self.next_block_base_fee_per_gas);
18941893
options.beneficiary = Some(options.beneficiary.unwrap_or(self.beneficiary));
1895-
options.gas_limit = Some(
1896-
options
1897-
.gas_limit
1898-
.unwrap_or_else(|| self.mem_pool.block_gas_limit()),
1899-
);
1894+
options.gas_limit = Some(options.gas_limit.unwrap_or_else(|| self.block_gas_limit()));
19001895

19011896
let evm_config = self.create_evm_config(None)?;
19021897

@@ -2359,7 +2354,7 @@ fn create_blockchain_and_state(
23592354
config.chain_id,
23602355
config.hardfork,
23612356
GenesisBlockOptions {
2362-
gas_limit: Some(config.block_gas_limit),
2357+
gas_limit: Some(config.block_gas_limit.get()),
23632358
timestamp: config.initial_date.map(|d| {
23642359
d.duration_since(UNIX_EPOCH)
23652360
.expect("initial date must be after UNIX epoch")
@@ -3014,7 +3009,11 @@ mod tests {
30143009
#[test]
30153010
fn mine_and_commit_block_leaves_unmined_transactions() -> anyhow::Result<()> {
30163011
let mut fixture = ProviderTestFixture::new_local()?;
3017-
fixture.provider_data.set_block_gas_limit(55_000)?;
3012+
3013+
// SAFETY: literal is non-zero
3014+
fixture
3015+
.provider_data
3016+
.set_block_gas_limit(unsafe { NonZeroU64::new_unchecked(55_000) })?;
30183017

30193018
// Actual gas usage is 21_000
30203019
let transaction1 = fixture.signed_dummy_transaction(0, Some(0))?;
@@ -3581,7 +3580,8 @@ mod tests {
35813580
}));
35823581

35833582
let config = ProviderConfig {
3584-
block_gas_limit: 1_000_000,
3583+
// SAFETY: literal is non-zero
3584+
block_gas_limit: unsafe { NonZeroU64::new_unchecked(1_000_000) },
35853585
chain_id: 1,
35863586
coinbase: Address::ZERO,
35873587
hardfork: SpecId::LONDON,

‎crates/edr_provider/src/error.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use edr_evm::{
1616
};
1717
use ethers_core::types::transaction::eip712::Eip712Error;
1818

19-
use crate::data::CreationError;
19+
use crate::{data::CreationError, IntervalConfigConversionError};
2020

2121
#[derive(Debug, thiserror::Error)]
2222
pub enum ProviderError<LoggerErrorT> {
@@ -131,6 +131,12 @@ pub enum ProviderError<LoggerErrorT> {
131131
/// Cannot set account nonce when the mem pool is not empty
132132
#[error("Cannot set account nonce when the transaction pool is not empty")]
133133
SetAccountNonceWithPendingTransactions,
134+
/// `evm_setBlockGasLimit` was called with a gas limit of zero.
135+
#[error("Block gas limit must be greater than 0")]
136+
SetBlockGasLimitMustBeGreaterThanZero,
137+
/// The `evm_setIntervalMining` method was called with an invalid interval.
138+
#[error(transparent)]
139+
SetIntervalMiningConfigInvalid(#[from] IntervalConfigConversionError),
134140
/// The `hardhat_setNextBlockBaseFeePerGas` method is not supported due to
135141
/// an older hardfork.
136142
#[error("hardhat_setNextBlockBaseFeePerGas is disabled because EIP-1559 is not active")]
@@ -229,6 +235,8 @@ impl<LoggerErrorT: Debug> From<ProviderError<LoggerErrorT>> for jsonrpc::Error {
229235
ProviderError::Serialization(_) => INVALID_INPUT,
230236
ProviderError::SetAccountNonceLowerThanCurrent { .. } => INVALID_INPUT,
231237
ProviderError::SetAccountNonceWithPendingTransactions => INTERNAL_ERROR,
238+
ProviderError::SetBlockGasLimitMustBeGreaterThanZero => INVALID_INPUT,
239+
ProviderError::SetIntervalMiningConfigInvalid(_) => INVALID_PARAMS,
232240
ProviderError::SetMinGasPriceUnsupported => INVALID_INPUT,
233241
ProviderError::SetNextBlockBaseFeePerGasUnsupported { .. } => INVALID_INPUT,
234242
ProviderError::SetNextPrevRandaoUnsupported { .. } => INVALID_INPUT,

0 commit comments

Comments
 (0)
Please sign in to comment.