Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bin/ethlambda/src/checkpoint_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
5 changes: 4 additions & 1 deletion bin/ethlambda/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,10 @@ 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)
.inspect_err(|err| error!(%err, "Failed to insert anchor signed block into store"))
.map_err(|_| checkpoint_sync::CheckpointSyncError::StoreInsertSignedBlock)?;
Ok(store)
Comment thread
d4m014 marked this conversation as resolved.
}

Expand Down
4 changes: 3 additions & 1 deletion crates/blockchain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 10 additions & 8 deletions crates/blockchain/src/reaggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down
64 changes: 48 additions & 16 deletions crates/blockchain/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -119,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.
Expand Down Expand Up @@ -263,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;
Expand Down Expand Up @@ -573,12 +581,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.
Expand Down Expand Up @@ -1220,7 +1234,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 {
Expand Down Expand Up @@ -1251,16 +1267,22 @@ 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.
let off_head_justified = Checkpoint {
root: H256([9u8; 32]),
slot: 5,
};
store.update_checkpoints(ForkCheckpoints::new(b, Some(off_head_justified), None));
store.set_time(2 * INTERVALS_PER_SLOT);
store
.update_checkpoints(ForkCheckpoints::new(b, Some(off_head_justified), None))
.expect("update_checkpoints should succeed");
store
.set_time(2 * INTERVALS_PER_SLOT)
.expect("set_time should succeed");

let data = produce_attestation_data(&store, 2);

Expand Down Expand Up @@ -1289,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.
Expand Down Expand Up @@ -1331,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.
Expand Down Expand Up @@ -1372,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.
Expand Down Expand Up @@ -1412,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.
Expand Down Expand Up @@ -1443,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,
Expand Down
20 changes: 15 additions & 5 deletions crates/net/p2p/src/req_resp/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
22 changes: 13 additions & 9 deletions crates/net/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
Loading