use std::sync::Arc;
use std::time::{SystemTime, UNIX_EPOCH};
use alloy_provider::RootProvider;
use alloy_provider::network::AnyNetwork;
use alloy_rpc_client::RpcClient;
use alloy_transport::mock::Asserter;
use anyhow::Result;
use evm_fork_cache::cache::{
CacheConfig, CacheSpeedMode, EvmCache, EvmCacheBuilder, StorageBatchConfig,
};
fn mock_provider() -> Arc<RootProvider<AnyNetwork>> {
Arc::new(RootProvider::<AnyNetwork>::new(RpcClient::mocked(
Asserter::new(),
)))
}
fn unique_cache_dir(tag: &str) -> std::path::PathBuf {
let nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos();
std::env::temp_dir().join(format!("evm_fork_cache_chainid_{tag}_{nanos}"))
}
#[tokio::test(flavor = "multi_thread")]
async fn explicit_builder_chain_id_wins() -> Result<()> {
let cache = EvmCacheBuilder::new(mock_provider())
.chain_id(8453)
.build()
.await;
assert_eq!(cache.chain_id(), 8453);
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn unset_chain_id_falls_back_to_mainnet_when_inference_fails() -> Result<()> {
let cache = EvmCacheBuilder::new(mock_provider()).build().await;
assert_eq!(cache.chain_id(), 1);
let via_new = EvmCache::new(mock_provider()).await;
assert_eq!(via_new.chain_id(), 1);
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn cache_config_chain_id_is_used_when_no_explicit_value() -> Result<()> {
let dir = unique_cache_dir("config");
let cfg = CacheConfig::new(&dir, 10, Default::default(), Default::default());
let cache = EvmCacheBuilder::new(mock_provider())
.cache_config(cfg)
.build()
.await;
assert_eq!(cache.chain_id(), 10);
let _ = std::fs::remove_dir_all(&dir);
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn explicit_builder_chain_id_overrides_cache_config() -> Result<()> {
let dir = unique_cache_dir("override");
let cfg = CacheConfig::new(&dir, 10, Default::default(), Default::default());
let cache = EvmCacheBuilder::new(mock_provider())
.cache_config(cfg)
.chain_id(8453)
.build()
.await;
assert_eq!(cache.chain_id(), 8453);
let _ = std::fs::remove_dir_all(&dir);
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn set_chain_id_updates_after_construction() -> Result<()> {
let mut cache = EvmCacheBuilder::new(mock_provider()).build().await;
assert_eq!(cache.chain_id(), 1);
cache.set_chain_id(137); assert_eq!(cache.chain_id(), 137);
Ok(())
}
#[tokio::test(flavor = "multi_thread")]
async fn storage_batch_config_is_per_cache_instance() -> Result<()> {
let custom = StorageBatchConfig::new(321, 9);
let default_cache = EvmCacheBuilder::new(mock_provider()).build().await;
let fast_cache = EvmCacheBuilder::new(mock_provider())
.speed_mode(CacheSpeedMode::Fast)
.build()
.await;
let custom_cache = EvmCacheBuilder::new(mock_provider())
.storage_batch_config(custom)
.build()
.await;
assert_eq!(
default_cache.storage_batch_config(),
StorageBatchConfig::from(CacheSpeedMode::Slow)
);
assert_eq!(
fast_cache.storage_batch_config(),
StorageBatchConfig::from(CacheSpeedMode::Fast)
);
assert_eq!(custom_cache.storage_batch_config(), custom);
Ok(())
}