mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore: Bump revm to newest (#6357)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
16
Cargo.lock
generated
16
Cargo.lock
generated
@ -7038,17 +7038,20 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "revm"
|
||||
version = "3.5.0"
|
||||
source = "git+https://github.com/bluealloy/revm?branch=reth_freeze#ba28a42393604beeb2da5a339ac47d3d5d3f2271"
|
||||
source = "git+https://github.com/bluealloy/revm?branch=main#773b0b2ba7b961d80e8cb3fcd89b9edf2239f8f3"
|
||||
dependencies = [
|
||||
"auto_impl",
|
||||
"cfg-if",
|
||||
"revm-interpreter",
|
||||
"revm-precompile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "revm-inspectors"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/paradigmxyz/evm-inspectors?rev=e900523#e90052361276aebcdc67cb24d8e2c4d907b6d299"
|
||||
source = "git+https://github.com/paradigmxyz/evm-inspectors?branch=main#a6779fd969da55ff6a30397e8e5fd927001e443f"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"alloy-rpc-trace-types",
|
||||
@ -7065,15 +7068,16 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "revm-interpreter"
|
||||
version = "1.3.0"
|
||||
source = "git+https://github.com/bluealloy/revm?branch=reth_freeze#ba28a42393604beeb2da5a339ac47d3d5d3f2271"
|
||||
source = "git+https://github.com/bluealloy/revm?branch=main#773b0b2ba7b961d80e8cb3fcd89b9edf2239f8f3"
|
||||
dependencies = [
|
||||
"revm-primitives",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "revm-precompile"
|
||||
version = "2.2.0"
|
||||
source = "git+https://github.com/bluealloy/revm?branch=reth_freeze#ba28a42393604beeb2da5a339ac47d3d5d3f2271"
|
||||
source = "git+https://github.com/bluealloy/revm?branch=main#773b0b2ba7b961d80e8cb3fcd89b9edf2239f8f3"
|
||||
dependencies = [
|
||||
"aurora-engine-modexp",
|
||||
"c-kzg",
|
||||
@ -7089,10 +7093,9 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "revm-primitives"
|
||||
version = "1.3.0"
|
||||
source = "git+https://github.com/bluealloy/revm?branch=reth_freeze#ba28a42393604beeb2da5a339ac47d3d5d3f2271"
|
||||
source = "git+https://github.com/bluealloy/revm?branch=main#773b0b2ba7b961d80e8cb3fcd89b9edf2239f8f3"
|
||||
dependencies = [
|
||||
"alloy-primitives",
|
||||
"alloy-rlp",
|
||||
"auto_impl",
|
||||
"bitflags 2.4.2",
|
||||
"bitvec",
|
||||
@ -7614,6 +7617,7 @@ version = "1.0.113"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79"
|
||||
dependencies = [
|
||||
"indexmap 2.2.2",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
|
||||
@ -168,14 +168,14 @@ reth-transaction-pool = { path = "crates/transaction-pool" }
|
||||
reth-trie = { path = "crates/trie" }
|
||||
|
||||
# revm
|
||||
revm = { git = "https://github.com/bluealloy/revm", branch = "reth_freeze", features = [
|
||||
revm = { git = "https://github.com/bluealloy/revm", branch = "main", features = [
|
||||
"std",
|
||||
"secp256k1",
|
||||
], default-features = false }
|
||||
revm-primitives = { git = "https://github.com/bluealloy/revm", branch = "reth_freeze", features = [
|
||||
revm-primitives = { git = "https://github.com/bluealloy/revm", branch = "main", features = [
|
||||
"std",
|
||||
], default-features = false }
|
||||
revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev="e900523"}
|
||||
revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", branch = "main" }
|
||||
|
||||
# eth
|
||||
alloy-chains = { version = "0.1", feature = ["serde", "rlp", "arbitrary"] }
|
||||
@ -220,7 +220,7 @@ strum = "0.26"
|
||||
rayon = "1.7"
|
||||
itertools = "0.12"
|
||||
parking_lot = "0.12"
|
||||
metrics = "0.21.1" # Needed for `metrics-macro` to resolve the crate using `::metrics` notation
|
||||
metrics = "0.21.1" # Needed for `metrics-macro` to resolve the crate using `::metrics` notation
|
||||
hex-literal = "0.4"
|
||||
once_cell = "1.17"
|
||||
syn = "2.0"
|
||||
|
||||
@ -55,13 +55,19 @@ reth-trie.workspace = true
|
||||
reth-nippy-jar.workspace = true
|
||||
reth-node-api.workspace = true
|
||||
reth-node-ethereum.workspace = true
|
||||
reth-node-optimism = { workspace = true, optional = true, features = ["optimism"] }
|
||||
reth-node-optimism = { workspace = true, optional = true, features = [
|
||||
"optimism",
|
||||
] }
|
||||
reth-node-core.workspace = true
|
||||
|
||||
# crypto
|
||||
alloy-rlp.workspace = true
|
||||
alloy-chains.workspace = true
|
||||
secp256k1 = { workspace = true, features = ["global-context", "rand-std", "recovery"] }
|
||||
secp256k1 = { workspace = true, features = [
|
||||
"global-context",
|
||||
"rand-std",
|
||||
"recovery",
|
||||
] }
|
||||
revm-inspectors.workspace = true
|
||||
|
||||
# tracing
|
||||
@ -93,7 +99,12 @@ ratatui = "0.25.0"
|
||||
human_bytes = "0.4.1"
|
||||
|
||||
# async
|
||||
tokio = { workspace = true, features = ["sync", "macros", "time", "rt-multi-thread"] }
|
||||
tokio = { workspace = true, features = [
|
||||
"sync",
|
||||
"macros",
|
||||
"time",
|
||||
"rt-multi-thread",
|
||||
] }
|
||||
futures.workspace = true
|
||||
pin-project.workspace = true
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::{validate_version_specific_fields, AttributesValidationError, EngineApiMessageVersion};
|
||||
use reth_primitives::{
|
||||
revm::config::revm_spec_by_timestamp_after_merge,
|
||||
revm_primitives::{BlobExcessGasAndPrice, BlockEnv, CfgEnv, SpecId},
|
||||
revm_primitives::{BlobExcessGasAndPrice, BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId},
|
||||
Address, ChainSpec, Header, SealedBlock, Withdrawals, B256, U256,
|
||||
};
|
||||
use reth_rpc_types::{
|
||||
@ -74,8 +74,8 @@ pub trait PayloadBuilderAttributes: Send + Sync + std::fmt::Debug {
|
||||
/// Returns the withdrawals for the running payload job.
|
||||
fn withdrawals(&self) -> &Withdrawals;
|
||||
|
||||
/// Returns the configured [CfgEnv] and [BlockEnv] for the targeted payload (that has the
|
||||
/// `parent` as its parent).
|
||||
/// Returns the configured [CfgEnvWithHandlerCfg] and [BlockEnv] for the targeted payload (that
|
||||
/// has the `parent` as its parent).
|
||||
///
|
||||
/// The `chain_spec` is used to determine the correct chain id and hardfork for the payload
|
||||
/// based on its timestamp.
|
||||
@ -83,19 +83,18 @@ pub trait PayloadBuilderAttributes: Send + Sync + std::fmt::Debug {
|
||||
/// Block related settings are derived from the `parent` block and the configured attributes.
|
||||
///
|
||||
/// NOTE: This is only intended for beacon consensus (after merge).
|
||||
fn cfg_and_block_env(&self, chain_spec: &ChainSpec, parent: &Header) -> (CfgEnv, BlockEnv) {
|
||||
// TODO: should be different once revm has configurable cfgenv
|
||||
fn cfg_and_block_env(
|
||||
&self,
|
||||
chain_spec: &ChainSpec,
|
||||
parent: &Header,
|
||||
) -> (CfgEnvWithHandlerCfg, BlockEnv) {
|
||||
// TODO: should be different once revm has configurable CfgEnvWithHandlerCfg
|
||||
// configure evm env based on parent block
|
||||
let mut cfg = CfgEnv::default();
|
||||
cfg.chain_id = chain_spec.chain().id();
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
{
|
||||
cfg.optimism = chain_spec.is_optimism();
|
||||
}
|
||||
|
||||
// ensure we're not missing any timestamp based hardforks
|
||||
cfg.spec_id = revm_spec_by_timestamp_after_merge(chain_spec, self.timestamp());
|
||||
let spec_id = revm_spec_by_timestamp_after_merge(chain_spec, self.timestamp());
|
||||
|
||||
// if the parent block did not have excess blob gas (i.e. it was pre-cancun), but it is
|
||||
// cancun now, we need to set the excess blob gas to the default value
|
||||
@ -103,7 +102,7 @@ pub trait PayloadBuilderAttributes: Send + Sync + std::fmt::Debug {
|
||||
.next_block_excess_blob_gas()
|
||||
.map_or_else(
|
||||
|| {
|
||||
if cfg.spec_id == SpecId::CANCUN {
|
||||
if spec_id == SpecId::CANCUN {
|
||||
// default excess blob gas is zero
|
||||
Some(0)
|
||||
} else {
|
||||
@ -131,7 +130,7 @@ pub trait PayloadBuilderAttributes: Send + Sync + std::fmt::Debug {
|
||||
blob_excess_gas_and_price,
|
||||
};
|
||||
|
||||
(cfg, block_env)
|
||||
(CfgEnvWithHandlerCfg::new(cfg, spec_id), block_env)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use reth_primitives::{revm::env::fill_block_env, Address, ChainSpec, Header, Transaction, U256};
|
||||
use revm_primitives::{BlockEnv, CfgEnv, SpecId, TxEnv};
|
||||
use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, SpecId, TxEnv};
|
||||
|
||||
/// This represents the set of methods used to configure the EVM before execution.
|
||||
pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone {
|
||||
@ -11,9 +11,9 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone {
|
||||
where
|
||||
T: AsRef<Transaction>;
|
||||
|
||||
/// Fill [CfgEnv] fields according to the chain spec and given header
|
||||
/// Fill [CfgEnvWithHandlerCfg] fields according to the chain spec and given header
|
||||
fn fill_cfg_env(
|
||||
cfg_env: &mut CfgEnv,
|
||||
cfg_env: &mut CfgEnvWithHandlerCfg,
|
||||
chain_spec: &ChainSpec,
|
||||
header: &Header,
|
||||
total_difficulty: U256,
|
||||
@ -22,14 +22,14 @@ pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone {
|
||||
/// Convenience function to call both [fill_cfg_env](ConfigureEvmEnv::fill_cfg_env) and
|
||||
/// [fill_block_env].
|
||||
fn fill_cfg_and_block_env(
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
block_env: &mut BlockEnv,
|
||||
chain_spec: &ChainSpec,
|
||||
header: &Header,
|
||||
total_difficulty: U256,
|
||||
) {
|
||||
Self::fill_cfg_env(cfg, chain_spec, header, total_difficulty);
|
||||
let after_merge = cfg.spec_id >= SpecId::MERGE;
|
||||
let after_merge = cfg.handler_cfg.spec_id >= SpecId::MERGE;
|
||||
fill_block_env(block_env, chain_spec, header, after_merge);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use reth_node_api::ConfigureEvmEnv;
|
||||
use reth_primitives::{
|
||||
revm::{config::revm_spec, env::fill_tx_env},
|
||||
revm_primitives::{AnalysisKind, CfgEnv, TxEnv},
|
||||
revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv},
|
||||
Address, ChainSpec, Head, Header, Transaction, U256,
|
||||
};
|
||||
|
||||
@ -21,7 +21,7 @@ impl ConfigureEvmEnv for EthEvmConfig {
|
||||
}
|
||||
|
||||
fn fill_cfg_env(
|
||||
cfg_env: &mut CfgEnv,
|
||||
cfg_env: &mut CfgEnvWithHandlerCfg,
|
||||
chain_spec: &ChainSpec,
|
||||
header: &Header,
|
||||
total_difficulty: U256,
|
||||
@ -38,20 +38,21 @@ impl ConfigureEvmEnv for EthEvmConfig {
|
||||
);
|
||||
|
||||
cfg_env.chain_id = chain_spec.chain().id();
|
||||
cfg_env.spec_id = spec_id;
|
||||
cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse;
|
||||
|
||||
cfg_env.handler_cfg.spec_id = spec_id;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use reth_primitives::revm_primitives::BlockEnv;
|
||||
use reth_primitives::revm_primitives::{BlockEnv, CfgEnv, SpecId};
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_fill_cfg_and_block_env() {
|
||||
let mut cfg_env = CfgEnv::default();
|
||||
let mut cfg_env = CfgEnvWithHandlerCfg::new(CfgEnv::default(), SpecId::LATEST);
|
||||
let mut block_env = BlockEnv::default();
|
||||
let header = Header::default();
|
||||
let chain_spec = ChainSpec::default();
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use reth_node_api::ConfigureEvmEnv;
|
||||
use reth_primitives::{
|
||||
revm::{config::revm_spec, env::fill_op_tx_env},
|
||||
revm_primitives::{AnalysisKind, CfgEnv, TxEnv},
|
||||
revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv},
|
||||
Address, Bytes, ChainSpec, Head, Header, Transaction, U256,
|
||||
};
|
||||
|
||||
@ -21,7 +21,7 @@ impl ConfigureEvmEnv for OptimismEvmConfig {
|
||||
}
|
||||
|
||||
fn fill_cfg_env(
|
||||
cfg_env: &mut CfgEnv,
|
||||
cfg_env: &mut CfgEnvWithHandlerCfg,
|
||||
chain_spec: &ChainSpec,
|
||||
header: &Header,
|
||||
total_difficulty: U256,
|
||||
@ -38,23 +38,22 @@ impl ConfigureEvmEnv for OptimismEvmConfig {
|
||||
);
|
||||
|
||||
cfg_env.chain_id = chain_spec.chain().id();
|
||||
cfg_env.spec_id = spec_id;
|
||||
cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse;
|
||||
|
||||
// optimism-specific configuration
|
||||
cfg_env.optimism = chain_spec.is_optimism();
|
||||
cfg_env.handler_cfg.spec_id = spec_id;
|
||||
cfg_env.handler_cfg.is_optimism = chain_spec.is_optimism();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use reth_primitives::revm_primitives::BlockEnv;
|
||||
use reth_primitives::revm_primitives::{BlockEnv, CfgEnv, SpecId};
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_fill_cfg_and_block_env() {
|
||||
let mut cfg_env = CfgEnv::default();
|
||||
let mut cfg_env = CfgEnvWithHandlerCfg::new(CfgEnv::default(), SpecId::LATEST);
|
||||
let mut block_env = BlockEnv::default();
|
||||
let header = Header::default();
|
||||
let chain_spec = ChainSpec::default();
|
||||
|
||||
@ -31,8 +31,8 @@ use reth_revm::state_change::{
|
||||
use reth_tasks::TaskSpawner;
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
use revm::{
|
||||
primitives::{BlockEnv, CfgEnv, Env},
|
||||
Database, DatabaseCommit, State,
|
||||
primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg},
|
||||
Database, DatabaseCommit, Evm, State,
|
||||
};
|
||||
use std::{
|
||||
future::Future,
|
||||
@ -633,7 +633,7 @@ pub struct PayloadConfig<Attributes> {
|
||||
/// Pre-configured block environment.
|
||||
pub initialized_block_env: BlockEnv,
|
||||
/// Configuration for the environment.
|
||||
pub initialized_cfg: CfgEnv,
|
||||
pub initialized_cfg: CfgEnvWithHandlerCfg,
|
||||
/// The parent block.
|
||||
pub parent_block: Arc<SealedBlock>,
|
||||
/// Block extra data.
|
||||
@ -849,8 +849,8 @@ pub fn commit_withdrawals<DB: Database<Error = ProviderError>>(
|
||||
|
||||
/// Apply the [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788) pre block contract call.
|
||||
///
|
||||
/// This constructs a new [EVM](revm::EVM) with the given DB, and environment ([CfgEnv] and
|
||||
/// [BlockEnv]) to execute the pre block contract call.
|
||||
/// This constructs a new [Evm] with the given DB, and environment
|
||||
/// ([CfgEnvWithHandlerCfg] and [BlockEnv]) to execute the pre block contract call.
|
||||
///
|
||||
/// The parent beacon block root used for the call is gathered from the given
|
||||
/// [PayloadBuilderAttributes].
|
||||
@ -861,7 +861,7 @@ pub fn pre_block_beacon_root_contract_call<DB: Database + DatabaseCommit, Attrib
|
||||
db: &mut DB,
|
||||
chain_spec: &ChainSpec,
|
||||
block_number: u64,
|
||||
initialized_cfg: &CfgEnv,
|
||||
initialized_cfg: &CfgEnvWithHandlerCfg,
|
||||
initialized_block_env: &BlockEnv,
|
||||
attributes: &Attributes,
|
||||
) -> Result<(), PayloadBuilderError>
|
||||
@ -869,16 +869,15 @@ where
|
||||
DB::Error: std::fmt::Display,
|
||||
Attributes: PayloadBuilderAttributes,
|
||||
{
|
||||
// Configure the environment for the block.
|
||||
let env = Env {
|
||||
cfg: initialized_cfg.clone(),
|
||||
block: initialized_block_env.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// apply pre-block EIP-4788 contract call
|
||||
let mut evm_pre_block = revm::EVM::with_env(env);
|
||||
evm_pre_block.database(db);
|
||||
let mut evm_pre_block = Evm::builder()
|
||||
.with_db(db)
|
||||
.with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env(
|
||||
initialized_cfg.clone(),
|
||||
initialized_block_env.clone(),
|
||||
Default::default(),
|
||||
))
|
||||
.build();
|
||||
|
||||
// initialize a block from the env, because the pre block call needs the block itself
|
||||
apply_beacon_root_contract_call(
|
||||
|
||||
@ -25,7 +25,7 @@ mod builder {
|
||||
},
|
||||
eip4844::calculate_excess_blob_gas,
|
||||
proofs,
|
||||
revm::{compat::into_reth_log, env::tx_env_with_recovered},
|
||||
revm::env::tx_env_with_recovered,
|
||||
Block, Header, IntoRecoveredTransaction, Receipt, Receipts, EMPTY_OMMER_ROOT_HASH, U256,
|
||||
};
|
||||
use reth_provider::{BundleStateWithReceipts, StateProviderFactory};
|
||||
@ -33,7 +33,7 @@ mod builder {
|
||||
use reth_transaction_pool::{BestTransactionsAttributes, TransactionPool};
|
||||
use revm::{
|
||||
db::states::bundle_state::BundleRetention,
|
||||
primitives::{EVMError, Env, InvalidTransaction, ResultAndState},
|
||||
primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState},
|
||||
DatabaseCommit, State,
|
||||
};
|
||||
use tracing::{debug, trace, warn};
|
||||
@ -262,14 +262,14 @@ mod builder {
|
||||
}
|
||||
|
||||
// Configure the environment for the block.
|
||||
let env = Env {
|
||||
cfg: initialized_cfg.clone(),
|
||||
block: initialized_block_env.clone(),
|
||||
tx: tx_env_with_recovered(&tx),
|
||||
};
|
||||
|
||||
let mut evm = revm::EVM::with_env(env);
|
||||
evm.database(&mut db);
|
||||
let mut evm = revm::Evm::builder()
|
||||
.with_db(&mut db)
|
||||
.with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env(
|
||||
initialized_cfg.clone(),
|
||||
initialized_block_env.clone(),
|
||||
tx_env_with_recovered(&tx),
|
||||
))
|
||||
.build();
|
||||
|
||||
let ResultAndState { result, state } = match evm.transact() {
|
||||
Ok(res) => res,
|
||||
@ -295,7 +295,8 @@ mod builder {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// drop evm so db is released.
|
||||
drop(evm);
|
||||
// commit changes
|
||||
db.commit(state);
|
||||
|
||||
@ -320,7 +321,7 @@ mod builder {
|
||||
tx_type: tx.tx_type(),
|
||||
success: result.is_success(),
|
||||
cumulative_gas_used,
|
||||
logs: result.logs().into_iter().map(into_reth_log).collect(),
|
||||
logs: result.logs().into_iter().map(Into::into).collect(),
|
||||
}));
|
||||
|
||||
// update add to total fees
|
||||
|
||||
@ -22,7 +22,7 @@ mod builder {
|
||||
use reth_primitives::{
|
||||
constants::{BEACON_NONCE, EMPTY_RECEIPTS, EMPTY_TRANSACTIONS},
|
||||
proofs,
|
||||
revm::{compat::into_reth_log, env::tx_env_with_recovered},
|
||||
revm::env::tx_env_with_recovered,
|
||||
Block, Hardfork, Header, IntoRecoveredTransaction, Receipt, Receipts,
|
||||
EMPTY_OMMER_ROOT_HASH, U256,
|
||||
};
|
||||
@ -31,7 +31,7 @@ mod builder {
|
||||
use reth_transaction_pool::{BestTransactionsAttributes, TransactionPool};
|
||||
use revm::{
|
||||
db::states::bundle_state::BundleRetention,
|
||||
primitives::{EVMError, Env, InvalidTransaction, ResultAndState},
|
||||
primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState},
|
||||
DatabaseCommit, State,
|
||||
};
|
||||
use tracing::{debug, trace, warn};
|
||||
@ -209,11 +209,6 @@ mod builder {
|
||||
Client: StateProviderFactory,
|
||||
Pool: TransactionPool,
|
||||
{
|
||||
debug_assert!(
|
||||
args.config.initialized_cfg.optimism,
|
||||
"optimism payload builder called on non-optimism chain"
|
||||
);
|
||||
|
||||
let BuildArguments { client, pool, mut cached_reads, config, cancel, best_payload } = args;
|
||||
|
||||
let state_provider = client.state_by_block_hash(config.parent_block.hash)?;
|
||||
@ -299,15 +294,14 @@ mod builder {
|
||||
))
|
||||
})?;
|
||||
|
||||
// Configure the environment for the block.
|
||||
let env = Env {
|
||||
cfg: initialized_cfg.clone(),
|
||||
block: initialized_block_env.clone(),
|
||||
tx: tx_env_with_recovered(&sequencer_tx),
|
||||
};
|
||||
|
||||
let mut evm = revm::EVM::with_env(env);
|
||||
evm.database(&mut db);
|
||||
let mut evm = revm::Evm::builder()
|
||||
.with_db(&mut db)
|
||||
.with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env(
|
||||
initialized_cfg.clone(),
|
||||
initialized_block_env.clone(),
|
||||
tx_env_with_recovered(&sequencer_tx),
|
||||
))
|
||||
.build();
|
||||
|
||||
let ResultAndState { result, state } = match evm.transact() {
|
||||
Ok(res) => res,
|
||||
@ -325,6 +319,8 @@ mod builder {
|
||||
}
|
||||
};
|
||||
|
||||
// to realease the db reference drop evm.
|
||||
drop(evm);
|
||||
// commit changes
|
||||
db.commit(state);
|
||||
|
||||
@ -338,7 +334,7 @@ mod builder {
|
||||
tx_type: sequencer_tx.tx_type(),
|
||||
success: result.is_success(),
|
||||
cumulative_gas_used,
|
||||
logs: result.logs().into_iter().map(into_reth_log).collect(),
|
||||
logs: result.logs().into_iter().map(Into::into).collect(),
|
||||
deposit_nonce: depositor.map(|account| account.nonce),
|
||||
// The deposit receipt version was introduced in Canyon to indicate an update to how
|
||||
// receipt hashes should be computed when set. The state transition process
|
||||
@ -375,14 +371,15 @@ mod builder {
|
||||
let tx = pool_tx.to_recovered_transaction();
|
||||
|
||||
// Configure the environment for the block.
|
||||
let env = Env {
|
||||
cfg: initialized_cfg.clone(),
|
||||
block: initialized_block_env.clone(),
|
||||
tx: tx_env_with_recovered(&tx),
|
||||
};
|
||||
|
||||
let mut evm = revm::EVM::with_env(env);
|
||||
evm.database(&mut db);
|
||||
let mut evm = revm::Evm::builder()
|
||||
.with_db(&mut db)
|
||||
.with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env(
|
||||
initialized_cfg.clone(),
|
||||
initialized_block_env.clone(),
|
||||
tx_env_with_recovered(&tx),
|
||||
))
|
||||
.build();
|
||||
|
||||
let ResultAndState { result, state } = match evm.transact() {
|
||||
Ok(res) => res,
|
||||
@ -408,7 +405,8 @@ mod builder {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// to realease the db reference drop evm.
|
||||
drop(evm);
|
||||
// commit changes
|
||||
db.commit(state);
|
||||
|
||||
@ -423,7 +421,7 @@ mod builder {
|
||||
tx_type: tx.tx_type(),
|
||||
success: result.is_success(),
|
||||
cumulative_gas_used,
|
||||
logs: result.logs().into_iter().map(into_reth_log).collect(),
|
||||
logs: result.logs().into_iter().map(Into::into).collect(),
|
||||
deposit_nonce: None,
|
||||
deposit_receipt_version: None,
|
||||
}));
|
||||
|
||||
@ -2987,7 +2987,6 @@ Post-merge hard forks (timestamp based):
|
||||
assert_eq!(header.parent_beacon_block_root, Some(B256::ZERO));
|
||||
assert_eq!(header.blob_gas_used, Some(0));
|
||||
assert_eq!(header.excess_blob_gas, Some(0));
|
||||
println!("header: {:?}", header);
|
||||
|
||||
// check the genesis hash
|
||||
let genesis_hash = header.hash_slow();
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use crate::{Address, Bloom, Bytes, B256};
|
||||
use alloy_primitives::Log as AlloyLog;
|
||||
use alloy_rlp::{RlpDecodable, RlpEncodable};
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
|
||||
@ -20,6 +21,12 @@ pub struct Log {
|
||||
pub data: Bytes,
|
||||
}
|
||||
|
||||
impl From<AlloyLog> for Log {
|
||||
fn from(log: AlloyLog) -> Self {
|
||||
Self { address: log.address, topics: log.topics().to_vec(), data: log.data.data }
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculate receipt logs bloom.
|
||||
pub fn logs_bloom<'a, It>(logs: It) -> Bloom
|
||||
where
|
||||
|
||||
@ -3,20 +3,15 @@ use crate::{
|
||||
Account, Address, Log as RethLog, TransactionKind, KECCAK_EMPTY, U256,
|
||||
};
|
||||
use revm::{
|
||||
interpreter::gas::initial_tx_gas,
|
||||
interpreter::gas::validate_initial_tx_gas,
|
||||
primitives::{MergeSpec, ShanghaiSpec},
|
||||
};
|
||||
|
||||
/// Check equality between Revm and Reth `Log`s.
|
||||
pub fn is_log_equal(revm_log: &Log, reth_log: &crate::Log) -> bool {
|
||||
pub fn is_log_equal(revm_log: &Log, reth_log: &RethLog) -> bool {
|
||||
revm_log.address == reth_log.address &&
|
||||
revm_log.data == reth_log.data &&
|
||||
revm_log.topics == reth_log.topics
|
||||
}
|
||||
|
||||
/// Converts a Revm `Log` into a Reth `Log`.
|
||||
pub fn into_reth_log(log: Log) -> RethLog {
|
||||
RethLog { address: log.address, topics: log.topics, data: log.data }
|
||||
revm_log.data.data == reth_log.data &&
|
||||
revm_log.topics() == reth_log.topics
|
||||
}
|
||||
|
||||
/// Converts a Revm [`AccountInfo`] into a Reth [`Account`].
|
||||
@ -54,8 +49,8 @@ pub fn calculate_intrinsic_gas_after_merge(
|
||||
is_shanghai: bool,
|
||||
) -> u64 {
|
||||
if is_shanghai {
|
||||
initial_tx_gas::<ShanghaiSpec>(input, kind.is_create(), access_list)
|
||||
validate_initial_tx_gas::<ShanghaiSpec>(input, kind.is_create(), access_list)
|
||||
} else {
|
||||
initial_tx_gas::<MergeSpec>(input, kind.is_create(), access_list)
|
||||
validate_initial_tx_gas::<MergeSpec>(input, kind.is_create(), access_list)
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ use reth_primitives::{
|
||||
address, b256, hex, Address, Block, Bytes, ChainSpec, Hardfork, TransactionKind, B256, U256,
|
||||
};
|
||||
use revm::{
|
||||
primitives::{BedrockSpec, Bytecode, HashMap, RegolithSpec},
|
||||
primitives::{Bytecode, HashMap, SpecId},
|
||||
DatabaseCommit, L1BlockInfo,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
@ -86,7 +86,12 @@ pub fn parse_l1_info_tx(data: &[u8]) -> Result<L1BlockInfo, BlockExecutionError>
|
||||
),
|
||||
)?;
|
||||
|
||||
Ok(L1BlockInfo { l1_base_fee, l1_fee_overhead, l1_fee_scalar })
|
||||
let mut l1block = L1BlockInfo::default();
|
||||
l1block.l1_base_fee = l1_base_fee;
|
||||
l1block.l1_fee_overhead = Some(l1_fee_overhead);
|
||||
l1block.l1_base_fee_scalar = l1_fee_scalar;
|
||||
|
||||
Ok(l1block)
|
||||
}
|
||||
|
||||
/// An extension trait for [L1BlockInfo] that allows us to calculate the L1 cost of a transaction
|
||||
@ -133,17 +138,18 @@ impl RethL1BlockInfo for L1BlockInfo {
|
||||
return Ok(U256::ZERO)
|
||||
}
|
||||
|
||||
if chain_spec.is_fork_active_at_timestamp(Hardfork::Regolith, timestamp) {
|
||||
Ok(self.calculate_tx_l1_cost::<RegolithSpec>(input))
|
||||
let spec_id = if chain_spec.is_fork_active_at_timestamp(Hardfork::Regolith, timestamp) {
|
||||
SpecId::REGOLITH
|
||||
} else if chain_spec.is_fork_active_at_timestamp(Hardfork::Bedrock, timestamp) {
|
||||
Ok(self.calculate_tx_l1_cost::<BedrockSpec>(input))
|
||||
SpecId::BEDROCK
|
||||
} else {
|
||||
Err(reth_executor::BlockExecutionError::OptimismBlockExecution(
|
||||
return Err(reth_executor::BlockExecutionError::OptimismBlockExecution(
|
||||
reth_executor::OptimismBlockExecutionError::L1BlockInfoError {
|
||||
message: "Optimism hardforks are not active".to_string(),
|
||||
},
|
||||
))
|
||||
}
|
||||
};
|
||||
Ok(self.calculate_tx_l1_cost(input, spec_id))
|
||||
}
|
||||
|
||||
fn l1_data_gas(
|
||||
@ -152,17 +158,18 @@ impl RethL1BlockInfo for L1BlockInfo {
|
||||
timestamp: u64,
|
||||
input: &Bytes,
|
||||
) -> Result<U256, BlockExecutionError> {
|
||||
if chain_spec.is_fork_active_at_timestamp(Hardfork::Regolith, timestamp) {
|
||||
Ok(self.data_gas::<RegolithSpec>(input))
|
||||
let spec_id = if chain_spec.is_fork_active_at_timestamp(Hardfork::Regolith, timestamp) {
|
||||
SpecId::REGOLITH
|
||||
} else if chain_spec.is_fork_active_at_timestamp(Hardfork::Bedrock, timestamp) {
|
||||
Ok(self.data_gas::<BedrockSpec>(input))
|
||||
SpecId::BEDROCK
|
||||
} else {
|
||||
Err(reth_executor::BlockExecutionError::OptimismBlockExecution(
|
||||
return Err(reth_executor::BlockExecutionError::OptimismBlockExecution(
|
||||
reth_executor::OptimismBlockExecutionError::L1BlockInfoError {
|
||||
message: "Optimism hardforks are not active".to_string(),
|
||||
},
|
||||
))
|
||||
}
|
||||
};
|
||||
Ok(self.data_gas(input, spec_id))
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,7 +233,7 @@ mod test_l1_fee {
|
||||
|
||||
let l1_info: L1BlockInfo = super::extract_l1_info(&mock_block).unwrap();
|
||||
assert_eq!(l1_info.l1_base_fee, U256::from(652_114));
|
||||
assert_eq!(l1_info.l1_fee_overhead, U256::from(2100));
|
||||
assert_eq!(l1_info.l1_fee_scalar, U256::from(1_000_000));
|
||||
assert_eq!(l1_info.l1_fee_overhead, Some(U256::from(2100)));
|
||||
assert_eq!(l1_info.l1_base_fee_scalar, U256::from(1_000_000));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,10 +3,7 @@ use reth_interfaces::executor::{
|
||||
BlockExecutionError, BlockValidationError, OptimismBlockExecutionError,
|
||||
};
|
||||
use reth_node_api::ConfigureEvmEnv;
|
||||
use reth_primitives::{
|
||||
revm::compat::into_reth_log, revm_primitives::ResultAndState, BlockWithSenders, Hardfork,
|
||||
Receipt, U256,
|
||||
};
|
||||
use reth_primitives::{revm_primitives::ResultAndState, BlockWithSenders, Hardfork, Receipt, U256};
|
||||
use reth_provider::{BlockExecutor, BlockExecutorStats, BundleStateWithReceipts};
|
||||
use revm::DatabaseCommit;
|
||||
use std::time::Instant;
|
||||
@ -137,7 +134,7 @@ where
|
||||
success: result.is_success(),
|
||||
cumulative_gas_used,
|
||||
// convert to reth log
|
||||
logs: result.into_logs().into_iter().map(into_reth_log).collect(),
|
||||
logs: result.into_logs().into_iter().map(Into::into).collect(),
|
||||
#[cfg(feature = "optimism")]
|
||||
deposit_nonce: depositor.map(|account| account.nonce),
|
||||
// The deposit receipt version was introduced in Canyon to indicate an update to how
|
||||
@ -157,7 +154,7 @@ where
|
||||
fn take_output_state(&mut self) -> BundleStateWithReceipts {
|
||||
let receipts = std::mem::take(&mut self.receipts);
|
||||
BundleStateWithReceipts::new(
|
||||
self.evm.db().unwrap().take_bundle(),
|
||||
self.evm.context.evm.db.take_bundle(),
|
||||
receipts,
|
||||
self.first_block.unwrap_or_default(),
|
||||
)
|
||||
@ -168,6 +165,6 @@ where
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> Option<usize> {
|
||||
self.evm.db.as_ref().map(|db| db.bundle_size_hint())
|
||||
Some(self.evm.context.evm.db.bundle_size_hint())
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,9 +15,11 @@ use reth_provider::{
|
||||
BlockExecutor, BlockExecutorStats, ProviderError, PrunableBlockExecutor, StateProvider,
|
||||
};
|
||||
use revm::{
|
||||
db::{states::bundle_state::BundleRetention, StateDBBox},
|
||||
primitives::ResultAndState,
|
||||
State, EVM,
|
||||
db::{states::bundle_state::BundleRetention, EmptyDBTyped, StateDBBox},
|
||||
inspector_handle_register,
|
||||
interpreter::Host,
|
||||
primitives::{CfgEnvWithHandlerCfg, ResultAndState},
|
||||
Evm, State, StateBuilder,
|
||||
};
|
||||
use std::{sync::Arc, time::Instant};
|
||||
|
||||
@ -26,8 +28,6 @@ use reth_primitives::revm::env::fill_op_tx_env;
|
||||
#[cfg(not(feature = "optimism"))]
|
||||
use reth_primitives::revm::env::fill_tx_env;
|
||||
|
||||
#[cfg(not(feature = "optimism"))]
|
||||
use reth_primitives::revm::compat::into_reth_log;
|
||||
#[cfg(not(feature = "optimism"))]
|
||||
use reth_provider::BundleStateWithReceipts;
|
||||
#[cfg(not(feature = "optimism"))]
|
||||
@ -57,9 +57,7 @@ pub struct EVMProcessor<'a, EvmConfig> {
|
||||
/// The configured chain-spec
|
||||
pub(crate) chain_spec: Arc<ChainSpec>,
|
||||
/// revm instance that contains database and env environment.
|
||||
pub(crate) evm: EVM<StateDBBox<'a, ProviderError>>,
|
||||
/// Hook and inspector stack that we want to invoke on that hook.
|
||||
stack: InspectorStack,
|
||||
pub(crate) evm: Evm<'a, InspectorStack, StateDBBox<'a, ProviderError>>,
|
||||
/// The collection of receipts.
|
||||
/// Outer vector stores receipts for each block sequentially.
|
||||
/// The inner vector stores receipts ordered by transaction number.
|
||||
@ -94,11 +92,21 @@ where
|
||||
|
||||
/// Create a new pocessor with the given chain spec.
|
||||
pub fn new(chain_spec: Arc<ChainSpec>, evm_config: EvmConfig) -> Self {
|
||||
let evm = EVM::new();
|
||||
// create evm with boxed empty db that is going to be set later.
|
||||
let evm = Evm::builder()
|
||||
.with_db(
|
||||
Box::new(
|
||||
StateBuilder::new()
|
||||
.with_database_boxed(Box::new(EmptyDBTyped::<ProviderError>::new())),
|
||||
)
|
||||
.build(),
|
||||
)
|
||||
// Hook and inspector stack that we want to invoke on that hook.
|
||||
.with_external_context(InspectorStack::new(InspectorStackConfig::default()))
|
||||
.build();
|
||||
EVMProcessor {
|
||||
chain_spec,
|
||||
evm,
|
||||
stack: InspectorStack::new(InspectorStackConfig::default()),
|
||||
receipts: Receipts::new(),
|
||||
first_block: None,
|
||||
tip: None,
|
||||
@ -129,12 +137,13 @@ where
|
||||
revm_state: StateDBBox<'a, ProviderError>,
|
||||
evm_config: EvmConfig,
|
||||
) -> Self {
|
||||
let mut evm = EVM::new();
|
||||
evm.database(revm_state);
|
||||
let evm = Evm::builder()
|
||||
.with_db(revm_state)
|
||||
.with_external_context(InspectorStack::new(InspectorStackConfig::default()))
|
||||
.build();
|
||||
EVMProcessor {
|
||||
chain_spec,
|
||||
evm,
|
||||
stack: InspectorStack::new(InspectorStackConfig::default()),
|
||||
receipts: Receipts::new(),
|
||||
first_block: None,
|
||||
tip: None,
|
||||
@ -147,7 +156,7 @@ where
|
||||
|
||||
/// Configures the executor with the given inspectors.
|
||||
pub fn set_stack(&mut self, stack: InspectorStack) {
|
||||
self.stack = stack;
|
||||
self.evm.context.external = stack;
|
||||
}
|
||||
|
||||
/// Configure the executor with the given block.
|
||||
@ -157,10 +166,7 @@ where
|
||||
|
||||
/// Returns a reference to the database
|
||||
pub fn db_mut(&mut self) -> &mut StateDBBox<'a, ProviderError> {
|
||||
// Option will be removed from EVM in the future.
|
||||
// as it is always some.
|
||||
// https://github.com/bluealloy/revm/issues/697
|
||||
self.evm.db().expect("Database inside EVM is always set")
|
||||
&mut self.evm.context.evm.db
|
||||
}
|
||||
|
||||
/// Initializes the config and block env.
|
||||
@ -171,13 +177,17 @@ where
|
||||
|
||||
self.db_mut().set_state_clear_flag(state_clear_flag);
|
||||
|
||||
let mut cfg: CfgEnvWithHandlerCfg =
|
||||
CfgEnvWithHandlerCfg::new(self.evm.cfg().clone(), self.evm.spec_id());
|
||||
EvmConfig::fill_cfg_and_block_env(
|
||||
&mut self.evm.env.cfg,
|
||||
&mut self.evm.env.block,
|
||||
&mut cfg,
|
||||
self.evm.block_mut(),
|
||||
&self.chain_spec,
|
||||
header,
|
||||
total_difficulty,
|
||||
);
|
||||
*self.evm.cfg_mut() = cfg.cfg_env;
|
||||
self.evm.handler.modify_spec_id(cfg.handler_cfg.spec_id);
|
||||
}
|
||||
|
||||
/// Applies the pre-block call to the EIP-4788 beacon block root contract.
|
||||
@ -248,30 +258,34 @@ where
|
||||
) -> Result<ResultAndState, BlockExecutionError> {
|
||||
// Fill revm structure.
|
||||
#[cfg(not(feature = "optimism"))]
|
||||
fill_tx_env(&mut self.evm.env.tx, transaction, sender);
|
||||
fill_tx_env(self.evm.tx_mut(), transaction, sender);
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
{
|
||||
let mut envelope_buf = Vec::with_capacity(transaction.length_without_header());
|
||||
transaction.encode_enveloped(&mut envelope_buf);
|
||||
fill_op_tx_env(&mut self.evm.env.tx, transaction, sender, envelope_buf.into());
|
||||
fill_op_tx_env(self.evm.tx_mut(), transaction, sender, envelope_buf.into());
|
||||
}
|
||||
|
||||
let hash = transaction.hash();
|
||||
let out = if self.stack.should_inspect(&self.evm.env, hash) {
|
||||
// execution with inspector.
|
||||
let output = self.evm.inspect(&mut self.stack);
|
||||
let should_inspect = self.evm.context.external.should_inspect(self.evm.env(), hash);
|
||||
let out = if should_inspect {
|
||||
// push inspector handle register.
|
||||
self.evm.handler.append_handler_register_plain(inspector_handle_register);
|
||||
let output = self.evm.transact();
|
||||
tracing::trace!(
|
||||
target: "evm",
|
||||
?hash, ?output, ?transaction, env = ?self.evm.env,
|
||||
?hash, ?output, ?transaction, env = ?self.evm.context.evm.env,
|
||||
"Executed transaction"
|
||||
);
|
||||
// pop last handle register
|
||||
self.evm.handler.pop_handle_register();
|
||||
output
|
||||
} else {
|
||||
// main execution.
|
||||
self.evm.transact()
|
||||
};
|
||||
out.map_err(|e| BlockValidationError::EVM { hash, error: e.into() }.into())
|
||||
out.map_err(move |e| BlockValidationError::EVM { hash, error: e.into() }.into())
|
||||
}
|
||||
|
||||
/// Execute the block, verify gas usage and apply post-block state changes.
|
||||
@ -478,7 +492,7 @@ where
|
||||
success: result.is_success(),
|
||||
cumulative_gas_used,
|
||||
// convert to reth log
|
||||
logs: result.into_logs().into_iter().map(into_reth_log).collect(),
|
||||
logs: result.into_logs().into_iter().map(Into::into).collect(),
|
||||
});
|
||||
}
|
||||
|
||||
@ -488,7 +502,7 @@ where
|
||||
fn take_output_state(&mut self) -> BundleStateWithReceipts {
|
||||
let receipts = std::mem::take(&mut self.receipts);
|
||||
BundleStateWithReceipts::new(
|
||||
self.evm.db().unwrap().take_bundle(),
|
||||
self.evm.context.evm.db.take_bundle(),
|
||||
receipts,
|
||||
self.first_block.unwrap_or_default(),
|
||||
)
|
||||
@ -499,7 +513,7 @@ where
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> Option<usize> {
|
||||
self.evm.db.as_ref().map(|db| db.bundle_size_hint())
|
||||
Some(self.evm.context.evm.db.bundle_size_hint())
|
||||
}
|
||||
}
|
||||
|
||||
@ -785,7 +799,7 @@ mod tests {
|
||||
executor.init_env(&header, U256::ZERO);
|
||||
|
||||
// get the env
|
||||
let previous_env = executor.evm.env.clone();
|
||||
let previous_env = executor.evm.context.evm.env.clone();
|
||||
|
||||
// attempt to execute an empty block with parent beacon block root, this should not fail
|
||||
executor
|
||||
@ -806,7 +820,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// ensure that the env has not changed
|
||||
assert_eq!(executor.evm.env, previous_env);
|
||||
assert_eq!(executor.evm.context.evm.env, previous_env);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -953,7 +967,7 @@ mod tests {
|
||||
|
||||
// there is no system contract call so there should be NO STORAGE CHANGES
|
||||
// this means we'll check the transition state
|
||||
let state = executor.evm.db().unwrap();
|
||||
let state = executor.evm.context.evm.db;
|
||||
let transition_state = state
|
||||
.transition_state
|
||||
.clone()
|
||||
@ -1007,7 +1021,7 @@ mod tests {
|
||||
executor.init_env(&header, U256::ZERO);
|
||||
|
||||
// ensure that the env is configured with a base fee
|
||||
assert_eq!(executor.evm.env.block.basefee, U256::from(u64::MAX));
|
||||
assert_eq!(executor.evm.block().basefee, U256::from(u64::MAX));
|
||||
|
||||
// Now execute a block with the fixed header, ensure that it does not fail
|
||||
executor
|
||||
|
||||
@ -4,7 +4,7 @@ use reth_primitives::{
|
||||
constants::SYSTEM_ADDRESS, revm::env::fill_tx_env_with_beacon_root_contract_call, Address,
|
||||
ChainSpec, Header, Withdrawal, B256, U256,
|
||||
};
|
||||
use revm::{Database, DatabaseCommit, EVM};
|
||||
use revm::{interpreter::Host, Database, DatabaseCommit, Evm};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Collect all balance changes at the end of the block.
|
||||
@ -57,12 +57,12 @@ pub fn post_block_balance_increments(
|
||||
/// If cancun is not activated or the block is the genesis block, then this is a no-op, and no
|
||||
/// state changes are made.
|
||||
#[inline]
|
||||
pub fn apply_beacon_root_contract_call<DB: Database + DatabaseCommit>(
|
||||
pub fn apply_beacon_root_contract_call<EXT, DB: Database + DatabaseCommit>(
|
||||
chain_spec: &ChainSpec,
|
||||
block_timestamp: u64,
|
||||
block_number: u64,
|
||||
parent_beacon_block_root: Option<B256>,
|
||||
evm: &mut EVM<DB>,
|
||||
evm: &mut Evm<'_, EXT, DB>,
|
||||
) -> Result<(), BlockExecutionError>
|
||||
where
|
||||
DB::Error: std::fmt::Display,
|
||||
@ -87,15 +87,15 @@ where
|
||||
}
|
||||
|
||||
// get previous env
|
||||
let previous_env = evm.env.clone();
|
||||
let previous_env = Box::new(evm.env().clone());
|
||||
|
||||
// modify env for pre block call
|
||||
fill_tx_env_with_beacon_root_contract_call(&mut evm.env, parent_beacon_block_root);
|
||||
fill_tx_env_with_beacon_root_contract_call(&mut evm.context.evm.env, parent_beacon_block_root);
|
||||
|
||||
let mut state = match evm.transact() {
|
||||
Ok(res) => res.state,
|
||||
Err(e) => {
|
||||
evm.env = previous_env;
|
||||
evm.context.evm.env = previous_env;
|
||||
return Err(BlockValidationError::BeaconRootContractCall {
|
||||
parent_beacon_block_root: Box::new(parent_beacon_block_root),
|
||||
message: e.to_string(),
|
||||
@ -105,13 +105,12 @@ where
|
||||
};
|
||||
|
||||
state.remove(&SYSTEM_ADDRESS);
|
||||
state.remove(&evm.env.block.coinbase);
|
||||
state.remove(&evm.block().coinbase);
|
||||
|
||||
let db = evm.db().expect("db to not be moved");
|
||||
db.commit(state);
|
||||
evm.context.evm.db.commit(state);
|
||||
|
||||
// re-set the previous env
|
||||
evm.env = previous_env;
|
||||
evm.context.evm.env = previous_env;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -248,7 +248,7 @@ impl AuthServerConfigBuilder {
|
||||
.max_connections(500)
|
||||
// bump the default request size slightly, there aren't any methods exposed with
|
||||
// dynamic request params that can exceed this
|
||||
.max_request_body_size(25 * 1024 * 1024)
|
||||
.max_request_body_size(5 * 1024 * 1024)
|
||||
.set_id_provider(EthSubscriptionIdProvider::default())
|
||||
}),
|
||||
}
|
||||
|
||||
@ -295,12 +295,12 @@ where
|
||||
self.inner.task_spawner.spawn_blocking(Box::pin(async move {
|
||||
if count > MAX_PAYLOAD_BODIES_LIMIT {
|
||||
tx.send(Err(EngineApiError::PayloadRequestTooLarge { len: count })).ok();
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
if start == 0 || count == 0 {
|
||||
tx.send(Err(EngineApiError::InvalidBodiesRange { start, count })).ok();
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
let mut result = Vec::with_capacity(count as usize);
|
||||
@ -324,7 +324,7 @@ where
|
||||
}
|
||||
Err(err) => {
|
||||
tx.send(Err(EngineApiError::Internal(Box::new(err)))).ok();
|
||||
return
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -14,10 +14,8 @@ use alloy_rlp::{Decodable, Encodable};
|
||||
use async_trait::async_trait;
|
||||
use jsonrpsee::core::RpcResult;
|
||||
use reth_primitives::{
|
||||
revm::env::tx_env_with_recovered,
|
||||
revm_primitives::{db::DatabaseCommit, BlockEnv, CfgEnv},
|
||||
Address, Block, BlockId, BlockNumberOrTag, Bytes, TransactionSignedEcRecovered, Withdrawals,
|
||||
B256,
|
||||
revm::env::tx_env_with_recovered, Address, Block, BlockId, BlockNumberOrTag, Bytes,
|
||||
TransactionSignedEcRecovered, Withdrawals, B256,
|
||||
};
|
||||
use reth_provider::{
|
||||
BlockReaderIdExt, ChainSpecProvider, HeaderProvider, StateProviderBox, TransactionVariant,
|
||||
@ -31,7 +29,10 @@ use reth_rpc_types::{
|
||||
},
|
||||
BlockError, Bundle, CallRequest, RichBlock, StateContext,
|
||||
};
|
||||
use revm::{db::CacheDB, primitives::Env};
|
||||
use revm::{
|
||||
db::CacheDB,
|
||||
primitives::{db::DatabaseCommit, BlockEnv, CfgEnvWithHandlerCfg, Env, EnvWithHandlerCfg},
|
||||
};
|
||||
use revm_inspectors::tracing::{
|
||||
js::{JsInspector, TransactionContext},
|
||||
FourByteInspector, TracingInspector, TracingInspectorConfig,
|
||||
@ -73,7 +74,7 @@ where
|
||||
&self,
|
||||
at: BlockId,
|
||||
transactions: Vec<TransactionSignedEcRecovered>,
|
||||
cfg: CfgEnv,
|
||||
cfg: CfgEnvWithHandlerCfg,
|
||||
block_env: BlockEnv,
|
||||
opts: GethDebugTracingOptions,
|
||||
) -> EthResult<Vec<TraceResult>> {
|
||||
@ -89,7 +90,10 @@ where
|
||||
while let Some((index, tx)) = transactions.next() {
|
||||
let tx_hash = tx.hash;
|
||||
let tx = tx_env_with_recovered(&tx);
|
||||
let env = Env { cfg: cfg.clone(), block: block_env.clone(), tx };
|
||||
let env = EnvWithHandlerCfg::new(
|
||||
Env::boxed(cfg.cfg_env.clone(), block_env.clone(), tx),
|
||||
cfg.handler_cfg.spec_id,
|
||||
);
|
||||
let (result, state_changes) = this
|
||||
.trace_transaction(
|
||||
opts.clone(),
|
||||
@ -233,7 +237,10 @@ where
|
||||
tx.hash,
|
||||
)?;
|
||||
|
||||
let env = Env { cfg, block: block_env, tx: tx_env_with_recovered(&tx) };
|
||||
let env = EnvWithHandlerCfg::new(
|
||||
Env::boxed(cfg.cfg_env.clone(), block_env, tx_env_with_recovered(&tx)),
|
||||
cfg.handler_cfg.spec_id,
|
||||
);
|
||||
this.trace_transaction(
|
||||
opts,
|
||||
env,
|
||||
@ -426,7 +433,10 @@ where
|
||||
// Execute all transactions until index
|
||||
for tx in transactions {
|
||||
let tx = tx_env_with_recovered(&tx);
|
||||
let env = Env { cfg: cfg.clone(), block: block_env.clone(), tx };
|
||||
let env = EnvWithHandlerCfg::new(
|
||||
Env::boxed(cfg.cfg_env.clone(), block_env.clone(), tx),
|
||||
cfg.handler_cfg.spec_id,
|
||||
);
|
||||
let (res, _) = transact(&mut db, env)?;
|
||||
db.commit(res.state);
|
||||
}
|
||||
@ -483,7 +493,7 @@ where
|
||||
fn trace_transaction(
|
||||
&self,
|
||||
opts: GethDebugTracingOptions,
|
||||
env: Env,
|
||||
env: EnvWithHandlerCfg,
|
||||
db: &mut SubState<StateProviderBox>,
|
||||
transaction_context: Option<TransactionContext>,
|
||||
) -> EthResult<(GethTrace, revm_primitives::State)> {
|
||||
|
||||
@ -25,7 +25,9 @@ use reth_rpc_types::{
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
use revm::{
|
||||
db::{CacheDB, DatabaseRef},
|
||||
primitives::{BlockEnv, CfgEnv, Env, ExecutionResult, Halt, TransactTo},
|
||||
primitives::{
|
||||
BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult, HaltReason, TransactTo,
|
||||
},
|
||||
DatabaseCommit,
|
||||
};
|
||||
use tracing::trace;
|
||||
@ -124,7 +126,8 @@ where
|
||||
let transactions = block.into_transactions_ecrecovered().take(num_txs);
|
||||
for tx in transactions {
|
||||
let tx = tx_env_with_recovered(&tx);
|
||||
let env = Env { cfg: cfg.clone(), block: block_env.clone(), tx };
|
||||
let env =
|
||||
EnvWithHandlerCfg::new_with_cfg_env(cfg.clone(), block_env.clone(), tx);
|
||||
let (res, _) = transact(&mut db, env)?;
|
||||
db.commit(res.state);
|
||||
}
|
||||
@ -173,7 +176,7 @@ where
|
||||
/// This will execute the [CallRequest] and find the best gas limit via binary search
|
||||
pub fn estimate_gas_with<S>(
|
||||
&self,
|
||||
mut cfg: CfgEnv,
|
||||
mut cfg: CfgEnvWithHandlerCfg,
|
||||
block: BlockEnv,
|
||||
request: CallRequest,
|
||||
state: S,
|
||||
@ -328,7 +331,7 @@ where
|
||||
}
|
||||
ExecutionResult::Halt { reason, .. } => {
|
||||
match reason {
|
||||
Halt::OutOfGas(_) | Halt::InvalidFEOpcode => {
|
||||
HaltReason::OutOfGas(_) | HaltReason::InvalidFEOpcode => {
|
||||
// either out of gas or invalid opcode can be thrown dynamically if
|
||||
// gasLeft is too low, so we treat this as `out of gas`, we know this
|
||||
// call succeeds with a higher gaslimit. common usage of invalid opcode in openzeppelin <https://github.com/OpenZeppelin/openzeppelin-contracts/blob/94697be8a3f0dfcd95dfb13ffbd39b5973f5c65d/contracts/metatx/ERC2771Forwarder.sol#L360-L367>
|
||||
@ -401,13 +404,13 @@ where
|
||||
// can consume the list since we're not using the request anymore
|
||||
let initial = request.access_list.take().unwrap_or_default();
|
||||
|
||||
let precompiles = get_precompiles(env.cfg.spec_id);
|
||||
let precompiles = get_precompiles(env.handler_cfg.spec_id);
|
||||
let mut inspector = AccessListInspector::new(initial, from, to, precompiles);
|
||||
let (result, env) = inspect(&mut db, env, &mut inspector)?;
|
||||
|
||||
match result.result {
|
||||
ExecutionResult::Halt { reason, .. } => Err(match reason {
|
||||
Halt::NonceOverflow => RpcInvalidTransactionError::NonceMaxValue,
|
||||
HaltReason::NonceOverflow => RpcInvalidTransactionError::NonceMaxValue,
|
||||
halt => RpcInvalidTransactionError::EvmHalt(halt),
|
||||
}),
|
||||
ExecutionResult::Revert { output, .. } => {
|
||||
@ -418,9 +421,16 @@ where
|
||||
|
||||
let access_list = inspector.into_access_list();
|
||||
|
||||
let cfg_with_spec_id = CfgEnvWithHandlerCfg::new(env.cfg.clone(), env.handler_cfg.spec_id);
|
||||
// calculate the gas used using the access list
|
||||
request.access_list = Some(access_list.clone());
|
||||
let gas_used = self.estimate_gas_with(env.cfg, env.block, request, db.db.state(), None)?;
|
||||
let gas_used = self.estimate_gas_with(
|
||||
cfg_with_spec_id,
|
||||
env.block.clone(),
|
||||
request,
|
||||
db.db.state(),
|
||||
None,
|
||||
)?;
|
||||
|
||||
Ok(AccessListWithGasUsed { access_list, gas_used })
|
||||
}
|
||||
@ -431,7 +441,7 @@ where
|
||||
#[inline]
|
||||
fn map_out_of_gas_err<S>(
|
||||
env_gas_limit: U256,
|
||||
mut env: Env,
|
||||
mut env: EnvWithHandlerCfg,
|
||||
mut db: &mut CacheDB<StateProviderDatabase<S>>,
|
||||
) -> EthApiError
|
||||
where
|
||||
|
||||
@ -17,7 +17,7 @@ use reth_interfaces::RethResult;
|
||||
use reth_network_api::NetworkInfo;
|
||||
use reth_node_api::ConfigureEvmEnv;
|
||||
use reth_primitives::{
|
||||
revm_primitives::{BlockEnv, CfgEnv},
|
||||
revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg},
|
||||
Address, BlockId, BlockNumberOrTag, ChainInfo, SealedBlockWithSenders, B256, U256, U64,
|
||||
};
|
||||
|
||||
@ -27,6 +27,7 @@ use reth_provider::{
|
||||
use reth_rpc_types::{SyncInfo, SyncStatus};
|
||||
use reth_tasks::{TaskSpawner, TokioTaskExecutor};
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
use revm_primitives::{CfgEnv, SpecId};
|
||||
use std::{
|
||||
fmt::Debug,
|
||||
future::Future,
|
||||
@ -265,7 +266,7 @@ where
|
||||
Network: NetworkInfo + Send + Sync + 'static,
|
||||
EvmConfig: ConfigureEvmEnv + Clone + 'static,
|
||||
{
|
||||
/// Configures the [CfgEnv] and [BlockEnv] for the pending block
|
||||
/// Configures the [CfgEnvWithHandlerCfg] and [BlockEnv] for the pending block
|
||||
///
|
||||
/// If no pending block is available, this will derive it from the `latest` block
|
||||
pub(crate) fn pending_block_env_and_cfg(&self) -> EthResult<PendingBlockEnv> {
|
||||
@ -289,11 +290,11 @@ where
|
||||
PendingBlockEnvOrigin::DerivedFromLatest(latest)
|
||||
};
|
||||
|
||||
let mut cfg = CfgEnv::default();
|
||||
let mut cfg = CfgEnvWithHandlerCfg::new(CfgEnv::default(), SpecId::LATEST);
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
{
|
||||
cfg.optimism = self.provider().chain_spec().is_optimism();
|
||||
cfg.handler_cfg.is_optimism = self.provider().chain_spec().is_optimism();
|
||||
}
|
||||
|
||||
let mut block_env = BlockEnv::default();
|
||||
|
||||
@ -4,9 +4,9 @@ use crate::eth::error::{EthApiError, EthResult};
|
||||
use reth_primitives::{
|
||||
constants::{eip4844::MAX_DATA_GAS_PER_BLOCK, BEACON_NONCE},
|
||||
proofs,
|
||||
revm::{compat::into_reth_log, env::tx_env_with_recovered},
|
||||
revm::env::tx_env_with_recovered,
|
||||
revm_primitives::{
|
||||
BlockEnv, CfgEnv, EVMError, Env, InvalidTransaction, ResultAndState, SpecId,
|
||||
BlockEnv, CfgEnvWithHandlerCfg, EVMError, Env, InvalidTransaction, ResultAndState, SpecId,
|
||||
},
|
||||
Block, BlockId, BlockNumberOrTag, ChainSpec, Header, IntoRecoveredTransaction, Receipt,
|
||||
Receipts, SealedBlockWithSenders, SealedHeader, B256, EMPTY_OMMER_ROOT_HASH, U256,
|
||||
@ -18,13 +18,14 @@ use reth_revm::{
|
||||
};
|
||||
use reth_transaction_pool::{BestTransactionsAttributes, TransactionPool};
|
||||
use revm::{db::states::bundle_state::BundleRetention, Database, DatabaseCommit, State};
|
||||
use revm_primitives::EnvWithHandlerCfg;
|
||||
use std::time::Instant;
|
||||
|
||||
/// Configured [BlockEnv] and [CfgEnv] for a pending block
|
||||
/// Configured [BlockEnv] and [CfgEnvWithHandlerCfg] for a pending block
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct PendingBlockEnv {
|
||||
/// Configured [CfgEnv] for the pending block.
|
||||
pub(crate) cfg: CfgEnv,
|
||||
/// Configured [CfgEnvWithHandlerCfg] for the pending block.
|
||||
pub(crate) cfg: CfgEnvWithHandlerCfg,
|
||||
/// Configured [BlockEnv] for the pending block.
|
||||
pub(crate) block_env: BlockEnv,
|
||||
/// Origin block for the config
|
||||
@ -131,10 +132,9 @@ impl PendingBlockEnv {
|
||||
|
||||
// Configure the environment for the block.
|
||||
let env =
|
||||
Env { cfg: cfg.clone(), block: block_env.clone(), tx: tx_env_with_recovered(&tx) };
|
||||
Env::boxed(cfg.cfg_env.clone(), block_env.clone(), tx_env_with_recovered(&tx));
|
||||
|
||||
let mut evm = revm::EVM::with_env(env);
|
||||
evm.database(&mut db);
|
||||
let mut evm = revm::Evm::builder().with_env(env).with_db(&mut db).build();
|
||||
|
||||
let ResultAndState { result, state } = match evm.transact() {
|
||||
Ok(res) => res,
|
||||
@ -157,7 +157,8 @@ impl PendingBlockEnv {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// drop evm to release db reference.
|
||||
drop(evm);
|
||||
// commit changes
|
||||
db.commit(state);
|
||||
|
||||
@ -182,7 +183,7 @@ impl PendingBlockEnv {
|
||||
tx_type: tx.tx_type(),
|
||||
success: result.is_success(),
|
||||
cumulative_gas_used,
|
||||
logs: result.logs().into_iter().map(into_reth_log).collect(),
|
||||
logs: result.logs().into_iter().map(Into::into).collect(),
|
||||
#[cfg(feature = "optimism")]
|
||||
deposit_nonce: None,
|
||||
#[cfg(feature = "optimism")]
|
||||
@ -233,7 +234,7 @@ impl PendingBlockEnv {
|
||||
|
||||
// check if cancun is activated to set eip4844 header fields correctly
|
||||
let blob_gas_used =
|
||||
if cfg.spec_id >= SpecId::CANCUN { Some(sum_blob_gas_used) } else { None };
|
||||
if cfg.handler_cfg.spec_id >= SpecId::CANCUN { Some(sum_blob_gas_used) } else { None };
|
||||
|
||||
let header = Header {
|
||||
parent_hash,
|
||||
@ -266,8 +267,8 @@ impl PendingBlockEnv {
|
||||
|
||||
/// Apply the [EIP-4788](https://eips.ethereum.org/EIPS/eip-4788) pre block contract call.
|
||||
///
|
||||
/// This constructs a new [EVM](revm::EVM) with the given DB, and environment ([CfgEnv] and
|
||||
/// [BlockEnv]) to execute the pre block contract call.
|
||||
/// This constructs a new [Evm](revm::Evm) with the given DB, and environment [CfgEnvWithHandlerCfg]
|
||||
/// and [BlockEnv]) to execute the pre block contract call.
|
||||
///
|
||||
/// This uses [apply_beacon_root_contract_call] to ultimately apply the beacon root contract state
|
||||
/// change.
|
||||
@ -275,23 +276,22 @@ fn pre_block_beacon_root_contract_call<DB: Database + DatabaseCommit>(
|
||||
db: &mut DB,
|
||||
chain_spec: &ChainSpec,
|
||||
block_number: u64,
|
||||
initialized_cfg: &CfgEnv,
|
||||
initialized_cfg: &CfgEnvWithHandlerCfg,
|
||||
initialized_block_env: &BlockEnv,
|
||||
parent_beacon_block_root: Option<B256>,
|
||||
) -> EthResult<()>
|
||||
where
|
||||
DB::Error: std::fmt::Display,
|
||||
{
|
||||
// Configure the environment for the block.
|
||||
let env = Env {
|
||||
cfg: initialized_cfg.clone(),
|
||||
block: initialized_block_env.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// apply pre-block EIP-4788 contract call
|
||||
let mut evm_pre_block = revm::EVM::with_env(env);
|
||||
evm_pre_block.database(db);
|
||||
let mut evm_pre_block = revm::Evm::builder()
|
||||
.with_db(db)
|
||||
.with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env(
|
||||
initialized_cfg.clone(),
|
||||
initialized_block_env.clone(),
|
||||
Default::default(),
|
||||
))
|
||||
.build();
|
||||
|
||||
// initialize a block from the env, because the pre block call needs the block itself
|
||||
apply_beacon_root_contract_call(
|
||||
|
||||
@ -18,7 +18,6 @@ use reth_node_api::ConfigureEvmEnv;
|
||||
use reth_primitives::{
|
||||
eip4844::calc_blob_gasprice,
|
||||
revm::env::{fill_block_env_with_coinbase, tx_env_with_recovered},
|
||||
revm_primitives::{db::DatabaseCommit, Env, ExecutionResult, ResultAndState, SpecId, State},
|
||||
Address, BlockId, BlockNumberOrTag, Bytes, FromRecoveredPooledTransaction, Header,
|
||||
IntoRecoveredTransaction, Receipt, SealedBlock, SealedBlockWithSenders,
|
||||
TransactionKind::{Call, Create},
|
||||
@ -39,7 +38,10 @@ use reth_rpc_types_compat::transaction::from_recovered_with_block_context;
|
||||
use reth_transaction_pool::{TransactionOrigin, TransactionPool};
|
||||
use revm::{
|
||||
db::CacheDB,
|
||||
primitives::{BlockEnv, CfgEnv},
|
||||
primitives::{
|
||||
db::DatabaseCommit, BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ExecutionResult,
|
||||
ResultAndState, SpecId, State,
|
||||
},
|
||||
Inspector,
|
||||
};
|
||||
|
||||
@ -70,7 +72,8 @@ pub(crate) type StateCacheDB = CacheDB<StateProviderDatabase<StateProviderBox>>;
|
||||
/// There are subtle differences between when transacting [CallRequest]:
|
||||
///
|
||||
/// The endpoints `eth_call` and `eth_estimateGas` and `eth_createAccessList` should always
|
||||
/// __disable__ the base fee check in the [Env] [Cfg](revm_primitives::CfgEnv).
|
||||
/// __disable__ the base fee check in the [EnvWithHandlerCfg]
|
||||
/// [Cfg](revm_primitives::CfgEnvWithHandlerCfg).
|
||||
///
|
||||
/// The behaviour for tracing endpoints is not consistent across clients.
|
||||
/// Geth also disables the basefee check for tracing: <https://github.com/ethereum/go-ethereum/blob/bc0b87ca196f92e5af49bd33cc190ef0ec32b197/eth/tracers/api.go#L955-L955>
|
||||
@ -104,12 +107,16 @@ pub trait EthTransactions: Send + Sync {
|
||||
/// for.
|
||||
/// If the [BlockId] is pending, this will return the "Pending" tag, otherwise this returns the
|
||||
/// hash of the exact block.
|
||||
async fn evm_env_at(&self, at: BlockId) -> EthResult<(CfgEnv, BlockEnv, BlockId)>;
|
||||
async fn evm_env_at(&self, at: BlockId)
|
||||
-> EthResult<(CfgEnvWithHandlerCfg, BlockEnv, BlockId)>;
|
||||
|
||||
/// Returns the revm evm env for the raw block header
|
||||
///
|
||||
/// This is used for tracing raw blocks
|
||||
async fn evm_env_for_raw_block(&self, at: &Header) -> EthResult<(CfgEnv, BlockEnv)>;
|
||||
async fn evm_env_for_raw_block(
|
||||
&self,
|
||||
at: &Header,
|
||||
) -> EthResult<(CfgEnvWithHandlerCfg, BlockEnv)>;
|
||||
|
||||
/// Get all transactions in the block with the given hash.
|
||||
///
|
||||
@ -177,8 +184,8 @@ pub trait EthTransactions: Send + Sync {
|
||||
/// Prepares the state and env for the given [CallRequest] at the given [BlockId] and executes
|
||||
/// the closure on a new task returning the result of the closure.
|
||||
///
|
||||
/// This returns the configured [Env] for the given [CallRequest] at the given [BlockId] and
|
||||
/// with configured call settings: `prepare_call_env`.
|
||||
/// This returns the configured [EnvWithHandlerCfg] for the given [CallRequest] at the given
|
||||
/// [BlockId] and with configured call settings: `prepare_call_env`.
|
||||
async fn spawn_with_call_at<F, R>(
|
||||
&self,
|
||||
request: CallRequest,
|
||||
@ -187,7 +194,7 @@ pub trait EthTransactions: Send + Sync {
|
||||
f: F,
|
||||
) -> EthResult<R>
|
||||
where
|
||||
F: FnOnce(StateCacheDB, Env) -> EthResult<R> + Send + 'static,
|
||||
F: FnOnce(StateCacheDB, EnvWithHandlerCfg) -> EthResult<R> + Send + 'static,
|
||||
R: Send + 'static;
|
||||
|
||||
/// Executes the call request at the given [BlockId].
|
||||
@ -196,7 +203,7 @@ pub trait EthTransactions: Send + Sync {
|
||||
request: CallRequest,
|
||||
at: BlockId,
|
||||
overrides: EvmOverrides,
|
||||
) -> EthResult<(ResultAndState, Env)>;
|
||||
) -> EthResult<(ResultAndState, EnvWithHandlerCfg)>;
|
||||
|
||||
/// Executes the call request at the given [BlockId] on a new task and returns the result of the
|
||||
/// inspect call.
|
||||
@ -206,7 +213,7 @@ pub trait EthTransactions: Send + Sync {
|
||||
at: BlockId,
|
||||
overrides: EvmOverrides,
|
||||
inspector: I,
|
||||
) -> EthResult<(ResultAndState, Env)>
|
||||
) -> EthResult<(ResultAndState, EnvWithHandlerCfg)>
|
||||
where
|
||||
I: Inspector<StateCacheDB> + Send + 'static;
|
||||
|
||||
@ -214,12 +221,12 @@ pub trait EthTransactions: Send + Sync {
|
||||
/// config.
|
||||
///
|
||||
/// The callback is then called with the [TracingInspector] and the [ResultAndState] after the
|
||||
/// configured [Env] was inspected.
|
||||
/// configured [EnvWithHandlerCfg] was inspected.
|
||||
///
|
||||
/// Caution: this is blocking
|
||||
fn trace_at<F, R>(
|
||||
&self,
|
||||
env: Env,
|
||||
env: EnvWithHandlerCfg,
|
||||
config: TracingInspectorConfig,
|
||||
at: BlockId,
|
||||
f: F,
|
||||
@ -233,10 +240,10 @@ pub trait EthTransactions: Send + Sync {
|
||||
/// config.
|
||||
///
|
||||
/// The callback is then called with the [TracingInspector] and the [ResultAndState] after the
|
||||
/// configured [Env] was inspected.
|
||||
/// configured [EnvWithHandlerCfg] was inspected.
|
||||
async fn spawn_trace_at_with_state<F, R>(
|
||||
&self,
|
||||
env: Env,
|
||||
env: EnvWithHandlerCfg,
|
||||
config: TracingInspectorConfig,
|
||||
at: BlockId,
|
||||
f: F,
|
||||
@ -364,7 +371,10 @@ where
|
||||
.await
|
||||
}
|
||||
|
||||
async fn evm_env_at(&self, at: BlockId) -> EthResult<(CfgEnv, BlockEnv, BlockId)> {
|
||||
async fn evm_env_at(
|
||||
&self,
|
||||
at: BlockId,
|
||||
) -> EthResult<(CfgEnvWithHandlerCfg, BlockEnv, BlockId)> {
|
||||
if at.is_pending() {
|
||||
let PendingBlockEnv { cfg, block_env, origin } = self.pending_block_env_and_cfg()?;
|
||||
Ok((cfg, block_env, origin.state_block_id()))
|
||||
@ -379,11 +389,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
async fn evm_env_for_raw_block(&self, header: &Header) -> EthResult<(CfgEnv, BlockEnv)> {
|
||||
async fn evm_env_for_raw_block(
|
||||
&self,
|
||||
header: &Header,
|
||||
) -> EthResult<(CfgEnvWithHandlerCfg, BlockEnv)> {
|
||||
// get the parent config first
|
||||
let (cfg, mut block_env, _) = self.evm_env_at(header.parent_hash.into()).await?;
|
||||
|
||||
let after_merge = cfg.spec_id >= SpecId::MERGE;
|
||||
let after_merge = cfg.handler_cfg.spec_id >= SpecId::MERGE;
|
||||
fill_block_env_with_coinbase(&mut block_env, header, after_merge, header.beneficiary);
|
||||
|
||||
Ok((cfg, block_env))
|
||||
@ -634,7 +647,7 @@ where
|
||||
f: F,
|
||||
) -> EthResult<R>
|
||||
where
|
||||
F: FnOnce(StateCacheDB, Env) -> EthResult<R> + Send + 'static,
|
||||
F: FnOnce(StateCacheDB, EnvWithHandlerCfg) -> EthResult<R> + Send + 'static,
|
||||
R: Send + 'static,
|
||||
{
|
||||
let (cfg, block_env, at) = self.evm_env_at(at).await?;
|
||||
@ -664,7 +677,7 @@ where
|
||||
request: CallRequest,
|
||||
at: BlockId,
|
||||
overrides: EvmOverrides,
|
||||
) -> EthResult<(ResultAndState, Env)> {
|
||||
) -> EthResult<(ResultAndState, EnvWithHandlerCfg)> {
|
||||
self.spawn_with_call_at(request, at, overrides, move |mut db, env| transact(&mut db, env))
|
||||
.await
|
||||
}
|
||||
@ -675,7 +688,7 @@ where
|
||||
at: BlockId,
|
||||
overrides: EvmOverrides,
|
||||
inspector: I,
|
||||
) -> EthResult<(ResultAndState, Env)>
|
||||
) -> EthResult<(ResultAndState, EnvWithHandlerCfg)>
|
||||
where
|
||||
I: Inspector<StateCacheDB> + Send + 'static,
|
||||
{
|
||||
@ -685,7 +698,7 @@ where
|
||||
|
||||
fn trace_at<F, R>(
|
||||
&self,
|
||||
env: Env,
|
||||
env: EnvWithHandlerCfg,
|
||||
config: TracingInspectorConfig,
|
||||
at: BlockId,
|
||||
f: F,
|
||||
@ -705,7 +718,7 @@ where
|
||||
|
||||
async fn spawn_trace_at_with_state<F, R>(
|
||||
&self,
|
||||
env: Env,
|
||||
env: EnvWithHandlerCfg,
|
||||
config: TracingInspectorConfig,
|
||||
at: BlockId,
|
||||
f: F,
|
||||
@ -773,7 +786,8 @@ where
|
||||
// replay all transactions prior to the targeted transaction
|
||||
replay_transactions_until(&mut db, cfg.clone(), block_env.clone(), block_txs, tx.hash)?;
|
||||
|
||||
let env = Env { cfg, block: block_env, tx: tx_env_with_recovered(&tx) };
|
||||
let env =
|
||||
EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, tx_env_with_recovered(&tx));
|
||||
|
||||
let mut inspector = TracingInspector::new(config);
|
||||
let (res, _, db) = inspect_and_return_db(db, env, &mut inspector)?;
|
||||
@ -866,7 +880,7 @@ where
|
||||
let mut db = CacheDB::new(StateProviderDatabase::new(state));
|
||||
|
||||
while let Some((tx_info, tx)) = transactions.next() {
|
||||
let env = Env { cfg: cfg.clone(), block: block_env.clone(), tx };
|
||||
let env = EnvWithHandlerCfg::new_with_cfg_env(cfg.clone(), block_env.clone(), tx);
|
||||
|
||||
let mut inspector = TracingInspector::new(config);
|
||||
let (res, _) = inspect(&mut db, env, &mut inspector)?;
|
||||
@ -1240,10 +1254,11 @@ pub(crate) fn build_transaction_receipt_with_block_receipts(
|
||||
if let Some(l1_block_info) = optimism_tx_meta.l1_block_info {
|
||||
if !transaction.is_deposit() {
|
||||
op_fields.l1_fee = optimism_tx_meta.l1_fee;
|
||||
op_fields.l1_gas_used =
|
||||
optimism_tx_meta.l1_data_gas.map(|dg| dg + l1_block_info.l1_fee_overhead);
|
||||
op_fields.l1_gas_used = optimism_tx_meta
|
||||
.l1_data_gas
|
||||
.map(|dg| dg + l1_block_info.l1_fee_overhead.unwrap_or_default());
|
||||
op_fields.l1_fee_scalar =
|
||||
Some(l1_block_info.l1_fee_scalar.div(U256::from(1_000_000)));
|
||||
Some(l1_block_info.l1_base_fee_scalar.div(U256::from(1_000_000)));
|
||||
op_fields.l1_gas_price = Some(l1_block_info.l1_base_fee);
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,8 +20,9 @@ use reth_rpc_api::EthCallBundleApiServer;
|
||||
use reth_rpc_types::{EthCallBundle, EthCallBundleResponse, EthCallBundleTransactionResult};
|
||||
use revm::{
|
||||
db::CacheDB,
|
||||
primitives::{Env, ResultAndState, TxEnv},
|
||||
primitives::{ResultAndState, TxEnv},
|
||||
};
|
||||
use revm_primitives::EnvWithHandlerCfg;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// `Eth` bundle implementation.
|
||||
@ -79,7 +80,7 @@ where
|
||||
.spawn_with_state_at_block(at, move |state| {
|
||||
let coinbase = block_env.coinbase;
|
||||
let basefee = Some(block_env.basefee.to::<u64>());
|
||||
let env = Env { cfg, block: block_env, tx: TxEnv::default() };
|
||||
let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block_env, TxEnv::default());
|
||||
let db = CacheDB::new(StateProviderDatabase::new(state));
|
||||
|
||||
let initial_coinbase = DatabaseRef::basic_ref(&db, coinbase)?
|
||||
@ -91,8 +92,8 @@ where
|
||||
let mut total_gas_fess = U256::ZERO;
|
||||
let mut hash_bytes = Vec::with_capacity(32 * transactions.len());
|
||||
|
||||
let mut evm = revm::EVM::with_env(env);
|
||||
evm.database(db);
|
||||
let mut evm =
|
||||
revm::Evm::builder().with_db(db).with_env_with_handler_cfg(env).build();
|
||||
|
||||
let mut results = Vec::with_capacity(transactions.len());
|
||||
let mut transactions = transactions.into_iter().peekable();
|
||||
@ -103,7 +104,7 @@ where
|
||||
let gas_price = tx
|
||||
.effective_tip_per_gas(basefee)
|
||||
.ok_or_else(|| RpcInvalidTransactionError::FeeCapTooLow)?;
|
||||
tx.try_fill_tx_env(&mut evm.env.tx)?;
|
||||
tx.try_fill_tx_env(evm.tx_mut())?;
|
||||
let ResultAndState { result, state } = evm.transact()?;
|
||||
|
||||
let gas_used = result.gas_used();
|
||||
@ -150,7 +151,7 @@ where
|
||||
if transactions.peek().is_some() {
|
||||
// need to apply the state changes of this call before executing
|
||||
// the next call
|
||||
evm.db.as_mut().expect("is set").commit(state)
|
||||
evm.context.evm.db.commit(state)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
21
crates/rpc/rpc/src/eth/cache/mod.rs
vendored
21
crates/rpc/rpc/src/eth/cache/mod.rs
vendored
@ -11,7 +11,7 @@ use reth_provider::{
|
||||
BlockReader, CanonStateNotification, EvmEnvProvider, StateProviderFactory, TransactionVariant,
|
||||
};
|
||||
use reth_tasks::{TaskSpawner, TokioTaskExecutor};
|
||||
use revm::primitives::{BlockEnv, CfgEnv};
|
||||
use revm::primitives::{BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId};
|
||||
use schnellru::{ByLength, Limiter};
|
||||
use std::{
|
||||
future::Future,
|
||||
@ -44,7 +44,7 @@ type BlockWithSendersResponseSender = oneshot::Sender<ProviderResult<Option<Bloc
|
||||
type ReceiptsResponseSender = oneshot::Sender<ProviderResult<Option<Arc<Vec<Receipt>>>>>;
|
||||
|
||||
/// The type that can send the response to a requested env
|
||||
type EnvResponseSender = oneshot::Sender<ProviderResult<(CfgEnv, BlockEnv)>>;
|
||||
type EnvResponseSender = oneshot::Sender<ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)>>;
|
||||
|
||||
type BlockLruCache<L> = MultiConsumerLruCache<
|
||||
B256,
|
||||
@ -56,7 +56,8 @@ type BlockLruCache<L> = MultiConsumerLruCache<
|
||||
type ReceiptsLruCache<L> =
|
||||
MultiConsumerLruCache<B256, Arc<Vec<Receipt>>, L, ReceiptsResponseSender>;
|
||||
|
||||
type EnvLruCache<L> = MultiConsumerLruCache<B256, (CfgEnv, BlockEnv), L, EnvResponseSender>;
|
||||
type EnvLruCache<L> =
|
||||
MultiConsumerLruCache<B256, (CfgEnvWithHandlerCfg, BlockEnv), L, EnvResponseSender>;
|
||||
|
||||
/// Provides async access to cached eth data
|
||||
///
|
||||
@ -252,7 +253,10 @@ impl EthStateCache {
|
||||
///
|
||||
/// Returns an error if the corresponding header (required for populating the envs) was not
|
||||
/// found.
|
||||
pub async fn get_evm_env(&self, block_hash: B256) -> ProviderResult<(CfgEnv, BlockEnv)> {
|
||||
pub async fn get_evm_env(
|
||||
&self,
|
||||
block_hash: B256,
|
||||
) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)> {
|
||||
let (response_tx, rx) = oneshot::channel();
|
||||
let _ = self.to_service.send(CacheAction::GetEnv { block_hash, response_tx });
|
||||
rx.await.map_err(|_| ProviderError::CacheServiceUnavailable)?
|
||||
@ -285,7 +289,7 @@ pub(crate) struct EthStateCacheService<
|
||||
> where
|
||||
LimitBlocks: Limiter<B256, BlockWithSenders>,
|
||||
LimitReceipts: Limiter<B256, Arc<Vec<Receipt>>>,
|
||||
LimitEnvs: Limiter<B256, (CfgEnv, BlockEnv)>,
|
||||
LimitEnvs: Limiter<B256, (CfgEnvWithHandlerCfg, BlockEnv)>,
|
||||
{
|
||||
/// The type used to lookup data from disk
|
||||
provider: Provider,
|
||||
@ -476,7 +480,10 @@ where
|
||||
this.action_task_spawner.spawn_blocking(Box::pin(async move {
|
||||
// Acquire permit
|
||||
let _permit = rate_limiter.acquire().await;
|
||||
let mut cfg = CfgEnv::default();
|
||||
let mut cfg = CfgEnvWithHandlerCfg::new(
|
||||
CfgEnv::default(),
|
||||
SpecId::LATEST,
|
||||
);
|
||||
let mut block_env = BlockEnv::default();
|
||||
let res = provider
|
||||
.fill_env_at(
|
||||
@ -551,7 +558,7 @@ enum CacheAction {
|
||||
GetReceipts { block_hash: B256, response_tx: ReceiptsResponseSender },
|
||||
BlockWithSendersResult { block_hash: B256, res: ProviderResult<Option<BlockWithSenders>> },
|
||||
ReceiptsResult { block_hash: B256, res: ProviderResult<Option<Arc<Vec<Receipt>>>> },
|
||||
EnvResult { block_hash: B256, res: Box<ProviderResult<(CfgEnv, BlockEnv)>> },
|
||||
EnvResult { block_hash: B256, res: Box<ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)>> },
|
||||
CacheNewCanonicalChain { blocks: Vec<SealedBlockWithSenders>, receipts: Vec<BlockReceipts> },
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ use reth_transaction_pool::error::{
|
||||
Eip4844PoolTransactionError, InvalidPoolTransactionError, PoolError, PoolErrorKind,
|
||||
PoolTransactionError,
|
||||
};
|
||||
use revm::primitives::{EVMError, ExecutionResult, Halt, OutOfGasError};
|
||||
use revm::primitives::{EVMError, ExecutionResult, HaltReason, OutOfGasError};
|
||||
use std::time::Duration;
|
||||
|
||||
/// Result alias
|
||||
@ -110,6 +110,9 @@ pub enum EthApiError {
|
||||
#[error(transparent)]
|
||||
#[cfg(feature = "optimism")]
|
||||
Optimism(#[from] OptimismEthApiError),
|
||||
/// Evm generic purpose error.
|
||||
#[error("Revm error: {0}")]
|
||||
EvmCustom(String),
|
||||
}
|
||||
|
||||
/// Eth Optimism Api Error
|
||||
@ -150,7 +153,8 @@ impl From<EthApiError> for ErrorObject<'static> {
|
||||
EthApiError::ExcessBlobGasNotSet |
|
||||
EthApiError::InvalidBlockData(_) |
|
||||
EthApiError::Internal(_) |
|
||||
EthApiError::TransactionNotFound => internal_rpc_err(error.to_string()),
|
||||
EthApiError::TransactionNotFound |
|
||||
EthApiError::EvmCustom(_) => internal_rpc_err(error.to_string()),
|
||||
EthApiError::UnknownBlockNumber | EthApiError::UnknownBlockOrTxIndex => {
|
||||
rpc_error_with_code(EthRpcErrorCode::ResourceNotFound.code(), error.to_string())
|
||||
}
|
||||
@ -234,6 +238,7 @@ where
|
||||
EthApiError::ExcessBlobGasNotSet
|
||||
}
|
||||
EVMError::Database(err) => err.into(),
|
||||
EVMError::Custom(err) => EthApiError::EvmCustom(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -320,7 +325,7 @@ pub enum RpcInvalidTransactionError {
|
||||
Revert(RevertError),
|
||||
/// Unspecific EVM halt error.
|
||||
#[error("EVM error {0:?}")]
|
||||
EvmHalt(Halt),
|
||||
EvmHalt(HaltReason),
|
||||
/// Invalid chain id set for the transaction.
|
||||
#[error("invalid chain ID")]
|
||||
InvalidChainId,
|
||||
@ -385,10 +390,10 @@ impl RpcInvalidTransactionError {
|
||||
/// Converts the halt error
|
||||
///
|
||||
/// Takes the configured gas limit of the transaction which is attached to the error
|
||||
pub(crate) fn halt(reason: Halt, gas_limit: u64) -> Self {
|
||||
pub(crate) fn halt(reason: HaltReason, gas_limit: u64) -> Self {
|
||||
match reason {
|
||||
Halt::OutOfGas(err) => RpcInvalidTransactionError::out_of_gas(err, gas_limit),
|
||||
Halt::NonceOverflow => RpcInvalidTransactionError::NonceMaxValue,
|
||||
HaltReason::OutOfGas(err) => RpcInvalidTransactionError::out_of_gas(err, gas_limit),
|
||||
HaltReason::NonceOverflow => RpcInvalidTransactionError::NonceMaxValue,
|
||||
err => RpcInvalidTransactionError::EvmHalt(err),
|
||||
}
|
||||
}
|
||||
@ -397,7 +402,7 @@ impl RpcInvalidTransactionError {
|
||||
pub(crate) fn out_of_gas(reason: OutOfGasError, gas_limit: u64) -> Self {
|
||||
let gas_limit = U256::from(gas_limit);
|
||||
match reason {
|
||||
OutOfGasError::BasicOutOfGas => RpcInvalidTransactionError::BasicOutOfGas(gas_limit),
|
||||
OutOfGasError::Basic => RpcInvalidTransactionError::BasicOutOfGas(gas_limit),
|
||||
OutOfGasError::Memory => RpcInvalidTransactionError::MemoryOutOfGas(gas_limit),
|
||||
OutOfGasError::Precompile => RpcInvalidTransactionError::PrecompileOutOfGas(gas_limit),
|
||||
OutOfGasError::InvalidOperand => {
|
||||
@ -449,7 +454,7 @@ impl From<revm::primitives::InvalidTransaction> for RpcInvalidTransactionError {
|
||||
InvalidTransaction::NonceOverflowInTransaction => {
|
||||
RpcInvalidTransactionError::NonceMaxValue
|
||||
}
|
||||
InvalidTransaction::CreateInitcodeSizeLimit => {
|
||||
InvalidTransaction::CreateInitCodeSizeLimit => {
|
||||
RpcInvalidTransactionError::MaxInitCodeSizeExceeded
|
||||
}
|
||||
InvalidTransaction::NonceTooHigh { .. } => RpcInvalidTransactionError::NonceTooHigh,
|
||||
|
||||
@ -17,13 +17,13 @@ use reth_rpc_types::{
|
||||
use revm::primitives::{Bytes, OptimismFields};
|
||||
use revm::{
|
||||
db::CacheDB,
|
||||
precompile::{Precompiles, SpecId as PrecompilesSpecId},
|
||||
primitives::{BlockEnv, CfgEnv, Env, ResultAndState, SpecId, TransactTo, TxEnv},
|
||||
Database, Inspector,
|
||||
};
|
||||
use revm_primitives::{
|
||||
db::{DatabaseCommit, DatabaseRef},
|
||||
Bytecode,
|
||||
inspector_handle_register,
|
||||
precompile::{PrecompileSpecId, Precompiles},
|
||||
primitives::{
|
||||
db::DatabaseRef, BlockEnv, Bytecode, CfgEnvWithHandlerCfg, EnvWithHandlerCfg,
|
||||
ResultAndState, SpecId, TransactTo, TxEnv,
|
||||
},
|
||||
Database, GetInspector,
|
||||
};
|
||||
use tracing::trace;
|
||||
|
||||
@ -116,33 +116,45 @@ impl FillableTransaction for TransactionSigned {
|
||||
/// Returns the addresses of the precompiles corresponding to the SpecId.
|
||||
#[inline]
|
||||
pub(crate) fn get_precompiles(spec_id: SpecId) -> impl IntoIterator<Item = Address> {
|
||||
let spec = PrecompilesSpecId::from_spec_id(spec_id);
|
||||
Precompiles::new(spec).addresses().into_iter().copied().map(Address::from)
|
||||
let spec = PrecompileSpecId::from_spec_id(spec_id);
|
||||
Precompiles::new(spec).addresses().copied().map(Address::from)
|
||||
}
|
||||
|
||||
/// Executes the [Env] against the given [Database] without committing state changes.
|
||||
pub(crate) fn transact<DB>(db: DB, env: Env) -> EthResult<(ResultAndState, Env)>
|
||||
/// Executes the [EnvWithHandlerCfg] against the given [Database] without committing state changes.
|
||||
pub(crate) fn transact<DB>(
|
||||
db: DB,
|
||||
env: EnvWithHandlerCfg,
|
||||
) -> EthResult<(ResultAndState, EnvWithHandlerCfg)>
|
||||
where
|
||||
DB: Database,
|
||||
<DB as Database>::Error: Into<EthApiError>,
|
||||
{
|
||||
let mut evm = revm::EVM::with_env(env);
|
||||
evm.database(db);
|
||||
let mut evm = revm::Evm::builder().with_db(db).with_env_with_handler_cfg(env).build();
|
||||
let res = evm.transact()?;
|
||||
Ok((res, evm.env))
|
||||
let (_, env) = evm.into_db_and_env_with_handler_cfg();
|
||||
Ok((res, env))
|
||||
}
|
||||
|
||||
/// Executes the [Env] against the given [Database] without committing state changes.
|
||||
pub(crate) fn inspect<DB, I>(db: DB, env: Env, inspector: I) -> EthResult<(ResultAndState, Env)>
|
||||
/// Executes the [EnvWithHandlerCfg] against the given [Database] without committing state changes.
|
||||
pub(crate) fn inspect<DB, I>(
|
||||
db: DB,
|
||||
env: EnvWithHandlerCfg,
|
||||
inspector: I,
|
||||
) -> EthResult<(ResultAndState, EnvWithHandlerCfg)>
|
||||
where
|
||||
DB: Database,
|
||||
<DB as Database>::Error: Into<EthApiError>,
|
||||
I: Inspector<DB>,
|
||||
I: GetInspector<DB>,
|
||||
{
|
||||
let mut evm = revm::EVM::with_env(env);
|
||||
evm.database(db);
|
||||
let res = evm.inspect(inspector)?;
|
||||
Ok((res, evm.env))
|
||||
let mut evm = revm::Evm::builder()
|
||||
.with_db(db)
|
||||
.with_external_context(inspector)
|
||||
.with_env_with_handler_cfg(env)
|
||||
.append_handler_register(inspector_handle_register)
|
||||
.build();
|
||||
let res = evm.transact()?;
|
||||
let (_, env) = evm.into_db_and_env_with_handler_cfg();
|
||||
Ok((res, env))
|
||||
}
|
||||
|
||||
/// Same as [inspect] but also returns the database again.
|
||||
@ -151,19 +163,23 @@ where
|
||||
/// this is still useful if there are certain trait bounds on the Inspector's database generic type
|
||||
pub(crate) fn inspect_and_return_db<DB, I>(
|
||||
db: DB,
|
||||
env: Env,
|
||||
env: EnvWithHandlerCfg,
|
||||
inspector: I,
|
||||
) -> EthResult<(ResultAndState, Env, DB)>
|
||||
) -> EthResult<(ResultAndState, EnvWithHandlerCfg, DB)>
|
||||
where
|
||||
DB: Database,
|
||||
<DB as Database>::Error: Into<EthApiError>,
|
||||
I: Inspector<DB>,
|
||||
I: GetInspector<DB>,
|
||||
{
|
||||
let mut evm = revm::EVM::with_env(env);
|
||||
evm.database(db);
|
||||
let res = evm.inspect(inspector)?;
|
||||
let db = evm.take_db();
|
||||
Ok((res, evm.env, db))
|
||||
let mut evm = revm::Evm::builder()
|
||||
.with_external_context(inspector)
|
||||
.with_db(db)
|
||||
.with_env_with_handler_cfg(env)
|
||||
.append_handler_register(inspector_handle_register)
|
||||
.build();
|
||||
let res = evm.transact()?;
|
||||
let (db, env) = evm.into_db_and_env_with_handler_cfg();
|
||||
Ok((res, env, db))
|
||||
}
|
||||
|
||||
/// Replays all the transactions until the target transaction is found.
|
||||
@ -175,7 +191,7 @@ where
|
||||
/// Returns the index of the target transaction in the given iterator.
|
||||
pub(crate) fn replay_transactions_until<DB, I, Tx>(
|
||||
db: &mut CacheDB<DB>,
|
||||
cfg: CfgEnv,
|
||||
cfg: CfgEnvWithHandlerCfg,
|
||||
block_env: BlockEnv,
|
||||
transactions: I,
|
||||
target_tx_hash: B256,
|
||||
@ -186,9 +202,14 @@ where
|
||||
I: IntoIterator<Item = Tx>,
|
||||
Tx: FillableTransaction,
|
||||
{
|
||||
let env = Env { cfg, block: block_env, tx: TxEnv::default() };
|
||||
let mut evm = revm::EVM::with_env(env);
|
||||
evm.database(db);
|
||||
let mut evm = revm::Evm::builder()
|
||||
.with_db(db)
|
||||
.with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env(
|
||||
cfg,
|
||||
block_env,
|
||||
Default::default(),
|
||||
))
|
||||
.build();
|
||||
let mut index = 0;
|
||||
for tx in transactions.into_iter() {
|
||||
if tx.hash() == target_tx_hash {
|
||||
@ -196,15 +217,14 @@ where
|
||||
break
|
||||
}
|
||||
|
||||
tx.try_fill_tx_env(&mut evm.env.tx)?;
|
||||
let res = evm.transact()?;
|
||||
evm.db.as_mut().expect("is set").commit(res.state);
|
||||
tx.try_fill_tx_env(evm.tx_mut())?;
|
||||
evm.transact_commit()?;
|
||||
index += 1;
|
||||
}
|
||||
Ok(index)
|
||||
}
|
||||
|
||||
/// Prepares the [Env] for execution.
|
||||
/// Prepares the [EnvWithHandlerCfg] for execution.
|
||||
///
|
||||
/// Does not commit any changes to the underlying database.
|
||||
///
|
||||
@ -213,13 +233,13 @@ where
|
||||
/// - `disable_eip3607` is set to `true`
|
||||
/// - `disable_base_fee` is set to `true`
|
||||
pub(crate) fn prepare_call_env<DB>(
|
||||
mut cfg: CfgEnv,
|
||||
mut cfg: CfgEnvWithHandlerCfg,
|
||||
block: BlockEnv,
|
||||
request: CallRequest,
|
||||
gas_limit: u64,
|
||||
db: &mut CacheDB<DB>,
|
||||
overrides: EvmOverrides,
|
||||
) -> EthResult<Env>
|
||||
) -> EthResult<EnvWithHandlerCfg>
|
||||
where
|
||||
DB: DatabaseRef,
|
||||
EthApiError: From<<DB as DatabaseRef>::Error>,
|
||||
@ -253,7 +273,7 @@ where
|
||||
db.block_hashes
|
||||
.extend(block_hashes.into_iter().map(|(num, hash)| (U256::from(num), hash)))
|
||||
}
|
||||
apply_block_overrides(*block_overrides, &mut env.block);
|
||||
apply_block_overrides(*block_overrides, &mut env.env.block);
|
||||
}
|
||||
|
||||
if request_gas.is_none() {
|
||||
@ -276,16 +296,16 @@ where
|
||||
Ok(env)
|
||||
}
|
||||
|
||||
/// Creates a new [Env] to be used for executing the [CallRequest] in `eth_call`.
|
||||
/// Creates a new [EnvWithHandlerCfg] to be used for executing the [CallRequest] in `eth_call`.
|
||||
///
|
||||
/// Note: this does _not_ access the Database to check the sender.
|
||||
pub(crate) fn build_call_evm_env(
|
||||
cfg: CfgEnv,
|
||||
cfg: CfgEnvWithHandlerCfg,
|
||||
block: BlockEnv,
|
||||
request: CallRequest,
|
||||
) -> EthResult<Env> {
|
||||
) -> EthResult<EnvWithHandlerCfg> {
|
||||
let tx = create_txn_env(&block, request)?;
|
||||
Ok(Env { cfg, block, tx })
|
||||
Ok(EnvWithHandlerCfg::new_with_cfg_env(cfg, block, tx))
|
||||
}
|
||||
|
||||
/// Configures a new [TxEnv] for the [CallRequest]
|
||||
|
||||
@ -11,8 +11,7 @@ use async_trait::async_trait;
|
||||
use jsonrpsee::core::RpcResult as Result;
|
||||
use reth_consensus_common::calc::{base_block_reward, block_reward};
|
||||
use reth_primitives::{
|
||||
revm::env::tx_env_with_recovered, revm_primitives::db::DatabaseCommit, BlockId,
|
||||
BlockNumberOrTag, Bytes, SealedHeader, B256, U256,
|
||||
revm::env::tx_env_with_recovered, BlockId, BlockNumberOrTag, Bytes, SealedHeader, B256, U256,
|
||||
};
|
||||
use reth_provider::{BlockReader, ChainSpecProvider, EvmEnvProvider, StateProviderFactory};
|
||||
use reth_revm::{
|
||||
@ -25,7 +24,10 @@ use reth_rpc_types::{
|
||||
trace::{filter::TraceFilter, parity::*, tracerequest::TraceCallRequest},
|
||||
BlockError, BlockOverrides, CallRequest, Index,
|
||||
};
|
||||
use revm::{db::CacheDB, primitives::Env};
|
||||
use revm::{
|
||||
db::{CacheDB, DatabaseCommit},
|
||||
primitives::EnvWithHandlerCfg,
|
||||
};
|
||||
use std::{collections::HashSet, sync::Arc};
|
||||
use tokio::sync::{AcquireError, OwnedSemaphorePermit};
|
||||
|
||||
@ -101,7 +103,7 @@ where
|
||||
.evm_env_at(block_id.unwrap_or(BlockId::Number(BlockNumberOrTag::Latest)))
|
||||
.await?;
|
||||
let tx = tx_env_with_recovered(&tx.into_ecrecovered_transaction());
|
||||
let env = Env { cfg, block, tx };
|
||||
let env = EnvWithHandlerCfg::new_with_cfg_env(cfg, block, tx);
|
||||
|
||||
let config = TracingInspectorConfig::from_parity_config(&trace_types);
|
||||
|
||||
|
||||
@ -383,7 +383,8 @@ mod tests {
|
||||
tx.get::<tables::Transactions>(0).err(),
|
||||
Some(DatabaseError::Open(reth_libmdbx::Error::NotFound.into()))
|
||||
); // Transaction is not timeout-ed
|
||||
assert!(!tx.metrics_handler.unwrap().backtrace_recorded.load(Ordering::Relaxed)); // Backtrace is not recorded
|
||||
assert!(!tx.metrics_handler.unwrap().backtrace_recorded.load(Ordering::Relaxed));
|
||||
// Backtrace is not recorded
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -402,6 +403,7 @@ mod tests {
|
||||
tx.get::<tables::Transactions>(0).err(),
|
||||
Some(DatabaseError::Open(reth_libmdbx::Error::ReadTransactionAborted.into()))
|
||||
); // Transaction is timeout-ed
|
||||
assert!(tx.metrics_handler.unwrap().backtrace_recorded.load(Ordering::Relaxed)); // Backtrace is recorded
|
||||
assert!(tx.metrics_handler.unwrap().backtrace_recorded.load(Ordering::Relaxed));
|
||||
// Backtrace is recorded
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ use reth_primitives::{
|
||||
SealedHeader, TransactionMeta, TransactionSigned, TransactionSignedNoHash, TxHash, TxNumber,
|
||||
Withdrawal, Withdrawals, B256, U256,
|
||||
};
|
||||
use revm::primitives::{BlockEnv, CfgEnv};
|
||||
use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg};
|
||||
use std::{
|
||||
ops::{RangeBounds, RangeInclusive},
|
||||
path::{Path, PathBuf},
|
||||
@ -440,7 +440,7 @@ impl<DB: Database> StageCheckpointReader for ProviderFactory<DB> {
|
||||
impl<DB: Database> EvmEnvProvider for ProviderFactory<DB> {
|
||||
fn fill_env_at<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
block_env: &mut BlockEnv,
|
||||
at: BlockHashOrNumber,
|
||||
evm_config: EvmConfig,
|
||||
@ -453,7 +453,7 @@ impl<DB: Database> EvmEnvProvider for ProviderFactory<DB> {
|
||||
|
||||
fn fill_env_with_header<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
block_env: &mut BlockEnv,
|
||||
header: &Header,
|
||||
evm_config: EvmConfig,
|
||||
@ -482,7 +482,7 @@ impl<DB: Database> EvmEnvProvider for ProviderFactory<DB> {
|
||||
|
||||
fn fill_cfg_env_at<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
at: BlockHashOrNumber,
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
@ -494,7 +494,7 @@ impl<DB: Database> EvmEnvProvider for ProviderFactory<DB> {
|
||||
|
||||
fn fill_cfg_env_with_header<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
header: &Header,
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
|
||||
@ -43,7 +43,7 @@ use reth_primitives::{
|
||||
TransactionSignedNoHash, TxHash, TxNumber, Withdrawal, Withdrawals, B256, U256,
|
||||
};
|
||||
use reth_trie::{prefix_set::PrefixSetMut, updates::TrieUpdates, HashedPostState, StateRoot};
|
||||
use revm::primitives::{BlockEnv, CfgEnv, SpecId};
|
||||
use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg, SpecId};
|
||||
use std::{
|
||||
collections::{hash_map, BTreeMap, BTreeSet, HashMap, HashSet},
|
||||
fmt::Debug,
|
||||
@ -1728,7 +1728,7 @@ impl<TX: DbTx> WithdrawalsProvider for DatabaseProvider<TX> {
|
||||
impl<TX: DbTx> EvmEnvProvider for DatabaseProvider<TX> {
|
||||
fn fill_env_at<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
block_env: &mut BlockEnv,
|
||||
at: BlockHashOrNumber,
|
||||
evm_config: EvmConfig,
|
||||
@ -1743,7 +1743,7 @@ impl<TX: DbTx> EvmEnvProvider for DatabaseProvider<TX> {
|
||||
|
||||
fn fill_env_with_header<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
block_env: &mut BlockEnv,
|
||||
header: &Header,
|
||||
_evm_config: EvmConfig,
|
||||
@ -1801,7 +1801,7 @@ impl<TX: DbTx> EvmEnvProvider for DatabaseProvider<TX> {
|
||||
|
||||
fn fill_cfg_env_at<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
at: BlockHashOrNumber,
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
@ -1815,7 +1815,7 @@ impl<TX: DbTx> EvmEnvProvider for DatabaseProvider<TX> {
|
||||
|
||||
fn fill_cfg_env_with_header<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
header: &Header,
|
||||
_evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
|
||||
@ -22,7 +22,7 @@ use reth_primitives::{
|
||||
TransactionSigned, TransactionSignedNoHash, TxHash, TxNumber, Withdrawal, Withdrawals, B256,
|
||||
U256,
|
||||
};
|
||||
use revm::primitives::{BlockEnv, CfgEnv};
|
||||
use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg};
|
||||
use std::{
|
||||
collections::{BTreeMap, HashSet},
|
||||
ops::{RangeBounds, RangeInclusive},
|
||||
@ -460,7 +460,7 @@ where
|
||||
{
|
||||
fn fill_env_at<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
block_env: &mut BlockEnv,
|
||||
at: BlockHashOrNumber,
|
||||
evm_config: EvmConfig,
|
||||
@ -473,7 +473,7 @@ where
|
||||
|
||||
fn fill_env_with_header<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
block_env: &mut BlockEnv,
|
||||
header: &Header,
|
||||
evm_config: EvmConfig,
|
||||
@ -502,7 +502,7 @@ where
|
||||
|
||||
fn fill_cfg_env_at<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
at: BlockHashOrNumber,
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
@ -514,7 +514,7 @@ where
|
||||
|
||||
fn fill_cfg_env_with_header<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
header: &Header,
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
|
||||
@ -18,7 +18,7 @@ use reth_primitives::{
|
||||
U256,
|
||||
};
|
||||
use reth_trie::updates::TrieUpdates;
|
||||
use revm::primitives::{BlockEnv, CfgEnv};
|
||||
use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg};
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap},
|
||||
ops::{RangeBounds, RangeInclusive},
|
||||
@ -558,7 +558,7 @@ impl StateProvider for MockEthProvider {
|
||||
impl EvmEnvProvider for MockEthProvider {
|
||||
fn fill_env_at<EvmConfig>(
|
||||
&self,
|
||||
_cfg: &mut CfgEnv,
|
||||
_cfg: &mut CfgEnvWithHandlerCfg,
|
||||
_block_env: &mut BlockEnv,
|
||||
_at: BlockHashOrNumber,
|
||||
_evm_config: EvmConfig,
|
||||
@ -571,7 +571,7 @@ impl EvmEnvProvider for MockEthProvider {
|
||||
|
||||
fn fill_env_with_header<EvmConfig>(
|
||||
&self,
|
||||
_cfg: &mut CfgEnv,
|
||||
_cfg: &mut CfgEnvWithHandlerCfg,
|
||||
_block_env: &mut BlockEnv,
|
||||
_header: &Header,
|
||||
_evm_config: EvmConfig,
|
||||
@ -600,7 +600,7 @@ impl EvmEnvProvider for MockEthProvider {
|
||||
|
||||
fn fill_cfg_env_at<EvmConfig>(
|
||||
&self,
|
||||
_cfg: &mut CfgEnv,
|
||||
_cfg: &mut CfgEnvWithHandlerCfg,
|
||||
_at: BlockHashOrNumber,
|
||||
_evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
@ -612,7 +612,7 @@ impl EvmEnvProvider for MockEthProvider {
|
||||
|
||||
fn fill_cfg_env_with_header<EvmConfig>(
|
||||
&self,
|
||||
_cfg: &mut CfgEnv,
|
||||
_cfg: &mut CfgEnvWithHandlerCfg,
|
||||
_header: &Header,
|
||||
_evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
|
||||
@ -20,7 +20,7 @@ use reth_primitives::{
|
||||
MAINNET, U256,
|
||||
};
|
||||
use reth_trie::updates::TrieUpdates;
|
||||
use revm::primitives::{BlockEnv, CfgEnv};
|
||||
use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg};
|
||||
use std::{
|
||||
ops::{RangeBounds, RangeInclusive},
|
||||
sync::Arc,
|
||||
@ -318,7 +318,7 @@ impl StateProvider for NoopProvider {
|
||||
impl EvmEnvProvider for NoopProvider {
|
||||
fn fill_env_at<EvmConfig>(
|
||||
&self,
|
||||
_cfg: &mut CfgEnv,
|
||||
_cfg: &mut CfgEnvWithHandlerCfg,
|
||||
_block_env: &mut BlockEnv,
|
||||
_at: BlockHashOrNumber,
|
||||
_evm_config: EvmConfig,
|
||||
@ -331,7 +331,7 @@ impl EvmEnvProvider for NoopProvider {
|
||||
|
||||
fn fill_env_with_header<EvmConfig>(
|
||||
&self,
|
||||
_cfg: &mut CfgEnv,
|
||||
_cfg: &mut CfgEnvWithHandlerCfg,
|
||||
_block_env: &mut BlockEnv,
|
||||
_header: &Header,
|
||||
_evm_config: EvmConfig,
|
||||
@ -360,7 +360,7 @@ impl EvmEnvProvider for NoopProvider {
|
||||
|
||||
fn fill_cfg_env_at<EvmConfig>(
|
||||
&self,
|
||||
_cfg: &mut CfgEnv,
|
||||
_cfg: &mut CfgEnvWithHandlerCfg,
|
||||
_at: BlockHashOrNumber,
|
||||
_evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
@ -372,7 +372,7 @@ impl EvmEnvProvider for NoopProvider {
|
||||
|
||||
fn fill_cfg_env_with_header<EvmConfig>(
|
||||
&self,
|
||||
_cfg: &mut CfgEnv,
|
||||
_cfg: &mut CfgEnvWithHandlerCfg,
|
||||
_header: &Header,
|
||||
_evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
use reth_interfaces::provider::ProviderResult;
|
||||
use reth_node_api::ConfigureEvmEnv;
|
||||
use reth_primitives::{BlockHashOrNumber, Header};
|
||||
use revm::primitives::{BlockEnv, CfgEnv};
|
||||
use revm::primitives::{BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId};
|
||||
|
||||
/// A provider type that knows chain specific information required to configure an
|
||||
/// [Env](revm::primitives::Env).
|
||||
/// [CfgEnvWithHandlerCfg].
|
||||
///
|
||||
/// This type is mainly used to provide required data to configure the EVM environment.
|
||||
#[auto_impl::auto_impl(&, Arc)]
|
||||
pub trait EvmEnvProvider: Send + Sync {
|
||||
/// Fills the [CfgEnv] and [BlockEnv] fields with values specific to the given
|
||||
/// Fills the [CfgEnvWithHandlerCfg] and [BlockEnv] fields with values specific to the given
|
||||
/// [BlockHashOrNumber].
|
||||
fn fill_env_at<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
block_env: &mut BlockEnv,
|
||||
at: BlockHashOrNumber,
|
||||
evm_config: EvmConfig,
|
||||
@ -21,25 +21,27 @@ pub trait EvmEnvProvider: Send + Sync {
|
||||
where
|
||||
EvmConfig: ConfigureEvmEnv;
|
||||
|
||||
/// Fills the default [CfgEnv] and [BlockEnv] fields with values specific to the given [Header].
|
||||
/// Fills the default [CfgEnvWithHandlerCfg] and [BlockEnv] fields with values specific to the
|
||||
/// given [Header].
|
||||
fn env_with_header<EvmConfig>(
|
||||
&self,
|
||||
header: &Header,
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<(CfgEnv, BlockEnv)>
|
||||
) -> ProviderResult<(CfgEnvWithHandlerCfg, BlockEnv)>
|
||||
where
|
||||
EvmConfig: ConfigureEvmEnv,
|
||||
{
|
||||
let mut cfg = CfgEnv::default();
|
||||
let mut cfg = CfgEnvWithHandlerCfg::new(CfgEnv::default(), SpecId::LATEST);
|
||||
let mut block_env = BlockEnv::default();
|
||||
self.fill_env_with_header::<EvmConfig>(&mut cfg, &mut block_env, header, evm_config)?;
|
||||
Ok((cfg, block_env))
|
||||
}
|
||||
|
||||
/// Fills the [CfgEnv] and [BlockEnv] fields with values specific to the given [Header].
|
||||
/// Fills the [CfgEnvWithHandlerCfg] and [BlockEnv] fields with values specific to the given
|
||||
/// [Header].
|
||||
fn fill_env_with_header<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
block_env: &mut BlockEnv,
|
||||
header: &Header,
|
||||
evm_config: EvmConfig,
|
||||
@ -61,20 +63,21 @@ pub trait EvmEnvProvider: Send + Sync {
|
||||
header: &Header,
|
||||
) -> ProviderResult<()>;
|
||||
|
||||
/// Fills the [CfgEnv] fields with values specific to the given [BlockHashOrNumber].
|
||||
/// Fills the [CfgEnvWithHandlerCfg] fields with values specific to the given
|
||||
/// [BlockHashOrNumber].
|
||||
fn fill_cfg_env_at<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
at: BlockHashOrNumber,
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
where
|
||||
EvmConfig: ConfigureEvmEnv;
|
||||
|
||||
/// Fills the [CfgEnv] fields with values specific to the given [Header].
|
||||
/// Fills the [CfgEnvWithHandlerCfg] fields with values specific to the given [Header].
|
||||
fn fill_cfg_env_with_header<EvmConfig>(
|
||||
&self,
|
||||
cfg: &mut CfgEnv,
|
||||
cfg: &mut CfgEnvWithHandlerCfg,
|
||||
header: &Header,
|
||||
evm_config: EvmConfig,
|
||||
) -> ProviderResult<()>
|
||||
|
||||
@ -305,6 +305,8 @@ pub enum ForkSpec {
|
||||
/// After Merge plus new PUSH0 opcode
|
||||
#[serde(alias = "Merge+3855")]
|
||||
MergePush0,
|
||||
/// Cancun
|
||||
Cancun,
|
||||
/// Fork Spec which is unknown to us
|
||||
#[serde(other)]
|
||||
Unknown,
|
||||
@ -335,6 +337,7 @@ impl From<ForkSpec> for ChainSpec {
|
||||
ForkSpec::MergeMeterInitCode => spec_builder.paris_activated(),
|
||||
ForkSpec::MergePush0 => spec_builder.paris_activated(),
|
||||
ForkSpec::Shanghai => spec_builder.shanghai_activated(),
|
||||
ForkSpec::Cancun => spec_builder.cancun_activated(),
|
||||
ForkSpec::ByzantiumToConstantinopleAt5 | ForkSpec::Constantinople => {
|
||||
panic!("Overridden with PETERSBURG")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user