Skip to content

Commit 0e1e44f

Browse files
committed
feat: added reorg configs in spec api
1 parent 2ce6b51 commit 0e1e44f

File tree

7 files changed

+161
-19
lines changed

7 files changed

+161
-19
lines changed

beacon_node/beacon_chain/src/chain_config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ use std::str::FromStr;
55
use std::{collections::HashSet, sync::LazyLock, time::Duration};
66
use types::{Checkpoint, Epoch, Hash256};
77

8+
// Reorg defaults - actual defaults come from network config in common/eth2_network_config
89
pub const DEFAULT_RE_ORG_HEAD_THRESHOLD: ReOrgThreshold = ReOrgThreshold(20);
910
pub const DEFAULT_RE_ORG_PARENT_THRESHOLD: ReOrgThreshold = ReOrgThreshold(160);
1011
pub const DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION: Epoch = Epoch::new(2);
12+
1113
/// Default to 1/12th of the slot, which is 1 second on mainnet.
1214
pub const DEFAULT_RE_ORG_CUTOFF_DENOMINATOR: u32 = 12;
1315
pub const DEFAULT_FORK_CHOICE_BEFORE_PROPOSAL_TIMEOUT: u64 = 250;

beacon_node/http_api/src/lib.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,11 @@ pub use publish_blocks::{
7070
ProvenancedBlock, publish_blinded_block, publish_block, reconstruct_block,
7171
};
7272
use serde::{Deserialize, Serialize};
73+
use serde_json::Value;
7374
use slot_clock::SlotClock;
7475
use ssz::Encode;
7576
pub use state_id::StateId;
77+
use std::collections::HashMap;
7678
use std::future::Future;
7779
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
7880
use std::path::PathBuf;
@@ -1821,8 +1823,36 @@ pub fn serve<T: BeaconChainTypes>(
18211823
.then(
18221824
move |task_spawner: TaskSpawner<T::EthSpec>, chain: Arc<BeaconChain<T>>| {
18231825
task_spawner.blocking_json_task(Priority::P0, move || {
1824-
let config_and_preset =
1825-
ConfigAndPreset::from_chain_spec::<T::EthSpec>(&chain.spec);
1826+
let mut overrides = HashMap::new();
1827+
overrides.insert(
1828+
"REORG_MAX_EPOCHS_SINCE_FINALIZATION".to_string(),
1829+
Value::String(
1830+
chain
1831+
.config
1832+
.re_org_max_epochs_since_finalization
1833+
.as_u64()
1834+
.to_string(),
1835+
),
1836+
);
1837+
if chain.config.re_org_head_threshold.is_some() {
1838+
overrides.insert(
1839+
"REORG_HEAD_WEIGHT_THRESHOLD".to_string(),
1840+
Value::String(
1841+
chain.config.re_org_head_threshold.unwrap().0.to_string(),
1842+
),
1843+
);
1844+
}
1845+
if chain.config.re_org_parent_threshold.is_some() {
1846+
overrides.insert(
1847+
"REORG_PARENT_WEIGHT_THRESHOLD".to_string(),
1848+
Value::String(
1849+
chain.config.re_org_parent_threshold.unwrap().0.to_string(),
1850+
),
1851+
);
1852+
}
1853+
let config_and_preset = ConfigAndPreset::from_chain_spec_with_overrides::<
1854+
T::EthSpec,
1855+
>(&chain.spec, Some(overrides));
18261856
Ok(api_types::GenericResponse::from(config_and_preset))
18271857
})
18281858
},

beacon_node/src/config.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use account_utils::{STDIN_INPUTS_FLAG, read_input_from_user};
22
use beacon_chain::chain_config::{
3-
DEFAULT_PREPARE_PAYLOAD_LOOKAHEAD_FACTOR, DEFAULT_RE_ORG_HEAD_THRESHOLD,
4-
DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION, DEFAULT_RE_ORG_PARENT_THRESHOLD,
5-
DisallowedReOrgOffsets, INVALID_HOLESKY_BLOCK_ROOT, ReOrgThreshold,
3+
DEFAULT_PREPARE_PAYLOAD_LOOKAHEAD_FACTOR, DisallowedReOrgOffsets, INVALID_HOLESKY_BLOCK_ROOT,
4+
ReOrgThreshold,
65
};
76
use beacon_chain::custody_context::NodeCustodyType;
87
use beacon_chain::graffiti_calculator::GraffitiOrigin;
@@ -730,21 +729,26 @@ pub fn get_config<E: EthSpec>(
730729
client_config.chain.re_org_head_threshold = None;
731730
client_config.chain.re_org_parent_threshold = None;
732731
} else {
732+
// Read reorg values from ChainSpec (from config YAML), then check for CLI overrides
733+
let head_threshold_from_spec = spec.reorg_head_weight_threshold;
734+
let parent_threshold_from_spec = spec.reorg_parent_weight_threshold;
735+
let epochs_from_spec = Epoch::new(spec.reorg_max_epochs_since_finalization);
736+
737+
// Apply CLI overrides if provided, otherwise use ChainSpec values
733738
client_config.chain.re_org_head_threshold = Some(
734739
clap_utils::parse_optional(cli_args, "proposer-reorg-threshold")?
735740
.map(ReOrgThreshold)
736-
.unwrap_or(DEFAULT_RE_ORG_HEAD_THRESHOLD),
741+
.unwrap_or(ReOrgThreshold(head_threshold_from_spec)),
737742
);
738743
client_config.chain.re_org_max_epochs_since_finalization =
739744
clap_utils::parse_optional(cli_args, "proposer-reorg-epochs-since-finalization")?
740-
.unwrap_or(DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION);
745+
.unwrap_or(epochs_from_spec);
741746
client_config.chain.re_org_cutoff_millis =
742747
clap_utils::parse_optional(cli_args, "proposer-reorg-cutoff")?;
743-
744748
client_config.chain.re_org_parent_threshold = Some(
745749
clap_utils::parse_optional(cli_args, "proposer-reorg-parent-threshold")?
746750
.map(ReOrgThreshold)
747-
.unwrap_or(DEFAULT_RE_ORG_PARENT_THRESHOLD),
751+
.unwrap_or(ReOrgThreshold(parent_threshold_from_spec)),
748752
);
749753

750754
if let Some(disallowed_offsets_str) =

consensus/types/src/core/chain_spec.rs

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,9 @@ pub struct ChainSpec {
137137
* Fork choice
138138
*/
139139
pub proposer_score_boost: Option<u64>,
140-
pub reorg_head_weight_threshold: Option<u64>,
141-
pub reorg_parent_weight_threshold: Option<u64>,
140+
pub reorg_head_weight_threshold: u64,
141+
pub reorg_parent_weight_threshold: u64,
142+
pub reorg_max_epochs_since_finalization: u64,
142143

143144
/*
144145
* Eth1
@@ -1028,8 +1029,9 @@ impl ChainSpec {
10281029
* Fork choice
10291030
*/
10301031
proposer_score_boost: Some(40),
1031-
reorg_head_weight_threshold: Some(20),
1032-
reorg_parent_weight_threshold: Some(160),
1032+
reorg_head_weight_threshold: 20,
1033+
reorg_parent_weight_threshold: 160,
1034+
reorg_max_epochs_since_finalization: 2,
10331035

10341036
/*
10351037
* Eth1
@@ -1394,8 +1396,9 @@ impl ChainSpec {
13941396
* Fork choice
13951397
*/
13961398
proposer_score_boost: Some(40),
1397-
reorg_head_weight_threshold: Some(20),
1398-
reorg_parent_weight_threshold: Some(160),
1399+
reorg_head_weight_threshold: 20,
1400+
reorg_parent_weight_threshold: 160,
1401+
reorg_max_epochs_since_finalization: 2,
13991402

14001403
/*
14011404
* Eth1
@@ -1811,6 +1814,16 @@ pub struct Config {
18111814
#[serde(skip_serializing_if = "Option::is_none")]
18121815
proposer_score_boost: Option<MaybeQuoted<u64>>,
18131816

1817+
#[serde(default = "default_reorg_head_weight_threshold")]
1818+
#[serde(with = "serde_utils::quoted_u64")]
1819+
reorg_head_weight_threshold: u64,
1820+
#[serde(default = "default_reorg_parent_weight_threshold")]
1821+
#[serde(with = "serde_utils::quoted_u64")]
1822+
reorg_parent_weight_threshold: u64,
1823+
#[serde(default = "default_reorg_max_epochs_since_finalization")]
1824+
#[serde(with = "serde_utils::quoted_u64")]
1825+
reorg_max_epochs_since_finalization: u64,
1826+
18141827
#[serde(with = "serde_utils::quoted_u64")]
18151828
deposit_chain_id: u64,
18161829
#[serde(with = "serde_utils::quoted_u64")]
@@ -1974,6 +1987,18 @@ const fn default_max_per_epoch_activation_churn_limit() -> u64 {
19741987
8
19751988
}
19761989

1990+
const fn default_reorg_head_weight_threshold() -> u64 {
1991+
20
1992+
}
1993+
1994+
const fn default_reorg_parent_weight_threshold() -> u64 {
1995+
160
1996+
}
1997+
1998+
const fn default_reorg_max_epochs_since_finalization() -> u64 {
1999+
2
2000+
}
2001+
19772002
const fn default_gas_limit_adjustment_factor() -> u64 {
19782003
1024
19792004
}
@@ -2263,6 +2288,10 @@ impl Config {
22632288

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

2291+
reorg_head_weight_threshold: spec.reorg_head_weight_threshold,
2292+
reorg_parent_weight_threshold: spec.reorg_parent_weight_threshold,
2293+
reorg_max_epochs_since_finalization: spec.reorg_max_epochs_since_finalization,
2294+
22662295
deposit_chain_id: spec.deposit_chain_id,
22672296
deposit_network_id: spec.deposit_network_id,
22682297
deposit_contract_address: spec.deposit_contract_address,
@@ -2351,6 +2380,9 @@ impl Config {
23512380
max_per_epoch_activation_churn_limit,
23522381
churn_limit_quotient,
23532382
proposer_score_boost,
2383+
reorg_head_weight_threshold,
2384+
reorg_parent_weight_threshold,
2385+
reorg_max_epochs_since_finalization,
23542386
deposit_chain_id,
23552387
deposit_network_id,
23562388
deposit_contract_address,
@@ -2423,6 +2455,9 @@ impl Config {
24232455
max_per_epoch_activation_churn_limit,
24242456
churn_limit_quotient,
24252457
proposer_score_boost: proposer_score_boost.map(|q| q.value),
2458+
reorg_head_weight_threshold,
2459+
reorg_parent_weight_threshold,
2460+
reorg_max_epochs_since_finalization,
24262461
deposit_chain_id,
24272462
deposit_network_id,
24282463
deposit_contract_address,

consensus/types/src/core/config_and_preset.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,28 @@ pub struct ConfigAndPreset {
4242
#[serde(flatten)]
4343
pub gloas_preset: GloasPreset,
4444
/// The `extra_fields` map allows us to gracefully decode fields intended for future hard forks.
45+
/// Also allows for overrides of config.yaml values from cli props - be sure to keep this field at the bottom of the struct
4546
#[serde(flatten)]
4647
pub extra_fields: HashMap<String, Value>,
4748
}
4849

4950
impl ConfigAndPreset {
5051
pub fn from_chain_spec<E: EthSpec>(spec: &ChainSpec) -> Self {
52+
Self::from_chain_spec_with_overrides::<E>(spec, None)
53+
}
54+
55+
/// Create ConfigAndPreset with optional overrides.
56+
pub fn from_chain_spec_with_overrides<E: EthSpec>(
57+
spec: &ChainSpec,
58+
overrides: Option<HashMap<String, Value>>,
59+
) -> Self {
5160
let mut config = Config::from_chain_spec::<E>(spec);
5261
let base_preset = BasePreset::from_chain_spec::<E>(spec);
5362
let altair_preset = AltairPreset::from_chain_spec::<E>(spec);
5463
let bellatrix_preset = BellatrixPreset::from_chain_spec::<E>(spec);
5564
let capella_preset = CapellaPreset::from_chain_spec::<E>(spec);
5665
let deneb_preset = DenebPreset::from_chain_spec::<E>(spec);
57-
let extra_fields = get_extra_fields(spec);
66+
let extra_fields = get_extra_fields(spec, overrides);
5867

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

111120
/// Get a hashmap of constants to add to the `PresetAndConfig`
112-
pub fn get_extra_fields(spec: &ChainSpec) -> HashMap<String, Value> {
121+
pub fn get_extra_fields(
122+
spec: &ChainSpec,
123+
overrides: Option<HashMap<String, Value>>,
124+
) -> HashMap<String, Value> {
113125
let hex_string = |value: &[u8]| format!("0x{}", hex::encode(value)).into();
114126
let u32_hex = |v: u32| hex_string(&v.to_le_bytes());
115127
let u8_hex = |v: u8| hex_string(&v.to_le_bytes());
116-
hashmap! {
128+
129+
let mut extra_fields = hashmap! {
117130
"bls_withdrawal_prefix".to_uppercase() => u8_hex(spec.bls_withdrawal_prefix_byte),
118131
"eth1_address_withdrawal_prefix".to_uppercase() => u8_hex(spec.eth1_address_withdrawal_prefix_byte),
119132
"domain_beacon_proposer".to_uppercase() => u32_hex(spec.domain_beacon_proposer),
@@ -141,7 +154,24 @@ pub fn get_extra_fields(spec: &ChainSpec) -> HashMap<String, Value> {
141154
"compounding_withdrawal_prefix".to_uppercase() => u8_hex(spec.compounding_withdrawal_prefix_byte),
142155
"unset_deposit_requests_start_index".to_uppercase() => spec.unset_deposit_requests_start_index.to_string().into(),
143156
"full_exit_request_amount".to_uppercase() => spec.full_exit_request_amount.to_string().into(),
157+
};
158+
159+
// Handle overrides
160+
if let Some(ref overrides_map) = overrides {
161+
for (key, value) in overrides_map.iter() {
162+
// Handle reorg config overrides given these configs from .yaml can be overidden from cli props
163+
match key.as_str() {
164+
"REORG_HEAD_WEIGHT_THRESHOLD"
165+
| "REORG_PARENT_WEIGHT_THRESHOLD"
166+
| "REORG_MAX_EPOCHS_SINCE_FINALIZATION" => {
167+
extra_fields.insert(key.to_string(), value.clone().to_string().into());
168+
}
169+
_ => {}
170+
}
171+
}
144172
}
173+
174+
extra_fields
145175
}
146176

147177
#[cfg(test)]

lighthouse/environment/tests/testnet_dir/config.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ CHURN_LIMIT_QUOTIENT: 65536
7676
# ---------------------------------------------------------------
7777
# 40%
7878
PROPOSER_SCORE_BOOST: 40
79+
# Proposer reorg configuration
80+
REORG_HEAD_WEIGHT_THRESHOLD: 20
81+
REORG_PARENT_WEIGHT_THRESHOLD: 160
82+
REORG_MAX_EPOCHS_SINCE_FINALIZATION: 2
7983

8084
# Deposit contract
8185
# ---------------------------------------------------------------

lighthouse/tests/beacon_node.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::exec::{CommandLineTestExec, CompletedTest};
22
use beacon_node::beacon_chain::chain_config::{
33
DEFAULT_RE_ORG_CUTOFF_DENOMINATOR, DEFAULT_RE_ORG_HEAD_THRESHOLD,
44
DEFAULT_RE_ORG_MAX_EPOCHS_SINCE_FINALIZATION, DEFAULT_SYNC_TOLERANCE_EPOCHS,
5-
DisallowedReOrgOffsets,
5+
DisallowedReOrgOffsets, ReOrgThreshold,
66
};
77
use beacon_node::beacon_chain::custody_context::NodeCustodyType;
88
use beacon_node::{
@@ -2839,3 +2839,40 @@ fn invalid_block_roots_default_mainnet() {
28392839
assert!(config.chain.invalid_block_roots.is_empty());
28402840
})
28412841
}
2842+
2843+
#[test]
2844+
fn test_proposer_reorg_threshold_from_cli() {
2845+
CommandLineTest::new()
2846+
.flag("proposer-reorg-threshold", Some("21"))
2847+
.flag("proposer-reorg-parent-threshold", Some("161"))
2848+
.flag("proposer-reorg-epochs-since-finalization", Some("3"))
2849+
.run_with_zero_port()
2850+
.with_config(|config| {
2851+
assert_eq!(config.chain.re_org_head_threshold, Some(ReOrgThreshold(21)));
2852+
assert_eq!(
2853+
config.chain.re_org_parent_threshold,
2854+
Some(ReOrgThreshold(161))
2855+
);
2856+
assert_eq!(
2857+
config.chain.re_org_max_epochs_since_finalization,
2858+
Epoch::new(3)
2859+
);
2860+
});
2861+
}
2862+
2863+
#[test]
2864+
fn test_proposer_reorg_threshold_from_yaml() {
2865+
CommandLineTest::new()
2866+
.run_with_zero_port()
2867+
.with_config(|config| {
2868+
assert_eq!(config.chain.re_org_head_threshold, Some(ReOrgThreshold(20)));
2869+
assert_eq!(
2870+
config.chain.re_org_parent_threshold,
2871+
Some(ReOrgThreshold(160))
2872+
);
2873+
assert_eq!(
2874+
config.chain.re_org_max_epochs_since_finalization,
2875+
Epoch::new(2)
2876+
);
2877+
});
2878+
}

0 commit comments

Comments
 (0)