mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
feat: add reth-revm crate (#1526)
This commit is contained in:
15
Cargo.lock
generated
15
Cargo.lock
generated
@ -4598,6 +4598,7 @@ dependencies = [
|
||||
"reth-interfaces",
|
||||
"reth-primitives",
|
||||
"reth-provider",
|
||||
"reth-revm",
|
||||
"reth-rlp",
|
||||
"revm",
|
||||
"rlp",
|
||||
@ -4843,6 +4844,16 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reth-revm"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"reth-interfaces",
|
||||
"reth-primitives",
|
||||
"reth-provider",
|
||||
"revm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reth-rlp"
|
||||
version = "0.1.2"
|
||||
@ -4887,11 +4898,11 @@ dependencies = [
|
||||
"jsonwebtoken",
|
||||
"pin-project",
|
||||
"rand 0.8.5",
|
||||
"reth-executor",
|
||||
"reth-interfaces",
|
||||
"reth-network-api",
|
||||
"reth-primitives",
|
||||
"reth-provider",
|
||||
"reth-revm",
|
||||
"reth-rlp",
|
||||
"reth-rpc-api",
|
||||
"reth-rpc-engine-api",
|
||||
@ -4953,6 +4964,7 @@ dependencies = [
|
||||
"reth-interfaces",
|
||||
"reth-primitives",
|
||||
"reth-provider",
|
||||
"reth-revm",
|
||||
"reth-rlp",
|
||||
"reth-rpc-types",
|
||||
"thiserror",
|
||||
@ -5048,6 +5060,7 @@ dependencies = [
|
||||
"reth-metrics-derive",
|
||||
"reth-primitives",
|
||||
"reth-provider",
|
||||
"reth-revm",
|
||||
"reth-rlp",
|
||||
"reth-staged-sync",
|
||||
"serde",
|
||||
|
||||
@ -16,6 +16,7 @@ members = [
|
||||
"crates/net/network",
|
||||
"crates/net/downloaders",
|
||||
"crates/primitives",
|
||||
"crates/revm",
|
||||
"crates/rlp",
|
||||
"crates/rlp/rlp-derive",
|
||||
"crates/rpc/ipc",
|
||||
|
||||
@ -10,6 +10,7 @@ readme = "README.md"
|
||||
# reth
|
||||
reth-primitives = { path = "../primitives" }
|
||||
reth-interfaces = { path = "../interfaces" }
|
||||
reth-revm = { path = "../revm" }
|
||||
reth-rlp = { path = "../rlp" }
|
||||
reth-db = { path = "../storage/db" }
|
||||
reth-provider = { path = "../storage/provider" }
|
||||
|
||||
@ -1,22 +1,22 @@
|
||||
use crate::{
|
||||
config::{revm_spec, WEI_2ETH, WEI_3ETH, WEI_5ETH},
|
||||
execution_result::{
|
||||
AccountChangeSet, AccountInfoChangeSet, ExecutionResult, TransactionChangeSet,
|
||||
},
|
||||
revm_wrap::{self, into_reth_log, to_reth_acc, SubState},
|
||||
use crate::execution_result::{
|
||||
AccountChangeSet, AccountInfoChangeSet, ExecutionResult, TransactionChangeSet,
|
||||
};
|
||||
use hashbrown::hash_map::Entry;
|
||||
use reth_interfaces::executor::{BlockExecutor, Error};
|
||||
use reth_primitives::{
|
||||
bloom::logs_bloom, Account, Address, Block, Bloom, ChainSpec, Hardfork, Head, Header, Log,
|
||||
Receipt, TransactionSigned, H256, U256,
|
||||
bloom::logs_bloom, Account, Address, Block, Bloom, ChainSpec, Hardfork, Header, Log, Receipt,
|
||||
TransactionSigned, H256, U256,
|
||||
};
|
||||
use reth_provider::StateProvider;
|
||||
use reth_revm::{
|
||||
config::{WEI_2ETH, WEI_3ETH, WEI_5ETH},
|
||||
database::SubState,
|
||||
env::{fill_block_env, fill_cfg_env, fill_tx_env},
|
||||
into_reth_log, to_reth_acc,
|
||||
};
|
||||
use revm::{
|
||||
db::AccountState,
|
||||
primitives::{
|
||||
Account as RevmAccount, AccountInfo, AnalysisKind, Bytecode, ResultAndState, SpecId,
|
||||
},
|
||||
primitives::{Account as RevmAccount, AccountInfo, Bytecode, ResultAndState, SpecId},
|
||||
EVM,
|
||||
};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
@ -63,24 +63,11 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn init_block_env(&mut self, header: &Header, total_difficulty: U256) {
|
||||
let spec_id = revm_spec(
|
||||
self.chain_spec,
|
||||
Head {
|
||||
number: header.number,
|
||||
timestamp: header.timestamp,
|
||||
difficulty: header.difficulty,
|
||||
total_difficulty,
|
||||
hash: Default::default(),
|
||||
},
|
||||
);
|
||||
|
||||
self.evm.env.cfg.chain_id = U256::from(self.chain_spec.chain().id());
|
||||
self.evm.env.cfg.spec_id = spec_id;
|
||||
self.evm.env.cfg.perf_all_precompiles_have_balance = false;
|
||||
self.evm.env.cfg.perf_analyse_created_bytecodes = AnalysisKind::Raw;
|
||||
|
||||
revm_wrap::fill_block_env(&mut self.evm.env.block, header, spec_id >= SpecId::MERGE);
|
||||
/// Initializes the config and block env.
|
||||
fn init_env(&mut self, header: &Header, total_difficulty: U256) {
|
||||
fill_cfg_env(&mut self.evm.env.cfg, self.chain_spec, header, total_difficulty);
|
||||
let after_merge = self.evm.env.cfg.spec_id >= SpecId::MERGE;
|
||||
fill_block_env(&mut self.evm.env.block, header, after_merge);
|
||||
}
|
||||
|
||||
/// Commit change to database and return change diff that is used to update state and create
|
||||
@ -356,7 +343,7 @@ where
|
||||
) -> Result<ExecutionResult, Error> {
|
||||
let senders = self.recover_senders(&block.body, senders)?;
|
||||
|
||||
self.init_block_env(&block.header, total_difficulty);
|
||||
self.init_env(&block.header, total_difficulty);
|
||||
|
||||
let mut cumulative_gas_used = 0;
|
||||
// output of execution
|
||||
@ -374,7 +361,7 @@ where
|
||||
}
|
||||
|
||||
// Fill revm structure.
|
||||
revm_wrap::fill_tx_env(&mut self.evm.env.tx, transaction, sender);
|
||||
fill_tx_env(&mut self.evm.env.tx, transaction, sender);
|
||||
|
||||
// Execute transaction.
|
||||
let out = if self.use_printer_tracer {
|
||||
@ -507,12 +494,12 @@ pub fn execute<DB: StateProvider>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::revm_wrap::State;
|
||||
use reth_primitives::{
|
||||
hex_literal::hex, keccak256, Account, Address, Bytes, ChainSpecBuilder, ForkCondition,
|
||||
StorageKey, H256, MAINNET, U256,
|
||||
};
|
||||
use reth_provider::{AccountProvider, BlockHashProvider, StateProvider};
|
||||
use reth_revm::database::State;
|
||||
use reth_rlp::Decodable;
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
|
||||
@ -7,12 +7,9 @@
|
||||
|
||||
//! Reth executor executes transaction in block of data.
|
||||
|
||||
pub mod config;
|
||||
pub mod eth_dao_fork;
|
||||
|
||||
/// Execution result types
|
||||
pub mod execution_result;
|
||||
/// Executor
|
||||
pub mod executor;
|
||||
/// Wrapper around revm database and types
|
||||
pub mod revm_wrap;
|
||||
|
||||
15
crates/revm/Cargo.toml
Normal file
15
crates/revm/Cargo.toml
Normal file
@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "reth-revm"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/paradigmxyz/reth"
|
||||
description = "reth specific revm utilities"
|
||||
|
||||
[dependencies]
|
||||
# reth
|
||||
reth-primitives = { path = "../primitives" }
|
||||
reth-interfaces = { path = "../interfaces" }
|
||||
reth-provider = { path = "../storage/provider" }
|
||||
|
||||
revm = { version = "3.0.0"}
|
||||
34
crates/revm/src/compat.rs
Normal file
34
crates/revm/src/compat.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use reth_primitives::{Account, Log as RethLog, H160, H256, KECCAK_EMPTY};
|
||||
use revm::primitives::{AccountInfo, Log};
|
||||
|
||||
/// Check equality between [`reth_primitives::Log`] and [`revm::primitives::Log`]
|
||||
pub fn is_log_equal(revm_log: &Log, reth_log: &reth_primitives::Log) -> bool {
|
||||
revm_log.topics.len() == reth_log.topics.len() &&
|
||||
revm_log.address.0 == reth_log.address.0 &&
|
||||
revm_log.data == reth_log.data.0 &&
|
||||
!revm_log
|
||||
.topics
|
||||
.iter()
|
||||
.zip(reth_log.topics.iter())
|
||||
.any(|(revm_topic, reth_topic)| revm_topic.0 != reth_topic.0)
|
||||
}
|
||||
|
||||
/// Into reth primitive [Log] from [revm::primitives::Log].
|
||||
pub fn into_reth_log(log: Log) -> RethLog {
|
||||
RethLog {
|
||||
address: H160(log.address.0),
|
||||
topics: log.topics.into_iter().map(|h| H256(h.0)).collect(),
|
||||
data: log.data.into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create reth primitive [Account] from [revm::primitives::AccountInfo].
|
||||
/// Check if revm bytecode hash is [KECCAK_EMPTY] and put None to reth [Account]
|
||||
pub fn to_reth_acc(revm_acc: &AccountInfo) -> Account {
|
||||
let code_hash = revm_acc.code_hash;
|
||||
Account {
|
||||
balance: revm_acc.balance,
|
||||
nonce: revm_acc.nonce,
|
||||
bytecode_hash: if code_hash == KECCAK_EMPTY { None } else { Some(code_hash) },
|
||||
}
|
||||
}
|
||||
63
crates/revm/src/database.rs
Normal file
63
crates/revm/src/database.rs
Normal file
@ -0,0 +1,63 @@
|
||||
use reth_interfaces::Error;
|
||||
use reth_primitives::{H160, H256, KECCAK_EMPTY, U256};
|
||||
use reth_provider::StateProvider;
|
||||
use revm::{
|
||||
db::{CacheDB, DatabaseRef},
|
||||
primitives::{AccountInfo, Bytecode},
|
||||
};
|
||||
|
||||
/// SubState of database. Uses revm internal cache with binding to reth StateProvider trait.
|
||||
pub type SubState<DB> = CacheDB<State<DB>>;
|
||||
|
||||
/// Wrapper around StateProvider that implements revm database trait
|
||||
pub struct State<DB: StateProvider>(pub DB);
|
||||
|
||||
impl<DB: StateProvider> State<DB> {
|
||||
/// Create new State with generic StateProvider.
|
||||
pub fn new(db: DB) -> Self {
|
||||
Self(db)
|
||||
}
|
||||
|
||||
/// Return inner state reference
|
||||
pub fn state(&self) -> &DB {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Return inner state mutable reference
|
||||
pub fn state_mut(&mut self) -> &mut DB {
|
||||
&mut self.0
|
||||
}
|
||||
|
||||
/// Consume State and return inner StateProvider.
|
||||
pub fn into_inner(self) -> DB {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<DB: StateProvider> DatabaseRef for State<DB> {
|
||||
type Error = Error;
|
||||
|
||||
fn basic(&self, address: H160) -> Result<Option<AccountInfo>, Self::Error> {
|
||||
Ok(self.0.basic_account(address)?.map(|account| AccountInfo {
|
||||
balance: account.balance,
|
||||
nonce: account.nonce,
|
||||
code_hash: account.bytecode_hash.unwrap_or(KECCAK_EMPTY),
|
||||
code: None,
|
||||
}))
|
||||
}
|
||||
|
||||
fn code_by_hash(&self, code_hash: H256) -> Result<Bytecode, Self::Error> {
|
||||
let bytecode = self.0.bytecode_by_hash(code_hash)?.unwrap_or_default();
|
||||
Ok(Bytecode::new_raw(bytecode.0))
|
||||
}
|
||||
|
||||
fn storage(&self, address: H160, index: U256) -> Result<U256, Self::Error> {
|
||||
let index = H256(index.to_be_bytes());
|
||||
let ret = self.0.storage(address, index)?.unwrap_or_default();
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
fn block_hash(&self, number: U256) -> Result<H256, Self::Error> {
|
||||
Ok(self.0.block_hash(number)?.unwrap_or_default())
|
||||
}
|
||||
}
|
||||
@ -1,70 +1,33 @@
|
||||
use reth_interfaces::Error;
|
||||
use crate::config::revm_spec;
|
||||
use reth_primitives::{
|
||||
Account, Address, Header, Log as RethLog, Transaction, TransactionKind, TransactionSigned,
|
||||
TxEip1559, TxEip2930, TxLegacy, H160, H256, KECCAK_EMPTY, U256,
|
||||
};
|
||||
use reth_provider::StateProvider;
|
||||
use revm::{
|
||||
db::{CacheDB, DatabaseRef},
|
||||
primitives::{AccountInfo, BlockEnv, Bytecode, Log, TransactTo, TxEnv},
|
||||
Address, ChainSpec, Head, Header, Transaction, TransactionKind, TransactionSigned, TxEip1559,
|
||||
TxEip2930, TxLegacy, U256,
|
||||
};
|
||||
use revm::primitives::{AnalysisKind, BlockEnv, CfgEnv, TransactTo, TxEnv};
|
||||
|
||||
/// SubState of database. Uses revm internal cache with binding to reth StateProvider trait.
|
||||
pub type SubState<DB> = CacheDB<State<DB>>;
|
||||
/// Fill [CfgEnv] fields according to the chain spec and given header
|
||||
pub fn fill_cfg_env(
|
||||
cfg_env: &mut CfgEnv,
|
||||
chain_spec: &ChainSpec,
|
||||
header: &Header,
|
||||
total_difficulty: U256,
|
||||
) {
|
||||
let spec_id = revm_spec(
|
||||
chain_spec,
|
||||
Head {
|
||||
number: header.number,
|
||||
timestamp: header.timestamp,
|
||||
difficulty: header.difficulty,
|
||||
total_difficulty,
|
||||
hash: Default::default(),
|
||||
},
|
||||
);
|
||||
|
||||
/// Wrapper around StateProvider that implements revm database trait
|
||||
pub struct State<DB: StateProvider>(pub DB);
|
||||
|
||||
impl<DB: StateProvider> State<DB> {
|
||||
/// Create new State with generic StateProvider.
|
||||
pub fn new(db: DB) -> Self {
|
||||
Self(db)
|
||||
}
|
||||
|
||||
/// Return inner state reference
|
||||
pub fn state(&self) -> &DB {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Return inner state mutable reference
|
||||
pub fn state_mut(&mut self) -> &mut DB {
|
||||
&mut self.0
|
||||
}
|
||||
|
||||
/// Consume State and return inner StateProvider.
|
||||
pub fn into_inner(self) -> DB {
|
||||
self.0
|
||||
}
|
||||
cfg_env.chain_id = U256::from(chain_spec.chain().id());
|
||||
cfg_env.spec_id = spec_id;
|
||||
cfg_env.perf_all_precompiles_have_balance = false;
|
||||
cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Raw;
|
||||
}
|
||||
|
||||
impl<DB: StateProvider> DatabaseRef for State<DB> {
|
||||
type Error = Error;
|
||||
|
||||
fn basic(&self, address: H160) -> Result<Option<AccountInfo>, Self::Error> {
|
||||
Ok(self.0.basic_account(address)?.map(|account| AccountInfo {
|
||||
balance: account.balance,
|
||||
nonce: account.nonce,
|
||||
code_hash: account.bytecode_hash.unwrap_or(KECCAK_EMPTY),
|
||||
code: None,
|
||||
}))
|
||||
}
|
||||
|
||||
fn code_by_hash(&self, code_hash: H256) -> Result<Bytecode, Self::Error> {
|
||||
let bytecode = self.0.bytecode_by_hash(code_hash)?.unwrap_or_default();
|
||||
Ok(Bytecode::new_raw(bytecode.0))
|
||||
}
|
||||
|
||||
fn storage(&self, address: H160, index: U256) -> Result<U256, Self::Error> {
|
||||
let index = H256(index.to_be_bytes());
|
||||
let ret = self.0.storage(address, index)?.unwrap_or_default();
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
fn block_hash(&self, number: U256) -> Result<H256, Self::Error> {
|
||||
Ok(self.0.block_hash(number)?.unwrap_or_default())
|
||||
}
|
||||
}
|
||||
|
||||
/// Fill block environment from Block.
|
||||
pub fn fill_block_env(block_env: &mut BlockEnv, header: &Header, after_merge: bool) {
|
||||
block_env.number = U256::from(header.number);
|
||||
@ -179,35 +142,3 @@ pub fn fill_tx_env(tx_env: &mut TxEnv, transaction: &TransactionSigned, sender:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Check equality between [`reth_primitives::Log`] and [`revm::primitives::Log`]
|
||||
pub fn is_log_equal(revm_log: &Log, reth_log: &reth_primitives::Log) -> bool {
|
||||
revm_log.topics.len() == reth_log.topics.len() &&
|
||||
revm_log.address.0 == reth_log.address.0 &&
|
||||
revm_log.data == reth_log.data.0 &&
|
||||
!revm_log
|
||||
.topics
|
||||
.iter()
|
||||
.zip(reth_log.topics.iter())
|
||||
.any(|(revm_topic, reth_topic)| revm_topic.0 != reth_topic.0)
|
||||
}
|
||||
|
||||
/// Into reth primitive [Log] from [revm::primitives::Log].
|
||||
pub fn into_reth_log(log: Log) -> RethLog {
|
||||
RethLog {
|
||||
address: H160(log.address.0),
|
||||
topics: log.topics.into_iter().map(|h| H256(h.0)).collect(),
|
||||
data: log.data.into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create reth primitive [Account] from [revm::primitives::AccountInfo].
|
||||
/// Check if revm bytecode hash is [KECCAK_EMPTY] and put None to reth [Account]
|
||||
pub fn to_reth_acc(revm_acc: &AccountInfo) -> Account {
|
||||
let code_hash = revm_acc.code_hash;
|
||||
Account {
|
||||
balance: revm_acc.balance,
|
||||
nonce: revm_acc.nonce,
|
||||
bytecode_hash: if code_hash == KECCAK_EMPTY { None } else { Some(code_hash) },
|
||||
}
|
||||
}
|
||||
20
crates/revm/src/lib.rs
Normal file
20
crates/revm/src/lib.rs
Normal file
@ -0,0 +1,20 @@
|
||||
#![warn(missing_docs, unreachable_pub, unused_crate_dependencies)]
|
||||
#![deny(unused_must_use, rust_2018_idioms)]
|
||||
#![doc(test(
|
||||
no_crate_inject,
|
||||
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
|
||||
))]
|
||||
|
||||
//! revm utils and implementations specific to reth.
|
||||
|
||||
pub mod config;
|
||||
|
||||
/// Contains glue code for integrating reth database into revm's [Database](revm::Database).
|
||||
pub mod database;
|
||||
|
||||
/// Helpers for configuring revm [Env](revm::primitives::Env)
|
||||
pub mod env;
|
||||
|
||||
/// Helpers for type compatibility between reth and revm types
|
||||
mod compat;
|
||||
pub use compat::*;
|
||||
@ -13,6 +13,7 @@ reth-interfaces = { path = "../../interfaces" }
|
||||
reth-provider = { path = "../../storage/provider" }
|
||||
reth-rlp = { path = "../../rlp" }
|
||||
reth-executor = { path = "../../executor" }
|
||||
reth-revm = { path = "../../revm" }
|
||||
reth-rpc-types = { path = "../rpc-types" }
|
||||
|
||||
# async
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
use crate::{message::EngineApiMessageVersion, EngineApiError, EngineApiMessage, EngineApiResult};
|
||||
use futures::StreamExt;
|
||||
use reth_executor::{
|
||||
executor,
|
||||
revm_wrap::{State, SubState},
|
||||
};
|
||||
use reth_executor::executor;
|
||||
use reth_interfaces::consensus::ForkchoiceState;
|
||||
use reth_primitives::{
|
||||
proofs::{self, EMPTY_LIST_HASH},
|
||||
@ -11,6 +8,7 @@ use reth_primitives::{
|
||||
H64, U256,
|
||||
};
|
||||
use reth_provider::{BlockProvider, HeaderProvider, StateProviderFactory};
|
||||
use reth_revm::database::{State, SubState};
|
||||
use reth_rlp::Decodable;
|
||||
use reth_rpc_types::engine::{
|
||||
ExecutionPayload, ExecutionPayloadBodies, ForkchoiceUpdated, PayloadAttributes, PayloadStatus,
|
||||
|
||||
@ -19,7 +19,7 @@ reth-provider = { path = "../../storage/provider", features = ["test-utils"] }
|
||||
reth-transaction-pool = { path = "../../transaction-pool", features = ["test-utils"]}
|
||||
reth-network-api = { path = "../../net/network-api", features = ["test-utils"] }
|
||||
reth-rpc-engine-api = { path = "../rpc-engine-api" }
|
||||
reth-executor = { path = "../../executor" }
|
||||
reth-revm = { path = "../../revm" }
|
||||
reth-tasks = { path = "../../tasks" }
|
||||
|
||||
# eth
|
||||
|
||||
@ -3,9 +3,9 @@
|
||||
#![allow(unused)] // TODO rm later
|
||||
|
||||
use crate::{eth::error::EthResult, EthApi};
|
||||
use reth_executor::revm_wrap::{State, SubState};
|
||||
use reth_primitives::{BlockId, U256};
|
||||
use reth_provider::{BlockProvider, StateProvider, StateProviderFactory};
|
||||
use reth_revm::database::{State, SubState};
|
||||
use reth_rpc_types::CallRequest;
|
||||
use revm::primitives::{BlockEnv, Env, ResultAndState};
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ normal = [
|
||||
reth-primitives = { path = "../primitives" }
|
||||
reth-interfaces = { path = "../interfaces" }
|
||||
reth-executor = { path = "../executor" }
|
||||
reth-revm = { path = "../revm" }
|
||||
reth-rlp = { path = "../rlp" }
|
||||
reth-db = { path = "../storage/db" }
|
||||
reth-provider = { path = "../storage/provider" }
|
||||
|
||||
@ -9,13 +9,11 @@ use reth_db::{
|
||||
tables,
|
||||
transaction::{DbTx, DbTxMut},
|
||||
};
|
||||
use reth_executor::{
|
||||
execution_result::AccountChangeSet,
|
||||
revm_wrap::{State, SubState},
|
||||
};
|
||||
use reth_executor::execution_result::AccountChangeSet;
|
||||
use reth_interfaces::provider::Error as ProviderError;
|
||||
use reth_primitives::{Address, Block, ChainSpec, Hardfork, StorageEntry, H256, MAINNET, U256};
|
||||
use reth_provider::{LatestStateProviderRef, Transaction};
|
||||
use reth_revm::database::{State, SubState};
|
||||
use std::fmt::Debug;
|
||||
use tracing::*;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user