From 866000fcddffd3fb8dbdb0b811eee41cf5c6244a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 9 Jan 2025 18:25:51 -0300 Subject: [PATCH 1/3] Add fs2 dependency --- Cargo.lock | 1 + Cargo.toml | 1 + rpc-state-reader/Cargo.toml | 1 + 3 files changed, 3 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 3d3b6f17..d2e3333d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6183,6 +6183,7 @@ dependencies = [ "cairo-native", "cairo-vm", "flate2", + "fs2", "pretty_assertions_sorted", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index f3a768e6..09b6f5a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ tracing = "0.1" serde_json = "1.0.116" serde_with = "3.11.0" serde = "1.0.197" +fs2 = "0.4.3" cairo-native = { git = "https://github.com/lambdaclass/cairo_native.git", rev = "6a4efafa26d6a0424dee593d2091206c6e9f428d" } anyhow = "1.0" # Sequencer Dependencies diff --git a/rpc-state-reader/Cargo.toml b/rpc-state-reader/Cargo.toml index 0125c195..f223c5ec 100644 --- a/rpc-state-reader/Cargo.toml +++ b/rpc-state-reader/Cargo.toml @@ -30,6 +30,7 @@ starknet_gateway = { workspace = true } tracing = { workspace = true } anyhow.workspace = true sierra-emu.workspace = true +fs2.workspace = true [dev-dependencies] pretty_assertions_sorted = "1.2.3" From 6407ab473317e6ffb52ad925b655b1a527f87437 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Thu, 9 Jan 2025 18:44:33 -0300 Subject: [PATCH 2/3] Implement file locking and cache merging --- rpc-state-reader/src/cache.rs | 45 +++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/rpc-state-reader/src/cache.rs b/rpc-state-reader/src/cache.rs index 1ce70879..0338a9e4 100644 --- a/rpc-state-reader/src/cache.rs +++ b/rpc-state-reader/src/cache.rs @@ -2,11 +2,13 @@ use std::{ cell::RefCell, collections::{hash_map::Entry, HashMap}, fs::{self, File}, + io::Seek, path::PathBuf, }; use blockifier::state::state_api::{StateReader as BlockifierStateReader, StateResult}; use cairo_vm::Felt252; +use fs2::FileExt; use serde::{Deserialize, Serialize}; use serde_with::serde_as; use starknet::core::types::ContractClass; @@ -59,8 +61,23 @@ impl Drop for RpcCachedStateReader { let path = PathBuf::from(format!("rpc_cache/{}.json", self.reader.block_number)); let parent = path.parent().unwrap(); fs::create_dir_all(parent).unwrap(); - let file = File::create(path).unwrap(); - serde_json::to_writer_pretty(file, &self.state).unwrap(); + + let mut file = File::options() + .read(true) + .write(true) + .create(true) + .open(path) + .unwrap(); + file.lock_exclusive().unwrap(); + + if let Ok(new_state) = serde_json::from_reader::<_, RpcCache>(&file) { + merge_cache(self.state.get_mut(), new_state); + } + file.set_len(0).unwrap(); + file.seek(std::io::SeekFrom::Start(0)).unwrap(); + + serde_json::to_writer_pretty(&file, &self.state).unwrap(); + file.unlock().unwrap(); } } @@ -70,9 +87,14 @@ impl RpcCachedStateReader { let path = PathBuf::from(format!("rpc_cache/{}.json", reader.block_number)); match File::open(path) { - Ok(file) => serde_json::from_reader(file).unwrap(), + Ok(file) => { + file.lock_shared().unwrap(); + let state = serde_json::from_reader(&file).unwrap(); + file.unlock().unwrap(); + state + } Err(_) => { - warn!("Cache for block {} was not found", reader.block_number); + warn!("Failed to read cache for block {}", reader.block_number); RpcCache::default() } } @@ -220,3 +242,18 @@ impl BlockifierStateReader for RpcCachedStateReader { todo!(); } } + +fn merge_cache(cache: &mut RpcCache, other: RpcCache) { + if cache.block.is_none() { + cache.block = other.block + } + cache.transactions.extend(other.transactions); + cache.contract_classes.extend(other.contract_classes); + cache.storage.extend(other.storage); + cache.nonces.extend(other.nonces); + cache.class_hashes.extend(other.class_hashes); + cache + .transaction_receipts + .extend(other.transaction_receipts); + cache.transaction_traces.extend(other.transaction_traces); +} From a7025c9df2556e355692e85095d648b55e3e0dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Fri, 10 Jan 2025 12:06:57 -0300 Subject: [PATCH 3/3] Clean up --- rpc-state-reader/src/cache.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rpc-state-reader/src/cache.rs b/rpc-state-reader/src/cache.rs index 0338a9e4..82287a55 100644 --- a/rpc-state-reader/src/cache.rs +++ b/rpc-state-reader/src/cache.rs @@ -66,13 +66,17 @@ impl Drop for RpcCachedStateReader { .read(true) .write(true) .create(true) + .truncate(false) .open(path) .unwrap(); file.lock_exclusive().unwrap(); - if let Ok(new_state) = serde_json::from_reader::<_, RpcCache>(&file) { - merge_cache(self.state.get_mut(), new_state); + // try to read old cache, and merge it with the current one + if let Ok(old_state) = serde_json::from_reader::<_, RpcCache>(&file) { + merge_cache(self.state.get_mut(), old_state); } + + // overwrite the file with the new cache file.set_len(0).unwrap(); file.seek(std::io::SeekFrom::Start(0)).unwrap();