diff --git a/bins/revme/src/statetest/runner.rs b/bins/revme/src/statetest/runner.rs index bee54a837c..c05d152480 100644 --- a/bins/revme/src/statetest/runner.rs +++ b/bins/revme/src/statetest/runner.rs @@ -255,12 +255,12 @@ pub fn execute_test_suit( env.cfg.spec_id, revm::primitives::SpecId::SPURIOUS_DRAGON, )); - let mut state = revm::db::State::builder() + let state = revm::db::State::builder() .with_cached_prestate(cache) .with_bundle_update() .build(); - let mut evm = revm::new(); - evm.database(&mut state); + let mut evm = revm::new(Default::default()); + *evm.db() = state; evm.env = env.clone(); // do the deed @@ -275,7 +275,7 @@ pub fn execute_test_suit( *elapsed.lock().unwrap() += timer; - let db = evm.db().unwrap(); + let db = &evm.db; let state_root = state_merkle_trie_root(db.cache.trie_account()); let logs = match &exec_result { Ok(ExecutionResult::Success { logs, .. }) => logs.clone(), @@ -293,14 +293,14 @@ pub fn execute_test_suit( env.cfg.spec_id, revm::primitives::SpecId::SPURIOUS_DRAGON, )); - let mut state = revm::db::StateBuilder::default() + let state = revm::db::StateBuilder::default() .with_cached_prestate(cache) .with_bundle_update() .build(); - evm.database(&mut state); + *evm.db() = state; let _ = evm.inspect_commit(TracerEip3155::new(Box::new(stdout()), false, false)); - let db = evm.db().unwrap(); + let db = evm.db; println!("{path:?} UNIT_TEST:{name}\n"); match &exec_result { Ok(ExecutionResult::Success { diff --git a/crates/revm/benches/bench.rs b/crates/revm/benches/bench.rs index d51e174d0c..84ca81e016 100644 --- a/crates/revm/benches/bench.rs +++ b/crates/revm/benches/bench.rs @@ -12,7 +12,7 @@ use std::time::Duration; type Evm = revm::EVM; fn analysis(c: &mut Criterion) { - let mut evm = revm::new(); + let mut evm = revm::new(Default::default()); evm.env.tx.caller = "0x1000000000000000000000000000000000000000" .parse() @@ -34,23 +34,23 @@ fn analysis(c: &mut Criterion) { .sample_size(10); let raw = Bytecode::new_raw(contract_data.clone()); - evm.database(BenchmarkDB::new_bytecode(raw)); + *evm.db() = BenchmarkDB::new_bytecode(raw); bench_transact(&mut g, &mut evm); let checked = Bytecode::new_raw(contract_data.clone()).to_checked(); - evm.database(BenchmarkDB::new_bytecode(checked)); + *evm.db() = BenchmarkDB::new_bytecode(checked); bench_transact(&mut g, &mut evm); let analysed = to_analysed(Bytecode::new_raw(contract_data)); - evm.database(BenchmarkDB::new_bytecode(analysed)); + *evm.db() = BenchmarkDB::new_bytecode(analysed); bench_transact(&mut g, &mut evm); g.finish(); } fn snailtracer(c: &mut Criterion) { - let mut evm = revm::new(); - evm.database(BenchmarkDB::new_bytecode(bytecode(SNAILTRACER))); + let mut evm = revm::new(Default::default()); + *evm.db() = BenchmarkDB::new_bytecode(bytecode(SNAILTRACER)); evm.env.tx.caller = "0x1000000000000000000000000000000000000000" .parse() @@ -73,8 +73,8 @@ fn snailtracer(c: &mut Criterion) { } fn transfer(c: &mut Criterion) { - let mut evm = revm::new(); - evm.database(BenchmarkDB::new_bytecode(Bytecode::new())); + let mut evm = revm::new(Default::default()); + *evm.db() = BenchmarkDB::new_bytecode(Bytecode::new()); evm.env.tx.caller = "0x0000000000000000000000000000000000000001" .parse() @@ -93,7 +93,7 @@ fn transfer(c: &mut Criterion) { } fn bench_transact(g: &mut BenchmarkGroup<'_, WallTime>, evm: &mut Evm) { - let state = match evm.db.as_mut().unwrap().0.state { + let state = match evm.db.0.state { BytecodeState::Raw => "raw", BytecodeState::Checked { .. } => "checked", BytecodeState::Analysed { .. } => "analysed", @@ -106,7 +106,7 @@ fn bench_eval(g: &mut BenchmarkGroup<'_, WallTime>, evm: &Evm) { g.bench_function("eval", |b| { let contract = Contract { input: evm.env.tx.data.clone(), - bytecode: BytecodeLocked::try_from(evm.db.as_ref().unwrap().0.clone()).unwrap(), + bytecode: BytecodeLocked::try_from(evm.db.0.clone()).unwrap(), ..Default::default() }; let mut host = DummyHost::new(evm.env.clone()); diff --git a/crates/revm/src/db/states/state.rs b/crates/revm/src/db/states/state.rs index 3ff9f81960..ba6440e6c7 100644 --- a/crates/revm/src/db/states/state.rs +++ b/crates/revm/src/db/states/state.rs @@ -62,6 +62,19 @@ impl State { } } +impl Default for State { + fn default() -> Self { + Self { + cache: Default::default(), + database: Default::default(), + transition_state: Default::default(), + bundle_state: Default::default(), + use_preloaded_bundle: Default::default(), + block_hashes: Default::default(), + } + } +} + impl State { /// Returns the size hint for the inner bundle state. /// See [BundleState::size_hint] for more info. diff --git a/crates/revm/src/evm.rs b/crates/revm/src/evm.rs index 8fcd4eabbc..671a659b0e 100644 --- a/crates/revm/src/evm.rs +++ b/crates/revm/src/evm.rs @@ -34,23 +34,22 @@ use revm_precompile::Precompiles; /// # struct SomeDatabase; // Mocking a database type for the purpose of this example /// # struct Env; // Assuming the type Env is defined somewhere /// -/// let evm: EVM = EVM::new(); -/// assert!(evm.db.is_none()); +/// let evm: EVM = EVM::new(SomeDatabase); /// ``` /// #[derive(Clone)] pub struct EVM { pub env: Env, - pub db: Option, + pub db: DB, } -pub fn new() -> EVM { - EVM::new() +pub fn new(db: DB) -> EVM { + EVM::new(db) } -impl Default for EVM { +impl Default for EVM { fn default() -> Self { - Self::new() + Self::new(Default::default()) } } @@ -58,7 +57,7 @@ impl EVM { /// Execute transaction and apply result to database pub fn transact_commit(&mut self) -> Result> { let ResultAndState { result, state } = self.transact()?; - self.db.as_mut().unwrap().commit(state); + self.db.commit(state); Ok(result) } @@ -68,7 +67,7 @@ impl EVM { inspector: INSP, ) -> Result> { let ResultAndState { result, state } = self.inspect(inspector)?; - self.db.as_mut().unwrap().commit(state); + self.db.commit(state); Ok(result) } } @@ -76,84 +75,58 @@ impl EVM { impl EVM { /// Do checks that could make transaction fail before call/create pub fn preverify_transaction(&mut self) -> Result<(), EVMError> { - if let Some(db) = self.db.as_mut() { - evm_inner::(&mut self.env, db, &mut NoOpInspector).preverify_transaction() - } else { - panic!("Database needs to be set"); - } + evm_inner::(&mut self.env, &mut self.db, &mut NoOpInspector) + .preverify_transaction() } /// Skip preverification steps and execute transaction without writing to DB, return change /// state. pub fn transact_preverified(&mut self) -> EVMResult { - if let Some(db) = self.db.as_mut() { - evm_inner::(&mut self.env, db, &mut NoOpInspector).transact_preverified() - } else { - panic!("Database needs to be set"); - } + evm_inner::(&mut self.env, &mut self.db, &mut NoOpInspector) + .transact_preverified() } /// Execute transaction without writing to DB, return change state. pub fn transact(&mut self) -> EVMResult { - if let Some(db) = self.db.as_mut() { - evm_inner::(&mut self.env, db, &mut NoOpInspector).transact() - } else { - panic!("Database needs to be set"); - } + evm_inner::(&mut self.env, &mut self.db, &mut NoOpInspector).transact() } /// Execute transaction with given inspector, without wring to DB. Return change state. pub fn inspect>(&mut self, mut inspector: INSP) -> EVMResult { - if let Some(db) = self.db.as_mut() { - evm_inner::(&mut self.env, db, &mut inspector).transact() - } else { - panic!("Database needs to be set"); - } + evm_inner::(&mut self.env, &mut self.db, &mut inspector).transact() } } impl<'a, DB: DatabaseRef> EVM { /// Do checks that could make transaction fail before call/create pub fn preverify_transaction_ref(&self) -> Result<(), EVMError> { - if let Some(db) = self.db.as_ref() { - evm_inner::<_, false>( - &mut self.env.clone(), - &mut WrapDatabaseRef(db), - &mut NoOpInspector, - ) - .preverify_transaction() - } else { - panic!("Database needs to be set"); - } + evm_inner::<_, false>( + &mut self.env.clone(), + &mut WrapDatabaseRef(&self.db), + &mut NoOpInspector, + ) + .preverify_transaction() } /// Skip preverification steps and execute transaction /// without writing to DB, return change state. pub fn transact_preverified_ref(&self) -> EVMResult { - if let Some(db) = self.db.as_ref() { - evm_inner::<_, false>( - &mut self.env.clone(), - &mut WrapDatabaseRef(db), - &mut NoOpInspector, - ) - .transact_preverified() - } else { - panic!("Database needs to be set"); - } + evm_inner::<_, false>( + &mut self.env.clone(), + &mut WrapDatabaseRef(&self.db), + &mut NoOpInspector, + ) + .transact_preverified() } /// Execute transaction without writing to DB, return change state. pub fn transact_ref(&self) -> EVMResult { - if let Some(db) = self.db.as_ref() { - evm_inner::<_, false>( - &mut self.env.clone(), - &mut WrapDatabaseRef(db), - &mut NoOpInspector, - ) - .transact() - } else { - panic!("Database needs to be set"); - } + evm_inner::<_, false>( + &mut self.env.clone(), + &mut WrapDatabaseRef(&self.db), + &mut NoOpInspector, + ) + .transact() } /// Execute transaction with given inspector, without wring to DB. Return change state. @@ -161,40 +134,28 @@ impl<'a, DB: DatabaseRef> EVM { &'a self, mut inspector: I, ) -> EVMResult { - if let Some(db) = self.db.as_ref() { - evm_inner::<_, true>( - &mut self.env.clone(), - &mut WrapDatabaseRef(db), - &mut inspector, - ) - .transact() - } else { - panic!("Database needs to be set"); - } + evm_inner::<_, true>( + &mut self.env.clone(), + &mut WrapDatabaseRef(&self.db), + &mut inspector, + ) + .transact() } } impl EVM { /// Creates a new [EVM] instance with the default environment, - pub fn new() -> Self { - Self::with_env(Default::default()) + pub fn new(db: DB) -> Self { + Self::with_env(Default::default(), db) } /// Creates a new [EVM] instance with the given environment. - pub fn with_env(env: Env) -> Self { - Self { env, db: None } - } - - pub fn database(&mut self, db: DB) { - self.db = Some(db); - } - - pub fn db(&mut self) -> Option<&mut DB> { - self.db.as_mut() + pub fn with_env(env: Env, db: DB) -> Self { + Self { env, db } } - pub fn take_db(&mut self) -> DB { - core::mem::take(&mut self.db).unwrap() + pub fn db(&mut self) -> &mut DB { + &mut self.db } } diff --git a/crates/revm/src/inspector/customprinter.rs b/crates/revm/src/inspector/customprinter.rs index ba69bdf249..f53e46e54a 100644 --- a/crates/revm/src/inspector/customprinter.rs +++ b/crates/revm/src/inspector/customprinter.rs @@ -132,7 +132,7 @@ mod test { use crate::primitives::hex_literal; // https://github.com/bluealloy/revm/issues/277 // checks this use case - let mut evm = crate::new(); + let mut evm = crate::new(Default::default()); let mut database = crate::InMemoryDB::default(); let code: crate::primitives::Bytes = hex_literal::hex!("5b597fb075978b6c412c64d169d56d839a8fe01b3f4607ed603b2c78917ce8be1430fe6101e8527ffe64706ecad72a2f5c97a95e006e279dc57081902029ce96af7edae5de116fec610208527f9fc1ef09d4dd80683858ae3ea18869fe789ddc365d8d9d800e26c9872bac5e5b6102285260276102485360d461024953601661024a53600e61024b53607d61024c53600961024d53600b61024e5360b761024f5360596102505360796102515360a061025253607261025353603a6102545360fb61025553601261025653602861025753600761025853606f61025953601761025a53606161025b53606061025c5360a661025d53602b61025e53608961025f53607a61026053606461026153608c6102625360806102635360d56102645360826102655360ae61026653607f6101e8610146610220677a814b184591c555735fdcca53617f4d2b9134b29090c87d01058e27e962047654f259595947443b1b816b65cdb6277f4b59c10a36f4e7b8658f5a5e6f5561").to_vec().into(); @@ -144,7 +144,7 @@ mod test { }; let callee = hex_literal::hex!("5fdcca53617f4d2b9134b29090c87d01058e27e9"); database.insert_account_info(crate::primitives::B160(callee), acc_info); - evm.database(database); + *evm.db() = database; evm.env.tx.caller = crate::primitives::B160(hex_literal::hex!( "5fdcca53617f4d2b9134b29090c87d01058e27e0" )); diff --git a/crates/revm/src/inspector/gas.rs b/crates/revm/src/inspector/gas.rs index 28ccf87f28..3c9229f767 100644 --- a/crates/revm/src/inspector/gas.rs +++ b/crates/revm/src/inspector/gas.rs @@ -227,8 +227,8 @@ mod tests { ]); let bytecode = Bytecode::new_raw(contract_data); - let mut evm = crate::new(); - evm.database(BenchmarkDB::new_bytecode(bytecode.clone())); + let mut evm = crate::new(Default::default()); + *evm.db() = BenchmarkDB::new_bytecode(bytecode.clone()); evm.env.tx.caller = B160(hex!("1000000000000000000000000000000000000000")); evm.env.tx.transact_to = TransactTo::Call(B160(hex!("0000000000000000000000000000000000000000"))); diff --git a/examples/fork_ref_transact.rs b/examples/fork_ref_transact.rs index 6dcd4dade1..af2c669259 100644 --- a/examples/fork_ref_transact.rs +++ b/examples/fork_ref_transact.rs @@ -67,10 +67,10 @@ async fn main() -> Result<()> { .unwrap(); // initialise an empty (default) EVM - let mut evm = EVM::new(); + let mut evm = EVM::new(Default::default()); // insert pre-built database from above - evm.database(cache_db); + *evm.db() = cache_db; // fill in missing bits of env struct // change that to whatever caller you want to be