diff --git a/Cargo.lock b/Cargo.lock
index 1ef97790c..59bcee4bf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4851,6 +4851,24 @@ dependencies = [
"reth-interfaces",
"reth-primitives",
"reth-provider",
+ "reth-revm-primitives",
+ "revm",
+]
+
+[[package]]
+name = "reth-revm-inspectors"
+version = "0.1.0"
+dependencies = [
+ "hashbrown 0.13.2",
+ "reth-primitives",
+ "revm",
+]
+
+[[package]]
+name = "reth-revm-primitives"
+version = "0.1.0"
+dependencies = [
+ "reth-primitives",
"revm",
]
diff --git a/Cargo.toml b/Cargo.toml
index d505dc105..32c3f42c1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,6 +17,8 @@ members = [
"crates/net/downloaders",
"crates/primitives",
"crates/revm",
+ "crates/revm/revm-primitives",
+ "crates/revm/revm-inspectors",
"crates/rlp",
"crates/rlp/rlp-derive",
"crates/rpc/ipc",
diff --git a/crates/revm/Cargo.toml b/crates/revm/Cargo.toml
index 1f740e83a..de419c346 100644
--- a/crates/revm/Cargo.toml
+++ b/crates/revm/Cargo.toml
@@ -11,5 +11,6 @@ description = "reth specific revm utilities"
reth-primitives = { path = "../primitives" }
reth-interfaces = { path = "../interfaces" }
reth-provider = { path = "../storage/provider" }
+reth-revm-primitives = { path = "./revm-primitives" }
revm = { version = "3.0.0"}
\ No newline at end of file
diff --git a/crates/revm/revm-inspectors/Cargo.toml b/crates/revm/revm-inspectors/Cargo.toml
new file mode 100644
index 000000000..5f21a007b
--- /dev/null
+++ b/crates/revm/revm-inspectors/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "reth-revm-inspectors"
+version = "0.1.0"
+edition = "2021"
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/paradigmxyz/reth"
+description = "revm inspector implementations used by reth"
+
+[dependencies]
+# reth
+reth-primitives = { path = "../../primitives" }
+
+revm = { version = "3.0.0" }
+# remove from reth and reexport from revm
+hashbrown = "0.13"
\ No newline at end of file
diff --git a/crates/revm/revm-inspectors/src/access_list.rs b/crates/revm/revm-inspectors/src/access_list.rs
new file mode 100644
index 000000000..5aa7ef32e
--- /dev/null
+++ b/crates/revm/revm-inspectors/src/access_list.rs
@@ -0,0 +1,108 @@
+use hashbrown::{HashMap, HashSet};
+use reth_primitives::{AccessList, AccessListItem, Address, H256};
+use revm::{
+ interpreter::{opcode, InstructionResult, Interpreter},
+ Database, EVMData, Inspector,
+};
+
+/// An [Inspector] that collects touched accounts and storage slots.
+///
+/// This can be used to construct an [AccessList] for a transaction via `eth_createAccessList`
+#[derive(Default, Debug)]
+pub struct AccessListInspector {
+ /// All addresses that should be excluded from the final accesslist
+ excluded: HashSet
,
+ /// All addresses and touched slots
+ access_list: HashMap>,
+}
+
+impl AccessListInspector {
+ /// Creates a new inspector instance
+ ///
+ /// The `access_list` is the provided access list from the call request
+ pub fn new(
+ access_list: AccessList,
+ from: Address,
+ to: Address,
+ precompiles: Vec,
+ ) -> Self {
+ AccessListInspector {
+ excluded: vec![from, to].iter().chain(precompiles.iter()).copied().collect(),
+ access_list: access_list
+ .0
+ .iter()
+ .map(|v| (v.address, v.storage_keys.iter().copied().collect()))
+ .collect(),
+ }
+ }
+
+ /// Returns list of addresses and storage keys used by the transaction. It gives you the list of
+ /// addresses and storage keys that were touched during execution.
+ pub fn into_access_list(self) -> AccessList {
+ let items = self.access_list.into_iter().map(|(address, slots)| AccessListItem {
+ address,
+ storage_keys: slots.into_iter().collect(),
+ });
+ AccessList(items.collect())
+ }
+
+ /// Returns list of addresses and storage keys used by the transaction. It gives you the list of
+ /// addresses and storage keys that were touched during execution.
+ pub fn access_list(&self) -> AccessList {
+ let items = self.access_list.iter().map(|(address, slots)| AccessListItem {
+ address: *address,
+ storage_keys: slots.iter().copied().collect(),
+ });
+ AccessList(items.collect())
+ }
+}
+
+impl Inspector for AccessListInspector
+where
+ DB: Database,
+{
+ fn step(
+ &mut self,
+ interpreter: &mut Interpreter,
+ _data: &mut EVMData<'_, DB>,
+ _is_static: bool,
+ ) -> InstructionResult {
+ let pc = interpreter.program_counter();
+ let op = interpreter.contract.bytecode.bytecode()[pc];
+
+ match op {
+ opcode::SLOAD | opcode::SSTORE => {
+ if let Ok(slot) = interpreter.stack().peek(0) {
+ let cur_contract = interpreter.contract.address;
+ self.access_list
+ .entry(cur_contract)
+ .or_default()
+ .insert(H256::from(slot.to_be_bytes()));
+ }
+ }
+ opcode::EXTCODECOPY |
+ opcode::EXTCODEHASH |
+ opcode::EXTCODESIZE |
+ opcode::BALANCE |
+ opcode::SELFDESTRUCT => {
+ if let Ok(slot) = interpreter.stack().peek(0) {
+ let addr: Address = H256::from(slot.to_be_bytes()).into();
+ if !self.excluded.contains(&addr) {
+ self.access_list.entry(addr).or_default();
+ }
+ }
+ }
+ opcode::DELEGATECALL | opcode::CALL | opcode::STATICCALL | opcode::CALLCODE => {
+ if let Ok(slot) = interpreter.stack().peek(1) {
+ let addr: Address = H256::from(slot.to_be_bytes()).into();
+ if !self.excluded.contains(&addr) {
+ self.access_list.entry(addr).or_default();
+ }
+ }
+ }
+ _ => (),
+ }
+
+ InstructionResult::Continue
+ }
+}
diff --git a/crates/revm/revm-inspectors/src/lib.rs b/crates/revm/revm-inspectors/src/lib.rs
new file mode 100644
index 000000000..cec3a9d09
--- /dev/null
+++ b/crates/revm/revm-inspectors/src/lib.rs
@@ -0,0 +1,11 @@
+#![warn(missing_docs, unreachable_pub, unused_crate_dependencies)]
+#![deny(unused_must_use, rust_2018_idioms)]
+#![doc(test(
+ no_crate_inject,
+ attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
+))]
+
+//! revm [Inspector](revm::Inspector) implementations
+
+/// An inspector implementation for an EIP2930 Accesslist
+pub mod access_list;
diff --git a/crates/revm/revm-primitives/Cargo.toml b/crates/revm/revm-primitives/Cargo.toml
new file mode 100644
index 000000000..57ccc160e
--- /dev/null
+++ b/crates/revm/revm-primitives/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "reth-revm-primitives"
+version = "0.1.0"
+edition = "2021"
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/paradigmxyz/reth"
+description = "core reth specific revm utilities"
+
+[dependencies]
+# reth
+reth-primitives = { path = "../../primitives" }
+
+revm = { version = "3.0.0" }
\ No newline at end of file
diff --git a/crates/revm/src/compat.rs b/crates/revm/revm-primitives/src/compat.rs
similarity index 100%
rename from crates/revm/src/compat.rs
rename to crates/revm/revm-primitives/src/compat.rs
diff --git a/crates/revm/src/config.rs b/crates/revm/revm-primitives/src/config.rs
similarity index 100%
rename from crates/revm/src/config.rs
rename to crates/revm/revm-primitives/src/config.rs
diff --git a/crates/revm/src/env.rs b/crates/revm/revm-primitives/src/env.rs
similarity index 100%
rename from crates/revm/src/env.rs
rename to crates/revm/revm-primitives/src/env.rs
diff --git a/crates/revm/revm-primitives/src/lib.rs b/crates/revm/revm-primitives/src/lib.rs
new file mode 100644
index 000000000..a989c0b65
--- /dev/null
+++ b/crates/revm/revm-primitives/src/lib.rs
@@ -0,0 +1,17 @@
+#![warn(missing_docs, unreachable_pub, unused_crate_dependencies)]
+#![deny(unused_must_use, rust_2018_idioms)]
+#![doc(test(
+ no_crate_inject,
+ attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
+))]
+
+//! revm utils and implementations specific to reth.
+
+pub mod config;
+
+/// Helpers for configuring revm [Env](revm::primitives::Env)
+pub mod env;
+
+/// Helpers for type compatibility between reth and revm types
+mod compat;
+pub use compat::*;
diff --git a/crates/revm/src/lib.rs b/crates/revm/src/lib.rs
index 642c2890e..21cc3790a 100644
--- a/crates/revm/src/lib.rs
+++ b/crates/revm/src/lib.rs
@@ -7,14 +7,8 @@
//! revm utils and implementations specific to reth.
-pub mod config;
-
/// Contains glue code for integrating reth database into revm's [Database](revm::Database).
pub mod database;
-/// Helpers for configuring revm [Env](revm::primitives::Env)
-pub mod env;
-
-/// Helpers for type compatibility between reth and revm types
-mod compat;
-pub use compat::*;
+/// reexport for convenience
+pub use reth_revm_primitives::*;