Update database and block replayer to handle payload envelopes (#8886)

Closes:

- https://github.com/sigp/lighthouse/issues/8869


  - Update `BlockReplayer` to support replay of execution payload envelopes.
- Update `HotColdDB` to load payload envelopes and feed them to the `BlockReplayer` for both hot + cold states. However the cold DB code is not fully working yet (see: https://github.com/sigp/lighthouse/issues/8958).
- Add `StatePayloadStatus` to allow callers to specify whether they want a state with a payload applied, or not.
- Fix the state cache to key by `StatePayloadStatus`.
- Lots of fixes to block production and block processing regarding state management.
- Initial test harness support for producing+processing Gloas blocks+envelopes
- A few new tests to cover Gloas DB operations


Co-Authored-By: Eitan Seri- Levi <eserilev@gmail.com>

Co-Authored-By: Eitan Seri-Levi <eserilev@ucsc.edu>

Co-Authored-By: Michael Sproul <michael@sigmaprime.io>

Co-Authored-By: Michael Sproul <michaelsproul@users.noreply.github.com>

Co-Authored-By: Jimmy Chen <jchen.tc@gmail.com>
This commit is contained in:
Michael Sproul
2026-03-12 10:06:25 +11:00
committed by GitHub
parent 6350a27031
commit bff72a920d
30 changed files with 1243 additions and 84 deletions

View File

@@ -2031,9 +2031,16 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// required information.
(justified_checkpoint, committee_len)
} else {
// We assume that the `Pending` state has the same shufflings as a `Full` state
// for the same block. Analysis: https://hackmd.io/@dapplion/gloas_dependant_root
let (advanced_state_root, mut state) = self
.store
.get_advanced_hot_state(beacon_block_root, request_slot, beacon_state_root)?
.get_advanced_hot_state(
beacon_block_root,
StatePayloadStatus::Pending,
request_slot,
beacon_state_root,
)?
.ok_or(Error::MissingBeaconState(beacon_state_root))?;
if state.current_epoch() < request_epoch {
partial_state_advance(
@@ -4662,12 +4669,19 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
if cached_head.head_block_root() == parent_block_root {
(Cow::Borrowed(head_state), cached_head.head_state_root())
} else {
// TODO(gloas): this function needs updating to be envelope-aware
// See: https://github.com/sigp/lighthouse/issues/8957
let block = self
.get_blinded_block(&parent_block_root)?
.ok_or(Error::MissingBeaconBlock(parent_block_root))?;
let (state_root, state) = self
.store
.get_advanced_hot_state(parent_block_root, proposal_slot, block.state_root())?
.get_advanced_hot_state(
parent_block_root,
StatePayloadStatus::Pending,
proposal_slot,
block.state_root(),
)?
.ok_or(Error::MissingBeaconState(block.state_root()))?;
(Cow::Owned(state), state_root)
};
@@ -6599,9 +6613,16 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let (mut state, state_root) = if let Some((state, state_root)) = head_state_opt {
(state, state_root)
} else {
// We assume that the `Pending` state has the same shufflings as a `Full` state
// for the same block. Analysis: https://hackmd.io/@dapplion/gloas_dependant_root
let (state_root, state) = self
.store
.get_advanced_hot_state(head_block_root, target_slot, head_block.state_root)?
.get_advanced_hot_state(
head_block_root,
StatePayloadStatus::Pending,
target_slot,
head_block.state_root,
)?
.ok_or(Error::MissingBeaconState(head_block.state_root))?;
(state, state_root)
};