Skip to content

Commit

Permalink
refactor: add handler constructor and Context to revm::ChainSpec
Browse files Browse the repository at this point in the history
  • Loading branch information
Wodann committed Jul 22, 2024
1 parent 3c6c4d3 commit 4856bea
Show file tree
Hide file tree
Showing 28 changed files with 236 additions and 385 deletions.
98 changes: 22 additions & 76 deletions crates/revm/src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
use crate::{
db::{Database, DatabaseRef, EmptyDB, WrapDatabaseRef},
handler::{
register::{self, EvmHandler},
CfgEnvWithChainSpec, EnvWithChainSpec,
},
primitives::{CfgEnv, ChainSpec, Env, EthChainSpec, InvalidTransaction, TransactionValidation},
Context, ContextWithChainSpec, Evm, EvmContext, Handler,
handler::{register, CfgEnvWithChainSpec, EnvWithChainSpec},
primitives::{self, CfgEnv, Env, EthChainSpec, InvalidTransaction, TransactionValidation},
ChainSpec, Context, ContextWithChainSpec, Evm, EvmContext, Handler,
};
use core::marker::PhantomData;
use std::boxed::Box;
Expand Down Expand Up @@ -33,8 +30,8 @@ impl<'a> Default for EvmBuilder<'a, SetGenericStage, EthChainSpec, (), EmptyDB>
fn default() -> Self {
Self {
context: Context::default(),
handler: EvmBuilder::<'_, SetGenericStage, _, _, _>::handler(
<EthChainSpec as ChainSpec>::Hardfork::default(),
handler: EthChainSpec::handler::<'a, (), EmptyDB>(
<EthChainSpec as primitives::ChainSpec>::Hardfork::default(),
),
phantom: PhantomData,
}
Expand All @@ -59,9 +56,7 @@ where

EvmBuilder {
context: Context::new(EvmContext::new(evm.inner.db), external),
handler: EvmBuilder::<'_, SetGenericStage, NewChainSpecT, _, _>::handler(
NewChainSpecT::Hardfork::default(),
),
handler: NewChainSpecT::handler::<'a, EXT, DB>(NewChainSpecT::Hardfork::default()),
phantom: PhantomData,
}
}
Expand All @@ -79,7 +74,7 @@ where
self.context.evm.with_db(EmptyDB::default()),
self.context.external,
),
handler: EvmBuilder::<'_, SetGenericStage, _, _, _>::handler(self.handler.spec_id()),
handler: ChainSpecT::handler::<'a, EXT, EmptyDB>(self.handler.spec_id()),
phantom: PhantomData,
}
}
Expand All @@ -90,7 +85,7 @@ where
) -> EvmBuilder<'a, SetGenericStage, ChainSpecT, EXT, ODB> {
EvmBuilder {
context: Context::new(self.context.evm.with_db(db), self.context.external),
handler: EvmBuilder::<'_, SetGenericStage, _, _, _>::handler(self.handler.spec_id()),
handler: ChainSpecT::handler::<'a, EXT, ODB>(self.handler.spec_id()),
phantom: PhantomData,
}
}
Expand All @@ -104,7 +99,7 @@ where
self.context.evm.with_db(WrapDatabaseRef(db)),
self.context.external,
),
handler: EvmBuilder::<'_, SetGenericStage, _, _, _>::handler(self.handler.spec_id()),
handler: ChainSpecT::handler::<'a, EXT, WrapDatabaseRef<ODB>>(self.handler.spec_id()),
phantom: PhantomData,
}
}
Expand All @@ -116,7 +111,7 @@ where
) -> EvmBuilder<'a, SetGenericStage, ChainSpecT, OEXT, DB> {
EvmBuilder {
context: Context::new(self.context.evm, external),
handler: EvmBuilder::<'_, SetGenericStage, _, _, _>::handler(self.handler.spec_id()),
handler: ChainSpecT::handler::<'a, OEXT, DB>(self.handler.spec_id()),
phantom: PhantomData,
}
}
Expand All @@ -130,7 +125,7 @@ where
self.context.evm.env = env;
EvmBuilder {
context: self.context,
handler: EvmBuilder::<'_, HandlerStage, _, _, _>::handler(spec_id),
handler: ChainSpecT::handler::<'a, EXT, DB>(spec_id),
phantom: PhantomData,
}
}
Expand All @@ -142,9 +137,7 @@ where
) -> EvmBuilder<'a, HandlerStage, ChainSpecT, OEXT, ODB> {
EvmBuilder {
context: context_with_handler_cfg.context,
handler: EvmBuilder::<'_, HandlerStage, _, _, _>::handler(
context_with_handler_cfg.spec_id,
),
handler: ChainSpecT::handler::<'a, OEXT, ODB>(context_with_handler_cfg.spec_id),
phantom: PhantomData,
}
}
Expand All @@ -158,7 +151,7 @@ where

