Skip to content

Commit 10225cd

Browse files
committed
fix: tests
1 parent 981dbb8 commit 10225cd

File tree

5 files changed

+223
-2
lines changed

5 files changed

+223
-2
lines changed

Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,7 @@ tokio = { version = "1", features = ["rt-multi-thread"] }
4646
tracing = "0.1"
4747

4848
url = "2"
49+
50+
[dev-dependencies]
51+
alloy-rpc-client = { version = "0.1.2" }
52+
alloy-transport-http = { version = "0.1.2" }

src/fork.rs renamed to src/backend.rs

+70
Original file line numberDiff line numberDiff line change
@@ -703,3 +703,73 @@ impl DatabaseRef for SharedBackend {
703703
})
704704
}
705705
}
706+
707+
#[cfg(test)]
708+
mod tests {
709+
use alloy_provider::{ProviderBuilder, RootProvider};
710+
use crate::cache::{BlockchainDbMeta, JsonBlockCacheDB};
711+
use super::*;
712+
use alloy_rpc_client::ClientBuilder;
713+
use alloy_transport_http::{Client, Http};
714+
use std::{collections::BTreeSet, path::PathBuf};
715+
716+
pub fn get_http_provider(endpoint: &str) -> RootProvider<Http<Client>, AnyNetwork> {
717+
ProviderBuilder::new()
718+
.network::<AnyNetwork>()
719+
.on_client(ClientBuilder::default().http(endpoint.parse().unwrap()))
720+
}
721+
722+
const ENDPOINT: Option<&str> = option_env!("ETH_RPC_URL");
723+
724+
#[tokio::test(flavor = "multi_thread")]
725+
async fn shared_backend() {
726+
let Some(endpoint) = ENDPOINT else { return };
727+
728+
let provider = get_http_provider(endpoint);
729+
let meta = BlockchainDbMeta {
730+
cfg_env: Default::default(),
731+
block_env: Default::default(),
732+
hosts: BTreeSet::from([endpoint.to_string()]),
733+
};
734+
735+
let db = BlockchainDb::new(meta, None);
736+
let backend = SharedBackend::spawn_backend(Arc::new(provider), db.clone(), None).await;
737+
738+
// some rng contract from etherscan
739+
let address: Address = "63091244180ae240c87d1f528f5f269134cb07b3".parse().unwrap();
740+
741+
let idx = U256::from(0u64);
742+
let value = backend.storage_ref(address, idx).unwrap();
743+
let account = backend.basic_ref(address).unwrap().unwrap();
744+
745+
let mem_acc = db.accounts().read().get(&address).unwrap().clone();
746+
assert_eq!(account.balance, mem_acc.balance);
747+
assert_eq!(account.nonce, mem_acc.nonce);
748+
let slots = db.storage().read().get(&address).unwrap().clone();
749+
assert_eq!(slots.len(), 1);
750+
assert_eq!(slots.get(&idx).copied().unwrap(), value);
751+
752+
let num = U256::from(10u64);
753+
let hash = backend.block_hash_ref(num).unwrap();
754+
let mem_hash = *db.block_hashes().read().get(&num).unwrap();
755+
assert_eq!(hash, mem_hash);
756+
757+
let max_slots = 5;
758+
let handle = std::thread::spawn(move || {
759+
for i in 1..max_slots {
760+
let idx = U256::from(i);
761+
let _ = backend.storage_ref(address, idx);
762+
}
763+
});
764+
handle.join().unwrap();
765+
let slots = db.storage().read().get(&address).unwrap().clone();
766+
assert_eq!(slots.len() as u64, max_slots);
767+
}
768+
769+
#[test]
770+
fn can_read_cache() {
771+
let cache_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("test-data/storage.json");
772+
let json = JsonBlockCacheDB::load(cache_path).unwrap();
773+
assert!(!json.db().accounts.read().is_empty());
774+
}
775+
}

src/cache.rs

