mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-21 14:58:31 +00:00
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:
@@ -99,7 +99,8 @@ use tracing::{Instrument, Span, debug, debug_span, error, info_span, instrument}
|
||||
use types::{
|
||||
BeaconBlockRef, BeaconState, BeaconStateError, BlobsList, ChainSpec, DataColumnSidecarList,
|
||||
Epoch, EthSpec, FullPayload, Hash256, InconsistentFork, KzgProofs, RelativeEpoch,
|
||||
SignedBeaconBlock, SignedBeaconBlockHeader, Slot, data::DataColumnSidecarError,
|
||||
SignedBeaconBlock, SignedBeaconBlockHeader, Slot, StatePayloadStatus,
|
||||
data::DataColumnSidecarError,
|
||||
};
|
||||
|
||||
/// Maximum block slot number. Block with slots bigger than this constant will NOT be processed.
|
||||
@@ -1491,7 +1492,11 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
|
||||
|
||||
let distance = block.slot().as_u64().saturating_sub(state.slot().as_u64());
|
||||
for _ in 0..distance {
|
||||
let state_root = if parent.beacon_block.slot() == state.slot() {
|
||||
// TODO(gloas): could do a similar optimisation here for Full blocks if we have access
|
||||
// to the parent envelope and its `state_root`.
|
||||
let state_root = if parent.beacon_block.slot() == state.slot()
|
||||
&& state.payload_status() == StatePayloadStatus::Pending
|
||||
{
|
||||
// If it happens that `pre_state` has *not* already been advanced forward a single
|
||||
// slot, then there is no need to compute the state root for this
|
||||
// `per_slot_processing` call since that state root is already stored in the parent
|
||||
@@ -1908,9 +1913,31 @@ fn load_parent<T: BeaconChainTypes, B: AsBlock<T::EthSpec>>(
|
||||
// Retrieve any state that is advanced through to at most `block.slot()`: this is
|
||||
// particularly important if `block` descends from the finalized/split block, but at a slot
|
||||
// prior to the finalized slot (which is invalid and inaccessible in our DB schema).
|
||||
//
|
||||
// Post-Gloas we must also fetch a state with the correct payload status. If the current
|
||||
// block builds upon the payload of its parent block, then we know the parent block is FULL
|
||||
// and we need to load the full state.
|
||||
let (payload_status, parent_state_root) =
|
||||
if block.as_block().fork_name_unchecked().gloas_enabled()
|
||||
&& let Ok(parent_bid_block_hash) = parent_block.payload_bid_block_hash()
|
||||
{
|
||||
if block.as_block().is_parent_block_full(parent_bid_block_hash) {
|
||||
// TODO(gloas): loading the envelope here is not very efficient
|
||||
let envelope = chain.store.get_payload_envelope(&root)?.ok_or_else(|| {
|
||||
BeaconChainError::DBInconsistent(format!(
|
||||
"Missing envelope for parent block {root:?}",
|
||||
))
|
||||
})?;
|
||||
(StatePayloadStatus::Full, envelope.message.state_root)
|
||||
} else {
|
||||
(StatePayloadStatus::Pending, parent_block.state_root())
|
||||
}
|
||||
} else {
|
||||
(StatePayloadStatus::Pending, parent_block.state_root())
|
||||
};
|
||||
let (parent_state_root, state) = chain
|
||||
.store
|
||||
.get_advanced_hot_state(root, block.slot(), parent_block.state_root())?
|
||||
.get_advanced_hot_state(root, payload_status, block.slot(), parent_state_root)?
|
||||
.ok_or_else(|| {
|
||||
BeaconChainError::DBInconsistent(
|
||||
format!("Missing state for parent block {root:?}",),
|
||||
@@ -1933,7 +1960,9 @@ fn load_parent<T: BeaconChainTypes, B: AsBlock<T::EthSpec>>(
|
||||
);
|
||||
}
|
||||
|
||||
let beacon_state_root = if state.slot() == parent_block.slot() {
|
||||
let beacon_state_root = if state.slot() == parent_block.slot()
|
||||
&& let StatePayloadStatus::Pending = payload_status
|
||||
{
|
||||
// Sanity check.
|
||||
if parent_state_root != parent_block.state_root() {
|
||||
return Err(BeaconChainError::DBInconsistent(format!(
|
||||
|
||||
Reference in New Issue
Block a user