Fast path for /eth/v1/beacon/blocks/head/root (#8729)

Closes:

- https://github.com/sigp/lighthouse/issues/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>
This commit is contained in:
Michael Sproul
2026-02-02 17:41:43 +11:00
committed by GitHub
parent 3ecf964385
commit 940fa81a5b
2 changed files with 30 additions and 1 deletions

View File

@@ -254,4 +254,12 @@ impl<E: EthSpec> EarlyAttesterCache<E> {
.filter(|item| item.beacon_block_root == block_root)
.map(|item| item.proto_block.clone())
}
/// Fetch the slot and block root of the current head block.
pub fn get_head_block_root(&self) -> Option<(Slot, Hash256)> {
self.item
.read()
.as_ref()
.map(|item| (item.block.slot(), item.beacon_block_root))
}
}

View File

@@ -1190,7 +1190,28 @@ pub fn serve<T: BeaconChainTypes>(
Priority::P1
};
task_spawner.blocking_json_task(priority, move || {
let (block_root, execution_optimistic, finalized) = block_id.root(&chain)?;
// Fast-path for the head block root. We read from the early attester cache
// so that we can produce sync committee messages for the new head prior
// to it being fully imported (written to the DB/etc). We also check that the
// cache is not stale or out of date by comparing against the cached head
// prior to using it.
//
// See: https://github.com/sigp/lighthouse/issues/8667
let (block_root, execution_optimistic, finalized) =
if let BlockId(eth2::types::BlockId::Head) = block_id
&& let Some((head_block_slot, head_block_root)) =
chain.early_attester_cache.get_head_block_root()
&& head_block_slot >= chain.canonical_head.cached_head().head_slot()
{
// We know execution is NOT optimistic if the block is from the early
// attester cache because only properly validated blocks are added.
// Similarly we know it is NOT finalized.
let execution_optimistic = false;
let finalized = false;
(head_block_root, execution_optimistic, finalized)
} else {
block_id.root(&chain)?
};
Ok(
api_types::GenericResponse::from(api_types::RootData::from(block_root))
.add_execution_optimistic_finalized(execution_optimistic, finalized),