From eea530e7dc3d9e022431caa1f5e5a561fcfe9a79 Mon Sep 17 00:00:00 2001 From: d4m014 <271264252+d4m014@users.noreply.github.com> Date: Thu, 25 Jun 2026 13:53:12 +0100 Subject: [PATCH 1/4] feat: make store begin_write callers return Result and update callers --- bin/ethlambda/src/main.rs | 4 +- crates/blockchain/src/lib.rs | 4 +- crates/blockchain/src/reaggregate.rs | 18 ++--- crates/blockchain/src/store.rs | 28 ++++++-- crates/net/p2p/src/req_resp/handlers.rs | 20 ++++-- crates/net/rpc/src/lib.rs | 22 +++--- crates/storage/src/store.rs | 89 +++++++++++++++++-------- 7 files changed, 127 insertions(+), 58 deletions(-) diff --git a/bin/ethlambda/src/main.rs b/bin/ethlambda/src/main.rs index b26481f2f..912fef062 100644 --- a/bin/ethlambda/src/main.rs +++ b/bin/ethlambda/src/main.rs @@ -736,7 +736,9 @@ async fn fetch_initial_state( let mut store = Store::get_forkchoice_store(backend, state, signed_block.message.clone()) .inspect_err(|err| error!(%err, "Failed to initialize store from anchor state and block")) .map_err(|_| checkpoint_sync::CheckpointSyncError::AnchorPairingMismatch)?; - store.insert_signed_block(anchor_root, signed_block); + store + .insert_signed_block(anchor_root, signed_block) + .expect("inserting anchor block signatures into store should succeed"); Ok(store) } diff --git a/crates/blockchain/src/lib.rs b/crates/blockchain/src/lib.rs index 4360377d3..db041a983 100644 --- a/crates/blockchain/src/lib.rs +++ b/crates/blockchain/src/lib.rs @@ -681,7 +681,9 @@ impl BlockChainServer { self.pending_block_parents.insert(block_root, missing_root); // Persist block data to DB (no LiveChain entry — invisible to fork choice) - self.store.insert_pending_block(block_root, signed_block); + self.store + .insert_pending_block(block_root, signed_block) + .expect("DB insert should succeed"); // Store only the H256 reference in memory self.pending_blocks diff --git a/crates/blockchain/src/reaggregate.rs b/crates/blockchain/src/reaggregate.rs index 53275fac7..082e00503 100644 --- a/crates/blockchain/src/reaggregate.rs +++ b/crates/blockchain/src/reaggregate.rs @@ -312,14 +312,16 @@ mod tests { fn select_skips_target_at_or_below_justified() { let mut store = empty_store(); // Justified at slot 5; an attestation with target.slot = 5 must be skipped. - store.update_checkpoints(ethlambda_storage::ForkCheckpoints::new( - store.head(), - Some(Checkpoint { - root: H256::ZERO, - slot: 5, - }), - None, - )); + store + .update_checkpoints(ethlambda_storage::ForkCheckpoints::new( + store.head(), + Some(Checkpoint { + root: H256::ZERO, + slot: 5, + }), + None, + )) + .expect("update_checkpoints should succeed"); let candidates = select_candidates(&store, &[make_att(6, 5, &[0, 1])]); assert!(candidates.is_empty()); } diff --git a/crates/blockchain/src/store.rs b/crates/blockchain/src/store.rs index 8f7807d20..1352cbb9f 100644 --- a/crates/blockchain/src/store.rs +++ b/crates/blockchain/src/store.rs @@ -58,7 +58,9 @@ pub fn update_head(store: &mut Store, log_tree: bool) { .get_state(&new_head) .map(|state| state.latest_finalized) .filter(|finalized| store.get_block_header(&finalized.root).is_some()); - store.update_checkpoints(ForkCheckpoints::new(new_head, None, finalized)); + store + .update_checkpoints(ForkCheckpoints::new(new_head, None, finalized)) + .expect("update_checkpoints should succeed"); if old_head != new_head { let old_slot = store @@ -573,12 +575,18 @@ fn on_block_core( .then_some(post_state.latest_justified); if let Some(justified) = justified { - store.update_checkpoints(ForkCheckpoints::new(store.head(), Some(justified), None)); + store + .update_checkpoints(ForkCheckpoints::new(store.head(), Some(justified), None)) + .expect("update_checkpoints should succeed"); } // Store signed block and state - store.insert_signed_block(block_root, signed_block.clone()); - store.insert_state(block_root, post_state); + store + .insert_signed_block(block_root, signed_block.clone()) + .expect("DB insert should succeed"); + store + .insert_state(block_root, post_state) + .expect("DB insert should succeed"); for att in block.body.attestations.iter() { // Count each participating validator as a valid attestation. @@ -1220,7 +1228,9 @@ mod tests { }, proof: make_signed_block_proof(0, vec![]), }; - store.insert_signed_block(root, signed_block); + store + .insert_signed_block(root, signed_block) + .expect("insert test block should succeed"); } fn new_test_store() -> Store { @@ -1251,7 +1261,9 @@ mod tests { let head_justified = Checkpoint { root: a, slot: 1 }; let mut head_state = State::from_genesis(1000, vec![]); head_state.latest_justified = head_justified; - store.insert_state(b, head_state); + store + .insert_state(b, head_state) + .expect("insert head state should succeed"); // Store's global justified latched onto a higher, off-head checkpoint, // as it would after a minority fork justified a slot the head never saw. @@ -1259,7 +1271,9 @@ mod tests { root: H256([9u8; 32]), slot: 5, }; - store.update_checkpoints(ForkCheckpoints::new(b, Some(off_head_justified), None)); + store + .update_checkpoints(ForkCheckpoints::new(b, Some(off_head_justified), None)) + .expect("update_checkpoints should succeed"); store.set_time(2 * INTERVALS_PER_SLOT); let data = produce_attestation_data(&store, 2); diff --git a/crates/net/p2p/src/req_resp/handlers.rs b/crates/net/p2p/src/req_resp/handlers.rs index ad041766a..2a88a9bb0 100644 --- a/crates/net/p2p/src/req_resp/handlers.rs +++ b/crates/net/p2p/src/req_resp/handlers.rs @@ -627,20 +627,30 @@ mod tests { let block_1 = signed_block(1, store.head()); let root_1 = block_1.message.hash_tree_root(); - store.insert_signed_block(root_1, block_1); + store + .insert_signed_block(root_1, block_1) + .expect("insert test block should succeed"); let block_2 = signed_block(2, root_1); let root_2 = block_2.message.hash_tree_root(); - store.insert_signed_block(root_2, block_2); + store + .insert_signed_block(root_2, block_2) + .expect("insert test block should succeed"); let side_block_3 = signed_block(3, root_1); let side_root_3 = side_block_3.message.hash_tree_root(); - store.insert_signed_block(side_root_3, side_block_3); + store + .insert_signed_block(side_root_3, side_block_3) + .expect("insert test block should succeed"); let block_4 = signed_block(4, root_2); let root_4 = block_4.message.hash_tree_root(); - store.insert_signed_block(root_4, block_4); - store.update_checkpoints(ForkCheckpoints::head_only(root_4)); + store + .insert_signed_block(root_4, block_4) + .expect("insert test block should succeed"); + store + .update_checkpoints(ForkCheckpoints::head_only(root_4)) + .expect("update_checkpoints should succeed"); let blocks = canonical_blocks_by_range(&store, 1, 4); let slots: Vec<_> = blocks.iter().map(|block| block.message.slot).collect(); diff --git a/crates/net/rpc/src/lib.rs b/crates/net/rpc/src/lib.rs index 092687656..99a2b44c8 100644 --- a/crates/net/rpc/src/lib.rs +++ b/crates/net/rpc/src/lib.rs @@ -446,15 +446,19 @@ mod tests { }; // Persist the signed block and mark it as the latest finalized checkpoint. - store.insert_signed_block(block_root, signed_block.clone()); - store.update_checkpoints(ForkCheckpoints::new( - block_root, - None, - Some(Checkpoint { - root: block_root, - slot: 1, - }), - )); + store + .insert_signed_block(block_root, signed_block.clone()) + .expect("insert_signed_block should succeed"); + store + .update_checkpoints(ForkCheckpoints::new( + block_root, + None, + Some(Checkpoint { + root: block_root, + slot: 1, + }), + )) + .expect("update_checkpoints should succeed"); let expected_ssz = signed_block.to_ssz(); diff --git a/crates/storage/src/store.rs b/crates/storage/src/store.rs index 0700b02a2..1587ae019 100644 --- a/crates/storage/src/store.rs +++ b/crates/storage/src/store.rs @@ -705,12 +705,13 @@ impl Store { T::from_ssz_bytes(&bytes).expect("valid encoding") } - fn set_metadata(&self, key: &[u8], value: &T) { + fn set_metadata(&self, key: &[u8], value: &T) -> Result<(), Error> { let mut batch = self.backend.begin_write().expect("write batch"); batch .put_batch(Table::Metadata, vec![(key.to_vec(), value.to_ssz())]) .expect("put metadata"); batch.commit().expect("commit"); + Ok(()) } // ============ Time ============ @@ -726,7 +727,7 @@ impl Store { /// Sets the current store time. pub fn set_time(&mut self, time: u64) { - self.set_metadata(KEY_TIME, &time); + self.set_metadata(KEY_TIME, &time).expect("set time"); } // ============ Config ============ @@ -752,7 +753,8 @@ impl Store { /// Sets the safe target block root. pub fn set_safe_target(&mut self, safe_target: H256) { - self.set_metadata(KEY_SAFE_TARGET, &safe_target); + self.set_metadata(KEY_SAFE_TARGET, &safe_target) + .expect("set safe target"); } // ============ Checkpoints ============ @@ -776,7 +778,7 @@ impl Store { /// - Finalized is updated if provided. /// /// When finalization advances, prunes the LiveChain index. - pub fn update_checkpoints(&mut self, checkpoints: ForkCheckpoints) { + pub fn update_checkpoints(&mut self, checkpoints: ForkCheckpoints) -> Result<(), Error> { // Read old finalized slot before updating metadata let old_finalized_slot = self.latest_finalized().slot; @@ -801,8 +803,11 @@ impl Store { if let Some(finalized) = checkpoints.finalized && finalized.slot > old_finalized_slot { - let pruned_chain = self.prune_live_chain(finalized.slot); + let pruned_chain = self + .prune_live_chain(finalized.slot) + .expect("prune live chain"); let pruned_sigs = self.prune_gossip_signatures(finalized.slot); + let pruned_payloads = self.prune_stale_aggregated_payloads(finalized.slot); if pruned_chain > 0 || pruned_sigs > 0 || pruned_payloads > 0 { @@ -812,6 +817,7 @@ impl Store { ); } } + Ok(()) } /// Prune old states and blocks to keep storage bounded. @@ -830,8 +836,12 @@ impl Store { let tip_slot = self .get_block_header(&self.head()) .map_or(finalized_slot, |header| header.slot); - let pruned_states = self.prune_old_states(&protected_roots); - let pruned_signatures = self.prune_old_block_signatures(finalized_slot, tip_slot); + let pruned_states = self + .prune_old_states(&protected_roots) + .expect("prune old states"); + let pruned_signatures = self + .prune_old_block_signatures(finalized_slot, tip_slot) + .expect("prune old block signatures"); if pruned_states > 0 || pruned_signatures > 0 { info!( pruned_states, @@ -890,7 +900,7 @@ impl Store { /// LiveChain index is pruned. /// /// Returns the number of entries pruned. - pub fn prune_live_chain(&mut self, finalized_slot: u64) -> usize { + pub fn prune_live_chain(&mut self, finalized_slot: u64) -> Result { let view = self.backend.begin_read().expect("read view"); // Collect keys to delete - stop once we hit finalized_slot @@ -909,7 +919,7 @@ impl Store { let count = keys_to_delete.len(); if count == 0 { - return 0; + return Ok(0); } let mut batch = self.backend.begin_write().expect("write batch"); @@ -917,7 +927,7 @@ impl Store { .delete_batch(Table::LiveChain, keys_to_delete) .expect("delete non-finalized chain entries"); batch.commit().expect("commit"); - count + Ok(count) } /// Prune gossip signatures for slots <= finalized_slot. @@ -946,7 +956,7 @@ impl Store { /// states whose roots appear in `protected_roots` (finalized, justified). /// /// Returns the number of states pruned. - pub fn prune_old_states(&mut self, protected_roots: &[H256]) -> usize { + pub fn prune_old_states(&mut self, protected_roots: &[H256]) -> Result { let view = self.backend.begin_read().expect("read view"); // Collect (root_bytes, slot) from BlockHeaders to determine state age. @@ -962,7 +972,7 @@ impl Store { drop(view); if entries.len() <= STATES_TO_KEEP { - return 0; + return Ok(0); } // Sort by slot descending (newest first) @@ -986,7 +996,7 @@ impl Store { .expect("delete old states"); batch.commit().expect("commit"); } - count + Ok(count) } /// Prune signatures of old finalized blocks, keeping a recent window. @@ -1005,12 +1015,16 @@ impl Store { /// safety, or re-aggregation once outside the window. /// /// Returns the number of signatures pruned. - pub fn prune_old_block_signatures(&mut self, finalized_slot: u64, tip_slot: u64) -> usize { + pub fn prune_old_block_signatures( + &mut self, + finalized_slot: u64, + tip_slot: u64, + ) -> Result { let cutoff = tip_slot.saturating_sub(SIGNATURE_PRUNING_RANGE); // Only prune when the whole window is finalized; never touch // non-finalized signatures. if cutoff > finalized_slot { - return 0; + return Ok(0); } let view = self.backend.begin_read().expect("read view"); @@ -1034,7 +1048,7 @@ impl Store { .expect("delete finalized block signatures"); batch.commit().expect("commit"); } - count + Ok(count) } /// Get the block header by root. @@ -1056,10 +1070,15 @@ impl Store { /// /// When the block is later processed via [`insert_signed_block`](Self::insert_signed_block), /// the same keys are overwritten (idempotent) and a `LiveChain` entry is added. - pub fn insert_pending_block(&mut self, root: H256, signed_block: SignedBlock) { + pub fn insert_pending_block( + &mut self, + root: H256, + signed_block: SignedBlock, + ) -> Result<(), Error> { let mut batch = self.backend.begin_write().expect("write batch"); write_signed_block(batch.as_mut(), &root, signed_block); batch.commit().expect("commit"); + Ok(()) } /// Insert a signed block, storing the block and signatures separately. @@ -1069,7 +1088,11 @@ impl Store { /// only storing signatures for non-genesis blocks. /// /// Takes ownership to avoid cloning large signature data. - pub fn insert_signed_block(&mut self, root: H256, signed_block: SignedBlock) { + pub fn insert_signed_block( + &mut self, + root: H256, + signed_block: SignedBlock, + ) -> Result<(), Error> { let mut batch = self.backend.begin_write().expect("write batch"); let block = write_signed_block(batch.as_mut(), &root, signed_block); @@ -1082,6 +1105,7 @@ impl Store { .expect("put non-finalized chain index"); batch.commit().expect("commit"); + Ok(()) } /// Get a block (header + body, no signatures) by root. @@ -1171,11 +1195,12 @@ impl Store { } /// Stores a state indexed by block root. - pub fn insert_state(&mut self, root: H256, state: State) { + pub fn insert_state(&mut self, root: H256, state: State) -> Result<(), Error> { let mut batch = self.backend.begin_write().expect("write batch"); let entries = vec![(root.to_ssz(), state.to_ssz())]; batch.put_batch(Table::States, entries).expect("put state"); batch.commit().expect("commit"); + Ok(()) } // ============ Attestation Extraction ============ @@ -1571,7 +1596,9 @@ mod tests { // tip = range + 10, finalized = range + 5, so cutoff = tip - range = 10. let tip_slot = SIGNATURE_PRUNING_RANGE + 10; let finalized_slot = SIGNATURE_PRUNING_RANGE + 5; - let pruned = store.prune_old_block_signatures(finalized_slot, tip_slot); + let pruned = store + .prune_old_block_signatures(finalized_slot, tip_slot) + .expect("prune"); // cutoff = 10: slots 0..9 pruned, slots 10..12 kept (within the window). assert_eq!(pruned, 10); @@ -1600,7 +1627,9 @@ mod tests { // cutoff = tip - range > finalized → prune nothing. let tip_slot = SIGNATURE_PRUNING_RANGE + 100; let finalized_slot = 5; - let pruned = store.prune_old_block_signatures(finalized_slot, tip_slot); + let pruned = store + .prune_old_block_signatures(finalized_slot, tip_slot) + .expect("prune"); assert_eq!(pruned, 0); assert_eq!(count_entries(backend.as_ref(), Table::BlockSignatures), 10); } @@ -1616,7 +1645,7 @@ mod tests { // Early chain: tip < SIGNATURE_PRUNING_RANGE → cutoff saturates to 0, // so nothing is old enough to prune even though slots are finalized. - let pruned = store.prune_old_block_signatures(9, 9); + let pruned = store.prune_old_block_signatures(9, 9).expect("prune"); assert_eq!(pruned, 0); assert_eq!(count_entries(backend.as_ref(), Table::BlockSignatures), 10); } @@ -1638,7 +1667,7 @@ mod tests { STATES_TO_KEEP ); - let pruned = store.prune_old_states(&[]); + let pruned = store.prune_old_states(&[]).expect("prune"); assert_eq!(pruned, 0); } @@ -1654,7 +1683,7 @@ mod tests { } assert_eq!(count_entries(backend.as_ref(), Table::States), total); - let pruned = store.prune_old_states(&[]); + let pruned = store.prune_old_states(&[]).expect("prune"); assert_eq!(pruned, 5); assert_eq!( count_entries(backend.as_ref(), Table::States), @@ -1684,7 +1713,9 @@ mod tests { let finalized_root = root(0); let justified_root = root(2); - let pruned = store.prune_old_states(&[finalized_root, justified_root]); + let pruned = store + .prune_old_states(&[finalized_root, justified_root]) + .expect("prune"); // 5 would be pruned, but 2 are protected assert_eq!(pruned, 3); @@ -1745,7 +1776,9 @@ mod tests { // Use the last inserted root as head. Calling update_checkpoints with // head_only triggers the fallback path (finalization doesn't advance). let head_root = root(total_states as u64 - 1); - store.update_checkpoints(ForkCheckpoints::head_only(head_root)); + store + .update_checkpoints(ForkCheckpoints::head_only(head_root)) + .expect(""); // update_checkpoints no longer prunes states/blocks inline — the caller // must invoke prune_old_data() separately (after a block cascade completes). @@ -1796,7 +1829,9 @@ mod tests { // Use the last inserted root as head let head_root = root(STATES_TO_KEEP as u64 - 1); - store.update_checkpoints(ForkCheckpoints::head_only(head_root)); + store + .update_checkpoints(ForkCheckpoints::head_only(head_root)) + .expect("update checkpoints"); store.prune_old_data(); // Nothing should be pruned (within retention window) From 5fef332213e1f2bf2da1f57fa45941d0fdb9cfed Mon Sep 17 00:00:00 2001 From: Damola Enitan <271264252+d4m014@users.noreply.github.com> Date: Thu, 25 Jun 2026 14:15:39 +0100 Subject: [PATCH 2/4] Update crates/storage/src/store.rs Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> --- crates/storage/src/store.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/storage/src/store.rs b/crates/storage/src/store.rs index 1587ae019..349e20bf4 100644 --- a/crates/storage/src/store.rs +++ b/crates/storage/src/store.rs @@ -1778,7 +1778,7 @@ mod tests { let head_root = root(total_states as u64 - 1); store .update_checkpoints(ForkCheckpoints::head_only(head_root)) - .expect(""); + .expect("update_checkpoints should succeed"); // update_checkpoints no longer prunes states/blocks inline — the caller // must invoke prune_old_data() separately (after a block cascade completes). From db6cbed5785b0de06be604952dcf2b24fe0ef348 Mon Sep 17 00:00:00 2001 From: d4m014 <271264252+d4m014@users.noreply.github.com> Date: Thu, 25 Jun 2026 14:31:44 +0100 Subject: [PATCH 3/4] fix: make a consistent error handling for insert_signed_block in fetch_initial_state --- bin/ethlambda/src/checkpoint_sync.rs | 2 ++ bin/ethlambda/src/main.rs | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/bin/ethlambda/src/checkpoint_sync.rs b/bin/ethlambda/src/checkpoint_sync.rs index b1abd69fa..9bed63723 100644 --- a/bin/ethlambda/src/checkpoint_sync.rs +++ b/bin/ethlambda/src/checkpoint_sync.rs @@ -67,6 +67,8 @@ pub enum CheckpointSyncError { AnchorPairingMismatch, #[error("no checkpoint urls configured")] NoCheckpointUrls, + #[error("failed to insert anchor signed block into store")] + StoreInsertSignedBlock, } /// Build the HTTP client used for checkpoint sync fetches. diff --git a/bin/ethlambda/src/main.rs b/bin/ethlambda/src/main.rs index 912fef062..20f6fd481 100644 --- a/bin/ethlambda/src/main.rs +++ b/bin/ethlambda/src/main.rs @@ -738,7 +738,8 @@ async fn fetch_initial_state( .map_err(|_| checkpoint_sync::CheckpointSyncError::AnchorPairingMismatch)?; store .insert_signed_block(anchor_root, signed_block) - .expect("inserting anchor block signatures into store should succeed"); + .inspect_err(|err| error!(%err, "Failed to insert anchor signed block into store")) + .map_err(|_| checkpoint_sync::CheckpointSyncError::StoreInsertSignedBlock)?; Ok(store) } From f99aa3baf05f8713a5cae6ab4add4a00f619a115 Mon Sep 17 00:00:00 2001 From: d4m014 <271264252+d4m014@users.noreply.github.com> Date: Thu, 25 Jun 2026 14:50:45 +0100 Subject: [PATCH 4/4] feat: update set_time and set_safe_target to return Result and update callers --- crates/blockchain/src/store.rs | 36 +++++++++++++++++++++++++--------- crates/storage/src/store.rs | 7 +++---- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/crates/blockchain/src/store.rs b/crates/blockchain/src/store.rs index 1352cbb9f..7de13c27b 100644 --- a/crates/blockchain/src/store.rs +++ b/crates/blockchain/src/store.rs @@ -121,7 +121,9 @@ fn update_safe_target(store: &mut Store) { &attestations, min_target_score, ); - store.set_safe_target(safe_target); + store + .set_safe_target(safe_target) + .expect("set_safe_target should succeed"); } /// Return whether `ancestor` lies on `descendant`'s parent chain. @@ -265,11 +267,15 @@ pub fn on_tick(store: &mut Store, timestamp_ms: u64, has_proposal: bool) { // If we're more than a slot behind, fast-forward to a slot before. // Operations are idempotent, so this should be fine. if time.saturating_sub(store.time()) > INTERVALS_PER_SLOT { - store.set_time(time - INTERVALS_PER_SLOT); + store + .set_time(time - INTERVALS_PER_SLOT) + .expect("set_time should succeed"); } while store.time() < time { - store.set_time(store.time() + 1); + store + .set_time(store.time() + 1) + .expect("set_time should succeed"); let slot = store.time() / INTERVALS_PER_SLOT; let interval = store.time() % INTERVALS_PER_SLOT; @@ -1274,7 +1280,9 @@ mod tests { store .update_checkpoints(ForkCheckpoints::new(b, Some(off_head_justified), None)) .expect("update_checkpoints should succeed"); - store.set_time(2 * INTERVALS_PER_SLOT); + store + .set_time(2 * INTERVALS_PER_SLOT) + .expect("set_time should succeed"); let data = produce_attestation_data(&store, 2); @@ -1303,7 +1311,9 @@ mod tests { insert_test_block(&mut store, base, 1, genesis); insert_test_block(&mut store, fork_left, 2, base); insert_test_block(&mut store, fork_right, 3, base); - store.set_time(3 * INTERVALS_PER_SLOT); + store + .set_time(3 * INTERVALS_PER_SLOT) + .expect("set_time should succeed"); // source=base, target=fork_left, head=fork_right: target and head share a // parent (base) but neither is an ancestor of the other. @@ -1345,7 +1355,9 @@ mod tests { insert_test_block(&mut store, fork_left, 2, base); insert_test_block(&mut store, fork_right, 3, base); insert_test_block(&mut store, fork_right_head, 4, fork_right); - store.set_time(4 * INTERVALS_PER_SLOT); + store + .set_time(4 * INTERVALS_PER_SLOT) + .expect("set_time should succeed"); // source=fork_left (abandoned branch), target=head=fork_right_head: // source precedes target in slot but lies off the target's chain. @@ -1386,7 +1398,9 @@ mod tests { insert_test_block(&mut store, b1, 1, genesis); insert_test_block(&mut store, b2, 2, b1); insert_test_block(&mut store, b3, 3, b2); - store.set_time(3 * INTERVALS_PER_SLOT); + store + .set_time(3 * INTERVALS_PER_SLOT) + .expect("set_time should succeed"); // head=b3 at slot 3, but the vote's own slot is 2: it claims to have seen // a head that did not yet exist when the vote was cast. @@ -1426,7 +1440,9 @@ mod tests { let b2 = H256([2u8; 32]); insert_test_block(&mut store, b1, 1, genesis); insert_test_block(&mut store, b2, 2, b1); - store.set_time(2 * INTERVALS_PER_SLOT); + store + .set_time(2 * INTERVALS_PER_SLOT) + .expect("set_time should succeed"); // A crafted gossip vote with a near-`u64::MAX` slot. The head-consistency // check passes (slot >= head.slot), so this exercises the time check. @@ -1457,7 +1473,9 @@ mod tests { let b2 = H256([2u8; 32]); insert_test_block(&mut store, b1, 1, genesis); insert_test_block(&mut store, b2, 2, b1); - store.set_time(2 * INTERVALS_PER_SLOT); + store + .set_time(2 * INTERVALS_PER_SLOT) + .expect("set_time should succeed"); let data = AttestationData { slot: 2, diff --git a/crates/storage/src/store.rs b/crates/storage/src/store.rs index 349e20bf4..a4b7a7252 100644 --- a/crates/storage/src/store.rs +++ b/crates/storage/src/store.rs @@ -726,8 +726,8 @@ impl Store { } /// Sets the current store time. - pub fn set_time(&mut self, time: u64) { - self.set_metadata(KEY_TIME, &time).expect("set time"); + pub fn set_time(&mut self, time: u64) -> Result<(), Error> { + self.set_metadata(KEY_TIME, &time) } // ============ Config ============ @@ -752,9 +752,8 @@ impl Store { } /// Sets the safe target block root. - pub fn set_safe_target(&mut self, safe_target: H256) { + pub fn set_safe_target(&mut self, safe_target: H256) -> Result<(), Error> { self.set_metadata(KEY_SAFE_TARGET, &safe_target) - .expect("set safe target"); } // ============ Checkpoints ============