diff --git a/crates/edr_evm/src/mempool.rs b/crates/edr_evm/src/mempool.rs index 6581640519..77eb30cf57 100644 --- a/crates/edr_evm/src/mempool.rs +++ b/crates/edr_evm/src/mempool.rs @@ -1,4 +1,4 @@ -use std::{cmp::Ordering, fmt::Debug}; +use std::{cmp::Ordering, fmt::Debug, num::NonZeroU64}; use edr_eth::{Address, B256, U256}; use indexmap::{map::Entry, IndexMap}; @@ -84,7 +84,7 @@ pub enum MemPoolAddTransactionError { #[error("Transaction gas limit is {transaction_gas_limit} and exceeds block gas limit of {block_gas_limit}")] ExceedsBlockGasLimit { /// The block gas limit - block_gas_limit: u64, + block_gas_limit: NonZeroU64, /// The transaction gas limit transaction_gas_limit: u64, }, @@ -166,7 +166,7 @@ impl OrderedTransaction { #[derive(Clone, Debug)] pub struct MemPool { /// The block's gas limit - block_gas_limit: u64, + block_gas_limit: NonZeroU64, /// Transactions that can be executed now pending_transactions: IndexMap>, /// Mapping of transaction hashes to transaction @@ -179,7 +179,7 @@ pub struct MemPool { impl MemPool { /// Constructs a new [`MemPool`] with the specified block gas limit. - pub fn new(block_gas_limit: u64) -> Self { + pub fn new(block_gas_limit: NonZeroU64) -> Self { Self { block_gas_limit, pending_transactions: IndexMap::new(), @@ -190,12 +190,12 @@ impl MemPool { } /// Retrieves the instance's block gas limit. - pub fn block_gas_limit(&self) -> u64 { + pub fn block_gas_limit(&self) -> NonZeroU64 { self.block_gas_limit } /// Sets the instance's block gas limit. - pub fn set_block_gas_limit(&mut self, state: &S, limit: u64) -> Result<(), S::Error> + pub fn set_block_gas_limit(&mut self, state: &S, limit: NonZeroU64) -> Result<(), S::Error> where S: StateRef + ?Sized, S::Error: Debug, @@ -270,7 +270,7 @@ impl MemPool { transaction: ExecutableTransaction, ) -> Result<(), MemPoolAddTransactionError> { let transaction_gas_limit = transaction.gas_limit(); - if transaction_gas_limit > self.block_gas_limit { + if transaction_gas_limit > self.block_gas_limit.get() { return Err(MemPoolAddTransactionError::ExceedsBlockGasLimit { block_gas_limit: self.block_gas_limit, transaction_gas_limit, @@ -380,10 +380,10 @@ impl MemPool { { fn is_valid_tx( transaction: &ExecutableTransaction, - block_gas_limit: u64, + block_gas_limit: NonZeroU64, sender: &AccountInfo, ) -> bool { - transaction.gas_limit() <= block_gas_limit + transaction.gas_limit() <= block_gas_limit.get() && transaction.upfront_cost() <= sender.balance // Remove all mined transactions && transaction.nonce() >= sender.nonce diff --git a/crates/edr_evm/src/test_utils.rs b/crates/edr_evm/src/test_utils.rs index ef5973b125..e8e9469d18 100644 --- a/crates/edr_evm/src/test_utils.rs +++ b/crates/edr_evm/src/test_utils.rs @@ -1,3 +1,5 @@ +use std::num::NonZeroU64; + use edr_eth::{ transaction::{Eip1559TransactionRequest, Eip155TransactionRequest, TransactionKind}, AccountInfo, Address, Bytes, HashMap, SpecId, U256, @@ -23,7 +25,8 @@ impl MemPoolTestFixture { let trie = AccountTrie::with_accounts(&accounts); MemPoolTestFixture { - mem_pool: MemPool::new(10_000_000u64), + // SAFETY: literal is non-zero + mem_pool: MemPool::new(unsafe { NonZeroU64::new_unchecked(10_000_000u64) }), state: TrieState::with_accounts(trie), } } @@ -37,7 +40,7 @@ impl MemPoolTestFixture { } /// Sets the block gas limit. - pub fn set_block_gas_limit(&mut self, block_gas_limit: u64) -> Result<(), StateError> { + pub fn set_block_gas_limit(&mut self, block_gas_limit: NonZeroU64) -> Result<(), StateError> { self.mem_pool .set_block_gas_limit(&self.state, block_gas_limit) } diff --git a/crates/edr_evm/tests/mem_pool.rs b/crates/edr_evm/tests/mem_pool.rs index 0f21ea51bd..35d7b67c44 100644 --- a/crates/edr_evm/tests/mem_pool.rs +++ b/crates/edr_evm/tests/mem_pool.rs @@ -1,5 +1,7 @@ #![cfg(feature = "test-utils")] +use std::num::NonZeroU64; + use edr_eth::{AccountInfo, Address, U256}; use edr_evm::{ state::{AccountModifierFn, StateDebug}, @@ -318,7 +320,7 @@ fn add_transaction_exceeds_block_limit() -> anyhow::Result<()> { let mut fixture = MemPoolTestFixture::with_accounts(&[(sender, AccountInfo::default())]); - let exceeds_block_limit = fixture.mem_pool.block_gas_limit() + 1; + let exceeds_block_limit = fixture.mem_pool.block_gas_limit().get() + 1; let transaction = dummy_eip155_transaction_with_limit(sender, 5, exceeds_block_limit)?; let result = fixture.add_transaction(transaction); @@ -625,23 +627,24 @@ fn last_pending_nonce_some_future_to_pending_queue() -> anyhow::Result<()> { #[test] fn set_block_gas_limit() -> anyhow::Result<()> { - const NEW_GAS_LIMIT: u64 = 15_000_000; + // SAFETY: literal is non-zero + const NEW_GAS_LIMIT: NonZeroU64 = unsafe { NonZeroU64::new_unchecked(15_000_000) }; let sender = Address::random(); let mut fixture = MemPoolTestFixture::with_accounts(&[(sender, AccountInfo::default())]); - assert_eq!(fixture.mem_pool.block_gas_limit(), 10_000_000); + assert_eq!(fixture.mem_pool.block_gas_limit().get(), 10_000_000); fixture.set_block_gas_limit(NEW_GAS_LIMIT)?; assert_eq!(fixture.mem_pool.block_gas_limit(), NEW_GAS_LIMIT); - let transaction = dummy_eip155_transaction_with_limit(sender, 0, NEW_GAS_LIMIT + 1)?; + let transaction = dummy_eip155_transaction_with_limit(sender, 0, NEW_GAS_LIMIT.get() + 1)?; let result = fixture.add_transaction(transaction); assert!(matches!( result, Err(MemPoolAddTransactionError::ExceedsBlockGasLimit { block_gas_limit, transaction_gas_limit }) - if block_gas_limit == NEW_GAS_LIMIT && transaction_gas_limit == NEW_GAS_LIMIT + 1 + if block_gas_limit == NEW_GAS_LIMIT && transaction_gas_limit == NEW_GAS_LIMIT.get() + 1 )); Ok(()) @@ -665,7 +668,8 @@ fn set_block_gas_limit_removes_invalid_transactions() -> anyhow::Result<()> { let future_transactions = fixture.mem_pool.future_transactions().collect::>(); assert_eq!(future_transactions.len(), 1); - fixture.set_block_gas_limit(5_000_000)?; + // SAFETY: literal is non-zero + fixture.set_block_gas_limit(unsafe { NonZeroU64::new_unchecked(5_000_000) })?; let pending_transactions = fixture.mem_pool.pending_transactions().collect::>(); assert_eq!(pending_transactions.len(), 0); @@ -708,7 +712,8 @@ fn set_block_gas_limit_moves_future_to_pending_queue() -> anyhow::Result<()> { assert_eq!(*future_transactions[0].pending(), transaction4); assert_eq!(*future_transactions[1].pending(), transaction5); - fixture.set_block_gas_limit(150_000)?; + // SAFETY: literal is non-zero + fixture.set_block_gas_limit(unsafe { NonZeroU64::new_unchecked(150_000) })?; let pending_transactions = fixture.mem_pool.pending_transactions().collect::>(); assert_eq!(pending_transactions.len(), 1); diff --git a/crates/edr_napi/src/provider/config.rs b/crates/edr_napi/src/provider/config.rs index 03a2987082..f2a5aec2e5 100644 --- a/crates/edr_napi/src/provider/config.rs +++ b/crates/edr_napi/src/provider/config.rs @@ -1,4 +1,5 @@ use std::{ + num::NonZeroU64, path::PathBuf, time::{Duration, SystemTime}, }; @@ -172,7 +173,15 @@ impl TryFrom for edr_provider::MiningConfig { .map(|interval| { let interval = match interval { Either::A(interval) => { - edr_provider::IntervalConfig::Fixed(interval.try_cast()?) + let interval = interval.try_cast()?; + let interval = NonZeroU64::new(interval).ok_or_else(|| { + napi::Error::new( + napi::Status::GenericFailure, + "Interval must be greater than 0", + ) + })?; + + edr_provider::IntervalConfig::Fixed(interval) } Either::B(IntervalRange { min, max }) => edr_provider::IntervalConfig::Range { min: min.try_cast()?, @@ -225,6 +234,14 @@ impl TryFrom for edr_provider::ProviderConfig { ) .collect::>()?; + let block_gas_limit = + NonZeroU64::new(value.block_gas_limit.try_cast()?).ok_or_else(|| { + napi::Error::new( + napi::Status::GenericFailure, + "Block gas limit must be greater than 0", + ) + })?; + Ok(Self { accounts: value .genesis_accounts @@ -235,7 +252,7 @@ impl TryFrom for edr_provider::ProviderConfig { allow_unlimited_contract_size: value.allow_unlimited_contract_size, bail_on_call_failure: value.bail_on_call_failure, bail_on_transaction_failure: value.bail_on_transaction_failure, - block_gas_limit: value.block_gas_limit.try_cast()?, + block_gas_limit, cache_dir: PathBuf::from( value .cache_dir diff --git a/crates/edr_provider/src/config.rs b/crates/edr_provider/src/config.rs index c3da9bced5..0fa99c485f 100644 --- a/crates/edr_provider/src/config.rs +++ b/crates/edr_provider/src/config.rs @@ -1,4 +1,4 @@ -use std::{path::PathBuf, time::SystemTime}; +use std::{num::NonZeroU64, path::PathBuf, time::SystemTime}; use edr_eth::{ block::BlobGas, spec::HardforkActivations, AccountInfo, Address, HashMap, SpecId, B256, U256, @@ -7,12 +7,12 @@ use edr_evm::{alloy_primitives::ChainId, MineOrdering}; use rand::Rng; use serde::{Deserialize, Serialize}; -use crate::{requests::hardhat::rpc_types::ForkConfig, OneUsizeOrTwo}; +use crate::requests::{hardhat::rpc_types::ForkConfig, IntervalConfig as IntervalConfigRequest}; /// Configuration for interval mining. #[derive(Clone, Debug, Deserialize, Serialize)] pub enum IntervalConfig { - Fixed(u64), + Fixed(NonZeroU64), Range { min: u64, max: u64 }, } @@ -20,23 +20,38 @@ impl IntervalConfig { /// Generates a (random) interval based on the configuration. pub fn generate_interval(&self) -> u64 { match self { - IntervalConfig::Fixed(interval) => *interval, + IntervalConfig::Fixed(interval) => interval.get(), IntervalConfig::Range { min, max } => rand::thread_rng().gen_range(*min..=*max), } } } -impl TryFrom for IntervalConfig { - type Error = (); - - fn try_from(value: OneUsizeOrTwo) -> Result { - match value { - OneUsizeOrTwo::One(0) => Err(()), - OneUsizeOrTwo::One(value) => Ok(Self::Fixed(value as u64)), - OneUsizeOrTwo::Two([min, max]) => Ok(Self::Range { - min: min as u64, - max: max as u64, - }), +/// An error that occurs when trying to convert [`IntervalConfigRequest`] to an +/// `Option`. +#[derive(Debug, thiserror::Error)] +pub enum IntervalConfigConversionError { + /// The minimum value in the range is greater than the maximum value. + #[error("Minimum value in range is greater than maximum value")] + MinGreaterThanMax, +} + +impl TryInto> for IntervalConfigRequest { + type Error = IntervalConfigConversionError; + + fn try_into(self) -> Result, Self::Error> { + match self { + Self::FixedOrDisabled(0) => Ok(None), + Self::FixedOrDisabled(value) => { + // Zero implies disabled + Ok(NonZeroU64::new(value).map(IntervalConfig::Fixed)) + } + Self::Range([min, max]) => { + if max >= min { + Ok(Some(IntervalConfig::Range { min, max })) + } else { + Err(IntervalConfigConversionError::MinGreaterThanMax) + } + } } } } @@ -65,7 +80,7 @@ pub struct ProviderConfig { pub bail_on_call_failure: bool, /// Whether to return an `Err` when a `eth_sendTransaction` fails pub bail_on_transaction_failure: bool, - pub block_gas_limit: u64, + pub block_gas_limit: NonZeroU64, pub cache_dir: PathBuf, pub chain_id: ChainId, pub chains: HashMap, diff --git a/crates/edr_provider/src/data.rs b/crates/edr_provider/src/data.rs index 858c8e2c47..078d350d30 100644 --- a/crates/edr_provider/src/data.rs +++ b/crates/edr_provider/src/data.rs @@ -3,12 +3,11 @@ mod call; mod gas; use std::{ - cmp, - cmp::Ordering, + cmp::{self, Ordering}, collections::BTreeMap, ffi::OsString, fmt::Debug, - num::NonZeroUsize, + num::{NonZeroU64, NonZeroUsize}, sync::Arc, time::{Duration, Instant, SystemTime, UNIX_EPOCH}, }; @@ -319,7 +318,7 @@ impl ProviderData { /// Retrieves the gas limit of the next block. pub fn block_gas_limit(&self) -> u64 { - self.mem_pool.block_gas_limit() + self.mem_pool.block_gas_limit().get() } /// Returns the default caller. @@ -1527,7 +1526,7 @@ impl ProviderData { /// Sets the gas limit used for mining new blocks. pub fn set_block_gas_limit( &mut self, - gas_limit: u64, + gas_limit: NonZeroU64, ) -> Result<(), ProviderError> { let state = self.current_state()?; self.mem_pool @@ -1892,11 +1891,7 @@ impl ProviderData { ) -> Result, ProviderError> { options.base_fee = options.base_fee.or(self.next_block_base_fee_per_gas); options.beneficiary = Some(options.beneficiary.unwrap_or(self.beneficiary)); - options.gas_limit = Some( - options - .gas_limit - .unwrap_or_else(|| self.mem_pool.block_gas_limit()), - ); + options.gas_limit = Some(options.gas_limit.unwrap_or_else(|| self.block_gas_limit())); let evm_config = self.create_evm_config(None)?; @@ -2359,7 +2354,7 @@ fn create_blockchain_and_state( config.chain_id, config.hardfork, GenesisBlockOptions { - gas_limit: Some(config.block_gas_limit), + gas_limit: Some(config.block_gas_limit.get()), timestamp: config.initial_date.map(|d| { d.duration_since(UNIX_EPOCH) .expect("initial date must be after UNIX epoch") @@ -3014,7 +3009,11 @@ mod tests { #[test] fn mine_and_commit_block_leaves_unmined_transactions() -> anyhow::Result<()> { let mut fixture = ProviderTestFixture::new_local()?; - fixture.provider_data.set_block_gas_limit(55_000)?; + + // SAFETY: literal is non-zero + fixture + .provider_data + .set_block_gas_limit(unsafe { NonZeroU64::new_unchecked(55_000) })?; // Actual gas usage is 21_000 let transaction1 = fixture.signed_dummy_transaction(0, Some(0))?; @@ -3581,7 +3580,8 @@ mod tests { })); let config = ProviderConfig { - block_gas_limit: 1_000_000, + // SAFETY: literal is non-zero + block_gas_limit: unsafe { NonZeroU64::new_unchecked(1_000_000) }, chain_id: 1, coinbase: Address::ZERO, hardfork: SpecId::LONDON, diff --git a/crates/edr_provider/src/error.rs b/crates/edr_provider/src/error.rs index 5305349a2f..3336e6d5ec 100644 --- a/crates/edr_provider/src/error.rs +++ b/crates/edr_provider/src/error.rs @@ -16,7 +16,7 @@ use edr_evm::{ }; use ethers_core::types::transaction::eip712::Eip712Error; -use crate::data::CreationError; +use crate::{data::CreationError, IntervalConfigConversionError}; #[derive(Debug, thiserror::Error)] pub enum ProviderError { @@ -131,6 +131,12 @@ pub enum ProviderError { /// Cannot set account nonce when the mem pool is not empty #[error("Cannot set account nonce when the transaction pool is not empty")] SetAccountNonceWithPendingTransactions, + /// `evm_setBlockGasLimit` was called with a gas limit of zero. + #[error("Block gas limit must be greater than 0")] + SetBlockGasLimitMustBeGreaterThanZero, + /// The `evm_setIntervalMining` method was called with an invalid interval. + #[error(transparent)] + SetIntervalMiningConfigInvalid(#[from] IntervalConfigConversionError), /// The `hardhat_setNextBlockBaseFeePerGas` method is not supported due to /// an older hardfork. #[error("hardhat_setNextBlockBaseFeePerGas is disabled because EIP-1559 is not active")] @@ -229,6 +235,8 @@ impl From> for jsonrpc::Error { ProviderError::Serialization(_) => INVALID_INPUT, ProviderError::SetAccountNonceLowerThanCurrent { .. } => INVALID_INPUT, ProviderError::SetAccountNonceWithPendingTransactions => INTERNAL_ERROR, + ProviderError::SetBlockGasLimitMustBeGreaterThanZero => INVALID_INPUT, + ProviderError::SetIntervalMiningConfigInvalid(_) => INVALID_PARAMS, ProviderError::SetMinGasPriceUnsupported => INVALID_INPUT, ProviderError::SetNextBlockBaseFeePerGasUnsupported { .. } => INVALID_INPUT, ProviderError::SetNextPrevRandaoUnsupported { .. } => INVALID_INPUT, diff --git a/crates/edr_provider/src/lib.rs b/crates/edr_provider/src/lib.rs index fb70c72b4d..7bcac6e9ee 100644 --- a/crates/edr_provider/src/lib.rs +++ b/crates/edr_provider/src/lib.rs @@ -35,8 +35,8 @@ pub use self::{ logger::{Logger, NoopLogger}, mock::CallOverrideResult, requests::{ - hardhat::rpc_types as hardhat_rpc_types, InvalidRequestReason, MethodInvocation, - OneUsizeOrTwo, ProviderRequest, U64OrUsize, + hardhat::rpc_types as hardhat_rpc_types, IntervalConfig as IntervalConfigRequest, + InvalidRequestReason, MethodInvocation, ProviderRequest, U64OrUsize, }, subscribe::*, }; diff --git a/crates/edr_provider/src/requests.rs b/crates/edr_provider/src/requests.rs index 2ce25abfb2..e22ca57a01 100644 --- a/crates/edr_provider/src/requests.rs +++ b/crates/edr_provider/src/requests.rs @@ -15,7 +15,7 @@ use ::serde::{ }; pub use crate::requests::{ - methods::{MethodInvocation, OneUsizeOrTwo, U64OrUsize}, + methods::{IntervalConfig, MethodInvocation, U64OrUsize}, serde::InvalidRequestReason, }; diff --git a/crates/edr_provider/src/requests/eth/evm.rs b/crates/edr_provider/src/requests/eth/evm.rs index 3793239cf9..200ea63563 100644 --- a/crates/edr_provider/src/requests/eth/evm.rs +++ b/crates/edr_provider/src/requests/eth/evm.rs @@ -1,4 +1,5 @@ use core::fmt::Debug; +use std::num::NonZeroU64; use edr_eth::{block::BlockOptions, U64}; use edr_evm::trace::Trace; @@ -55,7 +56,10 @@ pub fn handle_set_block_gas_limit_request( data: &mut ProviderData, gas_limit: U64, ) -> Result> { - data.set_block_gas_limit(gas_limit.as_limbs()[0])?; + let gas_limit = NonZeroU64::new(gas_limit.as_limbs()[0]) + .ok_or(ProviderError::SetBlockGasLimitMustBeGreaterThanZero)?; + + data.set_block_gas_limit(gas_limit)?; Ok(true) } diff --git a/crates/edr_provider/src/requests/eth/mine.rs b/crates/edr_provider/src/requests/eth/mine.rs index 8e1644ee84..804dd38b00 100644 --- a/crates/edr_provider/src/requests/eth/mine.rs +++ b/crates/edr_provider/src/requests/eth/mine.rs @@ -3,21 +3,16 @@ use std::sync::Arc; use tokio::{runtime, sync::Mutex}; -use crate::{ - data::ProviderData, interval::IntervalMiner, IntervalConfig, OneUsizeOrTwo, ProviderError, -}; +use crate::{data::ProviderData, interval::IntervalMiner, requests, IntervalConfig, ProviderError}; pub fn handle_set_interval_mining( data: Arc>>, interval_miner: &mut Option>, runtime: runtime::Handle, - config: OneUsizeOrTwo, + config: requests::IntervalConfig, ) -> Result> { - let config = IntervalConfig::try_from(config); - - *interval_miner = config - .ok() - .map(|config| IntervalMiner::new(runtime, config, data.clone())); + let config: Option = config.try_into()?; + *interval_miner = config.map(|config| IntervalMiner::new(runtime, config, data.clone())); Ok(true) } diff --git a/crates/edr_provider/src/requests/methods.rs b/crates/edr_provider/src/requests/methods.rs index 049537199f..b3bb2b1a69 100644 --- a/crates/edr_provider/src/requests/methods.rs +++ b/crates/edr_provider/src/requests/methods.rs @@ -263,7 +263,7 @@ pub enum MethodInvocation { EvmSetBlockGasLimit(U64), /// evm_setIntervalMining #[serde(rename = "evm_setIntervalMining", with = "edr_eth::serde::sequence")] - EvmSetIntervalMining(OneUsizeOrTwo), + EvmSetIntervalMining(IntervalConfig), /// evm_setNextBlockTimestamp #[serde( rename = "evm_setNextBlockTimestamp", @@ -482,14 +482,14 @@ impl MethodInvocation { } } -/// an input that can be either a single usize or an array of two usize values +/// an input that can be either a single `u64` or an array of two `u64` values #[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)] #[serde(untagged)] -pub enum OneUsizeOrTwo { - /// a single usize - One(usize), - /// an array of two usize values - Two([usize; 2]), +pub enum IntervalConfig { + /// A fixed value; or disabled, when zero. + FixedOrDisabled(u64), + /// an array of two `u64` values + Range([u64; 2]), } /// an input that can be either a U256 or a usize diff --git a/crates/edr_provider/src/test_utils.rs b/crates/edr_provider/src/test_utils.rs index a3b1b6aa5a..4251431738 100644 --- a/crates/edr_provider/src/test_utils.rs +++ b/crates/edr_provider/src/test_utils.rs @@ -1,4 +1,4 @@ -use std::{convert::Infallible, time::SystemTime}; +use std::{convert::Infallible, num::NonZeroU64, time::SystemTime}; use anyhow::anyhow; use edr_eth::{ @@ -57,7 +57,8 @@ pub fn create_test_config_with_fork(fork: Option) -> ProviderConfig allow_unlimited_contract_size: false, bail_on_call_failure: false, bail_on_transaction_failure: false, - block_gas_limit: 30_000_000, + // SAFETY: literal is non-zero + block_gas_limit: unsafe { NonZeroU64::new_unchecked(30_000_000) }, chain_id: 123, chains: HashMap::new(), coinbase: Address::from(U160::from(1)), diff --git a/crates/edr_provider/tests/eth_request_serialization.rs b/crates/edr_provider/tests/eth_request_serialization.rs index 6b70ab7535..c8eb38c721 100644 --- a/crates/edr_provider/tests/eth_request_serialization.rs +++ b/crates/edr_provider/tests/eth_request_serialization.rs @@ -10,7 +10,7 @@ use edr_eth::{ Address, Bytes, B256, U256, U64, }; use edr_evm::alloy_primitives::U160; -use edr_provider::{MethodInvocation, OneUsizeOrTwo, U64OrUsize}; +use edr_provider::{IntervalConfigRequest, MethodInvocation, U64OrUsize}; use crate::common::{ help_test_method_invocation_serde, help_test_method_invocation_serde_with_expected, @@ -479,12 +479,12 @@ fn test_evm_set_automine() { #[test] fn test_evm_set_interval_mining() { - help_test_method_invocation_serde(MethodInvocation::EvmSetIntervalMining(OneUsizeOrTwo::One( - 1000, - ))); - help_test_method_invocation_serde(MethodInvocation::EvmSetIntervalMining(OneUsizeOrTwo::Two( - [1000, 5000], - ))); + help_test_method_invocation_serde(MethodInvocation::EvmSetIntervalMining( + IntervalConfigRequest::FixedOrDisabled(1000), + )); + help_test_method_invocation_serde(MethodInvocation::EvmSetIntervalMining( + IntervalConfigRequest::Range([1000, 5000]), + )); } #[test] diff --git a/packages/hardhat-core/test/internal/hardhat-network/provider/modules/evm.ts b/packages/hardhat-core/test/internal/hardhat-network/provider/modules/evm.ts index d92f638450..d283aa3ca3 100644 --- a/packages/hardhat-core/test/internal/hardhat-network/provider/modules/evm.ts +++ b/packages/hardhat-core/test/internal/hardhat-network/provider/modules/evm.ts @@ -55,7 +55,7 @@ describe("Evm module", function () { ); }; - describe.skip("evm_increaseTime", async function () { + describe("evm_increaseTime", async function () { it("should increase the offset of time used for block timestamps", async function () { const blockNumber = rpcQuantityToNumber( await this.provider.send("eth_blockNumber") @@ -148,7 +148,7 @@ describe("Evm module", function () { }); }); - describe.skip("evm_setNextBlockTimestamp", async function () { + describe("evm_setNextBlockTimestamp", async function () { for (const { description, prepare } of [ { description: "without any special preparation", @@ -358,7 +358,7 @@ describe("Evm module", function () { } }); - describe.skip("evm_setBlockGasLimit", () => { + describe("evm_setBlockGasLimit", () => { it("validates block gas limit", async function () { await assertInvalidInputError( this.provider, @@ -487,14 +487,12 @@ describe("Evm module", function () { }); }); - describe.skip("evm_mine", async function () { + describe("evm_mine", async function () { it("should mine empty blocks", async function () { const firstBlockNumber = rpcQuantityToNumber( await this.provider.send("eth_blockNumber") ); - console.log("evm_mine", firstBlockNumber); - await this.provider.send("evm_mine"); const block: RpcBlockOutput = await this.provider.send( @@ -614,7 +612,7 @@ describe("Evm module", function () { assertQuantity(block.timestamp, timestamp); }); - describe("tests using sinon", () => { + describe.skip("tests using sinon", () => { let sinonClock: sinon.SinonFakeTimers; beforeEach(() => { @@ -643,7 +641,7 @@ describe("Evm module", function () { }); }); - describe.skip("evm_setAutomine", () => { + describe("evm_setAutomine", () => { it("should allow disabling automine", async function () { await this.provider.send("evm_setAutomine", [false]); const previousBlock = await this.provider.send("eth_blockNumber"); @@ -714,7 +712,7 @@ describe("Evm module", function () { }); }); - describe.skip("evm_setIntervalMining", () => { + describe("evm_setIntervalMining", () => { it("validates blockTime parameter", async function () { await assertInvalidArgumentsError( this.provider, @@ -740,7 +738,7 @@ describe("Evm module", function () { } }); - describe("using sinon", () => { + describe.skip("using sinon", () => { let sinonClock: sinon.SinonFakeTimers; beforeEach(() => { @@ -977,7 +975,7 @@ describe("Evm module", function () { assert.isFalse(reverted2); }); - it.skip("Deletes blocks mined after snapshot", async function () { + it("Deletes blocks mined after snapshot", async function () { const snapshotId: string = await this.provider.send( "evm_snapshot", [] @@ -1020,7 +1018,7 @@ describe("Evm module", function () { assert.isNull(blockByNumber); }); - it.skip("Deletes transactions mined after snapshot", async function () { + it("Deletes transactions mined after snapshot", async function () { const [, from] = await this.provider.send("eth_accounts"); const snapshotId: string = await this.provider.send( @@ -1053,7 +1051,7 @@ describe("Evm module", function () { assert.isNull(txHashAfter); }); - it.skip("Deletes pending transactions added after snapshot", async function () { + it("Deletes pending transactions added after snapshot", async function () { await this.provider.send("evm_setAutomine", [false]); const [, from] = await this.provider.send("eth_accounts"); @@ -1102,7 +1100,7 @@ describe("Evm module", function () { assert.lengthOf(pendingTransactionsAfter, 0); }); - it.skip("Re-adds the transactions that were mined after snapshot to the tx pool", async function () { + it("Re-adds the transactions that were mined after snapshot to the tx pool", async function () { await this.provider.send("evm_setAutomine", [false]); const [, from] = await this.provider.send("eth_accounts"); @@ -1153,7 +1151,7 @@ describe("Evm module", function () { assert.lengthOf(pendingTransactionsAfter, 2); }); - it.skip("TxPool state reverts back correctly to the snapshot state", async function () { + it("TxPool state reverts back correctly to the snapshot state", async function () { await this.provider.send("evm_setAutomine", [false]); const txHash1 = await this.provider.send("eth_sendTransaction", [ @@ -1208,7 +1206,7 @@ describe("Evm module", function () { ); }); - it.skip("Allows resending the same tx after a revert", async function () { + it("Allows resending the same tx after a revert", async function () { const [, from] = await this.provider.send("eth_accounts"); const snapshotId: string = await this.provider.send( @@ -1275,7 +1273,7 @@ describe("Evm module", function () { assert.isTrue(revertedTo1); }); - it.skip("Resets the blockchain so that new blocks are added with the right numbers", async function () { + it("Resets the blockchain so that new blocks are added with the right numbers", async function () { const blockNumber = rpcQuantityToNumber( await this.provider.send("eth_blockNumber") ); @@ -1326,7 +1324,7 @@ describe("Evm module", function () { await assertLatestBlockNumber(this.provider, blockNumber + 4); }); - it.skip("Restores the previous state", async function () { + it("Restores the previous state", async function () { // This is a very coarse test, as we know that the entire state is // managed by the vm, and is restored as a whole const [, from] = await this.provider.send("eth_accounts"); @@ -1438,7 +1436,7 @@ describe("Evm module", function () { }); }); - describe.skip(`${name} provider (allowBlocksWithSameTimestamp)`, function () { + describe(`${name} provider (allowBlocksWithSameTimestamp)`, function () { setCWD(); useProvider({ allowBlocksWithSameTimestamp: true });