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
36 changes: 0 additions & 36 deletions crates/blockchain/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,42 +417,6 @@ mod tests {
assert!(matches!(rx.try_recv(), Err(TryRecvError::Empty)));
}

/// A head whose header cannot be read is skipped (warn), while checkpoint
/// moves still emit.
#[test]
fn chain_event_diff_skips_head_with_missing_header() {
let mut store = test_store();
let bus = EventBus::new(8);
let mut rx = bus.subscribe();

let snapshot = ChainEventSnapshot::capture(&store);

// Point the head at a root with no stored header; advance finalized to
// a real block so its event still fires.
let orphan_head = H256([7u8; 32]);
let genesis = store.head().expect("store head exists");
let finalized_root = H256([8u8; 32]);
let finalized_state = H256([88u8; 32]);
insert_test_block(&mut store, finalized_root, 1, genesis, finalized_state);
let finalized = Checkpoint {
root: finalized_root,
slot: 1,
};
store
.update_checkpoints(ForkCheckpoints::new(orphan_head, None, Some(finalized)))
.expect("update_checkpoints should succeed");

snapshot.diff_and_emit(&store, &bus, 1);

match rx.try_recv().unwrap() {
ChainEvent::FinalizedCheckpoint { slot, block, state } => {
assert_eq!((slot, block, state), (1, finalized_root, finalized_state));
}
other => panic!("expected finalized_checkpoint only, got: {other:?}"),
}
assert!(matches!(rx.try_recv(), Err(TryRecvError::Empty)));
}

/// A head far below the wall-clock slot (catch-up/backfill) emits no
/// `head` event, but `justified_checkpoint`/`finalized_checkpoint` still
/// fire since only `head` is gated.
Expand Down
36 changes: 11 additions & 25 deletions crates/net/p2p/src/req_resp/handlers.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::{HashMap, HashSet};
use std::collections::HashSet;

use ethlambda_storage::Store;
use libp2p::{PeerId, request_response};
Expand Down Expand Up @@ -269,31 +269,17 @@ fn canonical_blocks_by_range(store: &Store, start_slot: u64, count: u64) -> Vec<
return Vec::new();
};

let mut roots_by_slot = HashMap::new();
let mut current_root = store.head().expect("head block exists");

while !current_root.is_zero() {
let Ok(Some(header)) = store.get_block_header(&current_root) else {
break;
};

if header.slot < start_slot {
break;
}

if header.slot <= end_slot {
roots_by_slot.insert(header.slot, current_root);
}

current_root = header.parent_root;
}

(start_slot..=end_slot)
.filter_map(|slot| {
let root = roots_by_slot.get(&slot)?;
store.get_signed_block(root).ok().flatten()
store
.get_signed_blocks_by_slot_range(start_slot, end_slot)
.inspect_err(|err| {
warn!(
start_slot,
end_slot,
?err,
"Failed to get signed blocks by slot range"
)
})
.collect()
.unwrap_or_default()
}

async fn handle_blocks_by_root_response(
Expand Down
6 changes: 5 additions & 1 deletion crates/storage/src/api/tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub enum Table {
/// finalized boundary are pruned (`prune_old_block_signatures`), while
/// headers and bodies are kept forever.
BlockSignatures,
/// Canonical block index: slot -> block root
BlockRoots,
/// State storage: H256 -> State
///
/// Holds full-state snapshots only: the bootstrap anchor plus one anchor
Expand All @@ -35,10 +37,11 @@ pub enum Table {
}

/// All table variants.
pub const ALL_TABLES: [Table; 7] = [
pub const ALL_TABLES: [Table; 8] = [
Table::BlockHeaders,
Table::BlockBodies,
Table::BlockSignatures,
Table::BlockRoots,
Table::States,
Table::StateDiffs,
Table::Metadata,
Expand All @@ -52,6 +55,7 @@ impl Table {
Table::BlockHeaders => "block_headers",
Table::BlockBodies => "block_bodies",
Table::BlockSignatures => "block_signatures",
Table::BlockRoots => "block_roots",
Table::States => "states",
Table::StateDiffs => "state_diffs",
Table::Metadata => "metadata",
Expand Down
4 changes: 4 additions & 0 deletions crates/storage/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use ethlambda_types::primitives::H256;

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("storage error: {0}")]
Storage(#[from] crate::api::Error),
#[error("unexpected missing block header for root {0}")]
UnexpectedMissingBlockHeader(H256),
}
Loading