mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-19 13:58:28 +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:
@@ -41,7 +41,7 @@ pub const BID_VALUE_SELF_BUILD: u64 = 0;
|
||||
pub const EXECUTION_PAYMENT_TRUSTLESS_BUILD: u64 = 0;
|
||||
|
||||
type ConsensusBlockValue = u64;
|
||||
type BlockProductionResult<E> = (BeaconBlock<E, FullPayload<E>>, ConsensusBlockValue);
|
||||
type BlockProductionResult<E> = (BeaconBlock<E>, BeaconState<E>, ConsensusBlockValue);
|
||||
|
||||
pub type PreparePayloadResult<E> = Result<BlockProposalContentsGloas<E>, BlockProductionError>;
|
||||
pub type PreparePayloadHandle<E> = JoinHandle<Option<PreparePayloadResult<E>>>;
|
||||
@@ -425,6 +425,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
))
|
||||
}
|
||||
|
||||
/// Complete a block by computing its state root, and
|
||||
///
|
||||
/// Return `(block, pending_state, block_value)` where:
|
||||
///
|
||||
/// - `pending_state` is the state post block application (prior to payload application)
|
||||
/// - `block_value` is the consensus-layer rewards for `block`
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn complete_partial_beacon_block_gloas(
|
||||
&self,
|
||||
@@ -433,7 +439,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
payload_data: Option<ExecutionPayloadData<T::EthSpec>>,
|
||||
mut state: BeaconState<T::EthSpec>,
|
||||
verification: ProduceBlockVerification,
|
||||
) -> Result<(BeaconBlock<T::EthSpec, FullPayload<T::EthSpec>>, u64), BlockProductionError> {
|
||||
) -> Result<BlockProductionResult<T::EthSpec>, BlockProductionError> {
|
||||
let PartialBeaconBlock {
|
||||
slot,
|
||||
proposer_index,
|
||||
@@ -545,6 +551,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
|
||||
drop(state_root_timer);
|
||||
|
||||
// Clone the Pending state (post-block, pre-envelope) for callers that need it.
|
||||
let pending_state = state.clone();
|
||||
|
||||
let (mut block, _) = signed_beacon_block.deconstruct();
|
||||
*block.state_root_mut() = state_root;
|
||||
|
||||
@@ -605,7 +614,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
"Produced beacon block"
|
||||
);
|
||||
|
||||
Ok((block, consensus_block_value))
|
||||
Ok((block, pending_state, consensus_block_value))
|
||||
}
|
||||
|
||||
// TODO(gloas) introduce `ProposerPreferences` so we can build out trustless
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::{sync::Arc, time::Duration};
|
||||
use proto_array::ProposerHeadError;
|
||||
use slot_clock::SlotClock;
|
||||
use tracing::{debug, error, info, instrument, warn};
|
||||
use types::{BeaconState, Hash256, Slot};
|
||||
use types::{BeaconState, Hash256, Slot, StatePayloadStatus};
|
||||
|
||||
use crate::{
|
||||
BeaconChain, BeaconChainTypes, BlockProductionError, StateSkipConfig,
|
||||
@@ -37,8 +37,14 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
};
|
||||
let (state, state_root_opt) = if head_slot < slot {
|
||||
// Attempt an aggressive re-org if configured and the conditions are right.
|
||||
if let Some((re_org_state, re_org_state_root)) =
|
||||
self.get_state_for_re_org(slot, head_slot, head_block_root)
|
||||
// TODO(gloas): re-enable reorgs
|
||||
let gloas_enabled = self
|
||||
.spec
|
||||
.fork_name_at_slot::<T::EthSpec>(slot)
|
||||
.gloas_enabled();
|
||||
if !gloas_enabled
|
||||
&& let Some((re_org_state, re_org_state_root)) =
|
||||
self.get_state_for_re_org(slot, head_slot, head_block_root)
|
||||
{
|
||||
info!(
|
||||
%slot,
|
||||
@@ -49,9 +55,30 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
} else {
|
||||
// Fetch the head state advanced through to `slot`, which should be present in the
|
||||
// state cache thanks to the state advance timer.
|
||||
// TODO(gloas): need to fix this once fork choice understands payloads
|
||||
// for now we just use the existence of the head's payload envelope to determine
|
||||
// whether we should build atop it
|
||||
let (payload_status, parent_state_root) = if gloas_enabled
|
||||
&& let Ok(Some(envelope)) = self.store.get_payload_envelope(&head_block_root)
|
||||
{
|
||||
debug!(
|
||||
%slot,
|
||||
parent_state_root = ?envelope.message.state_root,
|
||||
parent_block_root = ?head_block_root,
|
||||
"Building Gloas block on full state"
|
||||
);
|
||||
(StatePayloadStatus::Full, envelope.message.state_root)
|
||||
} else {
|
||||
(StatePayloadStatus::Pending, head_state_root)
|
||||
};
|
||||
let (state_root, state) = self
|
||||
.store
|
||||
.get_advanced_hot_state(head_block_root, slot, head_state_root)
|
||||
.get_advanced_hot_state(
|
||||
head_block_root,
|
||||
payload_status,
|
||||
slot,
|
||||
parent_state_root,
|
||||
)
|
||||
.map_err(BlockProductionError::FailedToLoadState)?
|
||||
.ok_or(BlockProductionError::UnableToProduceAtSlot(slot))?;
|
||||
(state, Some(state_root))
|
||||
@@ -204,7 +231,11 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
|
||||
let (state_root, state) = self
|
||||
.store
|
||||
.get_advanced_hot_state_from_cache(re_org_parent_block, slot)
|
||||
.get_advanced_hot_state_from_cache(
|
||||
re_org_parent_block,
|
||||
StatePayloadStatus::Pending,
|
||||
slot,
|
||||
)
|
||||
.or_else(|| {
|
||||
warn!(reason = "no state in cache", "Not attempting re-org");
|
||||
None
|
||||
|
||||
Reference in New Issue
Block a user