Skip to content

Commit 19e8538

Browse files
committed
Ensure difficulty/hash/epoch overrides change the ChainSpec (#2798)
* Unify loading of eth2_network_config * Apply overrides at lighthouse binary level * Remove duplicate override values * Add merge values to existing net configs * Make override flags global * Add merge fields to testing config * Add one to TTD * Fix failing engine tests * Fix test compile error * Remove TTD flags * Move get_eth2_network_config * Fix warn * Address review comments
1 parent 866b80f commit 19e8538

File tree

25 files changed

+249
-261
lines changed

25 files changed

+249
-261
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

beacon_node/beacon_chain/src/beacon_chain.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2893,7 +2893,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
28932893
let parent_hash;
28942894
if !is_merge_complete(&state) {
28952895
let terminal_pow_block_hash = execution_layer
2896-
.block_on(|execution_layer| execution_layer.get_terminal_pow_block_hash())
2896+
.block_on(|execution_layer| {
2897+
execution_layer.get_terminal_pow_block_hash(&self.spec)
2898+
})
28972899
.map_err(BlockProductionError::TerminalPoWBlockLookupFailed)?;
28982900

28992901
if let Some(terminal_pow_block_hash) = terminal_pow_block_hash {

beacon_node/beacon_chain/src/block_verification.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,10 @@ impl<'a, T: BeaconChainTypes> FullyVerifiedBlock<'a, T> {
11191119

11201120
let is_valid_terminal_pow_block = execution_layer
11211121
.block_on(|execution_layer| {
1122-
execution_layer.is_valid_terminal_pow_block_hash(execution_payload.parent_hash)
1122+
execution_layer.is_valid_terminal_pow_block_hash(
1123+
execution_payload.parent_hash,
1124+
&chain.spec,
1125+
)
11231126
})
11241127
.map_err(ExecutionPayloadError::from)?;
11251128

beacon_node/beacon_chain/src/test_utils.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,6 @@ where
330330
}
331331

332332
pub fn execution_layer(mut self, urls: &[&str]) -> Self {
333-
let spec = self.spec.clone().expect("cannot build without spec");
334333
assert!(
335334
self.execution_layer.is_none(),
336335
"execution layer already defined"
@@ -345,8 +344,6 @@ where
345344
.unwrap();
346345
let execution_layer = ExecutionLayer::from_urls(
347346
urls,
348-
spec.terminal_total_difficulty,
349-
spec.terminal_block_hash,
350347
Some(Address::repeat_byte(42)),
351348
el_runtime.task_executor.clone(),
352349
el_runtime.log.clone(),
@@ -364,6 +361,7 @@ where
364361
spec.terminal_total_difficulty,
365362
DEFAULT_TERMINAL_BLOCK,
366363
spec.terminal_block_hash,
364+
spec.terminal_block_hash_activation_epoch,
367365
);
368366
self.execution_layer = Some(mock.el.clone());
369367
self.mock_execution_layer = Some(mock);

beacon_node/client/src/builder.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -148,19 +148,10 @@ where
148148
None
149149
};
150150

151-
let terminal_total_difficulty = config
152-
.terminal_total_difficulty_override
153-
.unwrap_or(spec.terminal_total_difficulty);
154-
let terminal_block_hash = config
155-
.terminal_block_hash_override
156-
.unwrap_or(spec.terminal_block_hash);
157-
158151
let execution_layer = if let Some(execution_endpoints) = config.execution_endpoints {
159152
let context = runtime_context.service_context("exec".into());
160153
let execution_layer = ExecutionLayer::from_urls(
161154
execution_endpoints,
162-
terminal_total_difficulty,
163-
terminal_block_hash,
164155
config.fee_recipient,
165156
context.executor.clone(),
166157
context.log().clone(),

beacon_node/client/src/config.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use beacon_chain::types::Epoch;
21
use directory::DEFAULT_ROOT_DIR;
32
use network::NetworkConfig;
43
use sensitive_url::SensitiveUrl;
54
use serde_derive::{Deserialize, Serialize};
65
use std::fs;
76
use std::path::PathBuf;
8-
use types::{Address, Graffiti, Hash256, PublicKeyBytes, Uint256};
7+
use types::{Address, Graffiti, PublicKeyBytes};
98

109
/// Default directory name for the freezer database under the top-level data dir.
1110
const DEFAULT_FREEZER_DB_DIR: &str = "freezer_db";
@@ -76,9 +75,6 @@ pub struct Config {
7675
pub chain: beacon_chain::ChainConfig,
7776
pub eth1: eth1::Config,
7877
pub execution_endpoints: Option<Vec<SensitiveUrl>>,
79-
pub terminal_total_difficulty_override: Option<Uint256>,
80-
pub terminal_block_hash_override: Option<Hash256>,
81-
pub terminal_block_hash_epoch_override: Option<Epoch>,
8278
pub fee_recipient: Option<Address>,
8379
pub http_api: http_api::Config,
8480
pub http_metrics: http_metrics::Config,
@@ -101,9 +97,6 @@ impl Default for Config {
10197
sync_eth1_chain: false,
10298
eth1: <_>::default(),
10399
execution_endpoints: None,
104-
terminal_total_difficulty_override: None,
105-
terminal_block_hash_override: None,
106-
terminal_block_hash_epoch_override: None,
107100
fee_recipient: None,
108101
disabled_forks: Vec::new(),
109102
graffiti: Graffiti::default(),

beacon_node/execution_layer/src/lib.rs

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use tokio::{
1818
sync::{Mutex, MutexGuard},
1919
time::{sleep, sleep_until, Instant},
2020
};
21+
use types::ChainSpec;
2122

2223
pub use engine_api::{http::HttpJsonRpc, ExecutePayloadResponseStatus};
2324

@@ -47,8 +48,6 @@ impl From<ApiError> for Error {
4748

4849
struct Inner {
4950
engines: Engines<HttpJsonRpc>,
50-
terminal_total_difficulty: Uint256,
51-
terminal_block_hash: Hash256,
5251
fee_recipient: Option<Address>,
5352
execution_blocks: Mutex<LruCache<Hash256, ExecutionBlock>>,
5453
executor: TaskExecutor,
@@ -73,8 +72,6 @@ impl ExecutionLayer {
7372
/// Instantiate `Self` with `urls.len()` engines, all using the JSON-RPC via HTTP.
7473
pub fn from_urls(
7574
urls: Vec<SensitiveUrl>,
76-
terminal_total_difficulty: Uint256,
77-
terminal_block_hash: Hash256,
7875
fee_recipient: Option<Address>,
7976
executor: TaskExecutor,
8077
log: Logger,
@@ -98,8 +95,6 @@ impl ExecutionLayer {
9895
latest_forkchoice_state: <_>::default(),
9996
log: log.clone(),
10097
},
101-
terminal_total_difficulty,
102-
terminal_block_hash,
10398
fee_recipient,
10499
execution_blocks: Mutex::new(LruCache::new(EXECUTION_BLOCKS_LRU_CACHE_SIZE)),
105100
executor,
@@ -121,14 +116,6 @@ impl ExecutionLayer {
121116
&self.inner.executor
122117
}
123118

124-
fn terminal_total_difficulty(&self) -> Uint256 {
125-
self.inner.terminal_total_difficulty
126-
}
127-
128-
fn terminal_block_hash(&self) -> Hash256 {
129-
self.inner.terminal_block_hash
130-
}
131-
132119
fn fee_recipient(&self) -> Result<Address, Error> {
133120
self.inner
134121
.fee_recipient
@@ -455,11 +442,14 @@ impl ExecutionLayer {
455442
/// `get_terminal_pow_block_hash`
456443
///
457444
/// https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/merge/validator.md
458-
pub async fn get_terminal_pow_block_hash(&self) -> Result<Option<Hash256>, Error> {
445+
pub async fn get_terminal_pow_block_hash(
446+
&self,
447+
spec: &ChainSpec,
448+
) -> Result<Option<Hash256>, Error> {
459449
let hash_opt = self
460450
.engines()
461451
.first_success(|engine| async move {
462-
if self.terminal_block_hash() != Hash256::zero() {
452+
if spec.terminal_block_hash != Hash256::zero() {
463453
// Note: the specification is written such that if there are multiple blocks in
464454
// the PoW chain with the terminal block hash, then to select 0'th one.
465455
//
@@ -468,11 +458,12 @@ impl ExecutionLayer {
468458
// hash. Such a scenario would be a devestating hash collision with external
469459
// implications far outweighing those here.
470460
Ok(self
471-
.get_pow_block(engine, self.terminal_block_hash())
461+
.get_pow_block(engine, spec.terminal_block_hash)
472462
.await?
473463
.map(|block| block.block_hash))
474464
} else {
475-
self.get_pow_block_hash_at_total_difficulty(engine).await
465+
self.get_pow_block_hash_at_total_difficulty(engine, spec)
466+
.await
476467
}
477468
})
478469
.await
@@ -482,8 +473,8 @@ impl ExecutionLayer {
482473
info!(
483474
self.log(),
484475
"Found terminal block hash";
485-
"terminal_block_hash_override" => ?self.terminal_block_hash(),
486-
"terminal_total_difficulty" => ?self.terminal_total_difficulty(),
476+
"terminal_block_hash_override" => ?spec.terminal_block_hash,
477+
"terminal_total_difficulty" => ?spec.terminal_total_difficulty,
487478
"block_hash" => ?hash,
488479
);
489480
}
@@ -503,6 +494,7 @@ impl ExecutionLayer {
503494
async fn get_pow_block_hash_at_total_difficulty(
504495
&self,
505496
engine: &Engine<HttpJsonRpc>,
497+
spec: &ChainSpec,
506498
) -> Result<Option<Hash256>, ApiError> {
507499
let mut ttd_exceeding_block = None;
508500
let mut block = engine
@@ -518,7 +510,7 @@ impl ExecutionLayer {
518510
//
519511
// https://github.com/ethereum/consensus-specs/issues/2636
520512
loop {
521-
if block.total_difficulty >= self.terminal_total_difficulty() {
513+
if block.total_difficulty >= spec.terminal_total_difficulty {
522514
ttd_exceeding_block = Some(block.block_hash);
523515

524516
// Try to prevent infinite loops.
@@ -565,6 +557,7 @@ impl ExecutionLayer {
565557
pub async fn is_valid_terminal_pow_block_hash(
566558
&self,
567559
block_hash: Hash256,
560+
spec: &ChainSpec,
568561
) -> Result<Option<bool>, Error> {
569562
let broadcast_results = self
570563
.engines()
@@ -574,7 +567,7 @@ impl ExecutionLayer {
574567
self.get_pow_block(engine, pow_block.parent_hash).await?
575568
{
576569
return Ok(Some(
577-
self.is_valid_terminal_pow_block(pow_block, pow_parent),
570+
self.is_valid_terminal_pow_block(pow_block, pow_parent, spec),
578571
));
579572
}
580573
}
@@ -618,15 +611,19 @@ impl ExecutionLayer {
618611
/// This function should remain internal.
619612
///
620613
/// External users should use `self.is_valid_terminal_pow_block_hash`.
621-
fn is_valid_terminal_pow_block(&self, block: ExecutionBlock, parent: ExecutionBlock) -> bool {
622-
if block.block_hash == self.terminal_block_hash() {
614+
fn is_valid_terminal_pow_block(
615+
&self,
616+
block: ExecutionBlock,
617+
parent: ExecutionBlock,
618+
spec: &ChainSpec,
619+
) -> bool {
620+
if block.block_hash == spec.terminal_block_hash {
623621
return true;
624622
}
625623

626-
let is_total_difficulty_reached =
627-
block.total_difficulty >= self.terminal_total_difficulty();
624+
let is_total_difficulty_reached = block.total_difficulty >= spec.terminal_total_difficulty;
628625
let is_parent_total_difficulty_valid =
629-
parent.total_difficulty < self.terminal_total_difficulty();
626+
parent.total_difficulty < spec.terminal_total_difficulty;
630627
is_total_difficulty_reached && is_parent_total_difficulty_valid
631628
}
632629

@@ -685,14 +682,14 @@ mod test {
685682
async fn finds_valid_terminal_block_hash() {
686683
MockExecutionLayer::default_params()
687684
.move_to_block_prior_to_terminal_block()
688-
.with_terminal_block(|el, _| async move {
689-
assert_eq!(el.get_terminal_pow_block_hash().await.unwrap(), None)
685+
.with_terminal_block(|spec, el, _| async move {
686+
assert_eq!(el.get_terminal_pow_block_hash(&spec).await.unwrap(), None)
690687
})
691688
.await
692689
.move_to_terminal_block()
693-
.with_terminal_block(|el, terminal_block| async move {
690+
.with_terminal_block(|spec, el, terminal_block| async move {
694691
assert_eq!(
695-
el.get_terminal_pow_block_hash().await.unwrap(),
692+
el.get_terminal_pow_block_hash(&spec).await.unwrap(),
696693
Some(terminal_block.unwrap().block_hash)
697694
)
698695
})
@@ -703,9 +700,9 @@ mod test {
703700
async fn verifies_valid_terminal_block_hash() {
704701
MockExecutionLayer::default_params()
705702
.move_to_terminal_block()
706-
.with_terminal_block(|el, terminal_block| async move {
703+
.with_terminal_block(|spec, el, terminal_block| async move {
707704
assert_eq!(
708-
el.is_valid_terminal_pow_block_hash(terminal_block.unwrap().block_hash)
705+
el.is_valid_terminal_pow_block_hash(terminal_block.unwrap().block_hash, &spec)
709706
.await
710707
.unwrap(),
711708
Some(true)
@@ -718,11 +715,11 @@ mod test {
718715
async fn rejects_invalid_terminal_block_hash() {
719716
MockExecutionLayer::default_params()
720717
.move_to_terminal_block()
721-
.with_terminal_block(|el, terminal_block| async move {
718+
.with_terminal_block(|spec, el, terminal_block| async move {
722719
let invalid_terminal_block = terminal_block.unwrap().parent_hash;
723720

724721
assert_eq!(
725-
el.is_valid_terminal_pow_block_hash(invalid_terminal_block)
722+
el.is_valid_terminal_pow_block_hash(invalid_terminal_block, &spec)
726723
.await
727724
.unwrap(),
728725
Some(false)
@@ -735,11 +732,11 @@ mod test {
735732
async fn rejects_unknown_terminal_block_hash() {
736733
MockExecutionLayer::default_params()
737734
.move_to_terminal_block()
738-
.with_terminal_block(|el, _| async move {
735+
.with_terminal_block(|spec, el, _| async move {
739736
let missing_terminal_block = Hash256::repeat_byte(42);
740737

741738
assert_eq!(
742-
el.is_valid_terminal_pow_block_hash(missing_terminal_block)
739+
el.is_valid_terminal_pow_block_hash(missing_terminal_block, &spec)
743740
.await
744741
.unwrap(),
745742
None

0 commit comments

Comments
 (0)