EvmBuilder {
context: self.context,
handler: EvmBuilder::<'_, HandlerStage, _, _, _>::handler(cfg_env_and_spec_id.spec_id),
handler: ChainSpecT::handler::<'a, EXT, DB>(cfg_env_and_spec_id.spec_id),
phantom: PhantomData,
}
}
Expand Down Expand Up @@ -194,7 +187,7 @@ where
self.context.evm.with_db(EmptyDB::default()),
self.context.external,
),
handler: EvmBuilder::<'_, HandlerStage, _, _, _>::handler(self.handler.spec_id()),
handler: ChainSpecT::handler::<'a, EXT, EmptyDB>(self.handler.spec_id()),
phantom: PhantomData,
}
}
Expand All @@ -207,7 +200,7 @@ where
) -> EvmBuilder<'a, SetGenericStage, ChainSpecT, EXT, ODB> {
EvmBuilder {
context: Context::new(self.context.evm.with_db(db), self.context.external),
handler: EvmBuilder::<'_, SetGenericStage, _, _, _>::handler(self.handler.spec_id()),
handler: ChainSpecT::handler::<'a, EXT, ODB>(self.handler.spec_id()),
phantom: PhantomData,
}
}
Expand All @@ -223,7 +216,7 @@ where
self.context.evm.with_db(WrapDatabaseRef(db)),
self.context.external,
),
handler: EvmBuilder::<'_, SetGenericStage, _, _, _>::handler(self.handler.spec_id()),
handler: ChainSpecT::handler::<'a, EXT, WrapDatabaseRef<ODB>>(self.handler.spec_id()),
phantom: PhantomData,
}
}
Expand All @@ -236,7 +229,7 @@ where
) -> EvmBuilder<'a, SetGenericStage, ChainSpecT, OEXT, DB> {
EvmBuilder {
context: Context::new(self.context.evm, external),
handler: EvmBuilder::<'_, SetGenericStage, _, _, _>::handler(self.handler.spec_id()),
handler: ChainSpecT::handler::<'a, OEXT, DB>(self.handler.spec_id()),
phantom: PhantomData,
}
}
Expand Down Expand Up @@ -410,13 +403,6 @@ where
ChainSpecT:
ChainSpec<Transaction: TransactionValidation<ValidationError: From<InvalidTransaction>>>,
{
/// Creates the default handler.
///
/// This is useful for adding optimism handle register.
fn handler(spec_id: ChainSpecT::Hardfork) -> EvmHandler<'a, ChainSpecT, EXT, DB> {
Handler::mainnet_with_spec(spec_id)
}

/// Sets specification Id , that will mark the version of EVM.
/// It represent the hard fork of ethereum.
///
Expand All @@ -436,7 +422,7 @@ where

