Skip to content

Commit

Permalink
test mapping 2
Browse files Browse the repository at this point in the history
  • Loading branch information
forcodedancing committed Oct 13, 2024
1 parent 10b4a02 commit 50ddf6a
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 39 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.

1 change: 1 addition & 0 deletions crates/chain-state/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ derive_more.workspace = true
metrics.workspace = true
parking_lot.workspace = true
pin-project.workspace = true
schnellru.workspace = true

# optional deps for test-utils
alloy-signer = { workspace = true, optional = true }
Expand Down
78 changes: 39 additions & 39 deletions crates/chain-state/src/cache/plain_state.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use lazy_static::lazy_static;
use quick_cache::sync::Cache;
use reth_primitives::{Account, Address, Bytecode, StorageKey, StorageValue, B256, U256};
use reth_revm::db::{BundleState, OriginalValuesKnown};
use schnellru::{ByLength, LruMap};
use std::{
collections::{HashMap, HashSet},
sync::Mutex,
sync::{Arc, Mutex, RwLock},
};

use reth_primitives::{Account, Address, Bytecode, StorageKey, StorageValue, B256, U256};
use reth_revm::db::{BundleState, OriginalValuesKnown};
use tracing::info;

// Cache sizes
Expand All @@ -21,15 +21,11 @@ lazy_static! {
/// Account cache
pub(crate) static ref PLAIN_ACCOUNTS: Cache<Address, Account> = Cache::new(ACCOUNT_CACHE_SIZE);

/// Storage cache
pub(crate) static ref PLAIN_STORAGES: Cache<AddressStorageKey, StorageValue> = Cache::new(STORAGE_CACHE_SIZE);

/// Contract cache
/// The size of contract is large and the hot contracts should be limited.
pub(crate) static ref CONTRACT_CODES: Cache<B256, Bytecode> = Cache::new(CONTRACT_CACHE_SIZE);

/// Mapping for deleting storages
static ref PLAIN_STORAGES_MAPPING: Mutex<HashMap<Address, HashSet<B256>>> = Mutex::new(HashMap::new());
pub(crate) static ref STORAGES: Mutex<LruMap<Address, LruMap<B256, U256>>> = Mutex::new(LruMap::new(ByLength::new(ACCOUNT_CACHE_SIZE as u32)));
}

