Skip to content

Commit 9017a3b

Browse files
committed
feat: add "needs db" type state to TrevmBuilder
1 parent f05e169 commit 9017a3b

File tree

6 files changed

+47
-40
lines changed

6 files changed

+47
-40
lines changed

examples/basic_transact.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ impl Tx for SampleTx {
3939
// Produce aliases for the Trevm type
4040
trevm_aliases!(TracerEip3155, InMemoryDB);
4141

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

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

@@ -72,6 +72,4 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
7272
println!("Execution error: {e:?}");
7373
}
7474
};
75-
76-
Ok(())
7775
}

examples/fork_ref_transact.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ async fn main() -> eyre::Result<()> {
6060
// initialise an empty (default) EVM
6161
let evm = TrevmBuilder::new()
6262
.with_db(cache_db)
63-
.build_trevm()?
63+
.build_trevm()
6464
.fill_cfg(&NoopCfg)
6565
.fill_block(&NoopBlock)
6666
.fill_tx(&GetReservesFiller)

src/evm/builder.rs

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{evm::Trevm, helpers::Ctx, EvmNeedsCfg};
22
use revm::{
3-
database::in_memory_db::InMemoryDB, handler::EthPrecompiles, inspector::NoOpInspector,
4-
precompile::Precompiles, primitives::hardfork::SpecId, Database, Inspector, MainBuilder,
3+
handler::EthPrecompiles, inspector::NoOpInspector, precompile::Precompiles,
4+
primitives::hardfork::SpecId, Database, Inspector, MainBuilder,
55
};
66

77
/// Error that can occur when building a Trevm instance.
@@ -13,48 +13,65 @@ pub enum TrevmBuilderError {
1313
DatabaseNotSet,
1414
}
1515

16+
#[allow(unnameable_types)]
17+
#[derive(Debug, Copy, Clone)]
18+
pub struct BuilderNeedsDb {
19+
_private: (),
20+
}
21+
22+
#[allow(unnameable_types)]
23+
#[derive(Debug, Copy, Clone)]
24+
pub struct BuilderReady<Db> {
25+
db: Db,
26+
}
27+
1628
/// A builder for [`Trevm`] that allows configuring the EVM.
1729
#[derive(Debug, Clone)]
18-
pub struct TrevmBuilder<Db, Insp> {
19-
pub(crate) db: Option<Db>,
30+
pub struct TrevmBuilder<Insp, State = BuilderNeedsDb> {
2031
pub(crate) insp: Insp,
2132
pub(crate) spec: SpecId,
2233
pub(crate) precompiles: Option<&'static Precompiles>,
34+
pub(crate) state: State,
2335
}
2436

25-
impl TrevmBuilder<InMemoryDB, NoOpInspector> {
37+
impl TrevmBuilder<NoOpInspector> {
2638
/// Create a new builder with the default database and inspector.
2739
#[allow(clippy::new_without_default)] // default would make bad devex :(
2840
pub const fn new() -> Self {
29-
Self { db: None, insp: NoOpInspector, spec: SpecId::PRAGUE, precompiles: None }
41+
Self {
42+
insp: NoOpInspector,
43+
spec: SpecId::PRAGUE,
44+
precompiles: None,
45+
state: BuilderNeedsDb { _private: () },
46+
}
3047
}
3148
}
3249

33-
impl<Db, Insp> TrevmBuilder<Db, Insp> {
50+
impl<Insp, State> TrevmBuilder<Insp, State> {
3451
/// Set the database for the EVM.
35-
pub fn with_db<Odb>(self, db: Odb) -> TrevmBuilder<Odb, Insp>
52+
pub fn with_db<Odb>(self, db: Odb) -> TrevmBuilder<Insp, BuilderReady<Odb>>
3653
where
37-
Db: Database,
54+
Odb: Database,
3855
{
3956
TrevmBuilder {
40-
db: Some(db),
4157
insp: self.insp,
4258
spec: self.spec,
4359
precompiles: self.precompiles,
60+
state: BuilderReady { db },
4461
}
4562
}
4663

4764
/// Set the inspector for the EVM.
4865
///
4966
/// Equivalent to [`Self::with_inspector`].
50-
pub fn with_insp<OInsp>(self, insp: OInsp) -> TrevmBuilder<Db, OInsp> {
51-
TrevmBuilder { db: self.db, insp, spec: self.spec, precompiles: self.precompiles }
67+
pub fn with_insp<OInsp>(self, insp: OInsp) -> TrevmBuilder<OInsp, State> {
68+
TrevmBuilder { insp, spec: self.spec, precompiles: self.precompiles, state: self.state }
5269
}
5370

5471
/// Set the inspector for the EVM.
5572
///
5673
/// Equivalent to [`Self::with_insp`].
57-
pub fn with_inspector<OInsp>(self, insp: OInsp) -> TrevmBuilder<Db, OInsp> {
74+
pub fn with_inspector<OInsp>(self, insp: OInsp) -> TrevmBuilder<OInsp, State> {
5875
self.with_insp(insp)
5976
}
6077

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

101+
impl<Insp, Db> TrevmBuilder<Insp, BuilderReady<Db>> {
83102
/// Build the Trevm instance.
84-
pub fn build_trevm(self) -> Result<EvmNeedsCfg<Db, Insp>, TrevmBuilderError>
103+
pub fn build_trevm(self) -> EvmNeedsCfg<Db, Insp>
85104
where
86105
Db: Database,
87106
Insp: Inspector<Ctx<Db>>,
88107
{
89-
let db = self.db.ok_or(TrevmBuilderError::DatabaseNotSet)?;
108+
let db = self.state.db;
90109
let ctx = Ctx::new(db, self.spec);
91110

92111
let mut evm = ctx.build_mainnet_with_inspector(self.insp);
@@ -95,7 +114,7 @@ impl<Db, Insp> TrevmBuilder<Db, Insp> {
95114
evm.precompiles = EthPrecompiles { precompiles, spec: self.spec };
96115
}
97116

98-
Ok(Trevm::from(evm))
117+
Trevm::from(evm)
99118
}
100119
}
101120

src/evm/has_tx.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,7 @@ mod tests {
264264
let log_address = Address::repeat_byte(0x32);
265265

266266
// Set up trevm, and test balances.
267-
let mut trevm =
268-
TrevmBuilder::new().with_db(db).with_spec_id(SpecId::PRAGUE).build_trevm().unwrap();
267+
let mut trevm = TrevmBuilder::new().with_db(db).with_spec_id(SpecId::PRAGUE).build_trevm();
269268
let _ = trevm.test_set_balance(ALICE.address(), U256::from(ETH_TO_WEI));
270269
let _ = trevm.set_bytecode_unchecked(log_address, Bytecode::new_raw(LOG_DEPLOYED_BYTECODE));
271270

src/inspectors/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ mod test {
3535
.with_db(InMemoryDB::default())
3636
.with_insp(inspector)
3737
.build_trevm()
38-
.unwrap()
3938
.fill_cfg(&NoopCfg)
4039
.fill_block(&NoopBlock);
4140

src/lib.rs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,13 @@
4141
//! use revm::{database::in_memory_db::InMemoryDB};
4242
//! use trevm::{TrevmBuilder, EvmErrored, Cfg, Block, Tx};
4343
//!
44-
//! # fn t<C: Cfg, B: Block, T: Tx>(cfg: &C, block: &B, tx: &T)
45-
//! # -> Result<(), Box<dyn std::error::Error>> {
44+
//! # fn t<C: Cfg, B: Block, T: Tx>(cfg: &C, block: &B, tx: &T) {
4645
//! TrevmBuilder::new()
4746
//! .with_db(InMemoryDB::default())
48-
//! .build_trevm()?
47+
//! .build_trevm()
4948
//! .fill_cfg(cfg)
5049
//! .fill_block(block)
5150
//! .run_tx(tx);
52-
//! # Ok(())
5351
//! # }
5452
//! ```
5553
//! If you get stuck, don't worry! You _cannot_ invoke the wrong function or
@@ -118,14 +116,12 @@
118116
//! # use revm::{database::in_memory_db::InMemoryDB, inspector::NoOpInspector};
119117
//! # use trevm::{TrevmBuilder, EvmErrored, Cfg, BlockDriver};
120118
//! # use alloy::primitives::B256;
121-
//! # fn t<C: Cfg, D: BlockDriver<InMemoryDB, NoOpInspector>>(cfg: &C, mut driver: D)
122-
//! # -> Result<(), Box<dyn std::error::Error>> {
119+
//! # fn t<C: Cfg, D: BlockDriver<InMemoryDB, NoOpInspector>>(cfg: &C, mut driver: D) {
123120
//! let trevm = TrevmBuilder::new()
124121
//! .with_db(InMemoryDB::default())
125-
//! .build_trevm()?
122+
//! .build_trevm()
126123
//! .fill_cfg(cfg)
127124
//! .drive_block(&mut driver);
128-
//! # Ok(())
129125
//! # }
130126
//! ```
131127
//!
@@ -148,19 +144,17 @@
148144
//! # use revm::{database::in_memory_db::InMemoryDB};
149145
//! # use trevm::{TrevmBuilder, EvmErrored, Cfg, Block, Tx};
150146
//! # use alloy::primitives::B256;
151-
//! # fn t<C: Cfg, B: Block, T: Tx>(cfg: &C, block: &B, tx: &T)
152-
//! # -> Result<(), Box<dyn std::error::Error>> {
147+
//! # fn t<C: Cfg, B: Block, T: Tx>(cfg: &C, block: &B, tx: &T) {
153148
//! let trevm = match TrevmBuilder::new()
154149
//! .with_db(InMemoryDB::default())
155-
//! .build_trevm()?
150+
//! .build_trevm()
156151
//! .fill_cfg(cfg)
157152
//! .fill_block(block)
158153
//! .fill_tx(tx)
159154
//! .run() {
160155
//! Ok(trevm) => trevm.accept_state(),
161156
//! Err(e) => e.discard_error(),
162157
//! };
163-
//! # Ok(())
164158
//! # }
165159
//! ```
166160
//!
@@ -245,14 +239,13 @@
245239
//! # State, StateBuilder}};
246240
//! # use trevm::{TrevmBuilder, EvmErrored, Cfg, Block, Tx, BlockOutput,
247241
//! # EvmNeedsCfg, EvmNeedsBlock, EvmNeedsTx, EvmReady, EvmTransacted};
248-
//! # fn t<C: Cfg, B: Block, T: Tx>(cfg: &C, block: &B, tx: &T)
249-
//! # -> Result<(), Box<dyn std::error::Error>> {
242+
//! # fn t<C: Cfg, B: Block, T: Tx>(cfg: &C, block: &B, tx: &T) {
250243
//! let state = StateBuilder::new_with_database(InMemoryDB::default()).build();
251244
//!
252245
//! // Trevm starts in `EvmNeedsCfg`.
253246
//! let trevm: EvmNeedsCfg<_, _> = TrevmBuilder::new()
254247
//! .with_db(state)
255-
//! .build_trevm()?;
248+
//! .build_trevm();
256249
//!
257250
//! // Once the cfg is filled, we move to `EvmNeedsBlock`.
258251
//! let trevm: EvmNeedsBlock<_, _> = trevm.fill_cfg(cfg);
@@ -285,7 +278,6 @@
285278
//! // Finishing the EVM gets us the final changes and a list of block outputs
286279
//! // that includes the transaction receipts.
287280
//! let bundle: BundleState = trevm.finish();
288-
//! # Ok(())
289281
//! # }
290282
//! ```
291283
//!

0 commit comments

Comments
 (0)