diff --git a/examples/basic_transact.rs b/examples/basic_transact.rs index 1ca0245..c0a1817 100644 --- a/examples/basic_transact.rs +++ b/examples/basic_transact.rs @@ -39,7 +39,7 @@ impl Tx for SampleTx { // Produce aliases for the Trevm type trevm_aliases!(TracerEip3155, InMemoryDB); -fn main() -> Result<(), Box> { +fn main() { let mut db = revm::database::InMemoryDB::default(); let bytecode = Bytecode::new_raw(hex::decode(CONTRACT_BYTECODE).unwrap().into()); @@ -54,7 +54,7 @@ fn main() -> Result<(), Box> { let trevm = TrevmBuilder::new() .with_db(db) .with_insp(insp) - .build_trevm()? + .build_trevm() .fill_cfg(&NoopCfg) .fill_block(&NoopBlock); @@ -72,6 +72,4 @@ fn main() -> Result<(), Box> { println!("Execution error: {e:?}"); } }; - - Ok(()) } diff --git a/examples/fork_ref_transact.rs b/examples/fork_ref_transact.rs index b0cfcfb..c2cd2fd 100644 --- a/examples/fork_ref_transact.rs +++ b/examples/fork_ref_transact.rs @@ -60,7 +60,7 @@ async fn main() -> eyre::Result<()> { // initialise an empty (default) EVM let evm = TrevmBuilder::new() .with_db(cache_db) - .build_trevm()? + .build_trevm() .fill_cfg(&NoopCfg) .fill_block(&NoopBlock) .fill_tx(&GetReservesFiller) diff --git a/src/evm/builder.rs b/src/evm/builder.rs index f16c2a4..513a96a 100644 --- a/src/evm/builder.rs +++ b/src/evm/builder.rs @@ -1,7 +1,7 @@ use crate::{evm::Trevm, helpers::Ctx, EvmNeedsCfg}; use revm::{ - database::in_memory_db::InMemoryDB, handler::EthPrecompiles, inspector::NoOpInspector, - precompile::Precompiles, primitives::hardfork::SpecId, Database, Inspector, MainBuilder, + handler::EthPrecompiles, inspector::NoOpInspector, precompile::Precompiles, + primitives::hardfork::SpecId, Database, Inspector, MainBuilder, }; /// Error that can occur when building a Trevm instance. @@ -13,48 +13,65 @@ pub enum TrevmBuilderError { DatabaseNotSet, } +#[allow(unnameable_types)] +#[derive(Debug, Copy, Clone)] +pub struct BuilderNeedsDb { + _private: (), +} + +#[allow(unnameable_types)] +#[derive(Debug, Copy, Clone)] +pub struct BuilderReady { + db: Db, +} + /// A builder for [`Trevm`] that allows configuring the EVM. #[derive(Debug, Clone)] -pub struct TrevmBuilder { - pub(crate) db: Option, +pub struct TrevmBuilder { pub(crate) insp: Insp, pub(crate) spec: SpecId, pub(crate) precompiles: Option<&'static Precompiles>, + pub(crate) state: State, } -impl TrevmBuilder { +impl TrevmBuilder { /// Create a new builder with the default database and inspector. #[allow(clippy::new_without_default)] // default would make bad devex :( pub const fn new() -> Self { - Self { db: None, insp: NoOpInspector, spec: SpecId::PRAGUE, precompiles: None } + Self { + insp: NoOpInspector, + spec: SpecId::PRAGUE, + precompiles: None, + state: BuilderNeedsDb { _private: () }, + } } } -impl TrevmBuilder { +impl TrevmBuilder { /// Set the database for the EVM. - pub fn with_db(self, db: Odb) -> TrevmBuilder + pub fn with_db(self, db: Odb) -> TrevmBuilder> where - Db: Database, + Odb: Database, { TrevmBuilder { - db: Some(db), insp: self.insp, spec: self.spec, precompiles: self.precompiles, + state: BuilderReady { db }, } } /// Set the inspector for the EVM. /// /// Equivalent to [`Self::with_inspector`]. - pub fn with_insp(self, insp: OInsp) -> TrevmBuilder { - TrevmBuilder { db: self.db, insp, spec: self.spec, precompiles: self.precompiles } + pub fn with_insp(self, insp: OInsp) -> TrevmBuilder { + TrevmBuilder { insp, spec: self.spec, precompiles: self.precompiles, state: self.state } } /// Set the inspector for the EVM. /// /// Equivalent to [`Self::with_insp`]. - pub fn with_inspector(self, insp: OInsp) -> TrevmBuilder { + pub fn with_inspector(self, insp: OInsp) -> TrevmBuilder { self.with_insp(insp) } @@ -79,14 +96,16 @@ impl TrevmBuilder { self.precompiles = Some(Precompiles::new(self.spec.into())); self } +} +impl TrevmBuilder> { /// Build the Trevm instance. - pub fn build_trevm(self) -> Result, TrevmBuilderError> + pub fn build_trevm(self) -> EvmNeedsCfg where Db: Database, Insp: Inspector>, { - let db = self.db.ok_or(TrevmBuilderError::DatabaseNotSet)?; + let db = self.state.db; let ctx = Ctx::new(db, self.spec); let mut evm = ctx.build_mainnet_with_inspector(self.insp); @@ -95,7 +114,7 @@ impl TrevmBuilder { evm.precompiles = EthPrecompiles { precompiles, spec: self.spec }; } - Ok(Trevm::from(evm)) + Trevm::from(evm) } } diff --git a/src/evm/has_tx.rs b/src/evm/has_tx.rs index 2f0f787..7decc8c 100644 --- a/src/evm/has_tx.rs +++ b/src/evm/has_tx.rs @@ -264,8 +264,7 @@ mod tests { let log_address = Address::repeat_byte(0x32); // Set up trevm, and test balances. - let mut trevm = - TrevmBuilder::new().with_db(db).with_spec_id(SpecId::PRAGUE).build_trevm().unwrap(); + let mut trevm = TrevmBuilder::new().with_db(db).with_spec_id(SpecId::PRAGUE).build_trevm(); let _ = trevm.test_set_balance(ALICE.address(), U256::from(ETH_TO_WEI)); let _ = trevm.set_bytecode_unchecked(log_address, Bytecode::new_raw(LOG_DEPLOYED_BYTECODE)); diff --git a/src/inspectors/mod.rs b/src/inspectors/mod.rs index 18bb7e4..36cf040 100644 --- a/src/inspectors/mod.rs +++ b/src/inspectors/mod.rs @@ -35,7 +35,6 @@ mod test { .with_db(InMemoryDB::default()) .with_insp(inspector) .build_trevm() - .unwrap() .fill_cfg(&NoopCfg) .fill_block(&NoopBlock); diff --git a/src/lib.rs b/src/lib.rs index 9768299..2c0ef38 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,15 +41,13 @@ //! use revm::{database::in_memory_db::InMemoryDB}; //! use trevm::{TrevmBuilder, EvmErrored, Cfg, Block, Tx}; //! -//! # fn t(cfg: &C, block: &B, tx: &T) -//! # -> Result<(), Box> { +//! # fn t(cfg: &C, block: &B, tx: &T) { //! TrevmBuilder::new() //! .with_db(InMemoryDB::default()) -//! .build_trevm()? +//! .build_trevm() //! .fill_cfg(cfg) //! .fill_block(block) //! .run_tx(tx); -//! # Ok(()) //! # } //! ``` //! If you get stuck, don't worry! You _cannot_ invoke the wrong function or @@ -118,14 +116,12 @@ //! # use revm::{database::in_memory_db::InMemoryDB, inspector::NoOpInspector}; //! # use trevm::{TrevmBuilder, EvmErrored, Cfg, BlockDriver}; //! # use alloy::primitives::B256; -//! # fn t>(cfg: &C, mut driver: D) -//! # -> Result<(), Box> { +//! # fn t>(cfg: &C, mut driver: D) { //! let trevm = TrevmBuilder::new() //! .with_db(InMemoryDB::default()) -//! .build_trevm()? +//! .build_trevm() //! .fill_cfg(cfg) //! .drive_block(&mut driver); -//! # Ok(()) //! # } //! ``` //! @@ -148,11 +144,10 @@ //! # use revm::{database::in_memory_db::InMemoryDB}; //! # use trevm::{TrevmBuilder, EvmErrored, Cfg, Block, Tx}; //! # use alloy::primitives::B256; -//! # fn t(cfg: &C, block: &B, tx: &T) -//! # -> Result<(), Box> { +//! # fn t(cfg: &C, block: &B, tx: &T) { //! let trevm = match TrevmBuilder::new() //! .with_db(InMemoryDB::default()) -//! .build_trevm()? +//! .build_trevm() //! .fill_cfg(cfg) //! .fill_block(block) //! .fill_tx(tx) @@ -160,7 +155,6 @@ //! Ok(trevm) => trevm.accept_state(), //! Err(e) => e.discard_error(), //! }; -//! # Ok(()) //! # } //! ``` //! @@ -245,14 +239,13 @@ //! # State, StateBuilder}}; //! # use trevm::{TrevmBuilder, EvmErrored, Cfg, Block, Tx, BlockOutput, //! # EvmNeedsCfg, EvmNeedsBlock, EvmNeedsTx, EvmReady, EvmTransacted}; -//! # fn t(cfg: &C, block: &B, tx: &T) -//! # -> Result<(), Box> { +//! # fn t(cfg: &C, block: &B, tx: &T) { //! let state = StateBuilder::new_with_database(InMemoryDB::default()).build(); //! //! // Trevm starts in `EvmNeedsCfg`. //! let trevm: EvmNeedsCfg<_, _> = TrevmBuilder::new() //! .with_db(state) -//! .build_trevm()?; +//! .build_trevm(); //! //! // Once the cfg is filled, we move to `EvmNeedsBlock`. //! let trevm: EvmNeedsBlock<_, _> = trevm.fill_cfg(cfg); @@ -285,7 +278,6 @@ //! // Finishing the EVM gets us the final changes and a list of block outputs //! // that includes the transaction receipts. //! let bundle: BundleState = trevm.finish(); -//! # Ok(()) //! # } //! ``` //!