mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-19 05:48:31 +00:00
Remove merge transition code (#8761)
Co-Authored-By: dapplion <35266934+dapplion@users.noreply.github.com>
This commit is contained in:
@@ -12,19 +12,19 @@ use crate::{
|
||||
ExecutionPayloadError,
|
||||
};
|
||||
use execution_layer::{
|
||||
BlockProposalContents, BlockProposalContentsType, BuilderParams, NewPayloadRequest,
|
||||
PayloadAttributes, PayloadParameters, PayloadStatus,
|
||||
BlockProposalContentsType, BuilderParams, NewPayloadRequest, PayloadAttributes,
|
||||
PayloadParameters, PayloadStatus,
|
||||
};
|
||||
use fork_choice::{InvalidationOperation, PayloadVerificationStatus};
|
||||
use proto_array::{Block as ProtoBlock, ExecutionStatus};
|
||||
use slot_clock::SlotClock;
|
||||
use state_processing::per_block_processing::{
|
||||
compute_timestamp_at_slot, get_expected_withdrawals, is_execution_enabled,
|
||||
is_merge_transition_complete, partially_verify_execution_payload,
|
||||
partially_verify_execution_payload,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use tokio::task::JoinHandle;
|
||||
use tracing::{Instrument, debug, debug_span, warn};
|
||||
use tracing::{Instrument, debug_span, warn};
|
||||
use tree_hash::TreeHash;
|
||||
use types::execution::BlockProductionVersion;
|
||||
use types::*;
|
||||
@@ -32,12 +32,6 @@ use types::*;
|
||||
pub type PreparePayloadResult<E> = Result<BlockProposalContentsType<E>, BlockProductionError>;
|
||||
pub type PreparePayloadHandle<E> = JoinHandle<Option<PreparePayloadResult<E>>>;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub enum AllowOptimisticImport {
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
/// Signal whether the execution payloads of new blocks should be
|
||||
/// immediately verified with the EL or imported optimistically without
|
||||
/// any EL communication.
|
||||
@@ -218,78 +212,6 @@ async fn notify_new_payload<T: BeaconChainTypes>(
|
||||
}
|
||||
}
|
||||
|
||||
/// Verify that the block which triggers the merge is valid to be imported to fork choice.
|
||||
///
|
||||
/// ## Errors
|
||||
///
|
||||
/// Will return an error when using a pre-merge fork `state`. Ensure to only run this function
|
||||
/// after the merge fork.
|
||||
///
|
||||
/// ## Specification
|
||||
///
|
||||
/// Equivalent to the `validate_merge_block` function in the merge Fork Choice Changes:
|
||||
///
|
||||
/// https://github.com/ethereum/consensus-specs/blob/v1.1.5/specs/merge/fork-choice.md#validate_merge_block
|
||||
pub async fn validate_merge_block<T: BeaconChainTypes>(
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
block: BeaconBlockRef<'_, T::EthSpec>,
|
||||
allow_optimistic_import: AllowOptimisticImport,
|
||||
) -> Result<(), BlockError> {
|
||||
let spec = &chain.spec;
|
||||
let block_epoch = block.slot().epoch(T::EthSpec::slots_per_epoch());
|
||||
let execution_payload = block.execution_payload()?;
|
||||
|
||||
if spec.terminal_block_hash != ExecutionBlockHash::zero() {
|
||||
if block_epoch < spec.terminal_block_hash_activation_epoch {
|
||||
return Err(ExecutionPayloadError::InvalidActivationEpoch {
|
||||
activation_epoch: spec.terminal_block_hash_activation_epoch,
|
||||
epoch: block_epoch,
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
if execution_payload.parent_hash() != spec.terminal_block_hash {
|
||||
return Err(ExecutionPayloadError::InvalidTerminalBlockHash {
|
||||
terminal_block_hash: spec.terminal_block_hash,
|
||||
payload_parent_hash: execution_payload.parent_hash(),
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let execution_layer = chain
|
||||
.execution_layer
|
||||
.as_ref()
|
||||
.ok_or(ExecutionPayloadError::NoExecutionConnection)?;
|
||||
|
||||
let is_valid_terminal_pow_block = execution_layer
|
||||
.is_valid_terminal_pow_block_hash(execution_payload.parent_hash(), spec)
|
||||
.await
|
||||
.map_err(ExecutionPayloadError::from)?;
|
||||
|
||||
match is_valid_terminal_pow_block {
|
||||
Some(true) => Ok(()),
|
||||
Some(false) => Err(ExecutionPayloadError::InvalidTerminalPoWBlock {
|
||||
parent_hash: execution_payload.parent_hash(),
|
||||
}
|
||||
.into()),
|
||||
None => {
|
||||
if allow_optimistic_import == AllowOptimisticImport::Yes {
|
||||
debug!(
|
||||
block_hash = ?execution_payload.parent_hash(),
|
||||
msg = "the terminal block/parent was unavailable",
|
||||
"Optimistically importing merge transition block"
|
||||
);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ExecutionPayloadError::UnverifiedNonOptimisticCandidate.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Validate the gossip block's execution_payload according to the checks described here:
|
||||
/// https://github.com/ethereum/consensus-specs/blob/dev/specs/merge/p2p-interface.md#beacon_block
|
||||
pub fn validate_execution_payload_for_gossip<T: BeaconChainTypes>(
|
||||
@@ -305,14 +227,14 @@ pub fn validate_execution_payload_for_gossip<T: BeaconChainTypes>(
|
||||
|
||||
// Only apply this validation if this is a Bellatrix beacon block.
|
||||
if let Ok(execution_payload) = block.body().execution_payload() {
|
||||
// This logic should match `is_execution_enabled`. We use only the execution block hash of
|
||||
// the parent here in order to avoid loading the parent state during gossip verification.
|
||||
// Check parent execution status to determine if we should validate the payload.
|
||||
// We use only the execution status of the parent here to avoid loading the parent state
|
||||
// during gossip verification.
|
||||
|
||||
let is_merge_transition_complete = match parent_block.execution_status {
|
||||
// Optimistically declare that an "unknown" status block has completed the merge.
|
||||
let parent_has_execution = match parent_block.execution_status {
|
||||
// Parent has valid or optimistic execution status.
|
||||
ExecutionStatus::Valid(_) | ExecutionStatus::Optimistic(_) => true,
|
||||
// It's impossible for an irrelevant block to have completed the merge. It is pre-merge
|
||||
// by definition.
|
||||
// Pre-merge blocks have irrelevant execution status.
|
||||
ExecutionStatus::Irrelevant(_) => false,
|
||||
// If the parent has an invalid payload then it's impossible to build a valid block upon
|
||||
// it. Reject the block.
|
||||
@@ -323,7 +245,7 @@ pub fn validate_execution_payload_for_gossip<T: BeaconChainTypes>(
|
||||
}
|
||||
};
|
||||
|
||||
if is_merge_transition_complete || !execution_payload.is_default_with_empty_roots() {
|
||||
if parent_has_execution || !execution_payload.is_default_with_empty_roots() {
|
||||
let expected_timestamp = chain
|
||||
.slot_clock
|
||||
.start_of(block.slot())
|
||||
@@ -372,7 +294,6 @@ pub fn get_execution_payload<T: BeaconChainTypes>(
|
||||
// task.
|
||||
let spec = &chain.spec;
|
||||
let current_epoch = state.current_epoch();
|
||||
let is_merge_transition_complete = is_merge_transition_complete(state);
|
||||
let timestamp =
|
||||
compute_timestamp_at_slot(state, state.slot(), spec).map_err(BeaconStateError::from)?;
|
||||
let random = *state.get_randao_mix(current_epoch)?;
|
||||
@@ -399,7 +320,6 @@ pub fn get_execution_payload<T: BeaconChainTypes>(
|
||||
async move {
|
||||
prepare_execution_payload::<T>(
|
||||
&chain,
|
||||
is_merge_transition_complete,
|
||||
timestamp,
|
||||
random,
|
||||
proposer_index,
|
||||
@@ -423,8 +343,6 @@ pub fn get_execution_payload<T: BeaconChainTypes>(
|
||||
|
||||
/// Prepares an execution payload for inclusion in a block.
|
||||
///
|
||||
/// Will return `Ok(None)` if the Bellatrix fork has occurred, but a terminal block has not been found.
|
||||
///
|
||||
/// ## Errors
|
||||
///
|
||||
/// Will return an error when using a pre-Bellatrix fork `state`. Ensure to only run this function
|
||||
@@ -438,7 +356,6 @@ pub fn get_execution_payload<T: BeaconChainTypes>(
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn prepare_execution_payload<T>(
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
is_merge_transition_complete: bool,
|
||||
timestamp: u64,
|
||||
random: Hash256,
|
||||
proposer_index: u64,
|
||||
@@ -453,7 +370,6 @@ pub async fn prepare_execution_payload<T>(
|
||||
where
|
||||
T: BeaconChainTypes,
|
||||
{
|
||||
let current_epoch = builder_params.slot.epoch(T::EthSpec::slots_per_epoch());
|
||||
let spec = &chain.spec;
|
||||
let fork = spec.fork_name_at_slot::<T::EthSpec>(builder_params.slot);
|
||||
let execution_layer = chain
|
||||
@@ -461,42 +377,7 @@ where
|
||||
.as_ref()
|
||||
.ok_or(BlockProductionError::ExecutionLayerMissing)?;
|
||||
|
||||
let parent_hash = if !is_merge_transition_complete {
|
||||
let is_terminal_block_hash_set = spec.terminal_block_hash != ExecutionBlockHash::zero();
|
||||
let is_activation_epoch_reached =
|
||||
current_epoch >= spec.terminal_block_hash_activation_epoch;
|
||||
|
||||
if is_terminal_block_hash_set && !is_activation_epoch_reached {
|
||||
// Use the "empty" payload if there's a terminal block hash, but we haven't reached the
|
||||
// terminal block epoch yet.
|
||||
return Ok(BlockProposalContentsType::Full(
|
||||
BlockProposalContents::Payload {
|
||||
payload: FullPayload::default_at_fork(fork)?,
|
||||
block_value: Uint256::ZERO,
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
let terminal_pow_block_hash = execution_layer
|
||||
.get_terminal_pow_block_hash(spec, timestamp)
|
||||
.await
|
||||
.map_err(BlockProductionError::TerminalPoWBlockLookupFailed)?;
|
||||
|
||||
if let Some(terminal_pow_block_hash) = terminal_pow_block_hash {
|
||||
terminal_pow_block_hash
|
||||
} else {
|
||||
// If the merge transition hasn't occurred yet and the EL hasn't found the terminal
|
||||
// block, return an "empty" payload.
|
||||
return Ok(BlockProposalContentsType::Full(
|
||||
BlockProposalContents::Payload {
|
||||
payload: FullPayload::default_at_fork(fork)?,
|
||||
block_value: Uint256::ZERO,
|
||||
},
|
||||
));
|
||||
}
|
||||
} else {
|
||||
latest_execution_payload_header_block_hash
|
||||
};
|
||||
let parent_hash = latest_execution_payload_header_block_hash;
|
||||
|
||||
// Try to obtain the fork choice update parameters from the cached head.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user