Skip to content

Commit 940fa81

Browse files
Fast path for /eth/v1/beacon/blocks/head/root (#8729)
Closes: - #8667 Use the `early_attester_cache` to serve the head block root (if present). This should be faster than waiting for the head to finish importing. Co-Authored-By: Michael Sproul <michael@sigmaprime.io>
1 parent 3ecf964 commit 940fa81

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

beacon_node/beacon_chain/src/early_attester_cache.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,4 +254,12 @@ impl<E: EthSpec> EarlyAttesterCache<E> {
254254
.filter(|item| item.beacon_block_root == block_root)
255255
.map(|item| item.proto_block.clone())
256256
}
257+
258+
/// Fetch the slot and block root of the current head block.
259+
pub fn get_head_block_root(&self) -> Option<(Slot, Hash256)> {
260+
self.item
261+
.read()
262+
.as_ref()
263+
.map(|item| (item.block.slot(), item.beacon_block_root))
264+
}
257265
}

beacon_node/http_api/src/lib.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1190,7 +1190,28 @@ pub fn serve<T: BeaconChainTypes>(
11901190
Priority::P1
11911191
};
11921192
task_spawner.blocking_json_task(priority, move || {
1193-
let (block_root, execution_optimistic, finalized) = block_id.root(&chain)?;
1193+
// Fast-path for the head block root. We read from the early attester cache
1194+
// so that we can produce sync committee messages for the new head prior
1195+
// to it being fully imported (written to the DB/etc). We also check that the
1196+
// cache is not stale or out of date by comparing against the cached head
1197+
// prior to using it.
1198+
//
1199+
// See: https://github.com/sigp/lighthouse/issues/8667
1200+
let (block_root, execution_optimistic, finalized) =
1201+
if let BlockId(eth2::types::BlockId::Head) = block_id
1202+
&& let Some((head_block_slot, head_block_root)) =
1203+
chain.early_attester_cache.get_head_block_root()
1204+
&& head_block_slot >= chain.canonical_head.cached_head().head_slot()
1205+
{
1206+
// We know execution is NOT optimistic if the block is from the early
1207+
// attester cache because only properly validated blocks are added.
1208+
// Similarly we know it is NOT finalized.
1209+
let execution_optimistic = false;
1210+
let finalized = false;
1211+
(head_block_root, execution_optimistic, finalized)
1212+
} else {
1213+
block_id.root(&chain)?
1214+
};
11941215
Ok(
11951216
api_types::GenericResponse::from(api_types::RootData::from(block_root))
11961217
.add_execution_optimistic_finalized(execution_optimistic, finalized),

0 commit comments

Comments
 (0)