mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
157 lines
5.1 KiB
Rust
157 lines
5.1 KiB
Rust
//! EVM config for vanilla optimism.
|
|
|
|
#![doc(
|
|
html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png",
|
|
html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256",
|
|
issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/"
|
|
)]
|
|
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
|
|
// The `optimism` feature must be enabled to use this crate.
|
|
#![cfg(feature = "optimism")]
|
|
|
|
use reth_chainspec::ChainSpec;
|
|
use reth_evm::{ConfigureEvm, ConfigureEvmEnv};
|
|
use reth_primitives::{
|
|
revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv},
|
|
transaction::FillTxEnv,
|
|
Address, Head, Header, TransactionSigned, U256,
|
|
};
|
|
use reth_revm::{inspector_handle_register, Database, Evm, EvmBuilder, GetInspector};
|
|
|
|
mod config;
|
|
pub use config::{revm_spec, revm_spec_by_timestamp_after_bedrock};
|
|
mod execute;
|
|
pub use execute::*;
|
|
pub mod l1;
|
|
pub use l1::*;
|
|
|
|
mod error;
|
|
pub use error::OptimismBlockExecutionError;
|
|
use revm_primitives::{Bytes, Env, OptimismFields, TxKind};
|
|
|
|
/// Optimism-related EVM configuration.
|
|
#[derive(Debug, Default, Clone, Copy)]
|
|
#[non_exhaustive]
|
|
pub struct OptimismEvmConfig;
|
|
|
|
impl ConfigureEvmEnv for OptimismEvmConfig {
|
|
fn fill_tx_env(&self, tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) {
|
|
transaction.fill_tx_env(tx_env, sender);
|
|
}
|
|
|
|
fn fill_tx_env_system_contract_call(
|
|
env: &mut Env,
|
|
caller: Address,
|
|
contract: Address,
|
|
data: Bytes,
|
|
) {
|
|
env.tx = TxEnv {
|
|
caller,
|
|
transact_to: TxKind::Call(contract),
|
|
// Explicitly set nonce to None so revm does not do any nonce checks
|
|
nonce: None,
|
|
gas_limit: 30_000_000,
|
|
value: U256::ZERO,
|
|
data,
|
|
// Setting the gas price to zero enforces that no value is transferred as part of the
|
|
// call, and that the call will not count against the block's gas limit
|
|
gas_price: U256::ZERO,
|
|
// The chain ID check is not relevant here and is disabled if set to None
|
|
chain_id: None,
|
|
// Setting the gas priority fee to None ensures the effective gas price is derived from
|
|
// the `gas_price` field, which we need to be zero
|
|
gas_priority_fee: None,
|
|
access_list: Vec::new(),
|
|
// blob fields can be None for this tx
|
|
blob_hashes: Vec::new(),
|
|
max_fee_per_blob_gas: None,
|
|
optimism: OptimismFields {
|
|
source_hash: None,
|
|
mint: None,
|
|
is_system_transaction: Some(false),
|
|
// The L1 fee is not charged for the EIP-4788 transaction, submit zero bytes for the
|
|
// enveloped tx size.
|
|
enveloped_tx: Some(Bytes::default()),
|
|
},
|
|
};
|
|
|
|
// ensure the block gas limit is >= the tx
|
|
env.block.gas_limit = U256::from(env.tx.gas_limit);
|
|
|
|
// disable the base fee check for this call by setting the base fee to zero
|
|
env.block.basefee = U256::ZERO;
|
|
}
|
|
|
|
fn fill_cfg_env(
|
|
cfg_env: &mut CfgEnvWithHandlerCfg,
|
|
chain_spec: &ChainSpec,
|
|
header: &Header,
|
|
total_difficulty: U256,
|
|
) {
|
|
let spec_id = revm_spec(
|
|
chain_spec,
|
|
&Head {
|
|
number: header.number,
|
|
timestamp: header.timestamp,
|
|
difficulty: header.difficulty,
|
|
total_difficulty,
|
|
hash: Default::default(),
|
|
},
|
|
);
|
|
|
|
cfg_env.chain_id = chain_spec.chain().id();
|
|
cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse;
|
|
|
|
cfg_env.handler_cfg.spec_id = spec_id;
|
|
cfg_env.handler_cfg.is_optimism = chain_spec.is_optimism();
|
|
}
|
|
}
|
|
|
|
impl ConfigureEvm for OptimismEvmConfig {
|
|
type DefaultExternalContext<'a> = ();
|
|
|
|
fn evm<'a, DB: Database + 'a>(&self, db: DB) -> Evm<'a, Self::DefaultExternalContext<'a>, DB> {
|
|
EvmBuilder::default().with_db(db).optimism().build()
|
|
}
|
|
|
|
fn evm_with_inspector<'a, DB, I>(&self, db: DB, inspector: I) -> Evm<'a, I, DB>
|
|
where
|
|
DB: Database + 'a,
|
|
I: GetInspector<DB>,
|
|
{
|
|
EvmBuilder::default()
|
|
.with_db(db)
|
|
.with_external_context(inspector)
|
|
.optimism()
|
|
.append_handler_register(inspector_handle_register)
|
|
.build()
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use reth_primitives::revm_primitives::{BlockEnv, CfgEnv};
|
|
use revm_primitives::SpecId;
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn test_fill_cfg_and_block_env() {
|
|
let mut cfg_env = CfgEnvWithHandlerCfg::new_with_spec_id(CfgEnv::default(), SpecId::LATEST);
|
|
let mut block_env = BlockEnv::default();
|
|
let header = Header::default();
|
|
let chain_spec = ChainSpec::default();
|
|
let total_difficulty = U256::ZERO;
|
|
|
|
OptimismEvmConfig::fill_cfg_and_block_env(
|
|
&mut cfg_env,
|
|
&mut block_env,
|
|
&chain_spec,
|
|
&header,
|
|
total_difficulty,
|
|
);
|
|
|
|
assert_eq!(cfg_env.chain_id, chain_spec.chain().id());
|
|
}
|
|
}
|