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 17, 2024
1 parent 3d7a2a8 commit 31771cc
Show file tree
Hide file tree
Showing 20 changed files with 195 additions and 127 deletions.
11 changes: 4 additions & 7 deletions crates/interpreter/src/host/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,8 @@ use std::vec::Vec;
use super::{AccountLoad, Eip7702CodeLoad, StateLoad};

/// A dummy [Host] implementation.
#[derive_where(Clone, Debug, Default; <EvmWiringT as ChainSpec>::Block, <EvmWiringT as ChainSpec>::Transaction)]
pub struct DummyHost<EvmWiringT>
where
EvmWiringT: EvmWiring,
{
#[derive_where(Clone, Debug, Default; <EvmWiringT::ChainSpec as ChainSpec>::Block, <EvmWiringT::ChainSpec as ChainSpec>::Transaction)]
pub struct DummyHost<EvmWiringT: EvmWiring> {
pub env: EnvWiring<EvmWiringT>,
pub storage: HashMap<U256, U256>,
pub transient_storage: HashMap<U256, U256>,
Expand Down Expand Up @@ -53,12 +50,12 @@ where
type EvmWiringT = EvmWiringT;

#[inline]
fn env(&self) -> &EnvWiring<Self::EvmWiringT> {
fn env(&self) -> &EnvWiring<EvmWiringT> {
&self.env
}

#[inline]
fn env_mut(&mut self) -> &mut EnvWiring<Self::EvmWiringT> {
fn env_mut(&mut self) -> &mut EnvWiring<EvmWiringT> {
&mut self.env
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use revm_primitives::EvmWiring;
use revm_primitives::{ChainSpec, EvmWiring};

use crate::primitives::{Address, Bytes, Eof, Transaction, U256};

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
7 changes: 5 additions & 2 deletions crates/optimism/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ impl<ChainSpecT> OptimismChainSpec for ChainSpecT where
}

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

impl<EvmWiringT> OptimismWiring for EvmWiringT where EvmWiringT: OptimismChainSpec + revm::EvmWiring {}
impl<EvmWiringT> OptimismWiring for EvmWiringT where
EvmWiringT: revm::EvmWiring<ChainSpec: OptimismChainSpec>
{
}
2 changes: 1 addition & 1 deletion crates/optimism/src/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl<DB: Database, EXT> EvmWiring for OptimismEvmWiring<DB, EXT> {
}

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
10 changes: 6 additions & 4 deletions crates/primitives/src/env.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
calc_blob_gasprice, AccessListItem, Account, Address, AuthorizationList, Block, Bytes,
ChainSpec, InvalidHeader, InvalidTransaction, Spec, SpecId, Transaction, TransactionValidation,
B256, MAX_BLOB_NUMBER_PER_BLOCK, MAX_CODE_SIZE, MAX_INITCODE_SIZE, U256,
ChainSpec, EvmWiring, InvalidHeader, InvalidTransaction, Spec, SpecId, Transaction,
TransactionValidation, B256, MAX_BLOB_NUMBER_PER_BLOCK, MAX_CODE_SIZE, MAX_INITCODE_SIZE, U256,
VERSIONED_HASH_VERSION_KZG,
};
use alloy_primitives::TxKind;
Expand All @@ -12,8 +12,10 @@ use std::boxed::Box;
use std::vec::Vec;

/// Subtype
pub type EnvWiring<EvmWiringT> =
Env<<EvmWiringT as ChainSpec>::Block, <EvmWiringT as ChainSpec>::Transaction>;
pub type EnvWiring<EvmWiringT> = Env<
<<EvmWiringT as EvmWiring>::ChainSpec as ChainSpec>::Block,
<<EvmWiringT as EvmWiring>::ChainSpec as ChainSpec>::Transaction,
>;

#[derive(Clone, Debug, Default)]
/// EVM environment configuration.
Expand Down
23 changes: 5 additions & 18 deletions crates/primitives/src/evm_wiring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ pub trait ChainSpec: Sized {
type HaltReason: HaltReasonTrait;
}

pub trait EvmWiring: ChainSpec + Sized {
pub trait EvmWiring: Sized {
/// Chain specification type.
type ChainSpec: ChainSpec;

/// External context type
type ExternalContext: Sized;

Expand All @@ -57,29 +60,13 @@ impl ChainSpec for EthereumChainSpec {
type HaltReason = crate::HaltReason;
}

pub trait WiringExtendsChainSpec {
/// The type of `ChainSpec` that this wiring extends.
type ChainSpec: ChainSpec;
}

impl<EvmWiringT: WiringExtendsChainSpec> ChainSpec for EvmWiringT {
type ChainContext = <EvmWiringT::ChainSpec as ChainSpec>::ChainContext;
type Block = <EvmWiringT::ChainSpec as ChainSpec>::Block;
type Transaction = <EvmWiringT::ChainSpec as ChainSpec>::Transaction;
type Hardfork = <EvmWiringT::ChainSpec as ChainSpec>::Hardfork;
type HaltReason = <EvmWiringT::ChainSpec as ChainSpec>::HaltReason;
}

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

impl<DB: Database, EXT> WiringExtendsChainSpec for EthereumWiring<DB, EXT> {
type ChainSpec = EthereumChainSpec;
}

impl<DB: Database, EXT: Debug> EvmWiring for EthereumWiring<DB, EXT> {
type ChainSpec = EthereumChainSpec;
type Database = DB;
type ExternalContext = EXT;
}
Expand Down
8 changes: 5 additions & 3 deletions crates/primitives/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ use core::fmt::{self, Debug};
use std::{boxed::Box, string::String, vec::Vec};

/// Result of EVM execution.
pub type EVMResult<EvmWiringT> =
EVMResultGeneric<ResultAndState<<EvmWiringT as ChainSpec>::HaltReason>, EvmWiringT>;
pub type EVMResult<EvmWiringT> = EVMResultGeneric<
ResultAndState<<<EvmWiringT as EvmWiring>::ChainSpec as ChainSpec>::HaltReason>,
EvmWiringT,
>;

/// Generic result of EVM execution. Used to represent error and generic output.
pub type EVMResultGeneric<T, EvmWiringT> = core::result::Result<T, EVMErrorWiring<EvmWiringT>>;
Expand Down Expand Up @@ -146,7 +148,7 @@ impl Output {

pub type EVMErrorWiring<EvmWiringT> = EVMError<
<<EvmWiringT as EvmWiring>::Database as Database>::Error,
<<EvmWiringT as ChainSpec>::Transaction as TransactionValidation>::ValidationError,
<<<EvmWiringT as EvmWiring>::ChainSpec as ChainSpec>::Transaction as TransactionValidation>::ValidationError,
>;

/// Main EVM error.
Expand Down
95 changes: 64 additions & 31 deletions crates/revm/src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::{
db::EmptyDB,
handler::register,
primitives::{CfgEnv, EnvWiring, EthereumWiring, InvalidTransaction, TransactionValidation},
primitives::{
CfgEnv, ChainSpec, EnvWiring, EthereumWiring, InvalidTransaction, TransactionValidation,
},
Context, Evm, EvmContext, EvmWiring, Handler,
};
use core::marker::PhantomData;
Expand Down Expand Up @@ -36,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 @@ -71,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 @@ -99,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 @@ -120,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 @@ -371,25 +388,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 @@ -403,29 +432,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 @@ -436,8 +466,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 @@ -446,7 +479,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 31771cc

Please sign in to comment.