Skip to content

Commit

Permalink
issue: cannot use databases by reference when using handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
Wodann committed Mar 2, 2024
1 parent 46bbcfc commit 0e13a8d
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 1 deletion.
5 changes: 5 additions & 0 deletions crates/revm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ name = "generate_block_traces"
path = "../../examples/generate_block_traces.rs"
required-features = ["std", "serde-json", "ethersdb"]

[[example]]
name = "db_by_ref"
path = "../../examples/db_by_ref.rs"
required-features = ["std", "serde-json"]

[[bench]]
name = "bench"
path = "benches/bench.rs"
Expand Down
2 changes: 1 addition & 1 deletion crates/revm/src/handler/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub type EvmHandler<'a, EXT, DB> = Handler<'a, Evm<'a, EXT, DB>, EXT, DB>;
pub type EvmInstructionTables<'a, EXT, DB> = InstructionTables<'a, Evm<'a, EXT, DB>>;

// Handle register
pub type HandleRegister<'a, EXT, DB> = fn(&mut EvmHandler<'a, EXT, DB>);
pub type HandleRegister<'a, EXT, DB> = for<'evm> fn(&'evm mut EvmHandler<'a, EXT, DB>);

// Boxed handle register
pub type HandleRegisterBox<'a, EXT, DB> = Box<dyn Fn(&mut EvmHandler<'a, EXT, DB>)>;
Expand Down
74 changes: 74 additions & 0 deletions examples/db_by_ref.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use revm::{
db::{CacheDB, EmptyDB, WrapDatabaseRef},
handler::register::HandleRegister,
inspector_handle_register,
inspectors::TracerEip3155,
primitives::ResultAndState,
Database, DatabaseCommit, Evm,
};

struct DebugContext<'evm, EXT, DB: Database> {
ext: EXT,
register_handles_fn: HandleRegister<'evm, EXT, DB>,
}

fn run_transaction<'db, 'evm, EXT>(
db: &'db CacheDB<EmptyDB>,
ext: EXT,
register_handles_fn: HandleRegister<'evm, EXT, WrapDatabaseRef<&'evm CacheDB<EmptyDB>>>,
) -> anyhow::Result<ResultAndState>
where
'db: 'evm,
{
let mut evm = Evm::builder()
.with_ref_db(db)
.with_external_context(ext)
.append_handler_register(register_handles_fn)
.build();

let result = evm.transact()?;

Ok(result)
}

fn run_transaction_and_commit_with_ext<'db, 'evm, EXT>(
db: &'db mut CacheDB<EmptyDB>,
ext: EXT,
register_handles_fn: HandleRegister<'evm, EXT, WrapDatabaseRef<&'evm CacheDB<EmptyDB>>>,
) -> anyhow::Result<()>
where
'db: 'evm,
{
let ResultAndState { state: changes, .. } = {
let db: &'evm _ = &*db;
run_transaction(db, ext, register_handles_fn)?
};

// Compile error: error[E0502]: cannot borrow `*db` as mutable because it is also borrowed as immutable
// The lifetime of `'evm` is extended beyond this function's scope because it is used in the `HandleRegister` function
db.commit(changes);

Ok(())
}

fn run_transaction_and_commit<'db>(db: &mut CacheDB<EmptyDB>) -> anyhow::Result<()> {
let mut evm = Evm::builder().with_ref_db(db).build();

let ResultAndState { state: changes, .. } = evm.transact()?;

// No compiler error because there is no lifetime parameter for the `HandleRegister` function
db.commit(changes);

Ok(())
}

fn main() -> anyhow::Result<()> {
let mut cache_db = CacheDB::new(EmptyDB::default());

let mut tracer = TracerEip3155::new(Box::new(std::io::stdout()), true, true);

run_transaction_and_commit_with_ext(&mut cache_db, &mut tracer, inspector_handle_register)?;
run_transaction_and_commit(&mut cache_db)?;

Ok(())
}

0 comments on commit 0e13a8d

Please sign in to comment.