Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions examples/basic_transact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl Tx for SampleTx {
// Produce aliases for the Trevm type
trevm_aliases!(TracerEip3155, InMemoryDB);

fn main() -> Result<(), Box<dyn std::error::Error>> {
fn main() {
let mut db = revm::database::InMemoryDB::default();

let bytecode = Bytecode::new_raw(hex::decode(CONTRACT_BYTECODE).unwrap().into());
Expand All @@ -54,7 +54,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let trevm = TrevmBuilder::new()
.with_db(db)
.with_insp(insp)
.build_trevm()?
.build_trevm()
.fill_cfg(&NoopCfg)
.fill_block(&NoopBlock);

Expand All @@ -72,6 +72,4 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Execution error: {e:?}");
}
};

Ok(())
}
2 changes: 1 addition & 1 deletion examples/fork_ref_transact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
51 changes: 35 additions & 16 deletions src/evm/builder.rs
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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: Db,
}

/// A builder for [`Trevm`] that allows configuring the EVM.
#[derive(Debug, Clone)]
pub struct TrevmBuilder<Db, Insp> {
pub(crate) db: Option<Db>,
pub struct TrevmBuilder<Insp, State = BuilderNeedsDb> {
pub(crate) insp: Insp,
pub(crate) spec: SpecId,
pub(crate) precompiles: Option<&'static Precompiles>,
pub(crate) state: State,
}

impl TrevmBuilder<InMemoryDB, NoOpInspector> {
impl TrevmBuilder<NoOpInspector> {
/// 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<Db, Insp> TrevmBuilder<Db, Insp> {
impl<Insp, State> TrevmBuilder<Insp, State> {
/// Set the database for the EVM.
pub fn with_db<Odb>(self, db: Odb) -> TrevmBuilder<Odb, Insp>
pub fn with_db<Odb>(self, db: Odb) -> TrevmBuilder<Insp, BuilderReady<Odb>>
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<OInsp>(self, insp: OInsp) -> TrevmBuilder<Db, OInsp> {
TrevmBuilder { db: self.db, insp, spec: self.spec, precompiles: self.precompiles }
pub fn with_insp<OInsp>(self, insp: OInsp) -> TrevmBuilder<OInsp, State> {
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<OInsp>(self, insp: OInsp) -> TrevmBuilder<Db, OInsp> {
pub fn with_inspector<OInsp>(self, insp: OInsp) -> TrevmBuilder<OInsp, State> {
self.with_insp(insp)
}

Expand All @@ -79,14 +96,16 @@ impl<Db, Insp> TrevmBuilder<Db, Insp> {
self.precompiles = Some(Precompiles::new(self.spec.into()));
self
}
}

impl<Insp, Db> TrevmBuilder<Insp, BuilderReady<Db>> {
/// Build the Trevm instance.
pub fn build_trevm(self) -> Result<EvmNeedsCfg<Db, Insp>, TrevmBuilderError>
pub fn build_trevm(self) -> EvmNeedsCfg<Db, Insp>
where
Db: Database,
Insp: Inspector<Ctx<Db>>,
{
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);
Expand All @@ -95,7 +114,7 @@ impl<Db, Insp> TrevmBuilder<Db, Insp> {
evm.precompiles = EthPrecompiles { precompiles, spec: self.spec };
}

Ok(Trevm::from(evm))
Trevm::from(evm)
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/evm/has_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
1 change: 0 additions & 1 deletion src/inspectors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ mod test {
.with_db(InMemoryDB::default())
.with_insp(inspector)
.build_trevm()
.unwrap()
.fill_cfg(&NoopCfg)
.fill_block(&NoopBlock);

Expand Down
24 changes: 8 additions & 16 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,13 @@
//! use revm::{database::in_memory_db::InMemoryDB};
//! use trevm::{TrevmBuilder, EvmErrored, Cfg, Block, Tx};
//!
//! # fn t<C: Cfg, B: Block, T: Tx>(cfg: &C, block: &B, tx: &T)
//! # -> Result<(), Box<dyn std::error::Error>> {
//! # fn t<C: Cfg, B: Block, T: Tx>(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
Expand Down Expand Up @@ -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<C: Cfg, D: BlockDriver<InMemoryDB, NoOpInspector>>(cfg: &C, mut driver: D)
//! # -> Result<(), Box<dyn std::error::Error>> {
//! # fn t<C: Cfg, D: BlockDriver<InMemoryDB, NoOpInspector>>(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(())
//! # }
//! ```
//!
Expand All @@ -148,19 +144,17 @@
//! # use revm::{database::in_memory_db::InMemoryDB};
//! # use trevm::{TrevmBuilder, EvmErrored, Cfg, Block, Tx};
//! # use alloy::primitives::B256;
//! # fn t<C: Cfg, B: Block, T: Tx>(cfg: &C, block: &B, tx: &T)
//! # -> Result<(), Box<dyn std::error::Error>> {
//! # fn t<C: Cfg, B: Block, T: Tx>(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)
//! .run() {
//! Ok(trevm) => trevm.accept_state(),
//! Err(e) => e.discard_error(),
//! };
//! # Ok(())
//! # }
//! ```
//!
Expand Down Expand Up @@ -245,14 +239,13 @@
//! # State, StateBuilder}};
//! # use trevm::{TrevmBuilder, EvmErrored, Cfg, Block, Tx, BlockOutput,
//! # EvmNeedsCfg, EvmNeedsBlock, EvmNeedsTx, EvmReady, EvmTransacted};
//! # fn t<C: Cfg, B: Block, T: Tx>(cfg: &C, block: &B, tx: &T)
//! # -> Result<(), Box<dyn std::error::Error>> {
//! # fn t<C: Cfg, B: Block, T: Tx>(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);
Expand Down Expand Up @@ -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(())
//! # }
//! ```
//!
Expand Down
Loading