+146
Original file line numberDiff line numberDiff line change
@@ -471,3 +471,149 @@ impl Drop for FlushJsonBlockCacheDB {
471471
trace!(target: "fork::cache", "flushed cache");
472472
}
473473
}
474+
475+
#[cfg(test)]
476+
mod tests {
477+
use super::*;
478+
479+
#[test]
480+
fn can_deserialize_cache() {
481+
let s = r#"{
482+
"meta": {
483+
"cfg_env": {
484+
"chain_id": 1337,
485+
"perf_analyse_created_bytecodes": "Analyse",
486+
"limit_contract_code_size": 18446744073709551615,
487+
"memory_limit": 4294967295,
488+
"disable_block_gas_limit": false,
489+
"disable_eip3607": false,
490+
"disable_base_fee": false
491+
},
492+
"block_env": {
493+
"number": "0xed3ddf",
494+
"coinbase": "0x0000000000000000000000000000000000000000",
495+
"timestamp": "0x6324bc3f",
496+
"difficulty": "0x0",
497+
"basefee": "0x2e5fda223",
498+
"gas_limit": "0x1c9c380",
499+
"prevrandao": "0x0000000000000000000000000000000000000000000000000000000000000000"
500+
},
501+
"hosts": [
502+
"eth-mainnet.alchemyapi.io"
503+
]
504+
},
505+
"accounts": {
506+
"0xb8ffc3cd6e7cf5a098a1c92f48009765b24088dc": {
507+
"balance": "0x0",
508+
"nonce": 10,
509+
"code_hash": "0x3ac64c95eedf82e5d821696a12daac0e1b22c8ee18a9fd688b00cfaf14550aad",
510+
"code": {
511+
"LegacyAnalyzed": {
512+
"bytecode": "0x00",
513+
"original_len": 0,
514+
"jump_table": {
515+
"order": "bitvec::order::Lsb0",
516+
"head": {
517+
"width": 8,
518+
"index": 0
519+
},
520+
"bits": 1,
521+
"data": [0]
522+
}
523+
}
524+
}
525+
}
526+
},
527+
"storage": {
528+
"0xa354f35829ae975e850e23e9615b11da1b3dc4de": {
529+
"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564": "0x5553444320795661756c74000000000000000000000000000000000000000000",
530+
"0x10": "0x37fd60ff8346",
531+
"0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563": "0xb",
532+
"0x6": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
533+
"0x5": "0x36ff5b93162e",
534+
"0x14": "0x29d635a8e000",
535+
"0x11": "0x63224c73",
536+
"0x2": "0x6"
537+
}
538+
},
539+
"block_hashes": {
540+
"0xed3deb": "0xbf7be3174b261ea3c377b6aba4a1e05d5fae7eee7aab5691087c20cf353e9877",
541+
"0xed3de9": "0xba1c3648e0aee193e7d00dffe4e9a5e420016b4880455641085a4731c1d32eef",
542+
"0xed3de8": "0x61d1491c03a9295fb13395cca18b17b4fa5c64c6b8e56ee9cc0a70c3f6cf9855",
543+
"0xed3de7": "0xb54560b5baeccd18350d56a3bee4035432294dc9d2b7e02f157813e1dee3a0be",
544+
"0xed3dea": "0x816f124480b9661e1631c6ec9ee39350bda79f0cbfc911f925838d88e3d02e4b"
545+
}
546+
}"#;
547+
548+
let cache: JsonBlockCacheData = serde_json::from_str(s).unwrap();
549+
assert_eq!(cache.data.accounts.read().len(), 1);
550+
assert_eq!(cache.data.storage.read().len(), 1);
551+
assert_eq!(cache.data.block_hashes.read().len(), 5);
552+
553+
let _s = serde_json::to_string(&cache).unwrap();
554+
}
555+
556+
#[test]
557+
fn can_deserialize_cache_post_4844() {
558+
let s = r#"{
559+
"meta": {
560+
"cfg_env": {
561+
"chain_id": 1,
562+
"kzg_settings": "Default",
563+
"perf_analyse_created_bytecodes": "Analyse",
564+
"limit_contract_code_size": 18446744073709551615,
565+
"memory_limit": 134217728,
566+
"disable_block_gas_limit": false,
567+
"disable_eip3607": true,
568+
"disable_base_fee": false,
569+
"optimism": false
570+
},
571+
"block_env": {
572+
"number": "0x11c99bc",
573+
"coinbase": "0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97",
574+
"timestamp": "0x65627003",
575+
"gas_limit": "0x1c9c380",
576+
"basefee": "0x64288ff1f",
577+
"difficulty": "0xc6b1a299886016dea3865689f8393b9bf4d8f4fe8c0ad25f0058b3569297c057",
578+
"prevrandao": "0xc6b1a299886016dea3865689f8393b9bf4d8f4fe8c0ad25f0058b3569297c057",
579+
"blob_excess_gas_and_price": {
580+
"excess_blob_gas": 0,
581+
"blob_gasprice": 1
582+
}
583+
},
584+
"hosts": [
585+
"eth-mainnet.alchemyapi.io"
586+
]
587+
},
588+
"accounts": {
589+
"0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97": {
590+
"balance": "0x8e0c373cfcdfd0eb",
591+
"nonce": 128912,
592+
"code_hash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
593+
"code": {
594+
"LegacyAnalyzed": {
595+
"bytecode": "0x00",
596+
"original_len": 0,
597+
"jump_table": {
598+
"order": "bitvec::order::Lsb0",
599+
"head": {
600+
"width": 8,
601+
"index": 0
602+
},
603+
"bits": 1,
604+
"data": [0]
605+
}
606+
}
607+
}
608+
}
609+
},
610+
"storage": {},
611+
"block_hashes": {}
612+
}"#;
613+
614+
let cache: JsonBlockCacheData = serde_json::from_str(s).unwrap();
615+
assert_eq!(cache.data.accounts.read().len(), 1);
616+
617+
let _s = serde_json::to_string(&cache).unwrap();
618+
}
619+
}

src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
#[macro_use]
66
extern crate tracing;
77

8+
pub mod backend;
89
pub mod cache;
910
pub mod error;
10-
pub mod fork;
1111

12+
pub use backend::{BackendHandler, SharedBackend};
1213
pub use cache::BlockchainDb;
1314
pub use error::{DatabaseError, DatabaseResult};
14-
pub use fork::{BackendHandler, SharedBackend};

test-data/storage.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"meta":{"cfg_env":{"chain_id":1,"spec_id":"LATEST","perf_all_precompiles_have_balance":false,"memory_limit":4294967295,"perf_analyse_created_bytecodes":"Analyse","limit_contract_code_size":24576,"disable_coinbase_tip":false},"block_env":{"number":"0xdc42b8","coinbase":"0x0000000000000000000000000000000000000000","timestamp":"0x1","difficulty":"0x0","basefee":"0x0","gas_limit":"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"},"hosts":["mainnet.infura.io"]},"accounts":{"0x63091244180ae240c87d1f528f5f269134cb07b3":{"balance":"0x0","code_hash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","code":null,"nonce":0}},"storage":{"0x63091244180ae240c87d1f528f5f269134cb07b3":{"0x0":"0x0","0x1":"0x0","0x2":"0x0","0x3":"0x0","0x4":"0x0","0x5":"0x0","0x6":"0x0","0x7":"0x0","0x8":"0x0","0x9":"0x0"}},"block_hashes":{}}

0 commit comments

Comments
 (0)