Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions beacon_node/beacon_chain/src/chain_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ use std::str::FromStr;
use std::{collections::HashSet, sync::LazyLock, time::Duration};
use types::{Checkpoint, Epoch, Hash256};

// Reorg defaults - actual defaults come from network config in common/eth2_network_config
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;
Expand Down
34 changes: 32 additions & 2 deletions beacon_node/http_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,11 @@ pub use publish_blocks::{
ProvenancedBlock, publish_blinded_block, publish_block, reconstruct_block,
};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use slot_clock::SlotClock;
use ssz::Encode;
pub use state_id::StateId;
use std::collections::HashMap;
use std::future::Future;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::path::PathBuf;
Expand Down Expand Up @@ -1821,8 +1823,36 @@ pub fn serve<T: BeaconChainTypes>(
.then(
move |task_spawner: TaskSpawner<T::EthSpec>, chain: Arc<BeaconChain<T>>| {
task_spawner.blocking_json_task(Priority::P0, move || {
let config_and_preset =
ConfigAndPreset::from_chain_spec::<T::EthSpec>(&chain.spec);
let mut overrides = HashMap::new();
overrides.insert(
"REORG_MAX_EPOCHS_SINCE_FINALIZATION".to_string(),
Value::String(
chain
.config
.re_org_max_epochs_since_finalization
.as_u64()
.to_string(),
),
);
if chain.config.re_org_head_threshold.is_some() {
overrides.insert(
"REORG_HEAD_WEIGHT_THRESHOLD".to_string(),
Value::String(
chain.config.re_org_head_threshold.unwrap().0.to_string(),
),
);
}
if chain.config.re_org_parent_threshold.is_some() {
overrides.insert(
"REORG_PARENT_WEIGHT_THRESHOLD".to_string(),
Value::String(
chain.config.re_org_parent_threshold.unwrap().0.to_string(),
),
);
}
let config_and_preset = ConfigAndPreset::from_chain_spec_with_overrides::<
T::EthSpec,
>(&chain.spec, Some(overrides));
Ok(api_types::GenericResponse::from(config_and_preset))
})
},
Expand Down
18 changes: 11 additions & 7 deletions beacon_node/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use account_utils::{STDIN_INPUTS_FLAG, read_input_from_user};
use beacon_chain::chain_config::{
DEFAULT_PREPARE_PAYLOAD_LOOKAHEAD_FACTOR, DEFAULT_RE_ORG_HEAD_THRESHOLD,
DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION, DEFAULT_RE_ORG_PARENT_THRESHOLD,
DisallowedReOrgOffsets, INVALID_HOLESKY_BLOCK_ROOT, ReOrgThreshold,
DEFAULT_PREPARE_PAYLOAD_LOOKAHEAD_FACTOR, DisallowedReOrgOffsets,
INVALID_HOLESKY_BLOCK_ROOT, ReOrgThreshold,
};
use beacon_chain::custody_context::NodeCustodyType;
use beacon_chain::graffiti_calculator::GraffitiOrigin;
Expand Down Expand Up @@ -730,21 +729,26 @@ pub fn get_config<E: EthSpec>(
client_config.chain.re_org_head_threshold = None;
client_config.chain.re_org_parent_threshold = None;
} else {
// Read reorg values from ChainSpec (from config YAML), then check for CLI overrides
let head_threshold_from_spec = spec.reorg_head_weight_threshold;
let parent_threshold_from_spec = spec.reorg_parent_weight_threshold;
let epochs_from_spec = Epoch::new(spec.reorg_max_epochs_since_finalization);

// Apply CLI overrides if provided, otherwise use ChainSpec values
client_config.chain.re_org_head_threshold = Some(
clap_utils::parse_optional(cli_args, "proposer-reorg-threshold")?
.map(ReOrgThreshold)
.unwrap_or(DEFAULT_RE_ORG_HEAD_THRESHOLD),
.unwrap_or(ReOrgThreshold(head_threshold_from_spec)),
);
client_config.chain.re_org_max_epochs_since_finalization =
clap_utils::parse_optional(cli_args, "proposer-reorg-epochs-since-finalization")?
.unwrap_or(DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION);
.unwrap_or(epochs_from_spec);
client_config.chain.re_org_cutoff_millis =
clap_utils::parse_optional(cli_args, "proposer-reorg-cutoff")?;

client_config.chain.re_org_parent_threshold = Some(
clap_utils::parse_optional(cli_args, "proposer-reorg-parent-threshold")?
.map(ReOrgThreshold)
.unwrap_or(DEFAULT_RE_ORG_PARENT_THRESHOLD),
.unwrap_or(ReOrgThreshold(parent_threshold_from_spec)),
);

if let Some(disallowed_offsets_str) =
Expand Down
32 changes: 26 additions & 6 deletions consensus/types/src/core/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,9 @@ pub struct ChainSpec {
* Fork choice
*/
pub proposer_score_boost: Option<u64>,
pub reorg_head_weight_threshold: Option<u64>,
pub reorg_parent_weight_threshold: Option<u64>,
pub reorg_head_weight_threshold: u64,
pub reorg_parent_weight_threshold: u64,
pub reorg_max_epochs_since_finalization: u64,

/*
* Eth1
Expand Down Expand Up @@ -1028,8 +1029,9 @@ impl ChainSpec {
* Fork choice
*/
proposer_score_boost: Some(40),
reorg_head_weight_threshold: Some(20),
reorg_parent_weight_threshold: Some(160),
reorg_head_weight_threshold: 20,
reorg_parent_weight_threshold: 160,
reorg_max_epochs_since_finalization: 2,

/*
* Eth1
Expand Down Expand Up @@ -1394,8 +1396,9 @@ impl ChainSpec {
* Fork choice
*/
proposer_score_boost: Some(40),
reorg_head_weight_threshold: Some(20),
reorg_parent_weight_threshold: Some(160),
reorg_head_weight_threshold: 20,
reorg_parent_weight_threshold: 160,
reorg_max_epochs_since_finalization: 2,

/*
* Eth1
Expand Down Expand Up @@ -1811,6 +1814,13 @@ pub struct Config {
#[serde(skip_serializing_if = "Option::is_none")]
proposer_score_boost: Option<MaybeQuoted<u64>>,

#[serde(with = "serde_utils::quoted_u64")]
reorg_head_weight_threshold: u64,
#[serde(with = "serde_utils::quoted_u64")]
reorg_parent_weight_threshold: u64,
#[serde(with = "serde_utils::quoted_u64")]
reorg_max_epochs_since_finalization: u64,

#[serde(with = "serde_utils::quoted_u64")]
deposit_chain_id: u64,
#[serde(with = "serde_utils::quoted_u64")]
Expand Down Expand Up @@ -2263,6 +2273,10 @@ impl Config {

proposer_score_boost: spec.proposer_score_boost.map(|value| MaybeQuoted { value }),

reorg_head_weight_threshold: spec.reorg_head_weight_threshold,
reorg_parent_weight_threshold: spec.reorg_parent_weight_threshold,
reorg_max_epochs_since_finalization: spec.reorg_max_epochs_since_finalization,

deposit_chain_id: spec.deposit_chain_id,
deposit_network_id: spec.deposit_network_id,
deposit_contract_address: spec.deposit_contract_address,
Expand Down Expand Up @@ -2351,6 +2365,9 @@ impl Config {
max_per_epoch_activation_churn_limit,
churn_limit_quotient,
proposer_score_boost,
reorg_head_weight_threshold,
reorg_parent_weight_threshold,
reorg_max_epochs_since_finalization,
deposit_chain_id,
deposit_network_id,
deposit_contract_address,
Expand Down Expand Up @@ -2423,6 +2440,9 @@ impl Config {
max_per_epoch_activation_churn_limit,
churn_limit_quotient,
proposer_score_boost: proposer_score_boost.map(|q| q.value),
reorg_head_weight_threshold,
reorg_parent_weight_threshold,
reorg_max_epochs_since_finalization,
deposit_chain_id,
deposit_network_id,
deposit_contract_address,
Expand Down
36 changes: 33 additions & 3 deletions consensus/types/src/core/config_and_preset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,28 @@ pub struct ConfigAndPreset {
#[serde(flatten)]
pub gloas_preset: GloasPreset,
/// The `extra_fields` map allows us to gracefully decode fields intended for future hard forks.
/// Also allows for overrides of config.yaml values from cli props - be sure to keep this field at the bottom of the struct
#[serde(flatten)]
pub extra_fields: HashMap<String, Value>,
}

impl ConfigAndPreset {
pub fn from_chain_spec<E: EthSpec>(spec: &ChainSpec) -> Self {
Self::from_chain_spec_with_overrides::<E>(spec, None)
}

/// Create ConfigAndPreset with optional overrides.
pub fn from_chain_spec_with_overrides<E: EthSpec>(
spec: &ChainSpec,
overrides: Option<HashMap<String, Value>>,
) -> Self {
let mut config = Config::from_chain_spec::<E>(spec);
let base_preset = BasePreset::from_chain_spec::<E>(spec);
let altair_preset = AltairPreset::from_chain_spec::<E>(spec);
let bellatrix_preset = BellatrixPreset::from_chain_spec::<E>(spec);
let capella_preset = CapellaPreset::from_chain_spec::<E>(spec);
let deneb_preset = DenebPreset::from_chain_spec::<E>(spec);
let extra_fields = get_extra_fields(spec);
let extra_fields = get_extra_fields(spec, overrides);

if spec.is_gloas_scheduled() {
let electra_preset = ElectraPreset::from_chain_spec::<E>(spec);
Expand Down Expand Up @@ -109,11 +118,15 @@ impl ConfigAndPreset {
}

/// Get a hashmap of constants to add to the `PresetAndConfig`
pub fn get_extra_fields(spec: &ChainSpec) -> HashMap<String, Value> {
pub fn get_extra_fields(
spec: &ChainSpec,
overrides: Option<HashMap<String, Value>>,
) -> HashMap<String, Value> {
let hex_string = |value: &[u8]| format!("0x{}", hex::encode(value)).into();
let u32_hex = |v: u32| hex_string(&v.to_le_bytes());
let u8_hex = |v: u8| hex_string(&v.to_le_bytes());
hashmap! {

let mut extra_fields = hashmap! {
"bls_withdrawal_prefix".to_uppercase() => u8_hex(spec.bls_withdrawal_prefix_byte),
"eth1_address_withdrawal_prefix".to_uppercase() => u8_hex(spec.eth1_address_withdrawal_prefix_byte),
"domain_beacon_proposer".to_uppercase() => u32_hex(spec.domain_beacon_proposer),
Expand Down Expand Up @@ -141,7 +154,24 @@ pub fn get_extra_fields(spec: &ChainSpec) -> HashMap<String, Value> {
"compounding_withdrawal_prefix".to_uppercase() => u8_hex(spec.compounding_withdrawal_prefix_byte),
"unset_deposit_requests_start_index".to_uppercase() => spec.unset_deposit_requests_start_index.to_string().into(),
"full_exit_request_amount".to_uppercase() => spec.full_exit_request_amount.to_string().into(),
};

// Handle overrides
if let Some(ref overrides_map) = overrides {
for (key, value) in overrides_map.iter() {
// Handle reorg config overrides given these configs from .yaml can be overidden from cli props
match key.as_str() {
"REORG_HEAD_WEIGHT_THRESHOLD"
| "REORG_PARENT_WEIGHT_THRESHOLD"
| "REORG_MAX_EPOCHS_SINCE_FINALIZATION" => {
extra_fields.insert(key.to_string(), value.clone().to_string().into());
}
_ => {}
}
}
}

extra_fields
}

#[cfg(test)]
Expand Down
4 changes: 4 additions & 0 deletions lighthouse/environment/tests/testnet_dir/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ CHURN_LIMIT_QUOTIENT: 65536
# ---------------------------------------------------------------
# 40%
PROPOSER_SCORE_BOOST: 40
# Proposer reorg configuration
REORG_HEAD_WEIGHT_THRESHOLD: 20
REORG_PARENT_WEIGHT_THRESHOLD: 160
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2

# Deposit contract
# ---------------------------------------------------------------
Expand Down
39 changes: 38 additions & 1 deletion lighthouse/tests/beacon_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::exec::{CommandLineTestExec, CompletedTest};
use beacon_node::beacon_chain::chain_config::{
DEFAULT_RE_ORG_CUTOFF_DENOMINATOR, DEFAULT_RE_ORG_HEAD_THRESHOLD,
DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION, DEFAULT_SYNC_TOLERANCE_EPOCHS,
DisallowedReOrgOffsets,
DisallowedReOrgOffsets, ReOrgThreshold,
};
use beacon_node::beacon_chain::custody_context::NodeCustodyType;
use beacon_node::{
Expand Down Expand Up @@ -2839,3 +2839,40 @@ fn invalid_block_roots_default_mainnet() {
assert!(config.chain.invalid_block_roots.is_empty());
})
}

#[test]
fn test_proposer_reorg_threshold_from_cli() {
CommandLineTest::new()
.flag("proposer-reorg-threshold", Some("21"))
.flag("proposer-reorg-parent-threshold", Some("161"))
.flag("proposer-reorg-epochs-since-finalization", Some("3"))
.run_with_zero_port()
.with_config(|config| {
assert_eq!(config.chain.re_org_head_threshold, Some(ReOrgThreshold(21)));
assert_eq!(
config.chain.re_org_parent_threshold,
Some(ReOrgThreshold(161))
);
assert_eq!(
config.chain.re_org_max_epochs_since_finalization,
Epoch::new(3)
);
});
}

#[test]
fn test_proposer_reorg_threshold_from_yaml() {
CommandLineTest::new()
.run_with_zero_port()
.with_config(|config| {
assert_eq!(config.chain.re_org_head_threshold, Some(ReOrgThreshold(20)));
assert_eq!(
config.chain.re_org_parent_threshold,
Some(ReOrgThreshold(160))
);
assert_eq!(
config.chain.re_org_max_epochs_since_finalization,
Epoch::new(2)
);
});
}