Fix block & state queries prior to genesis (#4761)

## Issue Addressed

Closes #4751

## Proposed Changes

Prevent `state_root_at_slot` and `block_root_at_slot` from erroring out due to a call to `self.slot()?` that fails before genesis. This fixes pre-genesis queries for:

- block at slot 0
- block by genesis block root
- state at slot 0
- state by genesis state root
- state at `finalized` tag
- state at `justified` tag
This commit is contained in:
Michael Sproul 2023-09-21 06:38:33 +00:00
parent d3fe3ad337
commit 0074a3b5f5

View File

@ -809,10 +809,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
/// ///
/// May return a database error. /// May return a database error.
pub fn state_root_at_slot(&self, request_slot: Slot) -> Result<Option<Hash256>, Error> { pub fn state_root_at_slot(&self, request_slot: Slot) -> Result<Option<Hash256>, Error> {
if request_slot > self.slot()? { if request_slot == self.spec.genesis_slot {
return Ok(None);
} else if request_slot == self.spec.genesis_slot {
return Ok(Some(self.genesis_state_root)); return Ok(Some(self.genesis_state_root));
} else if request_slot > self.slot()? {
return Ok(None);
} }
// Check limits w.r.t historic state bounds. // Check limits w.r.t historic state bounds.
@ -889,10 +889,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
/// ///
/// May return a database error. /// May return a database error.
fn block_root_at_slot_skips_none(&self, request_slot: Slot) -> Result<Option<Hash256>, Error> { fn block_root_at_slot_skips_none(&self, request_slot: Slot) -> Result<Option<Hash256>, Error> {
if request_slot > self.slot()? { if request_slot == self.spec.genesis_slot {
return Ok(None);
} else if request_slot == self.spec.genesis_slot {
return Ok(Some(self.genesis_block_root)); return Ok(Some(self.genesis_block_root));
} else if request_slot > self.slot()? {
return Ok(None);
} }
let prev_slot = request_slot.saturating_sub(1_u64); let prev_slot = request_slot.saturating_sub(1_u64);
@ -952,10 +952,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
/// ///
/// May return a database error. /// May return a database error.
fn block_root_at_slot_skips_prev(&self, request_slot: Slot) -> Result<Option<Hash256>, Error> { fn block_root_at_slot_skips_prev(&self, request_slot: Slot) -> Result<Option<Hash256>, Error> {
if request_slot > self.slot()? { if request_slot == self.spec.genesis_slot {
return Ok(None);
} else if request_slot == self.spec.genesis_slot {
return Ok(Some(self.genesis_block_root)); return Ok(Some(self.genesis_block_root));
} else if request_slot > self.slot()? {
return Ok(None);
} }
// Try an optimized path of reading the root directly from the head state. // Try an optimized path of reading the root directly from the head state.