Re-do head_payload_status

This commit is contained in:
Michael Sproul
2026-03-25 14:05:11 +11:00
parent c841603003
commit 8b448864f0
18 changed files with 143 additions and 119 deletions

View File

@@ -3935,7 +3935,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let fork_choice_timer = metrics::start_timer(&metrics::BLOCK_PROCESSING_FORK_CHOICE);
match fork_choice.get_head(current_slot, &self.spec) {
// This block became the head, add it to the early attester cache.
Ok(new_head_root) if new_head_root == block_root => {
Ok((new_head_root, _)) if new_head_root == block_root => {
if let Some(proto_block) = fork_choice.get_block(&block_root) {
let new_head_is_optimistic =
proto_block.execution_status.is_optimistic_or_invalid();
@@ -4906,6 +4906,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.and_then(|execution_status| execution_status.block_hash());
let forkchoice_update_params = ForkchoiceUpdateParameters {
head_root: info.parent_node.root(),
head_payload_status: canonical_forkchoice_params.head_payload_status,
head_hash: parent_head_hash,
justified_hash: canonical_forkchoice_params.justified_hash,
finalized_hash: canonical_forkchoice_params.finalized_hash,

View File

@@ -776,7 +776,7 @@ where
slot_clock.now().ok_or("Unable to read slot")?
};
let initial_head_block_root = fork_choice
let (initial_head_block_root, _head_payload_status) = fork_choice
.get_head(current_slot, &self.spec)
.map_err(|e| format!("Unable to get fork choice head: {:?}", e))?;

View File

@@ -108,6 +108,8 @@ pub struct CachedHead<E: EthSpec> {
/// This value may be distinct to the `self.snapshot.beacon_state.finalized_checkpoint`.
/// This value should be used over the beacon state value in practically all circumstances.
finalized_checkpoint: Checkpoint,
/// The payload status of the head block, as determined by fork choice.
head_payload_status: proto_array::PayloadStatus,
/// The `execution_payload.block_hash` of the block at the head of the chain. Set to `None`
/// before Bellatrix.
head_hash: Option<ExecutionBlockHash>,
@@ -227,11 +229,16 @@ impl<E: EthSpec> CachedHead<E> {
pub fn forkchoice_update_parameters(&self) -> ForkchoiceUpdateParameters {
ForkchoiceUpdateParameters {
head_root: self.snapshot.beacon_block_root,
head_payload_status: self.head_payload_status,
head_hash: self.head_hash,
justified_hash: self.justified_hash,
finalized_hash: self.finalized_hash,
}
}
pub fn head_payload_status(&self) -> proto_array::PayloadStatus {
self.head_payload_status
}
}
/// Represents the "canonical head" of the beacon chain.
@@ -269,6 +276,7 @@ impl<T: BeaconChainTypes> CanonicalHead<T> {
snapshot,
justified_checkpoint: fork_choice_view.justified_checkpoint,
finalized_checkpoint: fork_choice_view.finalized_checkpoint,
head_payload_status: forkchoice_update_params.head_payload_status,
head_hash: forkchoice_update_params.head_hash,
justified_hash: forkchoice_update_params.justified_hash,
finalized_hash: forkchoice_update_params.finalized_hash,
@@ -329,6 +337,7 @@ impl<T: BeaconChainTypes> CanonicalHead<T> {
snapshot: Arc::new(snapshot),
justified_checkpoint: fork_choice_view.justified_checkpoint,
finalized_checkpoint: fork_choice_view.finalized_checkpoint,
head_payload_status: forkchoice_update_params.head_payload_status,
head_hash: forkchoice_update_params.head_hash,
justified_hash: forkchoice_update_params.justified_hash,
finalized_hash: forkchoice_update_params.finalized_hash,
@@ -606,7 +615,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let mut fork_choice_write_lock = self.canonical_head.fork_choice_write_lock();
// Recompute the current head via the fork choice algorithm.
fork_choice_write_lock.get_head(current_slot, &self.spec)?;
let _ = fork_choice_write_lock.get_head(current_slot, &self.spec)?;
// Downgrade the fork choice write-lock to a read lock, without allowing access to any
// other writers.
@@ -710,6 +719,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
snapshot: Arc::new(new_snapshot),
justified_checkpoint: new_view.justified_checkpoint,
finalized_checkpoint: new_view.finalized_checkpoint,
head_payload_status: new_forkchoice_update_parameters.head_payload_status,
head_hash: new_forkchoice_update_parameters.head_hash,
justified_hash: new_forkchoice_update_parameters.justified_hash,
finalized_hash: new_forkchoice_update_parameters.finalized_hash,
@@ -737,6 +747,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
snapshot: old_cached_head.snapshot.clone(),
justified_checkpoint: new_view.justified_checkpoint,
finalized_checkpoint: new_view.finalized_checkpoint,
head_payload_status: new_forkchoice_update_parameters.head_payload_status,
head_hash: new_forkchoice_update_parameters.head_hash,
justified_hash: new_forkchoice_update_parameters.justified_hash,
finalized_hash: new_forkchoice_update_parameters.finalized_hash,

View File

@@ -1350,7 +1350,7 @@ async fn recover_from_invalid_head_by_importing_blocks() {
"the fork block should become the head"
);
let manual_get_head = rig
let (manual_get_head, _) = rig
.harness
.chain
.canonical_head

View File

@@ -5430,10 +5430,12 @@ fn assert_chains_pretty_much_the_same<T: BeaconChainTypes>(a: &BeaconChain<T>, b
.fork_choice_write_lock()
.get_head(slot, &spec)
.unwrap()
.0
== b.canonical_head
.fork_choice_write_lock()
.get_head(slot, &spec)
.unwrap(),
.unwrap()
.0,
"fork_choice heads should be equal"
);
}

View File

@@ -12,7 +12,7 @@ use eth2::{
BeaconNodeHttpClient, CONSENSUS_VERSION_HEADER, CONTENT_TYPE_HEADER, SSZ_CONTENT_TYPE_HEADER,
Timeouts,
};
use fork_choice::ForkchoiceUpdateParameters;
use fork_choice::{ForkchoiceUpdateParameters, PayloadStatus as FcPayloadStatus};
use parking_lot::RwLock;
use sensitive_url::SensitiveUrl;
use ssz::Encode;
@@ -934,6 +934,7 @@ impl<E: EthSpec> MockBuilder<E> {
finalized_hash: Some(finalized_execution_hash),
justified_hash: Some(justified_execution_hash),
head_root: head_block_root,
head_payload_status: FcPayloadStatus::Pending,
};
let _status = self

View File

@@ -92,6 +92,7 @@ impl<E: EthSpec> MockExecutionLayer<E> {
let head_block_root = Hash256::repeat_byte(42);
let forkchoice_update_params = ForkchoiceUpdateParameters {
head_root: head_block_root,
head_payload_status: fork_choice::PayloadStatus::Pending,
head_hash: Some(parent_hash),
justified_hash: None,
finalized_hash: None,