diff --git a/Cargo.lock b/Cargo.lock
index a8a72552de..37496615df 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1460,6 +1460,7 @@ name = "example-database-components"
version = "0.0.0"
dependencies = [
"auto_impl",
+ "derive_more 1.0.0",
"revm",
]
diff --git a/crates/context/interface/src/journaled_state.rs b/crates/context/interface/src/journaled_state.rs
index 7ec3f4840a..c4eee4717d 100644
--- a/crates/context/interface/src/journaled_state.rs
+++ b/crates/context/interface/src/journaled_state.rs
@@ -1,6 +1,6 @@
use core::ops::{Deref, DerefMut};
use database_interface::{Database, DatabaseGetter};
-use primitives::{Address, Log, B256, U256};
+use primitives::{Address, HashSet, Log, B256, U256};
use specification::hardfork::SpecId;
use state::{Account, Bytecode};
use std::boxed::Box;
@@ -17,10 +17,10 @@ pub trait Journal {
fn new(database: Self::Database) -> Self;
/// Returns the database.
- fn db(&self) -> &Self::Database;
+ fn db_ref(&self) -> &Self::Database;
/// Returns the mutable database.
- fn db_mut(&mut self) -> &mut Self::Database;
+ fn db(&mut self) -> &mut Self::Database;
/// Returns the storage value from Journal state.
///
@@ -63,6 +63,10 @@ pub trait Journal {
fn warm_account(&mut self, address: Address);
+ fn warm_precompiles(&mut self, addresses: HashSet
);
+
+ fn precompile_addresses(&self) -> &HashSet;
+
fn set_spec_id(&mut self, spec_id: SpecId);
fn touch_account(&mut self, address: Address);
diff --git a/crates/context/interface/src/result.rs b/crates/context/interface/src/result.rs
index ea79bdfb78..dafd85ccc3 100644
--- a/crates/context/interface/src/result.rs
+++ b/crates/context/interface/src/result.rs
@@ -54,6 +54,15 @@ impl ExecutionResult {
matches!(self, Self::Success { .. })
}
+ /// Returns created address if execution is Create transaction
+ /// and Contract was created.
+ pub fn created_address(&self) -> Option {
+ match self {
+ Self::Success { output, .. } => output.address().cloned(),
+ _ => None,
+ }
+ }
+
/// Returns true if execution result is a Halt.
pub fn is_halt(&self) -> bool {
matches!(self, Self::Halt { .. })
@@ -175,9 +184,9 @@ impl FromStringError for EVMError {
}
}
-impl> From for EVMError {
+impl From for EVMError {
fn from(value: InvalidTransaction) -> Self {
- Self::Transaction(value.into())
+ Self::Transaction(value)
}
}
diff --git a/crates/context/src/context.rs b/crates/context/src/context.rs
index 21383a0713..8608c04aa5 100644
--- a/crates/context/src/context.rs
+++ b/crates/context/src/context.rs
@@ -313,7 +313,7 @@ where
where
F: FnOnce(&mut DB),
{
- f(self.journaled_state.db_mut());
+ f(self.journaled_state.db());
}
pub fn modify_journal(&mut self, f: F)
@@ -395,7 +395,7 @@ where
if diff <= BLOCK_HASH_HISTORY {
return self
.journaled_state
- .db_mut()
+ .db()
.block_hash(requested_number)
.map_err(|e| self.error = Err(e))
.ok();
@@ -508,7 +508,11 @@ where
type Database = DB;
fn db(&mut self) -> &mut Self::Database {
- self.journaled_state.db_mut()
+ self.journaled_state.db()
+ }
+
+ fn db_ref(&self) -> &Self::Database {
+ self.journaled_state.db_ref()
}
}
diff --git a/crates/context/src/journaled_state.rs b/crates/context/src/journaled_state.rs
index 7badf33c8c..9926f3a098 100644
--- a/crates/context/src/journaled_state.rs
+++ b/crates/context/src/journaled_state.rs
@@ -52,6 +52,8 @@ pub struct JournaledState {
/// Note that this not include newly loaded accounts, account and storage
/// is considered warm if it is found in the `State`.
pub warm_preloaded_addresses: HashSet,
+ /// Precompile addresses
+ pub precompiles: HashSet,
}
impl Journal for JournaledState {
@@ -63,11 +65,11 @@ impl Journal for JournaledState {
Self::new(SpecId::LATEST, database)
}
- fn db(&self) -> &Self::Database {
+ fn db_ref(&self) -> &Self::Database {
&self.database
}
- fn db_mut(&mut self) -> &mut Self::Database {
+ fn db(&mut self) -> &mut Self::Database {
&mut self.database
}
@@ -112,6 +114,17 @@ impl Journal for JournaledState {
self.warm_preloaded_addresses.insert(address);
}
+ fn warm_precompiles(&mut self, address: HashSet) {
+ self.precompiles = address;
+ self.warm_preloaded_addresses
+ .extend(self.precompiles.iter());
+ }
+
+ #[inline]
+ fn precompile_addresses(&self) -> &HashSet {
+ &self.precompiles
+ }
+
/// Returns call depth.
#[inline]
fn depth(&self) -> usize {
@@ -212,6 +225,7 @@ impl Journal for JournaledState {
spec: _,
database: _,
warm_preloaded_addresses: _,
+ precompiles: _,
} = self;
*transient_storage = TransientStorage::default();
@@ -243,6 +257,7 @@ impl JournaledState {
depth: 0,
spec,
warm_preloaded_addresses: HashSet::default(),
+ precompiles: HashSet::default(),
}
}
diff --git a/crates/database/interface/src/async_db.rs b/crates/database/interface/src/async_db.rs
index 2b99a6bff2..0b85216e71 100644
--- a/crates/database/interface/src/async_db.rs
+++ b/crates/database/interface/src/async_db.rs
@@ -1,11 +1,11 @@
use core::future::Future;
+use crate::{DBErrorMarker, Database, DatabaseRef};
+use core::error::Error;
use primitives::{Address, B256, U256};
use state::{AccountInfo, Bytecode};
use tokio::runtime::{Handle, Runtime};
-use crate::{DBErrorMarker, Database, DatabaseRef};
-
/// The async EVM database interface
///
/// Contains the same methods as [Database], but it returns [Future] type instead.
@@ -13,7 +13,7 @@ use crate::{DBErrorMarker, Database, DatabaseRef};
/// Use [WrapDatabaseAsync] to provide [Database] implementation for a type that only implements this trait.
pub trait DatabaseAsync {
/// The database error type
- type Error: Send + DBErrorMarker;
+ type Error: Send + DBErrorMarker + Error;
/// Gets basic account information.
fn basic_async(
@@ -48,7 +48,7 @@ pub trait DatabaseAsync {
/// Use [WrapDatabaseAsync] to provide [DatabaseRef] implementation for a type that only implements this trait.
pub trait DatabaseAsyncRef {
/// The database error type
- type Error: Send + DBErrorMarker;
+ type Error: Send + DBErrorMarker + Error;
/// Gets basic account information.
fn basic_async_ref(
diff --git a/crates/database/interface/src/empty_db.rs b/crates/database/interface/src/empty_db.rs
index ec373139bd..db810a7872 100644
--- a/crates/database/interface/src/empty_db.rs
+++ b/crates/database/interface/src/empty_db.rs
@@ -1,4 +1,5 @@
use crate::{DBErrorMarker, Database, DatabaseRef};
+use core::error::Error;
use core::{convert::Infallible, fmt, marker::PhantomData};
use primitives::{keccak256, Address, B256, U256};
use state::{AccountInfo, Bytecode};
@@ -52,7 +53,7 @@ impl EmptyDBTyped {
}
}
-impl Database for EmptyDBTyped {
+impl Database for EmptyDBTyped {
type Error = E;
#[inline]
@@ -76,7 +77,7 @@ impl Database for EmptyDBTyped {
}
}
-impl DatabaseRef for EmptyDBTyped {
+impl DatabaseRef for EmptyDBTyped {
type Error = E;
#[inline]
diff --git a/crates/database/interface/src/lib.rs b/crates/database/interface/src/lib.rs
index d1678b6be5..a8772af3d4 100644
--- a/crates/database/interface/src/lib.rs
+++ b/crates/database/interface/src/lib.rs
@@ -8,6 +8,7 @@ extern crate alloc as std;
use core::convert::Infallible;
use auto_impl::auto_impl;
+use core::error::Error;
use primitives::{Address, HashMap, B256, U256};
use state::{Account, AccountInfo, Bytecode};
use std::string::String;
@@ -35,7 +36,7 @@ impl DBErrorMarker for String {}
#[auto_impl(&mut, Box)]
pub trait Database {
/// The database error type.
- type Error: DBErrorMarker;
+ type Error: DBErrorMarker + Error;
//type Bytecode: BytecodeTrait;
/// Gets basic account information.
@@ -67,7 +68,7 @@ pub trait DatabaseCommit {
#[auto_impl(&, &mut, Box, Rc, Arc)]
pub trait DatabaseRef {
/// The database error type.
- type Error: DBErrorMarker;
+ type Error: DBErrorMarker + Error;
/// Gets basic account information.
fn basic_ref(&self, address: Address) -> Result