Skip to content

Commit

Permalink
add ordered db feature gate
Browse files Browse the repository at this point in the history
  • Loading branch information
lightsing committed Jul 31, 2024
1 parent 03b0729 commit eb754e9
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 16 deletions.
1 change: 1 addition & 0 deletions crates/revm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ asm-keccak = ["revm-interpreter/asm-keccak", "revm-precompile/asm-keccak"]
portable = ["revm-precompile/portable", "revm-interpreter/portable"]

test-utils = []
ordered-cache-db = []

optimism = ["revm-interpreter/optimism", "revm-precompile/optimism"]
# Optimism default handler enabled Optimism handler register by default in EvmBuilder.
Expand Down
41 changes: 25 additions & 16 deletions crates/revm/src/db/in_memory_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ use crate::Database;
use core::convert::Infallible;
use std::vec::Vec;

#[cfg(not(feature = "ordered-cache-db"))]
use crate::primitives::hash_map::Entry as DbMapEntry;
#[cfg(not(feature = "ordered-cache-db"))]
use crate::primitives::HashMap as DbMap;
#[cfg(feature = "ordered-cache-db")]
use std::collections::btree_map::Entry as DbMapEntry;
#[cfg(feature = "ordered-cache-db")]
use std::collections::BTreeMap as DbMap;

#[cfg(feature = "scroll")]
use crate::primitives::POSEIDON_EMPTY;

Expand All @@ -25,13 +34,13 @@ pub type InMemoryDB = CacheDB<EmptyDB>;
pub struct CacheDB<ExtDB> {
/// Account info where None means it is not existing. Not existing state is needed for Pre TANGERINE forks.
/// `code` is always `None`, and bytecode can be found in `contracts`.
pub accounts: HashMap<Address, DbAccount>,
pub accounts: DbMap<Address, DbAccount>,
/// Tracks all contracts by their code hash.
pub contracts: HashMap<B256, Bytecode>,
pub contracts: DbMap<B256, Bytecode>,
/// All logs that were committed via [DatabaseCommit::commit].
pub logs: Vec<Log>,
/// All cached block hashes from the [DatabaseRef].
pub block_hashes: HashMap<U256, B256>,
pub block_hashes: DbMap<U256, B256>,
/// The underlying database ([DatabaseRef]) that is used to load data.
///
/// Note: this is read-only, data is never written to this database.
Expand All @@ -46,7 +55,7 @@ impl<ExtDB: Default> Default for CacheDB<ExtDB> {

impl<ExtDB> CacheDB<ExtDB> {
pub fn new(db: ExtDB) -> Self {
let mut contracts = HashMap::new();
let mut contracts = DbMap::new();
cfg_if::cfg_if! {
if #[cfg(not(feature = "scroll"))] {
contracts.insert(KECCAK_EMPTY, Bytecode::default());
Expand All @@ -56,10 +65,10 @@ impl<ExtDB> CacheDB<ExtDB> {
}
contracts.insert(B256::ZERO, Bytecode::default());
Self {
accounts: HashMap::new(),
accounts: DbMap::new(),
contracts,
logs: Vec::default(),
block_hashes: HashMap::new(),
block_hashes: DbMap::new(),
db,
}
}
Expand Down Expand Up @@ -111,8 +120,8 @@ impl<ExtDB: DatabaseRef> CacheDB<ExtDB> {
pub fn load_account(&mut self, address: Address) -> Result<&mut DbAccount, ExtDB::Error> {
let db = &self.db;
match self.accounts.entry(address) {
Entry::Occupied(entry) => Ok(entry.into_mut()),
Entry::Vacant(entry) => Ok(entry.insert(
DbMapEntry::Occupied(entry) => Ok(entry.into_mut()),
DbMapEntry::Vacant(entry) => Ok(entry.insert(
db.basic_ref(address)?
.map(|info| DbAccount {
info,
Expand Down Expand Up @@ -191,8 +200,8 @@ impl<ExtDB: DatabaseRef> Database for CacheDB<ExtDB> {

fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
let basic = match self.accounts.entry(address) {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(
DbMapEntry::Occupied(entry) => entry.into_mut(),
DbMapEntry::Vacant(entry) => entry.insert(
self.db
.basic_ref(address)?
.map(|info| DbAccount {
Expand All @@ -207,8 +216,8 @@ impl<ExtDB: DatabaseRef> Database for CacheDB<ExtDB> {

fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> {
match self.contracts.entry(code_hash) {
Entry::Occupied(entry) => Ok(entry.get().clone()),
Entry::Vacant(entry) => {
DbMapEntry::Occupied(entry) => Ok(entry.get().clone()),
DbMapEntry::Vacant(entry) => {
// if you return code bytes when basic fn is called this function is not needed.
Ok(entry.insert(self.db.code_by_hash_ref(code_hash)?).clone())
}
Expand All @@ -220,7 +229,7 @@ impl<ExtDB: DatabaseRef> Database for CacheDB<ExtDB> {
/// It is assumed that account is already loaded.
fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> {
match self.accounts.entry(address) {
Entry::Occupied(mut acc_entry) => {
DbMapEntry::Occupied(mut acc_entry) => {
let acc_entry = acc_entry.get_mut();
match acc_entry.storage.entry(index) {
Entry::Occupied(entry) => Ok(*entry.get()),
Expand All @@ -238,7 +247,7 @@ impl<ExtDB: DatabaseRef> Database for CacheDB<ExtDB> {
}
}
}
Entry::Vacant(acc_entry) => {
DbMapEntry::Vacant(acc_entry) => {
// acc needs to be loaded for us to access slots.
let info = self.db.basic_ref(address)?;
let (account, value) = if info.is_some() {
Expand All @@ -257,8 +266,8 @@ impl<ExtDB: DatabaseRef> Database for CacheDB<ExtDB> {

fn block_hash(&mut self, number: u64) -> Result<B256, Self::Error> {
match self.block_hashes.entry(U256::from(number)) {
Entry::Occupied(entry) => Ok(*entry.get()),
Entry::Vacant(entry) => {
DbMapEntry::Occupied(entry) => Ok(*entry.get()),
DbMapEntry::Vacant(entry) => {
let hash = self.db.block_hash_ref(number)?;
entry.insert(hash);
Ok(hash)
Expand Down

0 comments on commit eb754e9

Please sign in to comment.