/// Resets [`Handler`] to default mainnet.
pub fn reset_handler(mut self) -> Self {
self.handler = Self::handler(self.handler.spec_id());
self.handler = ChainSpecT::handler::<'a, EXT, DB>(self.handler.spec_id());
self
}
}
Expand All @@ -456,9 +442,6 @@ mod test {
use revm_precompile::PrecompileOutput;
use std::{cell::RefCell, rc::Rc, sync::Arc};

#[cfg(feature = "optimism")]
type TestChainSpec = crate::optimism::OptimismChainSpec;
#[cfg(not(feature = "optimism"))]
type TestChainSpec = crate::primitives::EthChainSpec;

/// Custom evm context
Expand All @@ -485,9 +468,6 @@ mod test {
db.insert_account_info(to_addr, AccountInfo::new(U256::ZERO, 0, code_hash, code))
})
.modify_tx_env(|tx| {
#[cfg(feature = "optimism")]
let transact_to = &mut tx.base.transact_to;
#[cfg(not(feature = "optimism"))]
let transact_to = &mut tx.transact_to;

*transact_to = TxKind::Call(to_addr)
Expand Down Expand Up @@ -543,9 +523,6 @@ mod test {
db.insert_account_info(to_addr, AccountInfo::new(U256::ZERO, 0, code_hash, code))
})
.modify_tx_env(|tx| {
#[cfg(feature = "optimism")]
let transact_to = &mut tx.base.transact_to;
#[cfg(not(feature = "optimism"))]
let transact_to = &mut tx.transact_to;

*transact_to = TxKind::Call(to_addr)
Expand Down Expand Up @@ -594,49 +571,21 @@ mod test {
Evm::builder()
.with_chain_spec::<TestChainSpec>()
.with_empty_db()
.modify_tx_env(|tx| {
#[cfg(feature = "optimism")]
let gas_limit = &mut tx.base.gas_limit;
#[cfg(not(feature = "optimism"))]
let gas_limit = &mut tx.gas_limit;

*gas_limit = 10
})
.modify_tx_env(|tx| tx.gas_limit = 10)
.build();
Evm::builder()
.with_chain_spec::<TestChainSpec>()
.modify_tx_env(|tx| {
#[cfg(feature = "optimism")]
let gas_limit = &mut tx.base.gas_limit;
#[cfg(not(feature = "optimism"))]
let gas_limit = &mut tx.gas_limit;

*gas_limit = 10
})
.modify_tx_env(|tx| tx.gas_limit = 10)
.build();
Evm::builder()
.with_chain_spec::<TestChainSpec>()
.with_empty_db()
.modify_tx_env(|tx| {
#[cfg(feature = "optimism")]
let gas_limit = &mut tx.base.gas_limit;
#[cfg(not(feature = "optimism"))]
let gas_limit = &mut tx.gas_limit;

*gas_limit = 10
})
.modify_tx_env(|tx| tx.gas_limit = 10)
.build();
Evm::builder()
.with_chain_spec::<TestChainSpec>()
.with_empty_db()
.modify_tx_env(|tx| {
#[cfg(feature = "optimism")]
let gas_limit = &mut tx.base.gas_limit;
#[cfg(not(feature = "optimism"))]
let gas_limit = &mut tx.gas_limit;

*gas_limit = 10
})
.modify_tx_env(|tx| tx.gas_limit = 10)
.build();

// with inspector handle
Expand Down Expand Up @@ -691,9 +640,6 @@ mod test {
}
}

#[cfg(feature = "optimism")]
let spec_id = crate::optimism::OptimismSpecId::HOMESTEAD;
#[cfg(not(feature = "optimism"))]
let spec_id = crate::primitives::SpecId::HOMESTEAD;

let mut evm = Evm::builder()
Expand Down
38 changes: 38 additions & 0 deletions crates/revm/src/chain_spec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use crate::{
handler::{ExecutionHandler, PostExecutionHandler, PreExecutionHandler, ValidationHandler},
interpreter::opcode::InstructionTables,
primitives::{db::Database, spec_to_generic, EthChainSpec},
EvmHandler,
};

pub trait ChainSpec: crate::primitives::ChainSpec {
/// The type that contains all context information for the chain's EVM execution.
type Context: Default;

/// Creates a new handler with the given hardfork.
fn handler<'evm, EXT, DB>(hardfork: Self::Hardfork) -> EvmHandler<'evm, Self, EXT, DB>
where
DB: Database;
}

impl ChainSpec for EthChainSpec {
type Context = ();

fn handler<'evm, EXT, DB>(hardfork: Self::Hardfork) -> EvmHandler<'evm, Self, EXT, DB>
where
DB: Database,
{
spec_to_generic!(
hardfork,
EvmHandler {
spec_id: hardfork,
instruction_table: InstructionTables::new_plain::<SPEC>(),
registers: Vec::new(),
validation: ValidationHandler::new::<SPEC>(),
pre_execution: PreExecutionHandler::new::<SPEC>(),
post_execution: PostExecutionHandler::mainnet::<SPEC>(),
execution: ExecutionHandler::new::<SPEC>(),
}
)
}
}
36 changes: 5 additions & 31 deletions crates/revm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub use context_precompiles::{
ContextPrecompile, ContextPrecompiles, ContextStatefulPrecompile, ContextStatefulPrecompileArc,
ContextStatefulPrecompileBox, ContextStatefulPrecompileMut,
};
use derive_where::derive_where;
pub use evm_context::EvmContext;
pub use inner_evm_context::InnerEvmContext;
use revm_interpreter::as_usize_saturated;
Expand All @@ -14,35 +15,21 @@ use crate::{
db::{Database, EmptyDB},
interpreter::{Host, LoadAccountResult, SStoreResult, SelfDestructResult},
primitives::{
Address, Block as _, Bytes, ChainSpec, Env, EthChainSpec, Log, B256, BLOCK_HASH_HISTORY,
U256,
Address, Block as _, Bytes, Env, EthChainSpec, Log, B256, BLOCK_HASH_HISTORY, U256,
},
ChainSpec,
};
use std::boxed::Box;

/// Main Context structure that contains both EvmContext and External context.
#[derive_where(Clone; ChainSpecT::Block, ChainSpecT::Context, ChainSpecT::Transaction, DB, DB::Error, EXT)]
pub struct Context<ChainSpecT: ChainSpec, EXT, DB: Database> {
/// Evm Context (internal context).
pub evm: EvmContext<ChainSpecT, DB>,
/// External contexts.
pub external: EXT,
}

impl<ChainSpecT, EXT, DB> Clone for Context<ChainSpecT, EXT, DB>
where
DB::Error: Clone,
ChainSpecT: ChainSpec<Block: Clone, Transaction: Clone>,
EXT: Clone,
DB: Database<Error: Clone> + Clone,
{
fn clone(&self) -> Self {
Self {
evm: self.evm.clone(),
external: self.external.clone(),
}
}
}

impl Default for Context<EthChainSpec, (), EmptyDB> {
fn default() -> Self {
Self::new_empty()
Expand Down Expand Up @@ -84,6 +71,7 @@ impl<ChainSpecT: ChainSpec, EXT, DB: Database> Context<ChainSpecT, EXT, DB> {
}

/// Context with handler configuration.
#[derive_where(Clone; ChainSpecT::Block, ChainSpecT::Context, ChainSpecT::Transaction, DB, DB::Error, EXT)]
pub struct ContextWithChainSpec<ChainSpecT: ChainSpec, EXT, DB: Database> {
/// Context of execution.
pub context: Context<ChainSpecT, EXT, DB>,
Expand All @@ -98,20 +86,6 @@ impl<ChainSpecT: ChainSpec, EXT, DB: Database> ContextWithChainSpec<ChainSpecT,
}
}

impl<ChainSpecT, EXT, DB> Clone for ContextWithChainSpec<ChainSpecT, EXT, DB>
where
ChainSpecT: ChainSpec<Block: Clone, Transaction: Clone>,
EXT: Clone,
DB: Database<Error: Clone> + Clone,
{
fn clone(&self) -> Self {
Self {
context: self.context.clone(),
spec_id: self.spec_id,
}
}
}

impl<ChainSpecT: ChainSpec, EXT, DB: Database> Host for Context<ChainSpecT, EXT, DB> {
type ChainSpecT = ChainSpecT;

Expand Down
Loading

0 comments on commit 4856bea

Please sign in to comment.