From 69ca34675b6c84ccd0dee0564e4a74dc4e0cb10a Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Wed, 3 Dec 2025 12:43:15 +0530 Subject: [PATCH 1/6] store the fvm events in blockstore and fetch from blockstore if not available in cache --- src/chain/store/chain_store.rs | 2 +- src/rpc/methods/chain.rs | 4 +-- src/rpc/methods/eth/filter/mod.rs | 7 +++--- src/shim/executor.rs | 29 ++++++++++++++++++++- src/state_manager/mod.rs | 42 ++++++++++++++++++++++++++++--- 5 files changed, 73 insertions(+), 11 deletions(-) diff --git a/src/chain/store/chain_store.rs b/src/chain/store/chain_store.rs index 1c178d1809ce..0db76e0f4c97 100644 --- a/src/chain/store/chain_store.rs +++ b/src/chain/store/chain_store.rs @@ -203,7 +203,7 @@ where Ok(()) } - pub fn get_tipset_key(&self, key: &Cid) -> Result, Error> { + pub fn get_tipset_key_by_events_root(&self, key: &Cid) -> Result, Error> { Ok(self.indices.read_obj(key)?) } diff --git a/src/rpc/methods/chain.rs b/src/rpc/methods/chain.rs index 44c4f229bfc3..7c014177d440 100644 --- a/src/rpc/methods/chain.rs +++ b/src/rpc/methods/chain.rs @@ -254,8 +254,8 @@ impl RpcMethod<1> for ChainGetEvents { let tsk = ctx .state_manager .chain_store() - .get_tipset_key(&root_cid)? - .with_context(|| format!("can't find events with cid {root_cid}"))?; + .get_tipset_key_by_events_root(&root_cid)? + .with_context(|| format!("can't find tipset for events root {root_cid}"))?; let ts = ctx.chain_store().load_required_tipset_or_heaviest(&tsk)?; diff --git a/src/rpc/methods/eth/filter/mod.rs b/src/rpc/methods/eth/filter/mod.rs index 26af0f091299..b0ff137f7e73 100644 --- a/src/rpc/methods/eth/filter/mod.rs +++ b/src/rpc/methods/eth/filter/mod.rs @@ -45,7 +45,6 @@ use anyhow::{Context, Error, anyhow, bail, ensure}; use cid::Cid; use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::IPLD_RAW; -use itertools::Itertools; use serde::*; use std::ops::RangeInclusive; use std::sync::Arc; @@ -384,11 +383,13 @@ impl EthEventHandler { .filter(|(cid, _)| cid.as_ref() == Some(events_root)) .map(|(_, v)| v); - let chain_events = filtered_events + // Do NOT deduplicate events - the AMT can legitimately contain duplicate events + // if a contract emits the same event multiple times. We must preserve the exact + // order and count of events as stored in the AMT. + let chain_events: Vec = filtered_events .into_iter() .flat_map(|events| events.into_iter()) .map(Into::into) - .unique() .collect(); Ok(chain_events) diff --git a/src/shim/executor.rs b/src/shim/executor.rs index 824766a0c5df..3c27c67e1955 100644 --- a/src/shim/executor.rs +++ b/src/shim/executor.rs @@ -7,7 +7,7 @@ use crate::shim::{ }; use crate::utils::get_size::{GetSize, vec_heap_size_with_fn_helper}; use cid::Cid; -use fil_actors_shared::fvm_ipld_amt::Amtv0; +use fil_actors_shared::fvm_ipld_amt::{Amt, Amtv0}; use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::RawBytes; use fvm_shared2::receipt::Receipt as Receipt_v2; @@ -339,6 +339,7 @@ impl ActorEvent { /// Event with extra information stamped by the FVM. #[derive(Clone, Debug, Serialize)] +#[serde(untagged)] pub enum StampedEvent { V3(StampedEvent_v3), V4(StampedEvent_v4), @@ -385,6 +386,32 @@ impl StampedEvent { Self::V4(v4) => v4.event.clone().into(), } } + + /// Loads events directly from the events AMT root CID. + /// Returns events in the exact order they are stored in the AMT. + pub fn get_events( + db: &DB, + events_root: &Cid, + ) -> anyhow::Result> { + let mut events = Vec::new(); + + // Try StampedEvent_v4 first (StampedEvent_v4 and StampedEvent_v3 are identical, use v4 here) + if let Ok(amt) = Amt::::load(events_root, db) { + amt.for_each(|_, event| { + events.push(StampedEvent::V4(event.clone())); + Ok(()) + })?; + } else { + // Fallback to StampedEvent_v3 + let amt = Amt::::load(events_root, db)?; + amt.for_each(|_, event| { + events.push(StampedEvent::V3(event.clone())); + Ok(()) + })?; + } + + Ok(events) + } } #[cfg(test)] diff --git a/src/state_manager/mod.rs b/src/state_manager/mod.rs index 1fa90d31a6a6..30457581a8e0 100644 --- a/src/state_manager/mod.rs +++ b/src/state_manager/mod.rs @@ -61,14 +61,14 @@ use crate::utils::get_size::{ GetSize, vec_heap_size_helper, vec_with_stack_only_item_heap_size_helper, }; use ahash::{HashMap, HashMapExt}; -use anyhow::{Context as _, bail}; +use anyhow::{Context as _, bail, ensure}; use bls_signatures::{PublicKey as BlsPublicKey, Serialize as _}; use chain_rand::ChainRand; use cid::Cid; pub use circulating_supply::GenesisInfo; use fil_actor_verifreg_state::v12::DataCap; use fil_actor_verifreg_state::v13::ClaimID; -use fil_actors_shared::fvm_ipld_amt::Amtv0 as Amt; +use fil_actors_shared::fvm_ipld_amt::{Amt, Amtv0}; use fil_actors_shared::fvm_ipld_bitfield::BitField; use fil_actors_shared::v12::runtime::DomainSeparationTag; use fil_actors_shared::v13::runtime::Policy; @@ -91,6 +91,7 @@ use tracing::{error, info, instrument, trace, warn}; pub use utils::is_valid_for_sending; const DEFAULT_TIPSET_CACHE_SIZE: NonZeroUsize = nonzero!(1024usize); +const EVENTS_AMT_BITWIDTH: u32 = 5; /// Intermediary for retrieving state objects and updating actor states. type CidPair = (Cid, Cid); @@ -560,11 +561,24 @@ where let ts = tipset.clone(); let this = Arc::clone(self); let cids = tipset.cids(); + let events_root = events_root.cloned(); self.receipt_event_cache_handler .get_events_or_else( key, Box::new(move || { Box::pin(async move { + // If the events are not in the cache, try to load them from the blockstore + if let Some(events_root) = events_root + && let Ok(stamped_events) = + StampedEvent::get_events(this.blockstore(), &events_root) + { + return Ok(StateEvents { + events: vec![stamped_events], + roots: vec![Some(events_root)], + }); + } + + // If the events are neither in the cache nor in the blockstore, compute them. let state_out = this .compute_tipset_state(ts, NO_CALLBACK, VMTrace::NotTraced) .await?; @@ -1986,8 +2000,28 @@ where let (receipts, events, events_roots) = vm.apply_block_messages(&block_messages, epoch, callback)?; - // step 5: construct receipt root from receipts and flush the state-tree - let receipt_root = Amt::new_from_iter(chain_index.db(), receipts)?; + // step 5: construct receipt root from receipts + let receipt_root = Amtv0::new_from_iter(chain_index.db(), receipts)?; + + // step 6: store events AMTs in the blockstore + for (msg_events, events_root) in events.iter().zip(events_roots.iter()) { + if let Some(event_root) = events_root { + // Store the events AMT - the root CID should match the one computed by FVM + let derived_event_root = Amt::new_from_iter_with_bit_width( + chain_index.db(), + EVENTS_AMT_BITWIDTH, + msg_events.iter(), + ) + .map_err(|e| Error::Other(format!("failed to store events AMT: {e}")))?; + + // Verify the stored root matches the FVM-computed root + ensure!( + derived_event_root.eq(event_root), + "Events AMT root mismatch: derived={derived_event_root}, actual={event_root}." + ); + } + } + let state_root = vm.flush()?; Ok(StateOutput { From cacf0c89c3c6c7432f67be24d780ab0a1db49ea3 Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Fri, 5 Dec 2025 17:50:18 +0530 Subject: [PATCH 2/6] add unit test and update the exisitng event API snapshot test --- src/state_manager/tests.rs | 196 +++++++++++++++++- .../subcommands/api_cmd/test_snapshots.txt | 2 +- 2 files changed, 194 insertions(+), 4 deletions(-) diff --git a/src/state_manager/tests.rs b/src/state_manager/tests.rs index be9b70a044bb..b9d1db37100d 100644 --- a/src/state_manager/tests.rs +++ b/src/state_manager/tests.rs @@ -11,7 +11,7 @@ use crate::shim::executor::{Receipt, StampedEvent}; use crate::utils::db::CborStoreExt; use crate::utils::multihash::MultihashCode; use cid::Cid; -use fil_actors_shared::fvm_ipld_amt::Amtv0 as Amt; +use fil_actors_shared::fvm_ipld_amt::{Amt, Amtv0}; use fvm_ipld_blockstore::Blockstore; use fvm_ipld_encoding::DAG_CBOR; use multihash_derive::MultihashDigest; @@ -348,7 +348,7 @@ fn test_update_receipt_and_events_cache_with_events() { event: fvm_shared4::event::ActorEvent { entries: vec![] }, })]; - let events_root = Amt::new_from_iter(&db, mock_event.clone()).unwrap(); + let events_root = Amtv0::new_from_iter(&db, mock_event.clone()).unwrap(); // Create state output with non-empty events let state_output = StateOutput { @@ -385,7 +385,7 @@ fn test_update_receipt_and_events_cache_receipts_success() { events_root: None, }); - let receipt_root = Amt::new_from_iter(&db, vec![receipt]).unwrap(); + let receipt_root = Amtv0::new_from_iter(&db, vec![receipt]).unwrap(); let state_output = StateOutput { state_root: create_dummy_cid(2), @@ -433,3 +433,193 @@ fn test_state_output_get_size() { let s = StateOutputValue::default(); assert_eq!(s.get_size(), std::mem::size_of_val(&s)); } + +fn create_raw_event_v4(emitter: u64, key: &str) -> fvm_shared4::event::StampedEvent { + fvm_shared4::event::StampedEvent { + emitter, + event: fvm_shared4::event::ActorEvent { + entries: vec![fvm_shared4::event::Entry { + flags: fvm_shared4::event::Flags::FLAG_INDEXED_ALL, + key: key.to_string(), + codec: fvm_ipld_encoding::IPLD_RAW, + value: key.as_bytes().to_vec(), + }], + }, + } +} + +fn create_raw_event_v3(emitter: u64, key: &str) -> fvm_shared3::event::StampedEvent { + fvm_shared3::event::StampedEvent { + emitter, + event: fvm_shared3::event::ActorEvent { + entries: vec![fvm_shared3::event::Entry { + flags: fvm_shared3::event::Flags::FLAG_INDEXED_ALL, + key: key.to_string(), + codec: fvm_ipld_encoding::IPLD_RAW, + value: key.as_bytes().to_vec(), + }], + }, + } +} + +#[test] +fn test_events_store_and_retrieve_basic() { + let db: MemoryDB = MemoryDB::default(); + + // Create some test events + let events = [ + create_raw_event_v4(1000, "event1"), + create_raw_event_v4(1001, "event2"), + create_raw_event_v4(1002, "event3"), + ]; + + // Store events in AMT with the same bitwidth as used in apply_block_messages + let events_root = + Amt::new_from_iter_with_bit_width(&db, EVENTS_AMT_BITWIDTH, events.iter()).unwrap(); + + // Retrieve events from the AMT + let retrieved_events = StampedEvent::get_events(&db, &events_root).unwrap(); + + // Verify count matches + assert_eq!(retrieved_events.len(), 3); + + // Verify content matches + assert_eq!(retrieved_events[0].emitter(), 1000); + assert_eq!(retrieved_events[1].emitter(), 1001); + assert_eq!(retrieved_events[2].emitter(), 1002); +} + +#[test] +fn test_events_entries_are_preserved_when_duplicates_are_stored() { + let db = MemoryDB::default(); + + // Create events with intentional duplicates (same content) + let event1 = create_raw_event_v4(1001, "event1"); + let event2 = create_raw_event_v4(1002, "event2"); + let event3 = create_raw_event_v4(1003, "event3"); + + let events = [event1.clone(), event1.clone(), event2, event3, event1]; + let events_root = + Amt::new_from_iter_with_bit_width(&db, EVENTS_AMT_BITWIDTH, events.iter()).unwrap(); + let retrieved_events = StampedEvent::get_events(&db, &events_root).unwrap(); + assert_eq!(retrieved_events.len(), 5); + // Verify the duplicates are at correct positions + assert_eq!(retrieved_events[0].emitter(), 1001); + assert_eq!(retrieved_events[1].emitter(), 1001); // duplicate + assert_eq!(retrieved_events[2].emitter(), 1002); + assert_eq!(retrieved_events[3].emitter(), 1003); + assert_eq!(retrieved_events[4].emitter(), 1001); // non consecutive duplicate +} + +#[test] +fn test_events_preserve_order() { + let db = MemoryDB::default(); + + // Create events with specific emitter IDs to track order + let events = [ + create_raw_event_v4(100, "first"), + create_raw_event_v4(200, "second"), + create_raw_event_v4(300, "third"), + create_raw_event_v4(400, "fourth"), + create_raw_event_v4(500, "fifth"), + ]; + let events_root = + Amt::new_from_iter_with_bit_width(&db, EVENTS_AMT_BITWIDTH, events.iter()).unwrap(); + let retrieved_events = StampedEvent::get_events(&db, &events_root).unwrap(); + + assert_eq!(retrieved_events.len(), 5); + assert_eq!(retrieved_events[0].emitter(), 100); + assert_eq!(retrieved_events[1].emitter(), 200); + assert_eq!(retrieved_events[2].emitter(), 300); + assert_eq!(retrieved_events[3].emitter(), 400); + assert_eq!(retrieved_events[4].emitter(), 500); +} + +#[test] +fn test_events_same_content_same_cid() { + let db = MemoryDB::default(); + + // Create identical event lists + let events1 = [ + create_raw_event_v4(1000, "event_a"), + create_raw_event_v4(1001, "event_b"), + ]; + let events2 = [ + create_raw_event_v4(1000, "event_a"), + create_raw_event_v4(1001, "event_b"), + ]; + + // Store both lists + let root1 = + Amt::new_from_iter_with_bit_width(&db, EVENTS_AMT_BITWIDTH, events1.iter()).unwrap(); + let root2 = + Amt::new_from_iter_with_bit_width(&db, EVENTS_AMT_BITWIDTH, events2.iter()).unwrap(); + + // Same content should produce same CID + assert_eq!( + root1, root2, + "Identical events should produce identical CIDs" + ); +} + +#[test] +fn test_events_empty_list() { + let db = MemoryDB::default(); + + let events: Vec = vec![]; + let events_root = + Amt::new_from_iter_with_bit_width(&db, EVENTS_AMT_BITWIDTH, events.iter()).unwrap(); + + let retrieved_events = StampedEvent::get_events(&db, &events_root).unwrap(); + assert!( + retrieved_events.is_empty(), + "Empty events list should return empty" + ); +} + +#[test] +fn test_events_v3_store_and_retrieve() { + let db = MemoryDB::default(); + + let events = [ + create_raw_event_v3(2000, "v3_event1"), + create_raw_event_v3(2001, "v3_event2"), + ]; + + // Store V3 events + let events_root = + Amt::new_from_iter_with_bit_width(&db, EVENTS_AMT_BITWIDTH, events.iter()).unwrap(); + let retrieved_events = StampedEvent::get_events(&db, &events_root).unwrap(); + + assert_eq!(retrieved_events.len(), 2); + assert_eq!(retrieved_events[0].emitter(), 2000); + assert_eq!(retrieved_events[1].emitter(), 2001); +} + +#[test] +fn test_identical_events_produce_same_root() { + let db = MemoryDB::default(); + + // Create identical event lists + let events1 = [ + create_raw_event_v4(1000, "event_a"), + create_raw_event_v4(1001, "event_b"), + ]; + let events2 = [ + create_raw_event_v4(1000, "event_a"), + create_raw_event_v4(1001, "event_b"), + ]; + + let root1 = + Amt::new_from_iter_with_bit_width(&db, EVENTS_AMT_BITWIDTH, events1.iter()).unwrap(); + let root2 = + Amt::new_from_iter_with_bit_width(&db, EVENTS_AMT_BITWIDTH, events2.iter()).unwrap(); + + assert_eq!(root1, root2); + let retrieved_events = StampedEvent::get_events(&db, &root1).unwrap(); + + // Each AMT contains 2 events, and since roots are the same, we get 2 events + assert_eq!(retrieved_events.len(), 2); + assert_eq!(retrieved_events[0].emitter(), 1000); + assert_eq!(retrieved_events[1].emitter(), 1001); +} diff --git a/src/tool/subcommands/api_cmd/test_snapshots.txt b/src/tool/subcommands/api_cmd/test_snapshots.txt index 0f1543e50108..6d53ad0dd125 100644 --- a/src/tool/subcommands/api_cmd/test_snapshots.txt +++ b/src/tool/subcommands/api_cmd/test_snapshots.txt @@ -4,7 +4,7 @@ filecoin_chaingetblockmessages_1736937164799678.rpcsnap.json.zst filecoin_chaingetevents_1746450533519970.rpcsnap.json.zst filecoin_chaingetevents_1746450533600537.rpcsnap.json.zst filecoin_chaingetevents_1746450551991052.rpcsnap.json.zst -filecoin_chaingetevents_1750327595269729.rpcsnap.json.zst +filecoin_chaingetevents_1764864316078100.rpcsnap.json.zst filecoin_chaingetfinalizedtipset_1759828121342574.rpcsnap.json.zst filecoin_chaingetgenesis_1736937286915866.rpcsnap.json.zst filecoin_chaingetmessage_1741270616352800.rpcsnap.json.zst From ad77eeec6bc43f162ed5e6927a3f43c21952dbad Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Fri, 5 Dec 2025 17:50:56 +0530 Subject: [PATCH 3/6] add empty check while fetching events and small fixes --- src/rpc/methods/eth/filter/mod.rs | 11 +++++++++-- src/state_manager/mod.rs | 15 ++++++++------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/rpc/methods/eth/filter/mod.rs b/src/rpc/methods/eth/filter/mod.rs index b0ff137f7e73..67a1c605cb80 100644 --- a/src/rpc/methods/eth/filter/mod.rs +++ b/src/rpc/methods/eth/filter/mod.rs @@ -285,7 +285,9 @@ impl EthEventHandler { ensure!( messages.len() == events.len(), - "Length of messages and events do not match" + "Length of messages ({}) and events ({}) do not match", + messages.len(), + events.len(), ); let mut event_count = 0; @@ -374,7 +376,12 @@ impl EthEventHandler { .tipset_state_events(tipset, Some(events_root)) .await?; - ensure!(state_events.roots.len() == state_events.events.len()); + ensure!( + state_events.roots.len() == state_events.events.len(), + "State events roots ({}) and events length ({}) mismatch ", + state_events.roots.len(), + state_events.events.len(), + ); let filtered_events = state_events .roots diff --git a/src/state_manager/mod.rs b/src/state_manager/mod.rs index 30457581a8e0..7ad927b6d4fc 100644 --- a/src/state_manager/mod.rs +++ b/src/state_manager/mod.rs @@ -91,7 +91,7 @@ use tracing::{error, info, instrument, trace, warn}; pub use utils::is_valid_for_sending; const DEFAULT_TIPSET_CACHE_SIZE: NonZeroUsize = nonzero!(1024usize); -const EVENTS_AMT_BITWIDTH: u32 = 5; +pub const EVENTS_AMT_BITWIDTH: u32 = 5; /// Intermediary for retrieving state objects and updating actor states. type CidPair = (Cid, Cid); @@ -567,18 +567,19 @@ where key, Box::new(move || { Box::pin(async move { - // If the events are not in the cache, try to load them from the blockstore - if let Some(events_root) = events_root - && let Ok(stamped_events) = - StampedEvent::get_events(this.blockstore(), &events_root) + // Try to load events directly from the blockstore + if let Some(stamped_events) = events_root + .as_ref() + .and_then(|root| StampedEvent::get_events(this.blockstore(), root).ok()) + .filter(|events| !events.is_empty()) { return Ok(StateEvents { events: vec![stamped_events], - roots: vec![Some(events_root)], + roots: vec![events_root], }); } - // If the events are neither in the cache nor in the blockstore, compute them. + // Fallback: compute the tipset state if events not found in the blockstore let state_out = this .compute_tipset_state(ts, NO_CALLBACK, VMTrace::NotTraced) .await?; From 5e5a7a2be34545710201579e71907a9a2dd5e6a7 Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Tue, 9 Dec 2025 18:24:29 +0530 Subject: [PATCH 4/6] refactor get events method and udpdate the snapshot tests --- src/rpc/methods/chain.rs | 11 +---- src/rpc/methods/eth/filter/mod.rs | 41 +++++-------------- src/state_manager/mod.rs | 15 +------ .../subcommands/api_cmd/test_snapshots.txt | 6 +-- 4 files changed, 16 insertions(+), 57 deletions(-) diff --git a/src/rpc/methods/chain.rs b/src/rpc/methods/chain.rs index 8903315f4a32..1ebb07dbd6c7 100644 --- a/src/rpc/methods/chain.rs +++ b/src/rpc/methods/chain.rs @@ -251,16 +251,7 @@ impl RpcMethod<1> for ChainGetEvents { ctx: Ctx, (root_cid,): Self::Params, ) -> Result { - let tsk = ctx - .state_manager - .chain_store() - .get_tipset_key_by_events_root(&root_cid)? - .with_context(|| format!("can't find tipset for events root {root_cid}"))?; - - let ts = ctx.chain_store().load_required_tipset_or_heaviest(&tsk)?; - - let events = EthEventHandler::collect_chain_events(&ctx, &ts, &root_cid).await?; - + let events = EthEventHandler::get_events_by_event_root(&ctx, &root_cid)?; Ok(events) } } diff --git a/src/rpc/methods/eth/filter/mod.rs b/src/rpc/methods/eth/filter/mod.rs index 67a1c605cb80..556437a35d41 100644 --- a/src/rpc/methods/eth/filter/mod.rs +++ b/src/rpc/methods/eth/filter/mod.rs @@ -37,7 +37,7 @@ use crate::rpc::reflect::Ctx; use crate::rpc::types::{Event, EventEntry}; use crate::shim::address::Address; use crate::shim::clock::ChainEpoch; -use crate::shim::executor::Entry; +use crate::shim::executor::{Entry, StampedEvent}; use crate::state_manager::StateEvents; use crate::utils::misc::env::env_or_default; use ahash::AHashMap as HashMap; @@ -366,39 +366,20 @@ impl EthEventHandler { Ok(()) } - pub async fn collect_chain_events( + /// Gets events by event root. + pub fn get_events_by_event_root( ctx: &Ctx, - tipset: &Tipset, events_root: &Cid, ) -> anyhow::Result> { - let state_events = ctx - .state_manager - .tipset_state_events(tipset, Some(events_root)) - .await?; - - ensure!( - state_events.roots.len() == state_events.events.len(), - "State events roots ({}) and events length ({}) mismatch ", - state_events.roots.len(), - state_events.events.len(), - ); - - let filtered_events = state_events - .roots - .into_iter() - .zip(state_events.events) - .filter(|(cid, _)| cid.as_ref() == Some(events_root)) - .map(|(_, v)| v); - - // Do NOT deduplicate events - the AMT can legitimately contain duplicate events - // if a contract emits the same event multiple times. We must preserve the exact - // order and count of events as stored in the AMT. - let chain_events: Vec = filtered_events - .into_iter() - .flat_map(|events| events.into_iter()) - .map(Into::into) - .collect(); + let state_events = + match StampedEvent::get_events(ctx.chain_store().blockstore(), events_root) { + Ok(e) => e, + Err(e) => { + return Err(anyhow::anyhow!("load events amt: {}", e)); + } + }; + let chain_events: Vec = state_events.into_iter().map(Into::into).collect(); Ok(chain_events) } diff --git a/src/state_manager/mod.rs b/src/state_manager/mod.rs index 7ad927b6d4fc..37a178fb04f9 100644 --- a/src/state_manager/mod.rs +++ b/src/state_manager/mod.rs @@ -555,30 +555,17 @@ where pub async fn tipset_state_events( self: &Arc, tipset: &Tipset, - events_root: Option<&Cid>, + _events_root: Option<&Cid>, ) -> anyhow::Result { let key = tipset.key(); let ts = tipset.clone(); let this = Arc::clone(self); let cids = tipset.cids(); - let events_root = events_root.cloned(); self.receipt_event_cache_handler .get_events_or_else( key, Box::new(move || { Box::pin(async move { - // Try to load events directly from the blockstore - if let Some(stamped_events) = events_root - .as_ref() - .and_then(|root| StampedEvent::get_events(this.blockstore(), root).ok()) - .filter(|events| !events.is_empty()) - { - return Ok(StateEvents { - events: vec![stamped_events], - roots: vec![events_root], - }); - } - // Fallback: compute the tipset state if events not found in the blockstore let state_out = this .compute_tipset_state(ts, NO_CALLBACK, VMTrace::NotTraced) diff --git a/src/tool/subcommands/api_cmd/test_snapshots.txt b/src/tool/subcommands/api_cmd/test_snapshots.txt index 0823d6a28cab..9cd6a473da01 100644 --- a/src/tool/subcommands/api_cmd/test_snapshots.txt +++ b/src/tool/subcommands/api_cmd/test_snapshots.txt @@ -1,10 +1,10 @@ filecoin_beacongetentry_1741270283524367.rpcsnap.json.zst filecoin_chaingetblock_1736937164811210.rpcsnap.json.zst filecoin_chaingetblockmessages_1736937164799678.rpcsnap.json.zst -filecoin_chaingetevents_1746450533519970.rpcsnap.json.zst -filecoin_chaingetevents_1746450533600537.rpcsnap.json.zst -filecoin_chaingetevents_1746450551991052.rpcsnap.json.zst filecoin_chaingetevents_1764864316078100.rpcsnap.json.zst +filecoin_chaingetevents_1765289237680041.rpcsnap.json.zst +filecoin_chaingetevents_1765289237680294.rpcsnap.json.zst +filecoin_chaingetevents_1765289237681455.rpcsnap.json.zst filecoin_chaingetfinalizedtipset_1759828121342574.rpcsnap.json.zst filecoin_chaingetgenesis_1736937286915866.rpcsnap.json.zst filecoin_chaingetmessage_1741270616352800.rpcsnap.json.zst From 35ac348ec62991841000ca92115d10156383c3d1 Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Tue, 9 Dec 2025 20:05:36 +0530 Subject: [PATCH 5/6] remove the indices store --- src/benchmark_private/tipset_validation.rs | 1 - src/chain/store/chain_store.rs | 37 ++--------------- src/chain_sync/chain_follower.rs | 1 - src/daemon/context.rs | 1 - src/daemon/db_util.rs | 7 +--- src/db/car/many.rs | 18 +------- src/db/memory.rs | 20 +-------- src/db/mod.rs | 41 ------------------- src/db/parity_db.rs | 28 +------------ src/libp2p/chain_exchange/provider.rs | 1 - src/rpc/methods/chain.rs | 1 - src/rpc/methods/eth/filter/mod.rs | 3 +- src/rpc/methods/sync.rs | 10 +---- src/state_manager/mod.rs | 6 --- src/state_manager/tests.rs | 1 - src/tool/offline_server/server.rs | 1 - .../subcommands/api_cmd/api_compare_tests.rs | 1 - .../api_cmd/generate_test_snapshot.rs | 30 +------------- src/tool/subcommands/api_cmd/test_snapshot.rs | 39 ++++++------------ src/tool/subcommands/index_cmd.rs | 1 - src/tool/subcommands/state_compute_cmd.rs | 2 - 21 files changed, 26 insertions(+), 224 deletions(-) diff --git a/src/benchmark_private/tipset_validation.rs b/src/benchmark_private/tipset_validation.rs index e1957393bad0..81e0a34d93ae 100644 --- a/src/benchmark_private/tipset_validation.rs +++ b/src/benchmark_private/tipset_validation.rs @@ -56,7 +56,6 @@ async fn prepare_validation( db.clone(), db.clone(), db.clone(), - db.clone(), chain_config, genesis_header, )?); diff --git a/src/chain/store/chain_store.rs b/src/chain/store/chain_store.rs index b0de52586e47..a90e8d14eb11 100644 --- a/src/chain/store/chain_store.rs +++ b/src/chain/store/chain_store.rs @@ -6,7 +6,7 @@ use super::{ index::{ChainIndex, ResolveNullTipset}, tipset_tracker::TipsetTracker, }; -use crate::db::{EthMappingsStore, EthMappingsStoreExt, IndicesStore, IndicesStoreExt}; +use crate::db::{EthMappingsStore, EthMappingsStoreExt}; use crate::interpreter::{BlockMessages, VMTrace}; use crate::libp2p_bitswap::{BitswapStoreRead, BitswapStoreReadWrite}; use crate::message::{ChainMessage, Message as MessageTrait, SignedMessage}; @@ -82,9 +82,6 @@ pub struct ChainStore { /// Ethereum mappings store eth_mappings: Arc, - /// Indices store - indices: Arc, - /// Needed by the Ethereum mapping. chain_config: Arc, } @@ -121,7 +118,6 @@ where db: Arc, heaviest_tipset_key_provider: Arc, eth_mappings: Arc, - indices: Arc, chain_config: Arc, genesis_block_header: CachingBlockHeader, ) -> anyhow::Result { @@ -139,7 +135,6 @@ where genesis_block_header, validated_blocks, eth_mappings, - indices, chain_config, }; @@ -204,15 +199,6 @@ where .map(|(cid, _)| cid)) } - pub fn put_index(&self, key: &Cid, value: &V) -> Result<(), Error> { - self.indices.write_obj(key, value)?; - Ok(()) - } - - pub fn get_tipset_key_by_events_root(&self, key: &Cid) -> Result, Error> { - Ok(self.indices.read_obj(key)?) - } - /// Expands tipset to tipset with all other headers in the same epoch using /// the tipset tracker. fn expand_tipset(&self, header: CachingBlockHeader) -> Result { @@ -754,15 +740,8 @@ mod tests { message_receipts: Cid::new_v1(DAG_CBOR, MultihashCode::Identity.digest(&[])), ..Default::default() }); - let cs = ChainStore::new( - db.clone(), - db.clone(), - db.clone(), - db, - chain_config, - gen_block.clone(), - ) - .unwrap(); + let cs = + ChainStore::new(db.clone(), db.clone(), db, chain_config, gen_block.clone()).unwrap(); assert_eq!(cs.genesis_block_header(), &gen_block); } @@ -776,15 +755,7 @@ mod tests { ..Default::default() }); - let cs = ChainStore::new( - db.clone(), - db.clone(), - db.clone(), - db, - chain_config, - gen_block, - ) - .unwrap(); + let cs = ChainStore::new(db.clone(), db.clone(), db, chain_config, gen_block).unwrap(); let cid = Cid::new_v1(DAG_CBOR, MultihashCode::Blake2b256.digest(&[1, 2, 3])); assert!(!cs.is_block_validated(&cid)); diff --git a/src/chain_sync/chain_follower.rs b/src/chain_sync/chain_follower.rs index 447740c5aacd..ff7a34488810 100644 --- a/src/chain_sync/chain_follower.rs +++ b/src/chain_sync/chain_follower.rs @@ -918,7 +918,6 @@ mod tests { db.clone(), db.clone(), db.clone(), - db.clone(), Default::default(), genesis_header.clone().into(), ) diff --git a/src/daemon/context.rs b/src/daemon/context.rs index 7e0399229b87..48d4e46a5ca5 100644 --- a/src/daemon/context.rs +++ b/src/daemon/context.rs @@ -245,7 +245,6 @@ async fn create_state_manager( Arc::clone(db), Arc::new(db.clone()), eth_mappings, - db.writer().clone(), chain_config.clone(), genesis_header.clone(), )?); diff --git a/src/daemon/db_util.rs b/src/daemon/db_util.rs index b5933e512cc3..f7d904d7d21b 100644 --- a/src/daemon/db_util.rs +++ b/src/daemon/db_util.rs @@ -329,14 +329,9 @@ where let epoch = ts.epoch(); let tsk = ts.key().clone(); - let state_output = state_manager + state_manager .compute_tipset_state(ts.clone(), NO_CALLBACK, VMTrace::NotTraced) .await?; - for events_root in state_output.events_roots.iter().flatten() { - tracing::trace!("Indexing events root @{epoch}: {events_root}"); - - state_manager.chain_store().put_index(events_root, &tsk)?; - } delegated_messages.append( &mut state_manager diff --git a/src/db/car/many.rs b/src/db/car/many.rs index ed5dc78810ff..100ab25bd4cc 100644 --- a/src/db/car/many.rs +++ b/src/db/car/many.rs @@ -11,8 +11,8 @@ use super::{AnyCar, ZstdFrameCache}; use crate::blocks::TipsetKey; use crate::db::{ - BlockstoreWriteOpsSubscribable, EthMappingsStore, IndicesStore, MemoryDB, PersistentStore, - SettingsStore, SettingsStoreExt, + BlockstoreWriteOpsSubscribable, EthMappingsStore, MemoryDB, PersistentStore, SettingsStore, + SettingsStoreExt, }; use crate::libp2p_bitswap::BitswapStoreReadWrite; use crate::rpc::eth::types::EthHash; @@ -251,20 +251,6 @@ impl EthMappingsStore for ManyCar { } } -impl IndicesStore for ManyCar { - fn read_bin(&self, key: &Cid) -> anyhow::Result>> { - IndicesStore::read_bin(self.writer(), key) - } - - fn write_bin(&self, key: &Cid, value: &[u8]) -> anyhow::Result<()> { - IndicesStore::write_bin(self.writer(), key, value) - } - - fn exists(&self, key: &Cid) -> anyhow::Result { - IndicesStore::exists(self.writer(), key) - } -} - impl super::super::HeaviestTipsetKeyProvider for ManyCar { fn heaviest_tipset_key(&self) -> anyhow::Result { match SettingsStoreExt::read_obj::(self, crate::db::setting_keys::HEAD_KEY)? { diff --git a/src/db/memory.rs b/src/db/memory.rs index d091ebc9ba8f..1b2015fdf50f 100644 --- a/src/db/memory.rs +++ b/src/db/memory.rs @@ -3,7 +3,7 @@ use super::{EthMappingsStore, SettingsStore, SettingsStoreExt}; use crate::blocks::TipsetKey; -use crate::db::{IndicesStore, PersistentStore}; +use crate::db::PersistentStore; use crate::libp2p_bitswap::{BitswapStoreRead, BitswapStoreReadWrite}; use crate::rpc::eth::types::EthHash; use crate::utils::db::car_stream::CarBlock; @@ -21,7 +21,6 @@ pub struct MemoryDB { blockchain_persistent_db: RwLock>>, settings_db: RwLock>>, pub eth_mappings_db: RwLock>>, - pub indices_db: RwLock>>, } impl MemoryDB { @@ -110,23 +109,6 @@ impl EthMappingsStore for MemoryDB { } } -impl IndicesStore for MemoryDB { - fn read_bin(&self, key: &Cid) -> anyhow::Result>> { - Ok(self.indices_db.read().get(key).cloned()) - } - - fn write_bin(&self, key: &Cid, value: &[u8]) -> anyhow::Result<()> { - self.indices_db - .write() - .insert(key.to_owned(), value.to_vec()); - Ok(()) - } - - fn exists(&self, key: &Cid) -> anyhow::Result { - Ok(self.indices_db.read().contains_key(key)) - } -} - impl Blockstore for MemoryDB { fn get(&self, k: &Cid) -> anyhow::Result>> { Ok(self.blockchain_db.read().get(k).cloned().or(self diff --git a/src/db/mod.rs b/src/db/mod.rs index 9712dfab063b..ef55e40aeaac 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -191,47 +191,6 @@ impl EthMappingsStoreExt for T { } } -pub trait IndicesStore { - fn read_bin(&self, key: &Cid) -> anyhow::Result>>; - - fn write_bin(&self, key: &Cid, value: &[u8]) -> anyhow::Result<()>; - - #[allow(dead_code)] - fn exists(&self, key: &Cid) -> anyhow::Result; -} - -impl IndicesStore for Arc { - fn read_bin(&self, key: &Cid) -> anyhow::Result>> { - IndicesStore::read_bin(self.as_ref(), key) - } - - fn write_bin(&self, key: &Cid, value: &[u8]) -> anyhow::Result<()> { - IndicesStore::write_bin(self.as_ref(), key, value) - } - - fn exists(&self, key: &Cid) -> anyhow::Result { - IndicesStore::exists(self.as_ref(), key) - } -} - -pub trait IndicesStoreExt { - fn read_obj(&self, key: &Cid) -> anyhow::Result>; - fn write_obj(&self, key: &Cid, value: &V) -> anyhow::Result<()>; -} - -impl IndicesStoreExt for T { - fn read_obj(&self, key: &Cid) -> anyhow::Result> { - match self.read_bin(key)? { - Some(bytes) => Ok(Some(fvm_ipld_encoding::from_slice(&bytes)?)), - None => Ok(None), - } - } - - fn write_obj(&self, key: &Cid, value: &V) -> anyhow::Result<()> { - self.write_bin(key, &fvm_ipld_encoding::to_vec(value)?) - } -} - /// Traits for collecting DB stats pub trait DBStatistics { fn get_statistics(&self) -> Option { diff --git a/src/db/parity_db.rs b/src/db/parity_db.rs index bf5c608f22ef..da4ac22d9751 100644 --- a/src/db/parity_db.rs +++ b/src/db/parity_db.rs @@ -1,7 +1,7 @@ // Copyright 2019-2025 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use super::{EthMappingsStore, IndicesStore, PersistentStore, SettingsStore}; +use super::{EthMappingsStore, PersistentStore, SettingsStore}; use crate::blocks::TipsetKey; use crate::db::{DBStatistics, parity_db_config::ParityDbConfig}; use crate::libp2p_bitswap::{BitswapStoreRead, BitswapStoreReadWrite}; @@ -39,8 +39,6 @@ pub enum DbColumn { /// Anything stored in this column can be considered permanent, unless manually /// deleted. PersistentGraph, - /// Column for storing indexed values. - Indices, } impl DbColumn { @@ -77,12 +75,6 @@ impl DbColumn { compression, ..Default::default() }, - DbColumn::Indices => parity_db::ColumnOptions { - preimage: false, - btree_index: false, - compression, - ..Default::default() - }, } }) .collect() @@ -229,23 +221,6 @@ impl EthMappingsStore for ParityDb { } } -impl IndicesStore for ParityDb { - fn read_bin(&self, key: &Cid) -> anyhow::Result>> { - self.read_from_column(key.to_bytes(), DbColumn::Indices) - } - - fn write_bin(&self, key: &Cid, value: &[u8]) -> anyhow::Result<()> { - self.write_to_column(key.to_bytes(), value, DbColumn::Indices) - } - - fn exists(&self, key: &Cid) -> anyhow::Result { - self.db - .get_size(DbColumn::Indices as u8, &key.to_bytes()) - .map(|size| size.is_some()) - .context("error checking if key exists") - } -} - fn has_subscribers(tx: &tokio::sync::broadcast::Sender) -> bool { tx.closed().now_or_never().is_none() } @@ -463,7 +438,6 @@ mod test { DbColumn::Settings => panic!("invalid column for IPLD data"), DbColumn::EthMappings => panic!("invalid column for IPLD data"), DbColumn::PersistentGraph => panic!("invalid column for GC enabled IPLD data"), - DbColumn::Indices => panic!("invalid indices column for IPLD data"), }; let actual = db.read_from_column(cid.to_bytes(), other_column).unwrap(); assert!(actual.is_none()); diff --git a/src/libp2p/chain_exchange/provider.rs b/src/libp2p/chain_exchange/provider.rs index a93fc6b05065..95ae31988a77 100644 --- a/src/libp2p/chain_exchange/provider.rs +++ b/src/libp2p/chain_exchange/provider.rs @@ -176,7 +176,6 @@ mod tests { let response = make_chain_exchange_response( &ChainStore::new( - db.clone(), db.clone(), db.clone(), db, diff --git a/src/rpc/methods/chain.rs b/src/rpc/methods/chain.rs index 1ebb07dbd6c7..87f678760562 100644 --- a/src/rpc/methods/chain.rs +++ b/src/rpc/methods/chain.rs @@ -1611,7 +1611,6 @@ mod tests { db, Arc::new(MemoryDB::default()), Arc::new(MemoryDB::default()), - Arc::new(MemoryDB::default()), Arc::new(ChainConfig::calibnet()), genesis_block_header, ) diff --git a/src/rpc/methods/eth/filter/mod.rs b/src/rpc/methods/eth/filter/mod.rs index 556437a35d41..661da2dd7ab4 100644 --- a/src/rpc/methods/eth/filter/mod.rs +++ b/src/rpc/methods/eth/filter/mod.rs @@ -280,8 +280,7 @@ impl EthEventHandler { let messages = ctx.chain_store().messages_for_tipset(tipset)?; - let StateEvents { events, .. } = - ctx.state_manager.tipset_state_events(tipset, None).await?; + let StateEvents { events, .. } = ctx.state_manager.tipset_state_events(tipset).await?; ensure!( messages.len() == events.len(), diff --git a/src/rpc/methods/sync.rs b/src/rpc/methods/sync.rs index fa2a13b66b31..ec356eb492ae 100644 --- a/src/rpc/methods/sync.rs +++ b/src/rpc/methods/sync.rs @@ -187,15 +187,7 @@ mod tests { }); let cs_arc = Arc::new( - ChainStore::new( - db.clone(), - db.clone(), - db.clone(), - db, - chain_config, - genesis_header, - ) - .unwrap(), + ChainStore::new(db.clone(), db.clone(), db, chain_config, genesis_header).unwrap(), ); let state_manager = Arc::new(StateManager::new(cs_arc.clone()).unwrap()); diff --git a/src/state_manager/mod.rs b/src/state_manager/mod.rs index 37a178fb04f9..4df0b7a7c848 100644 --- a/src/state_manager/mod.rs +++ b/src/state_manager/mod.rs @@ -492,15 +492,10 @@ where let state_output = self .compute_tipset_state(tipset.clone(), NO_CALLBACK, VMTrace::NotTraced) .await?; - for events_root in state_output.events_roots.iter().flatten() { - trace!("Indexing events root @{}: {}", tipset.epoch(), events_root); - self.chain_store().put_index(events_root, key)?; - } self.update_cache_with_state_output(key, &state_output); let ts_state = state_output.into(); - trace!("Completed tipset state calculation {:?}", tipset.cids()); Ok(ts_state) }) @@ -555,7 +550,6 @@ where pub async fn tipset_state_events( self: &Arc, tipset: &Tipset, - _events_root: Option<&Cid>, ) -> anyhow::Result { let key = tipset.key(); let ts = tipset.clone(); diff --git a/src/state_manager/tests.rs b/src/state_manager/tests.rs index b9d1db37100d..42c9ba96d52b 100644 --- a/src/state_manager/tests.rs +++ b/src/state_manager/tests.rs @@ -62,7 +62,6 @@ fn setup_chain_with_tipsets() -> TestChainSetup { db.clone(), db.clone(), db.clone(), - db.clone(), chain_config.clone(), genesis_header.clone().into(), ) diff --git a/src/tool/offline_server/server.rs b/src/tool/offline_server/server.rs index 14f72b95f3a1..9ade8e39e3e1 100644 --- a/src/tool/offline_server/server.rs +++ b/src/tool/offline_server/server.rs @@ -94,7 +94,6 @@ pub async fn start_offline_server( db.clone(), db.clone(), db.clone(), - db.clone(), chain_config, genesis_header.clone(), )?); diff --git a/src/tool/subcommands/api_cmd/api_compare_tests.rs b/src/tool/subcommands/api_cmd/api_compare_tests.rs index 19a073232ccf..52127364d060 100644 --- a/src/tool/subcommands/api_cmd/api_compare_tests.rs +++ b/src/tool/subcommands/api_cmd/api_compare_tests.rs @@ -2274,7 +2274,6 @@ async fn revalidate_chain(db: Arc, n_ts_to_validate: usize) -> anyhow:: db.clone(), db.clone(), db.clone(), - db.clone(), chain_config, genesis_header.clone(), )?); diff --git a/src/tool/subcommands/api_cmd/generate_test_snapshot.rs b/src/tool/subcommands/api_cmd/generate_test_snapshot.rs index f60f4e59afa8..c070db453434 100644 --- a/src/tool/subcommands/api_cmd/generate_test_snapshot.rs +++ b/src/tool/subcommands/api_cmd/generate_test_snapshot.rs @@ -10,8 +10,8 @@ use crate::{ chain_sync::network_context::SyncNetworkContext, daemon::db_util::load_all_forest_cars, db::{ - CAR_DB_DIR_NAME, EthMappingsStore, HeaviestTipsetKeyProvider, IndicesStore, MemoryDB, - SettingsStore, SettingsStoreExt, db_engine::open_db, parity_db::ParityDb, + CAR_DB_DIR_NAME, EthMappingsStore, HeaviestTipsetKeyProvider, MemoryDB, SettingsStore, + SettingsStoreExt, db_engine::open_db, parity_db::ParityDb, }, genesis::read_genesis_header, libp2p::{NetworkMessage, PeerManager}, @@ -89,13 +89,6 @@ pub(super) fn build_index(db: Arc>>) -> O .get_or_insert_with(ahash::HashMap::default) .insert(k.to_string(), Payload(v.clone())); } - let reader = db.tracker.indices_db.read(); - for (k, v) in reader.iter() { - index - .indices - .get_or_insert_with(ahash::HashMap::default) - .insert(k.to_string(), Payload(v.clone())); - } if index == Index::default() { None } else { @@ -121,7 +114,6 @@ async fn ctx( db.clone(), db.clone(), db.clone(), - db, chain_config, genesis_header, ) @@ -305,21 +297,3 @@ impl EthMappingsStore for ReadOpsTrackingStore { self.inner.delete(keys) } } - -impl IndicesStore for ReadOpsTrackingStore { - fn read_bin(&self, key: &Cid) -> anyhow::Result>> { - let result = self.inner.read_bin(key)?; - if let Some(v) = &result { - IndicesStore::write_bin(&self.tracker, key, v.as_slice())?; - } - self.inner.read_bin(key) - } - - fn write_bin(&self, key: &Cid, value: &[u8]) -> anyhow::Result<()> { - self.inner.write_bin(key, value) - } - - fn exists(&self, key: &Cid) -> anyhow::Result { - self.inner.exists(key) - } -} diff --git a/src/tool/subcommands/api_cmd/test_snapshot.rs b/src/tool/subcommands/api_cmd/test_snapshot.rs index e118341762bc..e431dc365821 100644 --- a/src/tool/subcommands/api_cmd/test_snapshot.rs +++ b/src/tool/subcommands/api_cmd/test_snapshot.rs @@ -22,7 +22,6 @@ use crate::{ shim::address::{CurrentNetwork, Network}, state_manager::StateManager, }; -use cid::Cid; use openrpc_types::ParamStructure; use parking_lot::RwLock; use serde::{Deserialize, Serialize}; @@ -53,20 +52,12 @@ pub struct RpcTestSnapshot { } fn backfill_eth_mappings(db: &MemoryDB, index: Option) -> anyhow::Result<()> { - if let Some(index) = index { - if let Some(mut guard) = db.eth_mappings_db.try_write() - && let Some(eth_mappings) = index.eth_mappings - { - for (k, v) in eth_mappings.iter() { - guard.insert(EthHash::from_str(k)?, v.0.clone()); - } - } - if let Some(mut guard) = db.indices_db.try_write() - && let Some(indices) = index.indices - { - for (k, v) in indices.iter() { - guard.insert(Cid::from_str(k)?, v.0.clone()); - } + if let Some(index) = index + && let Some(mut guard) = db.eth_mappings_db.try_write() + && let Some(eth_mappings) = index.eth_mappings + { + for (k, v) in eth_mappings.iter() { + guard.insert(EthHash::from_str(k)?, v.0.clone()); } } Ok(()) @@ -140,17 +131,13 @@ async fn ctx( let (tipset_send, _) = flume::bounded(5); let genesis_header = read_genesis_header(None, chain_config.genesis_bytes(&db).await?.as_deref(), &db).await?; - let chain_store = Arc::new( - ChainStore::new( - db.clone(), - db.clone(), - db.clone(), - db, - chain_config, - genesis_header.clone(), - ) - .unwrap(), - ); + let chain_store = Arc::new(ChainStore::new( + db.clone(), + db.clone(), + db, + chain_config, + genesis_header.clone(), + )?); let state_manager = Arc::new(StateManager::new(chain_store.clone()).unwrap()); let message_pool = MessagePool::new( MpoolRpcProvider::new(chain_store.publisher().clone(), state_manager.clone()), diff --git a/src/tool/subcommands/index_cmd.rs b/src/tool/subcommands/index_cmd.rs index 22b1b65ef3ee..9d56fbc35978 100644 --- a/src/tool/subcommands/index_cmd.rs +++ b/src/tool/subcommands/index_cmd.rs @@ -84,7 +84,6 @@ impl IndexCommands { db.clone(), db.clone(), db.clone(), - db.writer().clone(), chain_config, genesis_header.clone(), )?); diff --git a/src/tool/subcommands/state_compute_cmd.rs b/src/tool/subcommands/state_compute_cmd.rs index 17db9f1ce704..8b5523cfa74e 100644 --- a/src/tool/subcommands/state_compute_cmd.rs +++ b/src/tool/subcommands/state_compute_cmd.rs @@ -74,7 +74,6 @@ impl ComputeCommand { db.clone(), db.clone(), db.clone(), - db.clone(), chain_config, genesis_header, )?); @@ -136,7 +135,6 @@ impl ReplayComputeCommand { db.clone(), db.clone(), db.clone(), - db.clone(), chain_config, genesis_header, )?); From 1dd279f9829ae8ca5b46baa3b5bd3b567efd85a6 Mon Sep 17 00:00:00 2001 From: Aryan Tikarya Date: Wed, 10 Dec 2025 21:35:33 +0530 Subject: [PATCH 6/6] address comments --- src/shim/executor.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shim/executor.rs b/src/shim/executor.rs index 3c27c67e1955..cc2fca818f66 100644 --- a/src/shim/executor.rs +++ b/src/shim/executor.rs @@ -397,14 +397,14 @@ impl StampedEvent { // Try StampedEvent_v4 first (StampedEvent_v4 and StampedEvent_v3 are identical, use v4 here) if let Ok(amt) = Amt::::load(events_root, db) { - amt.for_each(|_, event| { + amt.for_each_cacheless(|_, event| { events.push(StampedEvent::V4(event.clone())); Ok(()) })?; } else { // Fallback to StampedEvent_v3 let amt = Amt::::load(events_root, db)?; - amt.for_each(|_, event| { + amt.for_each_cacheless(|_, event| { events.push(StampedEvent::V3(event.clone())); Ok(()) })?;