Skip to content

Commit

Permalink
feat: minimal propagation of database error to caller
Browse files Browse the repository at this point in the history
  • Loading branch information
Wodann committed Jan 9, 2023
1 parent 2be3798 commit 20dc06e
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 74 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions bins/revm-test/src/bin/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,28 @@ fn main() {

// just to spead up processor.
for _ in 0..10000 {
let (_, _) = evm.transact();
let (_, _) = evm.transact().expect("Transaction should succeed");
}

let timer = Instant::now();
for _ in 0..30000 {
let (_, _) = evm.transact();
let (_, _) = evm.transact().expect("Transaction should succeed");
}
println!("Raw elapsed time: {:?}", timer.elapsed());

evm.database(BenchmarkDB::new_bytecode(bytecode_checked));

let timer = Instant::now();
for _ in 0..30000 {
let (_, _) = evm.transact();
let (_, _) = evm.transact().expect("Transaction should succeed");
}
println!("Checked elapsed time: {:?}", timer.elapsed());

evm.database(BenchmarkDB::new_bytecode(bytecode_analysed));

let timer = Instant::now();
for _ in 0..30000 {
let (_, _) = evm.transact();
let (_, _) = evm.transact().expect("Transaction should succeed");
}
println!("Analysed elapsed time: {:?}", timer.elapsed());
}
2 changes: 1 addition & 1 deletion bins/revm-test/src/bin/snailtracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub fn simple_example() {
&bench_options,
"Snailtracer Host+Interpreter benchmark",
|| {
let (_, _) = evm.transact();
let (_, _) = evm.transact().expect("Transaction should succeed");
},
);

Expand Down
5 changes: 3 additions & 2 deletions bins/revme/src/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ pub fn execute_test_suit(path: &Path, elapsed: &Arc<Mutex<Duration>>) -> Result<
gas_refunded,
logs,
..
} = evm.transact_commit();
} = evm.transact_commit().expect("Transaction should succeed");
let timer = timer.elapsed();

