diff --git a/Cargo.toml b/Cargo.toml index a6d3152..a04a7db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,17 +25,19 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [dependencies] -alloy-primitives = { version = "1.0", features = ["map"] } -alloy-provider = { version = "1.0.3", default-features = false } -alloy-rpc-types = { version = "1.0.3", features = ["eth"] } -alloy-consensus = { version = "1.0.3", default-features = false } +alloy-chains = { version = "0.2", default-features = false, features = ["serde"] } +alloy-consensus = { version = "1.0.20", default-features = false } +alloy-hardforks = { version = "0.2.12", default-features = false } +alloy-primitives = { version = "1.2", features = ["map"] } +alloy-provider = { version = "1.0.20", default-features = false } +alloy-rpc-types = { version = "1.0.20", features = ["eth"] } eyre = "0.6" futures = "0.3" parking_lot = "0.12" -revm = { version = "24.0.0", features = ["std", "serde"] } +revm = { version = "27.0.2", features = ["std", "serde"] } serde = "1.0" serde_json = "1.0" @@ -47,7 +49,7 @@ tracing = "0.1" url = "2" [dev-dependencies] -alloy-rpc-client = "1.0.3" +alloy-rpc-client = "1.0.20" tiny_http = "0.12" # [patch.crates-io] diff --git a/src/backend.rs b/src/backend.rs index 5306320..9bcd49d 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -997,10 +997,11 @@ impl DatabaseRef for SharedBackend { mod tests { use super::*; use crate::cache::{BlockchainDbMeta, JsonBlockCacheDB}; + use alloy_consensus::BlockHeader; use alloy_provider::ProviderBuilder; use alloy_rpc_client::ClientBuilder; use serde::Deserialize; - use std::{collections::BTreeSet, fs, path::PathBuf}; + use std::{fs, path::PathBuf}; use tiny_http::{Response, Server}; pub fn get_http_provider(endpoint: &str) -> impl Provider + Clone { @@ -1017,7 +1018,9 @@ mod tests { let provider = get_http_provider(endpoint); let any_rpc_block = provider.get_block(BlockId::latest()).hashes().await.unwrap().unwrap(); - let _meta = BlockchainDbMeta::default().with_block(&any_rpc_block.inner); + let meta = BlockchainDbMeta::default().with_block(&any_rpc_block.inner); + + assert_eq!(meta.block_env.number, U256::from(any_rpc_block.header.number())); } #[tokio::test(flavor = "multi_thread")] @@ -1025,10 +1028,7 @@ mod tests { let Some(endpoint) = ENDPOINT else { return }; let provider = get_http_provider(endpoint); - let meta = BlockchainDbMeta { - block_env: Default::default(), - hosts: BTreeSet::from([endpoint.to_string()]), - }; + let meta = BlockchainDbMeta::new(Default::default(), endpoint.to_string()); let db = BlockchainDb::new(meta, None); let backend = SharedBackend::spawn_backend(Arc::new(provider), db.clone(), None).await; @@ -1076,10 +1076,7 @@ mod tests { let Some(endpoint) = ENDPOINT else { return }; let provider = get_http_provider(endpoint); - let meta = BlockchainDbMeta { - block_env: Default::default(), - hosts: BTreeSet::from([endpoint.to_string()]), - }; + let meta = BlockchainDbMeta::new(Default::default(), endpoint.to_string()); let db = BlockchainDb::new(meta, None); let backend = SharedBackend::spawn_backend(Arc::new(provider), db.clone(), None).await; @@ -1141,10 +1138,7 @@ mod tests { let Some(endpoint) = ENDPOINT else { return }; let provider = get_http_provider(endpoint); - let meta = BlockchainDbMeta { - block_env: Default::default(), - hosts: BTreeSet::from([endpoint.to_string()]), - }; + let meta = BlockchainDbMeta::new(Default::default(), endpoint.to_string()); let db = BlockchainDb::new(meta, None); let backend = SharedBackend::spawn_backend(Arc::new(provider), db.clone(), None).await; @@ -1203,10 +1197,7 @@ mod tests { let Some(endpoint) = ENDPOINT else { return }; let provider = get_http_provider(endpoint); - let meta = BlockchainDbMeta { - block_env: Default::default(), - hosts: BTreeSet::from([endpoint.to_string()]), - }; + let meta = BlockchainDbMeta::new(Default::default(), endpoint.to_string()); let db = BlockchainDb::new(meta, None); let backend = SharedBackend::spawn_backend(Arc::new(provider), db.clone(), None).await; @@ -1255,10 +1246,7 @@ mod tests { let Some(endpoint) = ENDPOINT else { return }; let provider = get_http_provider(endpoint); - let meta = BlockchainDbMeta { - block_env: Default::default(), - hosts: BTreeSet::from([endpoint.to_string()]), - }; + let meta = BlockchainDbMeta::new(Default::default(), endpoint.to_string()); // create a temporary file fs::copy("test-data/storage.json", "test-data/storage-tmp.json").unwrap(); @@ -1413,10 +1401,7 @@ mod tests { }); let provider = get_http_provider(&endpoint); - let meta = BlockchainDbMeta { - block_env: Default::default(), - hosts: BTreeSet::from([endpoint.to_string()]), - }; + let meta = BlockchainDbMeta::new(Default::default(), endpoint.to_string()); let db = BlockchainDb::new(meta, None); let provider_inner = provider.clone(); diff --git a/src/cache.rs b/src/cache.rs index 2c7779c..5c3b671 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -1,5 +1,8 @@ //! Cache related abstraction + +use alloy_chains::Chain; use alloy_consensus::BlockHeader; +use alloy_hardforks::EthereumHardfork; use alloy_primitives::{Address, B256, U256}; use alloy_provider::network::TransactionResponse; use parking_lot::RwLock; @@ -7,6 +10,7 @@ use revm::{ context::BlockEnv, context_interface::block::BlobExcessGasAndPrice, primitives::{ + eip4844::{BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN, BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE}, map::{AddressHashMap, HashMap}, KECCAK_EMPTY, }, @@ -123,8 +127,11 @@ impl BlockchainDb { } /// relevant identifying markers in the context of [BlockchainDb] -#[derive(Clone, Debug, Eq, Serialize, Default)] +#[derive(Clone, Debug, Default, Eq, Serialize)] pub struct BlockchainDbMeta { + /// The chain of the blockchain of the block environment + #[serde(default, skip_serializing_if = "Option::is_none")] + pub chain: Option, /// The block environment pub block_env: BlockEnv, /// All the hosts used to connect to @@ -139,25 +146,33 @@ impl BlockchainDbMeta { .and_then(|url| url.host().map(|host| host.to_string())) .unwrap_or(url); - Self { block_env, hosts: BTreeSet::from([host]) } + Self { chain: None, block_env, hosts: BTreeSet::from([host]) } } - /// Sets the [BlockEnv] of this instance using the provided [alloy_rpc_types::Block] + /// Sets the [BlockEnv] of this instance using the provided [Chain] and [alloy_rpc_types::Block] pub fn with_block( mut self, block: &alloy_rpc_types::Block, ) -> Self { + let blob_base_fee_update_fraction = + self.chain.map_or(BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE, |chain| { + match EthereumHardfork::from_chain_and_timestamp(chain, block.header.timestamp()) { + Some(EthereumHardfork::Cancun) => BLOB_BASE_FEE_UPDATE_FRACTION_CANCUN, + _ => BLOB_BASE_FEE_UPDATE_FRACTION_PRAGUE, + } + }); + self.block_env = BlockEnv { - number: block.header.number(), + number: U256::from(block.header.number()), beneficiary: block.header.beneficiary(), - timestamp: block.header.timestamp(), + timestamp: U256::from(block.header.timestamp()), difficulty: U256::from(block.header.difficulty()), basefee: block.header.base_fee_per_gas().unwrap_or_default(), gas_limit: block.header.gas_limit(), prevrandao: block.header.mix_hash(), blob_excess_gas_and_price: Some(BlobExcessGasAndPrice::new( block.header.excess_blob_gas().unwrap_or_default(), - false, + blob_base_fee_update_fraction, )), }; @@ -174,9 +189,16 @@ impl BlockchainDbMeta { self } + /// Sets the [Chain] of this instance + pub fn set_chain(mut self, chain: Chain) -> Self { + self.chain = Some(chain); + self + } + /// Sets the [BlockEnv] of this instance - pub fn set_block_env(mut self, block_env: revm::context::BlockEnv) { + pub fn set_block_env(mut self, block_env: revm::context::BlockEnv) -> Self { self.block_env = block_env; + self } } @@ -229,6 +251,7 @@ impl<'de> Deserialize<'de> for BlockchainDbMeta { // custom deserialize impl to not break existing cache files #[derive(Deserialize)] struct Meta { + chain: Option, block_env: BlockEnvBackwardsCompat, /// all the hosts used to connect to #[serde(alias = "host")] @@ -242,8 +265,9 @@ impl<'de> Deserialize<'de> for BlockchainDbMeta { Single(String), } - let Meta { block_env, hosts } = Meta::deserialize(deserializer)?; + let Meta { chain, block_env, hosts } = Meta::deserialize(deserializer)?; Ok(Self { + chain, block_env: block_env.inner, hosts: match hosts { Hosts::Multi(hosts) => hosts,