Skip to content

Commit

Permalink
refactor: make ChainSpec associated type on EvmWiring
Browse files Browse the repository at this point in the history
  • Loading branch information
Wodann committed Sep 19, 2024
1 parent 66adad0 commit b5b5da1
Show file tree
Hide file tree
Showing 21 changed files with 239 additions and 127 deletions.
7 changes: 4 additions & 3 deletions crates/inspector/src/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ mod tests {
bytecode::Bytecode,
interpreter::{opcode, Interpreter},
primitives::{address, Bytes, Log, TxKind},
wiring::EvmWiring as PrimitiveEvmWiring,
wiring::{DefaultEthereumWiring, EthereumWiring},
wiring::{
ChainSpec, DefaultEthereumWiring, EthereumWiring, EvmWiring as PrimitiveEvmWiring,
},
Evm, EvmWiring,
};

Expand Down Expand Up @@ -181,7 +182,7 @@ mod tests {
.with_db(BenchmarkDB::new_bytecode(bytecode.clone()))
.with_default_ext_ctx()
.modify_tx_env(|tx| {
*tx = <TestEvmWiring as PrimitiveEvmWiring>::Transaction::default();
*tx = <<TestEvmWiring as PrimitiveEvmWiring>::ChainSpec as ChainSpec>::Transaction::default();

tx.caller = address!("1000000000000000000000000000000000000000");
tx.transact_to = TxKind::Call(address!("0000000000000000000000000000000000000000"));
Expand Down
6 changes: 4 additions & 2 deletions crates/inspector/src/handler_register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,9 @@ mod tests {
database_interface::EmptyDB,
interpreter::{opcode, CallInputs, CallOutcome, CreateInputs, CreateOutcome},
primitives::{address, Bytes, TxKind},
wiring::{DefaultEthereumWiring, EthereumWiring, EvmWiring as PrimitiveEvmWiring},
wiring::{
ChainSpec, DefaultEthereumWiring, EthereumWiring, EvmWiring as PrimitiveEvmWiring,
},
Evm, EvmContext, EvmWiring,
};

Expand Down Expand Up @@ -374,7 +376,7 @@ mod tests {
.with_db(BenchmarkDB::new_bytecode(bytecode.clone()))
.with_external_context(StackInspector::default())
.modify_tx_env(|tx| {
*tx = <TestEvmWiring as PrimitiveEvmWiring>::Transaction::default();
*tx = <<TestEvmWiring as PrimitiveEvmWiring>::ChainSpec as ChainSpec>::Transaction::default();

tx.caller = address!("1000000000000000000000000000000000000000");
tx.transact_to = TxKind::Call(address!("0000000000000000000000000000000000000000"));
Expand Down
9 changes: 3 additions & 6 deletions crates/interpreter/src/host/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,17 @@ use crate::{Host, SStoreResult, SelfDestructResult};
use derive_where::derive_where;
use primitives::{hash_map::Entry, Address, Bytes, HashMap, Log, B256, KECCAK_EMPTY, U256};
use std::vec::Vec;
use wiring::{
default::{Env, EnvWiring},
EvmWiring,
};
use wiring::{default::EnvWiring, ChainSpec, EvmWiring};

use super::{AccountLoad, Eip7702CodeLoad, StateLoad};

/// A dummy [Host] implementation.
#[derive_where(Clone, Debug, Default; EvmWiringT::Block, EvmWiringT::Transaction)]
#[derive_where(Clone, Debug, Default; <EvmWiringT::ChainSpec as ChainSpec>::Block, <EvmWiringT::ChainSpec as ChainSpec>::Transaction)]
pub struct DummyHost<EvmWiringT>
where
EvmWiringT: EvmWiring,
{
pub env: Env<EvmWiringT::Block, EvmWiringT::Transaction>,
pub env: EnvWiring<EvmWiringT>,
pub storage: HashMap<U256, U256>,
pub transient_storage: HashMap<U256, U256>,
pub log: Vec<Log>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bytecode::Eof;
use primitives::{Address, Bytes, U256};
use wiring::{EvmWiring, Transaction};
use wiring::{ChainSpec, EvmWiring, Transaction};

/// EOF create can be called from two places:
/// * EOFCREATE opcode
Expand Down Expand Up @@ -75,7 +75,10 @@ impl EOFCreateInputs {
}

/// Creates new EOFCreateInputs from transaction.
pub fn new_tx<EvmWiringT: EvmWiring>(tx: &EvmWiringT::Transaction, gas_limit: u64) -> Self {
pub fn new_tx<EvmWiringT: EvmWiring>(
tx: &<EvmWiringT::ChainSpec as ChainSpec>::Transaction,
gas_limit: u64,
) -> Self {
EOFCreateInputs::new(
*tx.caller(),
*tx.value(),
Expand Down
18 changes: 13 additions & 5 deletions crates/optimism/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub use l1block::{L1BlockInfo, BASE_FEE_RECIPIENT, L1_BLOCK_CONTRACT, L1_FEE_REC
pub use result::{OptimismHaltReason, OptimismInvalidTransaction};
use revm::{
primitives::{Bytes, B256},
wiring::TransactionValidation,
wiring::{ChainSpec, TransactionValidation},
};
pub use spec::*;

Expand Down Expand Up @@ -63,8 +63,8 @@ pub trait OptimismTransaction {
}

/// Trait for an Optimism chain spec.
pub trait OptimismWiring:
revm::EvmWiring<
pub trait OptimismChainSpec:
ChainSpec<
ChainContext: OptimismContext,
Hardfork = OptimismSpecId,
HaltReason = OptimismHaltReason,
Expand All @@ -74,8 +74,8 @@ pub trait OptimismWiring:
{
}

impl<EvmWiringT> OptimismWiring for EvmWiringT where
EvmWiringT: revm::EvmWiring<
impl<ChainSpecT> OptimismChainSpec for ChainSpecT where
ChainSpecT: ChainSpec<
ChainContext: OptimismContext,
Hardfork = OptimismSpecId,
HaltReason = OptimismHaltReason,
Expand All @@ -84,3 +84,11 @@ impl<EvmWiringT> OptimismWiring for EvmWiringT where
>
{
}

/// Trait for Optimism `EvmWiring`.
pub trait OptimismWiring: revm::EvmWiring<ChainSpec: OptimismChainSpec> {}

impl<EvmWiringT> OptimismWiring for EvmWiringT where
EvmWiringT: revm::EvmWiring<ChainSpec: OptimismChainSpec>
{
}
23 changes: 15 additions & 8 deletions crates/optimism/src/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,34 @@ use revm::{
precompile::PrecompileSpecId,
specification::hardfork::{Spec, SpecId},
wiring::default::block::BlockEnv,
wiring::EvmWiring,
wiring::{ChainSpec, EvmWiring},
EvmHandler,
};

#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct OptimismChainSpec;

impl ChainSpec for OptimismChainSpec {
type Block = BlockEnv;
type ChainContext = Context;
type Transaction = TxEnv;
type Hardfork = OptimismSpecId;
type HaltReason = OptimismHaltReason;
}

#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct OptimismEvmWiring<DB: Database, EXT> {
_phantom: PhantomData<(DB, EXT)>,
phantom: PhantomData<(DB, EXT)>,
}

impl<DB: Database, EXT> EvmWiring for OptimismEvmWiring<DB, EXT> {
type Block = BlockEnv;
type ChainSpec = OptimismChainSpec;
type Database = DB;
type ChainContext = Context;
type ExternalContext = EXT;
type Hardfork = OptimismSpecId;
type HaltReason = OptimismHaltReason;
type Transaction = TxEnv;
}

impl<DB: Database, EXT> revm::EvmWiring for OptimismEvmWiring<DB, EXT> {
fn handler<'evm>(hardfork: Self::Hardfork) -> EvmHandler<'evm, Self>
fn handler<'evm>(hardfork: <Self::ChainSpec as ChainSpec>::Hardfork) -> EvmHandler<'evm, Self>
where
DB: Database,
{
Expand Down
93 changes: 62 additions & 31 deletions crates/revm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use wiring::{
default::{CfgEnv, EnvWiring},
result::InvalidTransaction,
transaction::TransactionValidation,
EthereumWiring,
ChainSpec, EthereumWiring,
};

/// Evm Builder allows building or modifying EVM.
Expand Down Expand Up @@ -38,16 +38,18 @@ impl<'a> Default for EvmBuilder<'a, SetGenericStage, EthereumWiring<EmptyDB, ()>

impl<'a, EvmWiringT: EvmWiring> EvmBuilder<'a, SetGenericStage, EvmWiringT>
where
EvmWiringT::Transaction: Default,
EvmWiringT::Block: Default,
<EvmWiringT::ChainSpec as ChainSpec>::Transaction: Default,
<EvmWiringT::ChainSpec as ChainSpec>::Block: Default,
{
/// Sets the [`EvmWiring`] that will be used by [`Evm`].
pub fn new() -> EvmBuilder<'a, SetGenericStage, EvmWiringT> {
EvmBuilder {
database: None,
external_context: None,
env: Some(Box::new(EnvWiring::<EvmWiringT>::default())),
handler: EvmWiringT::handler::<'a>(EvmWiringT::Hardfork::default()),
handler: EvmWiringT::handler::<'a>(
<EvmWiringT::ChainSpec as ChainSpec>::Hardfork::default(),
),
phantom: PhantomData,
}
}
Expand All @@ -73,25 +75,29 @@ impl<'a, EvmWiringT: EvmWiring> EvmBuilder<'a, SetGenericStage, EvmWiringT> {
self,
) -> EvmBuilder<'a, SetGenericStage, NewEvmWiringT>
where
NewEvmWiringT::Transaction: Default,
NewEvmWiringT::Block: Default,
<NewEvmWiringT::ChainSpec as ChainSpec>::Transaction: Default,
<NewEvmWiringT::ChainSpec as ChainSpec>::Block: Default,
{
EvmBuilder {
database: None,
external_context: None,
env: Some(Box::new(EnvWiring::<NewEvmWiringT>::default())),
handler: NewEvmWiringT::handler::<'a>(NewEvmWiringT::Hardfork::default()),
handler: NewEvmWiringT::handler::<'a>(
<NewEvmWiringT::ChainSpec as ChainSpec>::Hardfork::default(),
),
phantom: PhantomData,
}
}

pub fn reset_handler_with_external_context<
NewEvmWiringT: EvmWiring<
Database = EvmWiringT::Database,
Block = EvmWiringT::Block,
Transaction = EvmWiringT::Transaction,
Hardfork = EvmWiringT::Hardfork,
HaltReason = EvmWiringT::HaltReason,
ChainSpec: ChainSpec<
Block = <EvmWiringT::ChainSpec as ChainSpec>::Block,
Transaction = <EvmWiringT::ChainSpec as ChainSpec>::Transaction,
Hardfork = <EvmWiringT::ChainSpec as ChainSpec>::Hardfork,
HaltReason = <EvmWiringT::ChainSpec as ChainSpec>::HaltReason,
>,
>,
>(
self,
Expand All @@ -101,18 +107,22 @@ impl<'a, EvmWiringT: EvmWiring> EvmBuilder<'a, SetGenericStage, EvmWiringT> {
external_context: None,
env: self.env,
// Handler that will be used by EVM. It contains handle registers
handler: NewEvmWiringT::handler::<'a>(NewEvmWiringT::Hardfork::default()),
handler: NewEvmWiringT::handler::<'a>(
<NewEvmWiringT::ChainSpec as ChainSpec>::Hardfork::default(),
),
phantom: PhantomData,
}
}

pub fn reset_new_database<
NewEvmWiringT: EvmWiring<
ExternalContext = EvmWiringT::ExternalContext,
Block = EvmWiringT::Block,
Transaction = EvmWiringT::Transaction,
Hardfork = EvmWiringT::Hardfork,
HaltReason = EvmWiringT::HaltReason,
ChainSpec: ChainSpec<
Block = <EvmWiringT::ChainSpec as ChainSpec>::Block,
Transaction = <EvmWiringT::ChainSpec as ChainSpec>::Transaction,
Hardfork = <EvmWiringT::ChainSpec as ChainSpec>::Hardfork,
HaltReason = <EvmWiringT::ChainSpec as ChainSpec>::HaltReason,
>,
>,
>(
self,
Expand All @@ -122,16 +132,21 @@ impl<'a, EvmWiringT: EvmWiring> EvmBuilder<'a, SetGenericStage, EvmWiringT> {
external_context: self.external_context,
env: self.env,
// Handler that will be used by EVM. It contains handle registers
handler: NewEvmWiringT::handler::<'a>(NewEvmWiringT::Hardfork::default()),
handler: NewEvmWiringT::handler::<'a>(
<NewEvmWiringT::ChainSpec as ChainSpec>::Hardfork::default(),
),
phantom: PhantomData,
}
}
}

impl<'a, EvmWiringT> EvmBuilder<'a, SetGenericStage, EvmWiringT>
where
EvmWiringT:
EvmWiring<Transaction: TransactionValidation<ValidationError: From<InvalidTransaction>>>,
EvmWiringT: EvmWiring<
ChainSpec: ChainSpec<
Transaction: TransactionValidation<ValidationError: From<InvalidTransaction>>,
>,
>,
{
/// Creates the default [EvmWiring]::[crate::Database] that will be used by [`Evm`].
pub fn with_default_db(mut self) -> EvmBuilder<'a, SetGenericStage, EvmWiringT>
Expand Down Expand Up @@ -376,25 +391,37 @@ impl<'a, BuilderStage, EvmWiringT: EvmWiring> EvmBuilder<'a, BuilderStage, EvmWi
}

/// Allows modification of Evm's Transaction Environment.
pub fn modify_tx_env(mut self, f: impl FnOnce(&mut EvmWiringT::Transaction)) -> Self {
pub fn modify_tx_env(
mut self,
f: impl FnOnce(&mut <EvmWiringT::ChainSpec as ChainSpec>::Transaction),
) -> Self {
f(&mut self.env.as_mut().unwrap().tx);
self
}

/// Sets Evm's Transaction Environment.
pub fn with_tx_env(mut self, tx_env: EvmWiringT::Transaction) -> Self {
pub fn with_tx_env(
mut self,
tx_env: <EvmWiringT::ChainSpec as ChainSpec>::Transaction,
) -> Self {
self.env.as_mut().unwrap().tx = tx_env;
self
}

/// Allows modification of Evm's Block Environment.
pub fn modify_block_env(mut self, f: impl FnOnce(&mut EvmWiringT::Block)) -> Self {
pub fn modify_block_env(
mut self,
f: impl FnOnce(&mut <EvmWiringT::ChainSpec as ChainSpec>::Block),
) -> Self {
f(&mut self.env.as_mut().unwrap().block);
self
}

/// Sets Evm's Block Environment.
pub fn with_block_env(mut self, block_env: EvmWiringT::Block) -> Self {
pub fn with_block_env(
mut self,
block_env: <EvmWiringT::ChainSpec as ChainSpec>::Block,
) -> Self {
self.env.as_mut().unwrap().block = block_env;
self
}
Expand All @@ -408,29 +435,30 @@ impl<'a, BuilderStage, EvmWiringT: EvmWiring> EvmBuilder<'a, BuilderStage, EvmWi

impl<'a, BuilderStage, EvmWiringT> EvmBuilder<'a, BuilderStage, EvmWiringT>
where
EvmWiringT: EvmWiring<Block: Default>,
EvmWiringT: EvmWiring<ChainSpec: ChainSpec<Block: Default>>,
{
/// Clears Block environment of EVM.
pub fn with_clear_block_env(mut self) -> Self {
self.env.as_mut().unwrap().block = EvmWiringT::Block::default();
self.env.as_mut().unwrap().block = <EvmWiringT::ChainSpec as ChainSpec>::Block::default();
self
}
}

impl<'a, BuilderStage, EvmWiringT> EvmBuilder<'a, BuilderStage, EvmWiringT>
where
EvmWiringT: EvmWiring<Transaction: Default>,
EvmWiringT: EvmWiring<ChainSpec: ChainSpec<Transaction: Default>>,
{
/// Clears Transaction environment of EVM.
pub fn with_clear_tx_env(mut self) -> Self {
self.env.as_mut().unwrap().tx = EvmWiringT::Transaction::default();
self.env.as_mut().unwrap().tx =
<EvmWiringT::ChainSpec as ChainSpec>::Transaction::default();
self
}
}

impl<'a, BuilderStage, EvmWiringT> EvmBuilder<'a, BuilderStage, EvmWiringT>
where
EvmWiringT: EvmWiring<Block: Default, Transaction: Default>,
EvmWiringT: EvmWiring<ChainSpec: ChainSpec<Block: Default, Transaction: Default>>,
{
/// Clears Environment of EVM.
pub fn with_clear_env(mut self) -> Self {
Expand All @@ -441,8 +469,11 @@ where

impl<'a, BuilderStage, EvmWiringT: EvmWiring> EvmBuilder<'a, BuilderStage, EvmWiringT>
where
EvmWiringT:
EvmWiring<Transaction: TransactionValidation<ValidationError: From<InvalidTransaction>>>,
EvmWiringT: EvmWiring<
ChainSpec: ChainSpec<
Transaction: TransactionValidation<ValidationError: From<InvalidTransaction>>,
>,
>,
{
/// Sets specification Id , that will mark the version of EVM.
/// It represent the hard fork of ethereum.
Expand All @@ -451,7 +482,7 @@ where
///
/// When changed it will reapply all handle registers, this can be
/// expensive operation depending on registers.
pub fn with_spec_id(mut self, spec_id: EvmWiringT::Hardfork) -> Self {
pub fn with_spec_id(mut self, spec_id: <EvmWiringT::ChainSpec as ChainSpec>::Hardfork) -> Self {
self.handler.modify_spec_id(spec_id);
self
}
Expand Down
Loading

0 comments on commit b5b5da1

Please sign in to comment.