pub(crate) fn insert_account(k: Address, v: Account) {
Expand All @@ -38,46 +34,42 @@ pub(crate) fn insert_account(k: Address, v: Account) {

/// Insert storage into the cache
pub(crate) fn insert_storage(k: AddressStorageKey, v: U256) {
{
let mut map = PLAIN_STORAGES_MAPPING.lock().unwrap();
if let Some(set) = map.get_mut(&k.0) {
set.insert(k.1);
} else {
map.insert(k.0, HashSet::from([k.1]));
let mut outer = STORAGES.lock().unwrap();
match outer.get(&k.0) {
Some(inner) => {
inner.insert(k.1, v);
}
None => {
let mut inner = LruMap::new(ByLength::new(100));
inner.insert(k.1, v);
outer.insert(k.0, inner);
}
}

PLAIN_STORAGES.insert(k, v);
}

pub(crate) fn remove_storages(address: Address) {
let mut map = PLAIN_STORAGES_MAPPING.lock().unwrap();
if let Some(set) = map.remove(&address) {
for s in &set {
let storage_key = (address, *s);
PLAIN_STORAGES.remove(&storage_key);
}
}
let mut outer = STORAGES.lock().unwrap();
outer.remove(&address);
}
pub(crate) fn insert_storages(address: Address, storages: Vec<(U256, U256)>) {
if storages.is_empty() {
return;
}

{
let mut map = PLAIN_STORAGES_MAPPING.lock().unwrap();
if let Some(set) = map.get_mut(&address) {
set.extend(storages.iter().map(|(k, _)| StorageKey::from(*k)));
} else {
map.insert(
address,
HashSet::from_iter(storages.iter().map(|(k, _)| StorageKey::from(*k))),
);
let mut outer = STORAGES.lock().unwrap();
match outer.get(&address) {
Some(inner) => {
for (k, v) in storages {
inner.insert(StorageKey::from(k), v);
}
}
None => {
let mut inner = LruMap::new(ByLength::new(100));
for (k, v) in storages {
inner.insert(StorageKey::from(k), v);
}
outer.insert(address, inner);
}
}

for (k, v) in storages {
PLAIN_STORAGES.insert((address, StorageKey::from(k)), v);
}
}

Expand All @@ -88,7 +80,14 @@ pub(crate) fn get_account(k: &Address) -> Option<Account> {

// Get storage from cache
pub(crate) fn get_storage(k: &AddressStorageKey) -> Option<StorageValue> {
PLAIN_STORAGES.get(k)
let mut outer = STORAGES.lock().unwrap();
match outer.get(&k.0) {
Some(inner) => match inner.get(&k.1) {
Some(value) => Some(*value),
None => None,
},
None => None,
}
}

// Get code from cache
Expand Down Expand Up @@ -138,5 +137,6 @@ pub(crate) fn write_plain_state(bundle: BundleState) {
/// Clear cached accounts and storages.
pub(crate) fn clear_plain_state() {
PLAIN_ACCOUNTS.clear();
PLAIN_STORAGES.clear();
let mut outer = STORAGES.lock().unwrap();
outer.clear();
}
144 changes: 144 additions & 0 deletions crates/chain-state/src/cache/plain_state.rsold
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
use lazy_static::lazy_static;
use quick_cache::sync::Cache;
use reth_primitives::{Account, Address, Bytecode, StorageKey, StorageValue, B256, U256};
use reth_revm::db::{BundleState, OriginalValuesKnown};
use schnellru::{ByLength, LruMap};
use std::{
collections::{HashMap, HashSet},
sync::{Arc, Mutex, RwLock},
};
use tracing::info;

// Cache sizes
const ACCOUNT_CACHE_SIZE: usize = 1000000;
const STORAGE_CACHE_SIZE: usize = ACCOUNT_CACHE_SIZE * 10;
const CONTRACT_CACHE_SIZE: usize = ACCOUNT_CACHE_SIZE / 100;

// Type alias for address and storage key tuple
type AddressStorageKey = (Address, StorageKey);

lazy_static! {
/// Account cache
pub(crate) static ref PLAIN_ACCOUNTS: Cache<Address, Account> = Cache::new(ACCOUNT_CACHE_SIZE);

/// Storage cache
pub(crate) static ref PLAIN_STORAGES: Cache<AddressStorageKey, StorageValue> = Cache::new(STORAGE_CACHE_SIZE);

/// Contract cache
/// The size of contract is large and the hot contracts should be limited.
pub(crate) static ref CONTRACT_CODES: Cache<B256, Bytecode> = Cache::new(CONTRACT_CACHE_SIZE);

/// Mapping for deleting storages
static ref PLAIN_STORAGES_MAPPING: Mutex<HashMap<Address, HashSet<B256>>> = Mutex::new(HashMap::new());

pub(crate) static ref STORAGES: Arc<RwLock<LruMap<Address,HashMap<B256, U256>>>> = Arc::new(RwLock::new(LruMap::new(ByLength::new(ACCOUNT_CACHE_SIZE as u32))));
}

pub(crate) fn insert_account(k: Address, v: Account) {
PLAIN_ACCOUNTS.insert(k, v);
}

/// Insert storage into the cache
pub(crate) fn insert_storage(k: AddressStorageKey, v: U256) {
{
let mut map = PLAIN_STORAGES_MAPPING.lock().unwrap();
if let Some(set) = map.get_mut(&k.0) {
set.insert(k.1);
} else {
map.insert(k.0, HashSet::from([k.1]));
}
}

PLAIN_STORAGES.insert(k, v);
}

pub(crate) fn remove_storages(address: Address) {
let mut map = PLAIN_STORAGES_MAPPING.lock().unwrap();
if let Some(set) = map.remove(&address) {
for s in &set {
let storage_key = (address, *s);
PLAIN_STORAGES.remove(&storage_key);
}
}
}
pub(crate) fn insert_storages(address: Address, storages: Vec<(U256, U256)>) {
if storages.is_empty() {
return;
}

{
let mut map = PLAIN_STORAGES_MAPPING.lock().unwrap();
if let Some(set) = map.get_mut(&address) {
set.extend(storages.iter().map(|(k, _)| StorageKey::from(*k)));
} else {
map.insert(
address,
HashSet::from_iter(storages.iter().map(|(k, _)| StorageKey::from(*k))),
);
}
}

for (k, v) in storages {
PLAIN_STORAGES.insert((address, StorageKey::from(k)), v);
}
}

// Get account from cache
pub(crate) fn get_account(k: &Address) -> Option<Account> {
PLAIN_ACCOUNTS.get(k)
}

// Get storage from cache
pub(crate) fn get_storage(k: &AddressStorageKey) -> Option<StorageValue> {
PLAIN_STORAGES.get(k)
}

// Get code from cache
pub(crate) fn get_code(k: &B256) -> Option<Bytecode> {
CONTRACT_CODES.get(k)
}

// Insert code into cache
pub(crate) fn insert_code(k: B256, v: Bytecode) {
CONTRACT_CODES.insert(k, v);
}

/// Write committed state to cache.
pub(crate) fn write_plain_state(bundle: BundleState) {
let change_set = bundle.into_plain_state(OriginalValuesKnown::Yes);

// Update account cache
for (address, account_info) in &change_set.accounts {
match account_info {
None => {
PLAIN_ACCOUNTS.remove(address);
}
Some(acc) => {
PLAIN_ACCOUNTS.insert(
*address,
Account {
nonce: acc.nonce,
balance: acc.balance,
bytecode_hash: Some(acc.code_hash),
},
);
}
}
}

// Update storage cache
for storage in &change_set.storage {
if storage.wipe_storage {
info!(target: "blockchain_tree", "wipe_storage is true.");
remove_storages(storage.address);
}

insert_storages(storage.address, storage.storage.clone());
}
}

/// Clear cached accounts and storages.
pub(crate) fn clear_plain_state() {
PLAIN_ACCOUNTS.clear();
PLAIN_STORAGES.clear();
}

0 comments on commit 50ddf6a

Please sign in to comment.