From 7ea0a1c525f6e7e8c1d59096b52c9befe3239ff5 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Thu, 26 Sep 2024 13:18:14 +0530 Subject: [PATCH 1/7] feat: BlockchainDbMeta builder --- src/cache.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index ad1217e..8c445d9 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -1,8 +1,12 @@ //! Cache related abstraction use alloy_primitives::{Address, B256, U256}; +use alloy_provider::network::{HeaderResponse, TransactionResponse}; use parking_lot::RwLock; use revm::{ - primitives::{Account, AccountInfo, AccountStatus, HashMap as Map, KECCAK_EMPTY}, + primitives::{ + Account, AccountInfo, AccountStatus, BlobExcessGasAndPrice, BlockEnv, CfgEnv, + HashMap as Map, KECCAK_EMPTY, + }, DatabaseCommit, }; use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; @@ -115,10 +119,10 @@ impl BlockchainDb { } /// relevant identifying markers in the context of [BlockchainDb] -#[derive(Clone, Debug, Eq, Serialize)] +#[derive(Clone, Debug, Eq, Serialize, Default)] pub struct BlockchainDbMeta { - pub cfg_env: revm::primitives::CfgEnv, - pub block_env: revm::primitives::BlockEnv, + pub cfg_env: CfgEnv, + pub block_env: BlockEnv, /// all the hosts used to connect to pub hosts: BTreeSet, } @@ -133,6 +137,52 @@ impl BlockchainDbMeta { Self { cfg_env: env.cfg.clone(), block_env: env.block, hosts: BTreeSet::from([host]) } } + + /// Sets the chain_id in the [CfgEnv] of this instance. + /// + /// Remaining fields of [CfgEnv] are left unchanged. + pub const fn with_chain_id(mut self, chain_id: u64) -> Self { + self.cfg_env.chain_id = chain_id; + self + } + + /// Sets the [BlockEnv] of this instance using the provided [alloy_rpc_types::Block] + pub fn with_block(mut self, block: alloy_rpc_types::Block) -> Self { + self.block_env = BlockEnv { + number: U256::from(block.header.number()), + coinbase: block.header.coinbase(), + timestamp: U256::from(block.header.timestamp()), + difficulty: U256::from(block.header.difficulty()), + basefee: block.header.base_fee_per_gas().map(U256::from).unwrap_or_default(), + gas_limit: U256::from(block.header.gas_limit()), + prevrandao: block.header.mix_hash(), + blob_excess_gas_and_price: Some(BlobExcessGasAndPrice::new( + block.header.excess_blob_gas.map(|gas| gas as u64).unwrap_or_default(), + )), + }; + + self + } + + /// Infers the host from the provided url and adds it to the set of hosts + pub fn with_url(mut self, url: String) -> Self { + let host = Url::parse(&url) + .ok() + .and_then(|url| url.host().map(|host| host.to_string())) + .unwrap_or(url); + self.hosts.insert(host); + self + } + + /// Sets [CfgEnv] of this instance + pub fn set_cfg_env(mut self, cfg_env: revm::primitives::CfgEnv) { + self.cfg_env = cfg_env; + } + + /// Sets the [BlockEnv] of this instance + pub fn set_block_env(mut self, block_env: revm::primitives::BlockEnv) { + self.block_env = block_env; + } } // ignore hosts to not invalidate the cache when different endpoints are used, as it's commonly the From 895a9b229065649bc504004aaec93bfc5100fbef Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Thu, 26 Sep 2024 14:11:48 +0530 Subject: [PATCH 2/7] types nits Co-authored-by: Matthias Seitz --- src/cache.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 8c445d9..e43ee36 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -147,7 +147,7 @@ impl BlockchainDbMeta { } /// Sets the [BlockEnv] of this instance using the provided [alloy_rpc_types::Block] - pub fn with_block(mut self, block: alloy_rpc_types::Block) -> Self { + pub fn with_block(mut self, block: &alloy_rpc_types::Block) -> Self { self.block_env = BlockEnv { number: U256::from(block.header.number()), coinbase: block.header.coinbase(), @@ -165,7 +165,7 @@ impl BlockchainDbMeta { } /// Infers the host from the provided url and adds it to the set of hosts - pub fn with_url(mut self, url: String) -> Self { + pub fn with_url(mut self, url: &str) -> Self { let host = Url::parse(&url) .ok() .and_then(|url| url.host().map(|host| host.to_string())) From 4c205d3f28577ddfff2eb679dd80993ff6ec3a51 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Thu, 26 Sep 2024 14:15:03 +0530 Subject: [PATCH 3/7] nit --- src/cache.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cache.rs b/src/cache.rs index e43ee36..47be7e8 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -169,7 +169,7 @@ impl BlockchainDbMeta { let host = Url::parse(&url) .ok() .and_then(|url| url.host().map(|host| host.to_string())) - .unwrap_or(url); + .unwrap_or(url.to_string()); self.hosts.insert(host); self } From 2b468ad3141a0ffcfa91f8b0e49981dc96b3e735 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Thu, 26 Sep 2024 14:29:43 +0530 Subject: [PATCH 4/7] clippy --- src/cache.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cache.rs b/src/cache.rs index 47be7e8..7b926d8 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -166,7 +166,7 @@ impl BlockchainDbMeta { /// Infers the host from the provided url and adds it to the set of hosts pub fn with_url(mut self, url: &str) -> Self { - let host = Url::parse(&url) + let host = Url::parse(url) .ok() .and_then(|url| url.host().map(|host| host.to_string())) .unwrap_or(url.to_string()); From 295930618ddda6bb8ba11ce64f315883cc7699d6 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Thu, 26 Sep 2024 19:32:53 +0530 Subject: [PATCH 5/7] instantiate `Map`'s using default --- src/backend.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/backend.rs b/src/backend.rs index 457e6cb..84db30d 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -935,7 +935,7 @@ mod tests { code: None, code_hash: KECCAK_EMPTY, }; - let mut account_data: AddressData = Map::new(); + let mut account_data: AddressData = Map::default(); account_data.insert(address, new_acc.clone()); backend.insert_or_update_address(account_data); @@ -999,8 +999,8 @@ mod tests { // some rng contract from etherscan let address: Address = "63091244180ae240c87d1f528f5f269134cb07b3".parse().unwrap(); - let mut storage_data: StorageData = Map::new(); - let mut storage_info: StorageInfo = Map::new(); + let mut storage_data: StorageData = Map::default(); + let mut storage_info: StorageInfo = Map::default(); storage_info.insert(U256::from(20), U256::from(10)); storage_info.insert(U256::from(30), U256::from(15)); storage_info.insert(U256::from(40), U256::from(20)); @@ -1062,7 +1062,7 @@ mod tests { // some rng contract from etherscan // let address: Address = "63091244180ae240c87d1f528f5f269134cb07b3".parse().unwrap(); - let mut block_hash_data: BlockHashData = Map::new(); + let mut block_hash_data: BlockHashData = Map::default(); block_hash_data.insert(U256::from(1), B256::from(U256::from(1))); block_hash_data.insert(U256::from(2), B256::from(U256::from(2))); block_hash_data.insert(U256::from(3), B256::from(U256::from(3))); @@ -1123,8 +1123,8 @@ mod tests { // some rng contract from etherscan let address: Address = "63091244180ae240c87d1f528f5f269134cb07b3".parse().unwrap(); - let mut storage_data: StorageData = Map::new(); - let mut storage_info: StorageInfo = Map::new(); + let mut storage_data: StorageData = Map::default(); + let mut storage_info: StorageInfo = Map::default(); storage_info.insert(U256::from(1), U256::from(10)); storage_info.insert(U256::from(2), U256::from(15)); storage_info.insert(U256::from(3), U256::from(20)); @@ -1143,7 +1143,7 @@ mod tests { // nullify the code new_acc.code = Some(Bytecode::new_raw(([10, 20, 30, 40]).into())); - let mut account_data: AddressData = Map::new(); + let mut account_data: AddressData = Map::default(); account_data.insert(address, new_acc.clone()); backend.insert_or_update_address(account_data); @@ -1194,8 +1194,8 @@ mod tests { let json_db = BlockchainDb::new(meta, Some(cache_path)); - let mut storage_data: StorageData = Map::new(); - let mut storage_info: StorageInfo = Map::new(); + let mut storage_data: StorageData = Map::default(); + let mut storage_info: StorageInfo = Map::default(); storage_info.insert(U256::from(1), U256::from(10)); storage_info.insert(U256::from(2), U256::from(15)); storage_info.insert(U256::from(3), U256::from(20)); From 0c3dc19dd293fed72c4b507c838e8bec1f567a4a Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Thu, 26 Sep 2024 19:42:30 +0530 Subject: [PATCH 6/7] use AddressHashMap --- src/backend.rs | 5 +++-- src/cache.rs | 16 ++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/backend.rs b/src/backend.rs index 84db30d..fc24743 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -68,8 +68,9 @@ type FullBlockSender = OneshotSender>>>>; type TransactionSender = OneshotSender>>; -type AddressData = Map; -type StorageData = Map; +use alloy_primitives::map::AddressHashMap; +type AddressData = AddressHashMap; +type StorageData = AddressHashMap; type BlockHashData = Map; /// Request variants that are executed by the provider diff --git a/src/cache.rs b/src/cache.rs index 7b926d8..4139bec 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -4,8 +4,8 @@ use alloy_provider::network::{HeaderResponse, TransactionResponse}; use parking_lot::RwLock; use revm::{ primitives::{ - Account, AccountInfo, AccountStatus, BlobExcessGasAndPrice, BlockEnv, CfgEnv, - HashMap as Map, KECCAK_EMPTY, + map::AddressHashMap, Account, AccountInfo, AccountStatus, BlobExcessGasAndPrice, BlockEnv, + CfgEnv, HashMap as Map, KECCAK_EMPTY, }, DatabaseCommit, }; @@ -88,12 +88,12 @@ impl BlockchainDb { } /// Returns the map that holds the account related info - pub fn accounts(&self) -> &RwLock> { + pub fn accounts(&self) -> &RwLock> { &self.db.accounts } /// Returns the map that holds the storage related info - pub fn storage(&self) -> &RwLock> { + pub fn storage(&self) -> &RwLock> { &self.db.storage } @@ -298,9 +298,9 @@ impl<'de> Deserialize<'de> for BlockchainDbMeta { #[derive(Debug, Default)] pub struct MemDb { /// Account related data - pub accounts: RwLock>, + pub accounts: RwLock>, /// Storage related data - pub storage: RwLock>, + pub storage: RwLock>, /// All retrieved block hashes pub block_hashes: RwLock>, } @@ -496,8 +496,8 @@ impl<'de> Deserialize<'de> for JsonBlockCacheData { #[derive(Deserialize)] struct Data { meta: BlockchainDbMeta, - accounts: HashMap, - storage: HashMap>, + accounts: AddressHashMap, + storage: AddressHashMap>, block_hashes: HashMap, } From 7ac8ca465bcf39ec1a976ec45099208f5044b3aa Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Thu, 26 Sep 2024 19:47:05 +0530 Subject: [PATCH 7/7] use alloy-prim::HashMap --- src/cache.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index 4139bec..94b3d3f 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -4,14 +4,15 @@ use alloy_provider::network::{HeaderResponse, TransactionResponse}; use parking_lot::RwLock; use revm::{ primitives::{ - map::AddressHashMap, Account, AccountInfo, AccountStatus, BlobExcessGasAndPrice, BlockEnv, - CfgEnv, HashMap as Map, KECCAK_EMPTY, + map::{AddressHashMap, HashMap}, + Account, AccountInfo, AccountStatus, BlobExcessGasAndPrice, BlockEnv, CfgEnv, + HashMap as Map, KECCAK_EMPTY, }, DatabaseCommit, }; use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; use std::{ - collections::{BTreeSet, HashMap}, + collections::BTreeSet, fs, io::{BufWriter, Write}, path::{Path, PathBuf},