Deprecate some reorg-related CLI flags and read from spec (#9177)

- #9123


  


Co-Authored-By: Tan Chee Keong <tanck@sigmaprime.io>

Co-Authored-By: chonghe <44791194+chong-he@users.noreply.github.com>
This commit is contained in:
chonghe
2026-05-25 10:11:27 +08:00
committed by GitHub
parent b5d44bff36
commit 9b961960c4
16 changed files with 141 additions and 253 deletions

View File

@@ -113,7 +113,7 @@ use operation_pool::{
CompactAttestationRef, OperationPool, PersistedOperationPool, ReceivedPreCapella,
};
use parking_lot::{Mutex, RwLock, RwLockWriteGuard};
use proto_array::{DoNotReOrg, ProposerHeadError};
use proto_array::{DoNotReOrg, ProposerHeadError, ReOrgThreshold};
use rand::RngCore;
use safe_arith::SafeArith;
use slasher::Slasher;
@@ -5239,15 +5239,14 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let _timer = metrics::start_timer(&metrics::FORK_CHOICE_OVERRIDE_FCU_TIMES);
// Never override if proposer re-orgs are disabled.
let re_org_head_threshold = self
.config
.re_org_head_threshold
.ok_or(Box::new(DoNotReOrg::ReOrgsDisabled.into()))?;
if self.config.disable_proposer_reorg {
return Err(Box::new(DoNotReOrg::ReOrgsDisabled.into()));
};
let re_org_parent_threshold = self
.config
.re_org_parent_threshold
.ok_or(Box::new(DoNotReOrg::ReOrgsDisabled.into()))?;
let re_org_head_threshold = ReOrgThreshold(self.spec.reorg_head_weight_threshold);
let re_org_parent_threshold = ReOrgThreshold(self.spec.reorg_parent_weight_threshold);
let re_org_max_epochs_since_finalization =
Epoch::new(self.spec.reorg_max_epochs_since_finalization);
let head_block_root = canonical_forkchoice_params.head_root;
@@ -5260,7 +5259,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
re_org_head_threshold,
re_org_parent_threshold,
&self.config.re_org_disallowed_offsets,
self.config.re_org_max_epochs_since_finalization,
re_org_max_epochs_since_finalization,
)
.map_err(|e| e.map_inner_error(Error::ProposerHeadForkChoiceError))?;
@@ -5281,7 +5280,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.and_then(|slot_start| {
let now = self.slot_clock.now_duration()?;
let slot_delay = now.saturating_sub(slot_start);
Some(slot_delay <= self.config.re_org_cutoff(self.spec.get_slot_duration()))
let re_org_cutoff_duration = self
.spec
.compute_slot_component_duration(self.spec.proposer_reorg_cutoff_bps)
.ok()?;
Some(slot_delay <= re_org_cutoff_duration)
})
.unwrap_or(false)
} else {

View File

@@ -1,10 +1,10 @@
use std::{sync::Arc, time::Duration};
use fork_choice::PayloadStatus;
use proto_array::ProposerHeadError;
use proto_array::{ProposerHeadError, ReOrgThreshold};
use slot_clock::SlotClock;
use tracing::{debug, error, info, instrument, warn};
use types::{BeaconState, Hash256, SignedExecutionPayloadEnvelope, Slot};
use types::{BeaconState, Epoch, Hash256, SignedExecutionPayloadEnvelope, Slot};
use crate::{
BeaconChain, BeaconChainTypes, BlockProductionError, StateSkipConfig,
@@ -174,8 +174,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
head_slot: Slot,
canonical_head: Hash256,
) -> Option<(BeaconState<T::EthSpec>, Hash256)> {
let re_org_head_threshold = self.config.re_org_head_threshold?;
let re_org_parent_threshold = self.config.re_org_parent_threshold?;
let re_org_head_threshold = ReOrgThreshold(self.spec.reorg_head_weight_threshold);
let re_org_parent_threshold = ReOrgThreshold(self.spec.reorg_parent_weight_threshold);
let re_org_max_epochs_since_finalization =
Epoch::new(self.spec.reorg_max_epochs_since_finalization);
if self.spec.proposer_score_boost.is_none() {
warn!(
@@ -198,8 +200,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// 1. It seems we have time to propagate and still receive the proposer boost.
// 2. The current head block was seen late.
// 3. The `get_proposer_head` conditions from fork choice pass.
let proposing_on_time =
slot_delay < self.config.re_org_cutoff(self.spec.get_slot_duration());
let re_org_cutoff_duration = self
.spec
.compute_slot_component_duration(self.spec.proposer_reorg_cutoff_bps)
.ok()?;
let proposing_on_time = slot_delay < re_org_cutoff_duration;
if !proposing_on_time {
debug!(reason = "not proposing on time", "Not attempting re-org");
return None;
@@ -223,7 +229,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
re_org_head_threshold,
re_org_parent_threshold,
&self.config.re_org_disallowed_offsets,
self.config.re_org_max_epochs_since_finalization,
re_org_max_epochs_since_finalization,
)
.map_err(|e| match e {
ProposerHeadError::DoNotReOrg(reason) => {

View File

@@ -30,7 +30,7 @@ use kzg::Kzg;
use logging::crit;
use operation_pool::{OperationPool, PersistedOperationPool};
use parking_lot::{Mutex, RwLock};
use proto_array::{DisallowedReOrgOffsets, ReOrgThreshold};
use proto_array::DisallowedReOrgOffsets;
use rand::RngCore;
use rayon::prelude::*;
use slasher::Slasher;
@@ -47,8 +47,8 @@ use tracing::{debug, error, info, warn};
use tree_hash::TreeHash;
use types::data::CustodyIndex;
use types::{
BeaconState, BlobSidecarList, ChainSpec, ColumnIndex, DataColumnSidecarList, Epoch, EthSpec,
Hash256, SignedBeaconBlock, Slot,
BeaconState, BlobSidecarList, ChainSpec, ColumnIndex, DataColumnSidecarList, EthSpec, Hash256,
SignedBeaconBlock, Slot,
};
/// An empty struct used to "witness" all the `BeaconChainTypes` traits. It has no user-facing
@@ -176,21 +176,6 @@ where
self
}
/// Sets the proposer re-org threshold.
pub fn proposer_re_org_head_threshold(mut self, threshold: Option<ReOrgThreshold>) -> Self {
self.chain_config.re_org_head_threshold = threshold;
self
}
/// Sets the proposer re-org max epochs since finalization.
pub fn proposer_re_org_max_epochs_since_finalization(
mut self,
epochs_since_finalization: Epoch,
) -> Self {
self.chain_config.re_org_max_epochs_since_finalization = epochs_since_finalization;
self
}
/// Sets the proposer re-org disallowed offsets list.
pub fn proposer_re_org_disallowed_offsets(
mut self,

View File

@@ -1,15 +1,10 @@
use crate::custody_context::NodeCustodyType;
pub use proto_array::{DisallowedReOrgOffsets, ReOrgThreshold};
pub use proto_array::DisallowedReOrgOffsets;
use serde::{Deserialize, Serialize};
use std::str::FromStr;
use std::{collections::HashSet, sync::LazyLock, time::Duration};
use types::{Checkpoint, Epoch, Hash256};
use types::{Checkpoint, Hash256};
pub const DEFAULT_RE_ORG_HEAD_THRESHOLD: ReOrgThreshold = ReOrgThreshold(20);
pub const DEFAULT_RE_ORG_PARENT_THRESHOLD: ReOrgThreshold = ReOrgThreshold(160);
pub const DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION: Epoch = Epoch::new(2);
/// Default to 1/12th of the slot, which is 1 second on mainnet.
pub const DEFAULT_RE_ORG_CUTOFF_DENOMINATOR: u32 = 12;
pub const DEFAULT_FORK_CHOICE_BEFORE_PROPOSAL_TIMEOUT: u64 = 250;
/// Default fraction of a slot lookahead for payload preparation (12/3 = 4 seconds on mainnet).
@@ -41,14 +36,6 @@ pub struct ChainConfig {
pub archive: bool,
/// The max size of a message that can be sent over the network.
pub max_network_size: usize,
/// Maximum percentage of the head committee weight at which to attempt re-orging the canonical head.
pub re_org_head_threshold: Option<ReOrgThreshold>,
/// Minimum percentage of the parent committee weight at which to attempt re-orging the canonical head.
pub re_org_parent_threshold: Option<ReOrgThreshold>,
/// Maximum number of epochs since finalization for attempting a proposer re-org.
pub re_org_max_epochs_since_finalization: Epoch,
/// Maximum delay after the start of the slot at which to propose a reorging block.
pub re_org_cutoff_millis: Option<u64>,
/// Additional epoch offsets at which re-orging block proposals are not permitted.
///
/// By default this list is empty, but it can be useful for reacting to network conditions, e.g.
@@ -125,6 +112,8 @@ pub struct ChainConfig {
pub enable_partial_columns: bool,
/// The node's custody type, determining how many data columns to custody and sample.
pub node_custody_type: NodeCustodyType,
/// Disable proposer re-org
pub disable_proposer_reorg: bool,
}
impl Default for ChainConfig {
@@ -134,10 +123,6 @@ impl Default for ChainConfig {
weak_subjectivity_checkpoint: None,
archive: false,
max_network_size: 10 * 1_048_576, // 10M
re_org_head_threshold: Some(DEFAULT_RE_ORG_HEAD_THRESHOLD),
re_org_parent_threshold: Some(DEFAULT_RE_ORG_PARENT_THRESHOLD),
re_org_max_epochs_since_finalization: DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION,
re_org_cutoff_millis: None,
re_org_disallowed_offsets: DisallowedReOrgOffsets::default(),
fork_choice_before_proposal_timeout_ms: DEFAULT_FORK_CHOICE_BEFORE_PROPOSAL_TIMEOUT,
// Builder fallback configs that are set in `clap` will override these.
@@ -168,15 +153,7 @@ impl Default for ChainConfig {
disable_get_blobs: false,
enable_partial_columns: false,
node_custody_type: NodeCustodyType::Fullnode,
disable_proposer_reorg: false,
}
}
}
impl ChainConfig {
/// The latest delay from the start of the slot at which to attempt a 1-slot re-org.
pub fn re_org_cutoff(&self, slot_duration: Duration) -> Duration {
self.re_org_cutoff_millis
.map(Duration::from_millis)
.unwrap_or_else(|| slot_duration / DEFAULT_RE_ORG_CUTOFF_DENOMINATOR)
}
}