*elapsed.lock().unwrap() += timer;
Expand All @@ -272,7 +272,8 @@ pub fn execute_test_suit(path: &Path, elapsed: &Arc<Mutex<Duration>>) -> Result<
);
let mut database_cloned = database.clone();
evm.database(&mut database_cloned);
evm.inspect_commit(CustomPrintTracer::default());
evm.inspect_commit(CustomPrintTracer::default())
.expect("Transaction should succeed");
let db = evm.db().unwrap();
println!("{path:?} UNIT_TEST:{name}\n");
println!(
Expand Down
1 change: 1 addition & 0 deletions crates/revm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ hashbrown = { version = "0.13" }
hex = { version = "0.4", default-features = false }
revm-precompiles = { path = "../precompiles", version = "1.1.2", default-features = false }
revm-interpreter = { path = "../interpreter", default-features = false }
thiserror = { version = "1.0.38", default-features = false }

# Optional
serde = { version = "1.0", features = ["derive", "rc"], optional = true }
Expand Down
12 changes: 9 additions & 3 deletions crates/revm/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ mod in_memory_db;

#[cfg(feature = "ethersdb")]
pub mod ethersdb;

#[cfg(feature = "ethersdb")]
pub use ethersdb::EthersDB;

Expand All @@ -10,6 +11,8 @@ compile_error!(
"`web3db` feature is deprecated, drop-in replacement can be found with feature `ethersdb`"
);

use core::fmt::Debug;

use crate::AccountInfo;
use crate::U256;
use crate::{interpreter::bytecode::Bytecode, Account};
Expand All @@ -20,7 +23,8 @@ pub use in_memory_db::{AccountState, BenchmarkDB, CacheDB, DbAccount, EmptyDB, I

#[auto_impl(& mut, Box)]
pub trait Database {
type Error;
type Error: Debug;

/// Get basic account information.
fn basic(&mut self, address: B160) -> Result<Option<AccountInfo>, Self::Error>;
/// Get account code by its hash
Expand All @@ -39,7 +43,8 @@ pub trait DatabaseCommit {

#[auto_impl(&, Box, Arc)]
pub trait DatabaseRef {
type Error;
type Error: Debug;

/// Whether account at address exists.
//fn exists(&self, address: B160) -> Option<AccountInfo>;
/// Get basic account information.
Expand All @@ -63,8 +68,9 @@ impl<'a, Error> RefDBWrapper<'a, Error> {
}
}

impl<'a, Error> Database for RefDBWrapper<'a, Error> {
impl<'a, Error: Debug> Database for RefDBWrapper<'a, Error> {
type Error = Error;

/// Get basic account information.
fn basic(&mut self, address: B160) -> Result<Option<AccountInfo>, Self::Error> {
self.db.basic(address)
Expand Down
35 changes: 20 additions & 15 deletions crates/revm/src/evm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
db::{Database, DatabaseCommit, DatabaseRef, RefDBWrapper},
evm_impl::{EVMImpl, Transact},
evm_impl::{EVMImpl, Transact, TransactError},
inspectors::NoOpInspector,
journaled_state::State,
Env, ExecutionResult, Inspector,
Expand Down Expand Up @@ -43,22 +43,27 @@ impl<DB> Default for EVM<DB> {

impl<DB: Database + DatabaseCommit> EVM<DB> {
/// Execute transaction and apply result to database
pub fn transact_commit(&mut self) -> ExecutionResult {
let (exec_result, state) = self.transact();
self.db.as_mut().unwrap().commit(state);
exec_result
pub fn transact_commit(&mut self) -> Result<ExecutionResult, TransactError<DB::Error>> {
self.transact().map(|(exec_result, state)| {
self.db.as_mut().unwrap().commit(state);
exec_result
})
}
/// Inspect transaction and commit changes to database.
pub fn inspect_commit<INSP: Inspector<DB>>(&mut self, inspector: INSP) -> ExecutionResult {
let (exec_result, state) = self.inspect(inspector);
self.db.as_mut().unwrap().commit(state);
exec_result
pub fn inspect_commit<INSP: Inspector<DB>>(
&mut self,
inspector: INSP,
) -> Result<ExecutionResult, TransactError<DB::Error>> {
self.inspect(inspector).map(|(exec_result, state)| {
self.db.as_mut().unwrap().commit(state);
exec_result
})
}
}

impl<DB: Database> EVM<DB> {
/// Execute transaction without writing to DB, return change state.
pub fn transact(&mut self) -> (ExecutionResult, State) {
pub fn transact(&mut self) -> Result<(ExecutionResult, State), TransactError<DB::Error>> {
if let Some(db) = self.db.as_mut() {
let mut noop = NoOpInspector {};
let out = evm_inner::<DB, false>(&mut self.env, db, &mut noop).transact();
Expand All @@ -72,7 +77,7 @@ impl<DB: Database> EVM<DB> {
pub fn inspect<INSP: Inspector<DB>>(
&mut self,
mut inspector: INSP,
) -> (ExecutionResult, State) {
) -> Result<(ExecutionResult, State), TransactError<DB::Error>> {
if let Some(db) = self.db.as_mut() {
evm_inner::<DB, true>(&mut self.env, db, &mut inspector).transact()
} else {
Expand All @@ -83,7 +88,7 @@ impl<DB: Database> EVM<DB> {

impl<'a, DB: DatabaseRef> EVM<DB> {
/// Execute transaction without writing to DB, return change state.
pub fn transact_ref(&self) -> (ExecutionResult, State) {
pub fn transact_ref(&self) -> Result<(ExecutionResult, State), TransactError<DB::Error>> {
if let Some(db) = self.db.as_ref() {
let mut noop = NoOpInspector {};
let mut db = RefDBWrapper::new(db);
Expand All @@ -101,7 +106,7 @@ impl<'a, DB: DatabaseRef> EVM<DB> {
pub fn inspect_ref<INSP: Inspector<RefDBWrapper<'a, DB::Error>>>(
&'a self,
mut inspector: INSP,
) -> (ExecutionResult, State) {
) -> Result<(ExecutionResult, State), TransactError<DB::Error>> {
if let Some(db) = self.db.as_ref() {
let mut db = RefDBWrapper::new(db);
let db = &mut db;
Expand Down Expand Up @@ -146,7 +151,7 @@ macro_rules! create_evm {
$env,
$inspector,
Precompiles::new(to_precompile_id($spec::SPEC_ID)).clone(),
)) as Box<dyn Transact + 'a>
)) as Box<dyn Transact<DatabaseError = DB::Error> + 'a>
};
}

Expand Down Expand Up @@ -176,7 +181,7 @@ pub fn evm_inner<'a, DB: Database, const INSPECT: bool>(
env: &'a mut Env,
db: &'a mut DB,
insp: &'a mut dyn Inspector<DB>,
) -> Box<dyn Transact + 'a> {
) -> Box<dyn Transact<DatabaseError = DB::Error> + 'a> {
use specification::*;
match env.cfg.spec_id {
SpecId::FRONTIER | SpecId::FRONTIER_THAWING => create_evm!(FrontierSpec, db, env, insp),
Expand Down
Loading

0 comments on commit 20dc06e

Please sign in to comment.