From afe59afacd79c2b7a1afdd8679ab293f04676f4f Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Tue, 16 Nov 2021 11:46:12 +1100 Subject: [PATCH] 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 --- Cargo.lock | 152 +++++++++++++++++- beacon_node/beacon_chain/src/beacon_chain.rs | 4 +- .../beacon_chain/src/block_verification.rs | 5 +- beacon_node/beacon_chain/src/test_utils.rs | 4 +- beacon_node/client/src/builder.rs | 9 -- beacon_node/client/src/config.rs | 9 +- beacon_node/execution_layer/src/lib.rs | 71 ++++---- .../src/test_utils/mock_execution_layer.rs | 17 +- beacon_node/src/cli.rs | 36 ----- beacon_node/src/config.rs | 69 +++----- beacon_node/src/lib.rs | 5 +- boot_node/Cargo.toml | 1 + boot_node/src/config.rs | 16 +- boot_node/src/lib.rs | 16 +- common/clap_utils/Cargo.toml | 1 + common/clap_utils/src/lib.rs | 44 ++++- .../mainnet/config.yaml | 8 + .../prater/config.yaml | 8 + .../pyrmont/config.yaml | 8 + consensus/types/src/chain_spec.rs | 21 ++- lighthouse/environment/src/lib.rs | 8 +- .../environment/tests/testnet_dir/config.yaml | 8 + lighthouse/src/main.rs | 57 ++++++- lighthouse/tests/beacon_node.rs | 79 +-------- lighthouse/tests/boot_node.rs | 2 +- 25 files changed, 391 insertions(+), 267 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 602bfc261..1fe008b27 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -301,6 +301,7 @@ dependencies = [ "eth2_ssz 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "eth2_ssz_derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "eth2_ssz_types 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "execution_layer", "fork_choice", "futures", "genesis", @@ -318,6 +319,7 @@ dependencies = [ "rand 0.7.3", "rayon", "safe_arith", + "sensitive_url", "serde", "serde_derive", "slasher", @@ -480,6 +482,7 @@ dependencies = [ "beacon_node", "clap", "clap_utils", + "eth2_network_config", "eth2_ssz 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "hex", "lighthouse_network", @@ -682,6 +685,7 @@ dependencies = [ "dirs", "eth2_network_config", "eth2_ssz 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types 0.12.1", "hex", ] @@ -697,6 +701,7 @@ dependencies = [ "eth1", "eth2", "eth2_config", + "execution_layer", "genesis", "http_api", "http_metrics", @@ -1273,6 +1278,7 @@ dependencies = [ "eth2_ssz 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "eth2_ssz_derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ethereum-types 0.12.1", + "fork_choice", "fs2", "hex", "rayon", @@ -1571,6 +1577,7 @@ dependencies = [ name = "eth2_serde_utils" version = "0.1.0" dependencies = [ + "ethereum-types 0.12.1", "hex", "serde", "serde_derive", @@ -1782,6 +1789,35 @@ dependencies = [ "uint 0.9.1", ] +[[package]] +name = "execution_layer" +version = "0.1.0" +dependencies = [ + "async-trait", + "bytes", + "environment", + "eth1", + "eth2_serde_utils 0.1.0", + "eth2_ssz_types 0.2.1", + "exit-future", + "futures", + "hex", + "lru", + "parking_lot", + "reqwest", + "sensitive_url", + "serde", + "serde_json", + "slog", + "slot_clock", + "task_executor", + "tokio", + "tree_hash 0.4.0", + "tree_hash_derive 0.4.0", + "types", + "warp 0.3.0", +] + [[package]] name = "exit-future" version = "0.2.0" @@ -2383,7 +2419,7 @@ dependencies = [ "tokio-stream", "tree_hash 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "types", - "warp", + "warp 0.3.2", "warp_utils", ] @@ -2404,7 +2440,7 @@ dependencies = [ "store", "tokio", "types", - "warp", + "warp 0.3.2", "warp_utils", ] @@ -2580,6 +2616,15 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "input_buffer" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f97967975f448f1a7ddb12b0bc41069d09ed6a1c161a92687e057325db35d413" +dependencies = [ + "bytes", +] + [[package]] name = "instant" version = "0.1.12" @@ -2709,6 +2754,7 @@ dependencies = [ "eth2_ssz 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "eth2_wallet", "genesis", + "int_to_bytes", "lighthouse_network", "lighthouse_version", "log", @@ -3591,6 +3637,24 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +[[package]] +name = "multipart" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050aeedc89243f5347c3e237e3e13dc76fbe4ae3742a57b94dc14f69acf76d4" +dependencies = [ + "buf_redux", + "httparse", + "log", + "mime", + "mime_guess", + "quick-error", + "rand 0.7.3", + "safemem", + "tempfile", + "twoway", +] + [[package]] name = "multipart" version = "0.18.0" @@ -5986,6 +6050,19 @@ dependencies = [ "tokio-util", ] +[[package]] +name = "tokio-tungstenite" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1a5f475f1b9d077ea1017ecbc60890fda8e54942d680ca0b1d2b47cfa2d861b" +dependencies = [ + "futures-util", + "log", + "pin-project 1.0.8", + "tokio", + "tungstenite 0.12.0", +] + [[package]] name = "tokio-tungstenite" version = "0.15.0" @@ -5996,7 +6073,7 @@ dependencies = [ "log", "pin-project 1.0.8", "tokio", - "tungstenite", + "tungstenite 0.14.0", ] [[package]] @@ -6063,6 +6140,16 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project 1.0.8", + "tracing", +] + [[package]] name = "tracing-log" version = "0.1.2" @@ -6222,6 +6309,25 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "tungstenite" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ada8297e8d70872fa9a551d93250a9f407beb9f37ef86494eb20012a2ff7c24" +dependencies = [ + "base64 0.13.0", + "byteorder", + "bytes", + "http", + "httparse", + "input_buffer", + "log", + "rand 0.8.4", + "sha-1", + "url", + "utf-8", +] + [[package]] name = "tungstenite" version = "0.14.0" @@ -6270,7 +6376,7 @@ dependencies = [ "derivative", "eth2_hashing 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "eth2_interop_keypairs", - "eth2_serde_utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "eth2_serde_utils 0.1.0", "eth2_ssz 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "eth2_ssz_derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "eth2_ssz_types 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -6490,7 +6596,7 @@ dependencies = [ "types", "url", "validator_dir", - "warp", + "warp 0.3.2", "warp_utils", ] @@ -6556,6 +6662,36 @@ dependencies = [ "try-lock", ] +[[package]] +name = "warp" +version = "0.3.0" +source = "git+https://github.com/macladson/warp?rev=dfa259e#dfa259e19b7490e6bc4bf247e8b76f671d29a0eb" +dependencies = [ + "bytes", + "futures", + "headers", + "http", + "hyper", + "log", + "mime", + "mime_guess", + "multipart 0.17.1", + "percent-encoding", + "pin-project 1.0.8", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-rustls", + "tokio-stream", + "tokio-tungstenite 0.13.0", + "tokio-util", + "tower-service", + "tracing", + "tracing-futures", +] + [[package]] name = "warp" version = "0.3.2" @@ -6570,7 +6706,7 @@ dependencies = [ "log", "mime", "mime_guess", - "multipart", + "multipart 0.18.0", "percent-encoding", "pin-project 1.0.8", "scoped-tls", @@ -6580,7 +6716,7 @@ dependencies = [ "tokio", "tokio-rustls", "tokio-stream", - "tokio-tungstenite", + "tokio-tungstenite 0.15.0", "tokio-util", "tower-service", "tracing", @@ -6600,7 +6736,7 @@ dependencies = [ "state_processing", "tokio", "types", - "warp", + "warp 0.3.2", ] [[package]] diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 7b1d7a696..06eafc056 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -2893,7 +2893,9 @@ impl BeaconChain { let parent_hash; if !is_merge_complete(&state) { let terminal_pow_block_hash = execution_layer - .block_on(|execution_layer| execution_layer.get_terminal_pow_block_hash()) + .block_on(|execution_layer| { + execution_layer.get_terminal_pow_block_hash(&self.spec) + }) .map_err(BlockProductionError::TerminalPoWBlockLookupFailed)?; if let Some(terminal_pow_block_hash) = terminal_pow_block_hash { diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index f4f245f16..de37ff6fe 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -1119,7 +1119,10 @@ impl<'a, T: BeaconChainTypes> FullyVerifiedBlock<'a, T> { let is_valid_terminal_pow_block = execution_layer .block_on(|execution_layer| { - execution_layer.is_valid_terminal_pow_block_hash(execution_payload.parent_hash) + execution_layer.is_valid_terminal_pow_block_hash( + execution_payload.parent_hash, + &chain.spec, + ) }) .map_err(ExecutionPayloadError::from)?; diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index f53054ff2..25995616d 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -330,7 +330,6 @@ where } pub fn execution_layer(mut self, urls: &[&str]) -> Self { - let spec = self.spec.clone().expect("cannot build without spec"); assert!( self.execution_layer.is_none(), "execution layer already defined" @@ -345,8 +344,6 @@ where .unwrap(); let execution_layer = ExecutionLayer::from_urls( urls, - spec.terminal_total_difficulty, - spec.terminal_block_hash, Some(Address::repeat_byte(42)), el_runtime.task_executor.clone(), el_runtime.log.clone(), @@ -364,6 +361,7 @@ where spec.terminal_total_difficulty, DEFAULT_TERMINAL_BLOCK, spec.terminal_block_hash, + spec.terminal_block_hash_activation_epoch, ); self.execution_layer = Some(mock.el.clone()); self.mock_execution_layer = Some(mock); diff --git a/beacon_node/client/src/builder.rs b/beacon_node/client/src/builder.rs index 186bc9ed1..0d61e0922 100644 --- a/beacon_node/client/src/builder.rs +++ b/beacon_node/client/src/builder.rs @@ -148,19 +148,10 @@ where None }; - let terminal_total_difficulty = config - .terminal_total_difficulty_override - .unwrap_or(spec.terminal_total_difficulty); - let terminal_block_hash = config - .terminal_block_hash_override - .unwrap_or(spec.terminal_block_hash); - let execution_layer = if let Some(execution_endpoints) = config.execution_endpoints { let context = runtime_context.service_context("exec".into()); let execution_layer = ExecutionLayer::from_urls( execution_endpoints, - terminal_total_difficulty, - terminal_block_hash, config.fee_recipient, context.executor.clone(), context.log().clone(), diff --git a/beacon_node/client/src/config.rs b/beacon_node/client/src/config.rs index 53d307966..15ff7d024 100644 --- a/beacon_node/client/src/config.rs +++ b/beacon_node/client/src/config.rs @@ -1,11 +1,10 @@ -use beacon_chain::types::Epoch; use directory::DEFAULT_ROOT_DIR; use network::NetworkConfig; use sensitive_url::SensitiveUrl; use serde_derive::{Deserialize, Serialize}; use std::fs; use std::path::PathBuf; -use types::{Address, Graffiti, Hash256, PublicKeyBytes, Uint256}; +use types::{Address, Graffiti, PublicKeyBytes}; /// Default directory name for the freezer database under the top-level data dir. const DEFAULT_FREEZER_DB_DIR: &str = "freezer_db"; @@ -76,9 +75,6 @@ pub struct Config { pub chain: beacon_chain::ChainConfig, pub eth1: eth1::Config, pub execution_endpoints: Option>, - pub terminal_total_difficulty_override: Option, - pub terminal_block_hash_override: Option, - pub terminal_block_hash_epoch_override: Option, pub fee_recipient: Option
, pub http_api: http_api::Config, pub http_metrics: http_metrics::Config, @@ -101,9 +97,6 @@ impl Default for Config { sync_eth1_chain: false, eth1: <_>::default(), execution_endpoints: None, - terminal_total_difficulty_override: None, - terminal_block_hash_override: None, - terminal_block_hash_epoch_override: None, fee_recipient: None, disabled_forks: Vec::new(), graffiti: Graffiti::default(), diff --git a/beacon_node/execution_layer/src/lib.rs b/beacon_node/execution_layer/src/lib.rs index 27d0cc654..2c9395a05 100644 --- a/beacon_node/execution_layer/src/lib.rs +++ b/beacon_node/execution_layer/src/lib.rs @@ -18,6 +18,7 @@ use tokio::{ sync::{Mutex, MutexGuard}, time::{sleep, sleep_until, Instant}, }; +use types::ChainSpec; pub use engine_api::{http::HttpJsonRpc, ExecutePayloadResponseStatus}; @@ -47,8 +48,6 @@ impl From for Error { struct Inner { engines: Engines, - terminal_total_difficulty: Uint256, - terminal_block_hash: Hash256, fee_recipient: Option
, execution_blocks: Mutex>, executor: TaskExecutor, @@ -73,8 +72,6 @@ impl ExecutionLayer { /// Instantiate `Self` with `urls.len()` engines, all using the JSON-RPC via HTTP. pub fn from_urls( urls: Vec, - terminal_total_difficulty: Uint256, - terminal_block_hash: Hash256, fee_recipient: Option
, executor: TaskExecutor, log: Logger, @@ -98,8 +95,6 @@ impl ExecutionLayer { latest_forkchoice_state: <_>::default(), log: log.clone(), }, - terminal_total_difficulty, - terminal_block_hash, fee_recipient, execution_blocks: Mutex::new(LruCache::new(EXECUTION_BLOCKS_LRU_CACHE_SIZE)), executor, @@ -121,14 +116,6 @@ impl ExecutionLayer { &self.inner.executor } - fn terminal_total_difficulty(&self) -> Uint256 { - self.inner.terminal_total_difficulty - } - - fn terminal_block_hash(&self) -> Hash256 { - self.inner.terminal_block_hash - } - fn fee_recipient(&self) -> Result { self.inner .fee_recipient @@ -455,11 +442,14 @@ impl ExecutionLayer { /// `get_terminal_pow_block_hash` /// /// https://github.com/ethereum/consensus-specs/blob/v1.1.0/specs/merge/validator.md - pub async fn get_terminal_pow_block_hash(&self) -> Result, Error> { + pub async fn get_terminal_pow_block_hash( + &self, + spec: &ChainSpec, + ) -> Result, Error> { let hash_opt = self .engines() .first_success(|engine| async move { - if self.terminal_block_hash() != Hash256::zero() { + if spec.terminal_block_hash != Hash256::zero() { // Note: the specification is written such that if there are multiple blocks in // the PoW chain with the terminal block hash, then to select 0'th one. // @@ -468,11 +458,12 @@ impl ExecutionLayer { // hash. Such a scenario would be a devestating hash collision with external // implications far outweighing those here. Ok(self - .get_pow_block(engine, self.terminal_block_hash()) + .get_pow_block(engine, spec.terminal_block_hash) .await? .map(|block| block.block_hash)) } else { - self.get_pow_block_hash_at_total_difficulty(engine).await + self.get_pow_block_hash_at_total_difficulty(engine, spec) + .await } }) .await @@ -482,8 +473,8 @@ impl ExecutionLayer { info!( self.log(), "Found terminal block hash"; - "terminal_block_hash_override" => ?self.terminal_block_hash(), - "terminal_total_difficulty" => ?self.terminal_total_difficulty(), + "terminal_block_hash_override" => ?spec.terminal_block_hash, + "terminal_total_difficulty" => ?spec.terminal_total_difficulty, "block_hash" => ?hash, ); } @@ -503,6 +494,7 @@ impl ExecutionLayer { async fn get_pow_block_hash_at_total_difficulty( &self, engine: &Engine, + spec: &ChainSpec, ) -> Result, ApiError> { let mut ttd_exceeding_block = None; let mut block = engine @@ -518,7 +510,7 @@ impl ExecutionLayer { // // https://github.com/ethereum/consensus-specs/issues/2636 loop { - if block.total_difficulty >= self.terminal_total_difficulty() { + if block.total_difficulty >= spec.terminal_total_difficulty { ttd_exceeding_block = Some(block.block_hash); // Try to prevent infinite loops. @@ -565,6 +557,7 @@ impl ExecutionLayer { pub async fn is_valid_terminal_pow_block_hash( &self, block_hash: Hash256, + spec: &ChainSpec, ) -> Result, Error> { let broadcast_results = self .engines() @@ -574,7 +567,7 @@ impl ExecutionLayer { self.get_pow_block(engine, pow_block.parent_hash).await? { return Ok(Some( - self.is_valid_terminal_pow_block(pow_block, pow_parent), + self.is_valid_terminal_pow_block(pow_block, pow_parent, spec), )); } } @@ -618,15 +611,19 @@ impl ExecutionLayer { /// This function should remain internal. /// /// External users should use `self.is_valid_terminal_pow_block_hash`. - fn is_valid_terminal_pow_block(&self, block: ExecutionBlock, parent: ExecutionBlock) -> bool { - if block.block_hash == self.terminal_block_hash() { + fn is_valid_terminal_pow_block( + &self, + block: ExecutionBlock, + parent: ExecutionBlock, + spec: &ChainSpec, + ) -> bool { + if block.block_hash == spec.terminal_block_hash { return true; } - let is_total_difficulty_reached = - block.total_difficulty >= self.terminal_total_difficulty(); + let is_total_difficulty_reached = block.total_difficulty >= spec.terminal_total_difficulty; let is_parent_total_difficulty_valid = - parent.total_difficulty < self.terminal_total_difficulty(); + parent.total_difficulty < spec.terminal_total_difficulty; is_total_difficulty_reached && is_parent_total_difficulty_valid } @@ -685,14 +682,14 @@ mod test { async fn finds_valid_terminal_block_hash() { MockExecutionLayer::default_params() .move_to_block_prior_to_terminal_block() - .with_terminal_block(|el, _| async move { - assert_eq!(el.get_terminal_pow_block_hash().await.unwrap(), None) + .with_terminal_block(|spec, el, _| async move { + assert_eq!(el.get_terminal_pow_block_hash(&spec).await.unwrap(), None) }) .await .move_to_terminal_block() - .with_terminal_block(|el, terminal_block| async move { + .with_terminal_block(|spec, el, terminal_block| async move { assert_eq!( - el.get_terminal_pow_block_hash().await.unwrap(), + el.get_terminal_pow_block_hash(&spec).await.unwrap(), Some(terminal_block.unwrap().block_hash) ) }) @@ -703,9 +700,9 @@ mod test { async fn verifies_valid_terminal_block_hash() { MockExecutionLayer::default_params() .move_to_terminal_block() - .with_terminal_block(|el, terminal_block| async move { + .with_terminal_block(|spec, el, terminal_block| async move { assert_eq!( - el.is_valid_terminal_pow_block_hash(terminal_block.unwrap().block_hash) + el.is_valid_terminal_pow_block_hash(terminal_block.unwrap().block_hash, &spec) .await .unwrap(), Some(true) @@ -718,11 +715,11 @@ mod test { async fn rejects_invalid_terminal_block_hash() { MockExecutionLayer::default_params() .move_to_terminal_block() - .with_terminal_block(|el, terminal_block| async move { + .with_terminal_block(|spec, el, terminal_block| async move { let invalid_terminal_block = terminal_block.unwrap().parent_hash; assert_eq!( - el.is_valid_terminal_pow_block_hash(invalid_terminal_block) + el.is_valid_terminal_pow_block_hash(invalid_terminal_block, &spec) .await .unwrap(), Some(false) @@ -735,11 +732,11 @@ mod test { async fn rejects_unknown_terminal_block_hash() { MockExecutionLayer::default_params() .move_to_terminal_block() - .with_terminal_block(|el, _| async move { + .with_terminal_block(|spec, el, _| async move { let missing_terminal_block = Hash256::repeat_byte(42); assert_eq!( - el.is_valid_terminal_pow_block_hash(missing_terminal_block) + el.is_valid_terminal_pow_block_hash(missing_terminal_block, &spec) .await .unwrap(), None diff --git a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs index 6005910f6..dba78eb68 100644 --- a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs +++ b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs @@ -6,7 +6,7 @@ use environment::null_logger; use sensitive_url::SensitiveUrl; use std::sync::Arc; use task_executor::TaskExecutor; -use types::{Address, EthSpec, Hash256, Uint256}; +use types::{Address, ChainSpec, Epoch, EthSpec, Hash256, Uint256}; pub struct ExecutionLayerRuntime { pub runtime: Option>, @@ -50,6 +50,7 @@ pub struct MockExecutionLayer { pub server: MockServer, pub el: ExecutionLayer, pub el_runtime: ExecutionLayerRuntime, + pub spec: ChainSpec, } impl MockExecutionLayer { @@ -58,6 +59,7 @@ impl MockExecutionLayer { DEFAULT_TERMINAL_DIFFICULTY.into(), DEFAULT_TERMINAL_BLOCK, Hash256::zero(), + Epoch::new(0), ) } @@ -65,10 +67,16 @@ impl MockExecutionLayer { terminal_total_difficulty: Uint256, terminal_block: u64, terminal_block_hash: Hash256, + terminal_block_hash_activation_epoch: Epoch, ) -> Self { let el_runtime = ExecutionLayerRuntime::default(); let handle = el_runtime.runtime.as_ref().unwrap().handle(); + let mut spec = T::default_spec(); + spec.terminal_total_difficulty = terminal_total_difficulty; + spec.terminal_block_hash = terminal_block_hash; + spec.terminal_block_hash_activation_epoch = terminal_block_hash_activation_epoch; + let server = MockServer::new( handle, terminal_total_difficulty, @@ -80,8 +88,6 @@ impl MockExecutionLayer { let el = ExecutionLayer::from_urls( vec![url], - terminal_total_difficulty, - Hash256::zero(), Some(Address::repeat_byte(42)), el_runtime.task_executor.clone(), el_runtime.log.clone(), @@ -92,6 +98,7 @@ impl MockExecutionLayer { server, el, el_runtime, + spec, } } @@ -171,7 +178,7 @@ impl MockExecutionLayer { pub async fn with_terminal_block<'a, U, V>(self, func: U) -> Self where - U: Fn(ExecutionLayer, Option) -> V, + U: Fn(ChainSpec, ExecutionLayer, Option) -> V, V: Future, { let terminal_block_number = self @@ -183,7 +190,7 @@ impl MockExecutionLayer { .execution_block_generator() .execution_block_by_number(terminal_block_number); - func(self.el.clone(), terminal_block).await; + func(self.spec.clone(), self.el.clone(), terminal_block).await; self } } diff --git a/beacon_node/src/cli.rs b/beacon_node/src/cli.rs index d083e8181..7e656b8b6 100644 --- a/beacon_node/src/cli.rs +++ b/beacon_node/src/cli.rs @@ -399,42 +399,6 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> { will be used. Defaults to http://127.0.0.1:8545.") .takes_value(true) ) - .arg( - Arg::with_name("terminal-total-difficulty-override") - .long("terminal-total-difficulty-override") - .value_name("INTEGER") - .help("Used to coordinate manual overrides to the TERMINAL_TOTAL_DIFFICULTY parameter. \ - This flag should only be used if the user has a clear understanding that \ - the broad Ethereum community has elected to override the terminal difficulty. \ - Incorrect use of this flag will cause your node to experience a consensus - failure. Be extremely careful with this flag.") - .takes_value(true) - ) - .arg( - Arg::with_name("terminal-block-hash-override") - .long("terminal-block-hash-override") - .value_name("TERMINAL_BLOCK_HASH") - .help("Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH parameter. \ - Accepts a 256-bit decimal integer (not a hex value). \ - This flag should only be used if the user has a clear understanding that \ - the broad Ethereum community has elected to override the terminal PoW block. \ - Incorrect use of this flag will cause your node to experience a consensus - failure. Be extremely careful with this flag.") - .requires("terminal-block-hash-epoch-override") - .takes_value(true) - ) - .arg( - Arg::with_name("terminal-block-hash-epoch-override") - .long("terminal-block-hash-epoch-override") - .value_name("EPOCH") - .help("Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH \ - parameter. This flag should only be used if the user has a clear understanding \ - that the broad Ethereum community has elected to override the terminal PoW block. \ - Incorrect use of this flag will cause your node to experience a consensus - failure. Be extremely careful with this flag.") - .requires("terminal-block-hash-override") - .takes_value(true) - ) .arg( Arg::with_name("fee-recipient") .long("fee-recipient") diff --git a/beacon_node/src/config.rs b/beacon_node/src/config.rs index fc3ca2cc0..1ae72736b 100644 --- a/beacon_node/src/config.rs +++ b/beacon_node/src/config.rs @@ -1,8 +1,8 @@ use clap::ArgMatches; -use clap_utils::{flags::DISABLE_MALLOC_TUNING_FLAG, BAD_TESTNET_DIR_MESSAGE}; +use clap_utils::flags::DISABLE_MALLOC_TUNING_FLAG; use client::{ClientConfig, ClientGenesis}; use directory::{DEFAULT_BEACON_NODE_DIR, DEFAULT_NETWORK_DIR, DEFAULT_ROOT_DIR}; -use eth2_network_config::{Eth2NetworkConfig, DEFAULT_HARDCODED_NETWORK}; +use environment::RuntimeContext; use http_api::TlsConfig; use lighthouse_network::{multiaddr::Protocol, Enr, Multiaddr, NetworkConfig, PeerIdSerialized}; use sensitive_url::SensitiveUrl; @@ -14,9 +14,7 @@ use std::net::{IpAddr, Ipv4Addr, ToSocketAddrs}; use std::net::{TcpListener, UdpSocket}; use std::path::{Path, PathBuf}; use std::str::FromStr; -use types::{ - ChainSpec, Checkpoint, Epoch, EthSpec, Hash256, PublicKeyBytes, Uint256, GRAFFITI_BYTES_LEN, -}; +use types::{Checkpoint, Epoch, EthSpec, Hash256, PublicKeyBytes, GRAFFITI_BYTES_LEN}; /// Gets the fully-initialized global client. /// @@ -27,9 +25,11 @@ use types::{ /// response of some remote server. pub fn get_config( cli_args: &ArgMatches, - spec: &ChainSpec, - log: Logger, + context: &RuntimeContext, ) -> Result { + let spec = &context.eth2_config.spec; + let log = context.log(); + let mut client_config = ClientConfig { data_dir: get_data_dir(cli_args), ..Default::default() @@ -63,7 +63,7 @@ pub fn get_config( &mut client_config.network, cli_args, &client_config.data_dir, - &log, + log, false, )?; @@ -242,32 +242,7 @@ pub fn get_config( client_config.execution_endpoints = Some(client_config.eth1.endpoints.clone()); } - if let Some(string) = - clap_utils::parse_optional::(cli_args, "terminal-total-difficulty-override")? - { - let stripped = string.replace(",", ""); - let terminal_total_difficulty = Uint256::from_dec_str(&stripped).map_err(|e| { - format!( - "Could not parse --terminal-total-difficulty-override as decimal value: {:?}", - e - ) - })?; - - if client_config.execution_endpoints.is_none() { - return Err( - "The --merge flag must be provided when using --terminal-total-difficulty-override" - .into(), - ); - } - - client_config.terminal_total_difficulty_override = Some(terminal_total_difficulty); - } - client_config.fee_recipient = clap_utils::parse_optional(cli_args, "fee-recipient")?; - client_config.terminal_block_hash_override = - clap_utils::parse_optional(cli_args, "terminal-block-hash-override")?; - client_config.terminal_block_hash_epoch_override = - clap_utils::parse_optional(cli_args, "terminal-block-hash-epoch-override")?; if let Some(freezer_dir) = cli_args.value_of("freezer-dir") { client_config.freezer_db_path = Some(PathBuf::from(freezer_dir)); @@ -321,7 +296,10 @@ pub fn get_config( /* * Load the eth2 network dir to obtain some additional config values. */ - let eth2_network_config = get_eth2_network_config(cli_args)?; + let eth2_network_config = context + .eth2_network_config + .as_ref() + .ok_or("Context is missing eth2 network config")?; client_config.eth1.deposit_contract_address = format!("{:?}", spec.deposit_contract_address); client_config.eth1.deposit_contract_deploy_block = @@ -344,13 +322,16 @@ pub fn get_config( // Only append network config bootnodes if discovery is not disabled if !client_config.network.disable_discovery { - if let Some(mut boot_nodes) = eth2_network_config.boot_enr { - client_config.network.boot_nodes_enr.append(&mut boot_nodes) + if let Some(boot_nodes) = ð2_network_config.boot_enr { + client_config + .network + .boot_nodes_enr + .extend_from_slice(boot_nodes) } } client_config.genesis = if let Some(genesis_state_bytes) = - eth2_network_config.genesis_state_bytes + eth2_network_config.genesis_state_bytes.clone() { // Set up weak subjectivity sync, or start from the hardcoded genesis state. if let (Some(initial_state_path), Some(initial_block_path)) = ( @@ -782,20 +763,6 @@ pub fn get_data_dir(cli_args: &ArgMatches) -> PathBuf { .unwrap_or_else(|| PathBuf::from(".")) } -/// Try to parse the eth2 network config from the `network`, `testnet-dir` flags in that order. -/// Returns the default hardcoded testnet if neither flags are set. -pub fn get_eth2_network_config(cli_args: &ArgMatches) -> Result { - let optional_network_config = if cli_args.is_present("network") { - clap_utils::parse_hardcoded_network(cli_args, "network")? - } else if cli_args.is_present("testnet-dir") { - clap_utils::parse_testnet_dir(cli_args, "testnet-dir")? - } else { - // if neither is present, assume the default network - Eth2NetworkConfig::constant(DEFAULT_HARDCODED_NETWORK)? - }; - optional_network_config.ok_or_else(|| BAD_TESTNET_DIR_MESSAGE.to_string()) -} - /// A bit of hack to find an unused port. /// /// Does not guarantee that the given port is unused after the function exits, just that it was diff --git a/beacon_node/src/lib.rs b/beacon_node/src/lib.rs index d452e3e46..b536fb8cb 100644 --- a/beacon_node/src/lib.rs +++ b/beacon_node/src/lib.rs @@ -13,7 +13,7 @@ use beacon_chain::{ use clap::ArgMatches; pub use cli::cli_app; pub use client::{Client, ClientBuilder, ClientConfig, ClientGenesis}; -pub use config::{get_config, get_data_dir, get_eth2_network_config, set_network_config}; +pub use config::{get_config, get_data_dir, set_network_config}; use environment::RuntimeContext; pub use eth2_config::Eth2Config; use slasher::Slasher; @@ -46,8 +46,7 @@ impl ProductionBeaconNode { context: RuntimeContext, matches: ArgMatches<'static>, ) -> Result { - let client_config = - get_config::(&matches, &context.eth2_config().spec, context.log().clone())?; + let client_config = get_config::(&matches, &context)?; Self::new(context, client_config).await } diff --git a/boot_node/Cargo.toml b/boot_node/Cargo.toml index 520cb0639..ce8c6a1da 100644 --- a/boot_node/Cargo.toml +++ b/boot_node/Cargo.toml @@ -23,3 +23,4 @@ hex = "0.4.2" serde = "1.0.116" serde_derive = "1.0.116" serde_json = "1.0.66" +eth2_network_config = { path = "../common/eth2_network_config" } diff --git a/boot_node/src/config.rs b/boot_node/src/config.rs index 704cbb2a8..1e550e60c 100644 --- a/boot_node/src/config.rs +++ b/boot_node/src/config.rs @@ -1,5 +1,6 @@ -use beacon_node::{get_data_dir, get_eth2_network_config, set_network_config}; +use beacon_node::{get_data_dir, set_network_config}; use clap::ArgMatches; +use eth2_network_config::Eth2NetworkConfig; use lighthouse_network::discv5::{enr::CombinedKey, Discv5Config, Enr}; use lighthouse_network::{ discovery::{create_enr_builder_from_config, load_enr_from_disk, use_or_load_enr}, @@ -7,7 +8,6 @@ use lighthouse_network::{ }; use serde_derive::{Deserialize, Serialize}; use ssz::Encode; -use std::convert::TryFrom; use std::net::SocketAddr; use std::{marker::PhantomData, path::PathBuf}; use types::EthSpec; @@ -23,15 +23,13 @@ pub struct BootNodeConfig { phantom: PhantomData, } -impl TryFrom<&ArgMatches<'_>> for BootNodeConfig { - type Error = String; - - fn try_from(matches: &ArgMatches<'_>) -> Result { +impl BootNodeConfig { + pub fn new( + matches: &ArgMatches<'_>, + eth2_network_config: &Eth2NetworkConfig, + ) -> Result { let data_dir = get_data_dir(matches); - // Try and grab network config from input CLI params - let eth2_network_config = get_eth2_network_config(matches)?; - // Try and obtain bootnodes let boot_nodes = { diff --git a/boot_node/src/lib.rs b/boot_node/src/lib.rs index ed3a5655b..2afc06380 100644 --- a/boot_node/src/lib.rs +++ b/boot_node/src/lib.rs @@ -2,7 +2,7 @@ use clap::ArgMatches; use slog::{o, Drain, Level, Logger}; -use std::convert::TryFrom; +use eth2_network_config::Eth2NetworkConfig; use std::fs::File; use std::path::PathBuf; mod cli; @@ -19,6 +19,7 @@ pub fn run( lh_matches: &ArgMatches<'_>, bn_matches: &ArgMatches<'_>, eth_spec_id: EthSpecId, + eth2_network_config: &Eth2NetworkConfig, debug_level: String, ) { let debug_level = match debug_level.as_str() { @@ -56,8 +57,12 @@ pub fn run( let log = slog_scope::logger(); // Run the main function emitting any errors if let Err(e) = match eth_spec_id { - EthSpecId::Minimal => main::(lh_matches, bn_matches, log), - EthSpecId::Mainnet => main::(lh_matches, bn_matches, log), + EthSpecId::Minimal => { + main::(lh_matches, bn_matches, eth2_network_config, log) + } + EthSpecId::Mainnet => { + main::(lh_matches, bn_matches, eth2_network_config, log) + } } { slog::crit!(slog_scope::logger(), "{}", e); } @@ -66,6 +71,7 @@ pub fn run( fn main( lh_matches: &ArgMatches<'_>, bn_matches: &ArgMatches<'_>, + eth2_network_config: &Eth2NetworkConfig, log: slog::Logger, ) -> Result<(), String> { // Builds a custom executor for the bootnode @@ -74,8 +80,8 @@ fn main( .build() .map_err(|e| format!("Failed to build runtime: {}", e))?; - // Parse the CLI args into a useable config - let config: BootNodeConfig = BootNodeConfig::try_from(bn_matches)?; + // parse the CLI args into a useable config + let config: BootNodeConfig = BootNodeConfig::new(bn_matches, eth2_network_config)?; // Dump config if `dump-config` flag is set let dump_config = clap_utils::parse_optional::(lh_matches, "dump-config")?; diff --git a/common/clap_utils/Cargo.toml b/common/clap_utils/Cargo.toml index 9db525683..6af5d5e95 100644 --- a/common/clap_utils/Cargo.toml +++ b/common/clap_utils/Cargo.toml @@ -12,3 +12,4 @@ hex = "0.4.2" dirs = "3.0.1" eth2_network_config = { path = "../eth2_network_config" } eth2_ssz = "0.4.0" +ethereum-types = "0.12.1" diff --git a/common/clap_utils/src/lib.rs b/common/clap_utils/src/lib.rs index dc82cbe66..f8c6e8b7c 100644 --- a/common/clap_utils/src/lib.rs +++ b/common/clap_utils/src/lib.rs @@ -1,7 +1,8 @@ //! A helper library for parsing values from `clap::ArgMatches`. use clap::ArgMatches; -use eth2_network_config::Eth2NetworkConfig; +use eth2_network_config::{Eth2NetworkConfig, DEFAULT_HARDCODED_NETWORK}; +use ethereum_types::U256 as Uint256; use ssz::Decode; use std::path::PathBuf; use std::str::FromStr; @@ -13,6 +14,47 @@ pub const BAD_TESTNET_DIR_MESSAGE: &str = "The hard-coded testnet directory was or when there is no default public network to connect to. \ During these times you must specify a --testnet-dir."; +/// Try to parse the eth2 network config from the `network`, `testnet-dir` flags in that order. +/// Returns the default hardcoded testnet if neither flags are set. +pub fn get_eth2_network_config(cli_args: &ArgMatches) -> Result { + let optional_network_config = if cli_args.is_present("network") { + parse_hardcoded_network(cli_args, "network")? + } else if cli_args.is_present("testnet-dir") { + parse_testnet_dir(cli_args, "testnet-dir")? + } else { + // if neither is present, assume the default network + Eth2NetworkConfig::constant(DEFAULT_HARDCODED_NETWORK)? + }; + + let mut eth2_network_config = + optional_network_config.ok_or_else(|| BAD_TESTNET_DIR_MESSAGE.to_string())?; + + if let Some(string) = parse_optional::(cli_args, "terminal-total-difficulty-override")? + { + let stripped = string.replace(",", ""); + let terminal_total_difficulty = Uint256::from_dec_str(&stripped).map_err(|e| { + format!( + "Could not parse --terminal-total-difficulty-override as decimal value: {:?}", + e + ) + })?; + + eth2_network_config.config.terminal_total_difficulty = terminal_total_difficulty; + } + + if let Some(hash) = parse_optional(cli_args, "terminal-block-hash-override")? { + eth2_network_config.config.terminal_block_hash = hash; + } + + if let Some(epoch) = parse_optional(cli_args, "terminal-block-hash-epoch-override")? { + eth2_network_config + .config + .terminal_block_hash_activation_epoch = epoch; + } + + Ok(eth2_network_config) +} + /// Attempts to load the testnet dir at the path if `name` is in `matches`, returning an error if /// the path cannot be found or the testnet dir is invalid. pub fn parse_testnet_dir( diff --git a/common/eth2_network_config/built_in_network_configs/mainnet/config.yaml b/common/eth2_network_config/built_in_network_configs/mainnet/config.yaml index 8be60242b..a1d305bac 100644 --- a/common/eth2_network_config/built_in_network_configs/mainnet/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/mainnet/config.yaml @@ -3,6 +3,14 @@ # Extends the mainnet preset PRESET_BASE: 'mainnet' +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-2**10 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129638912 +# By default, don't use these params +TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000 +TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551615 + # Genesis # --------------------------------------------------------------- # `2**14` (= 16,384) diff --git a/common/eth2_network_config/built_in_network_configs/prater/config.yaml b/common/eth2_network_config/built_in_network_configs/prater/config.yaml index c1c537b78..5fc23d6af 100644 --- a/common/eth2_network_config/built_in_network_configs/prater/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/prater/config.yaml @@ -3,6 +3,14 @@ # Extends the mainnet preset PRESET_BASE: 'mainnet' +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-2**10 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129638912 +# By default, don't use these params +TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000 +TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551615 + # Genesis # --------------------------------------------------------------- # `2**14` (= 16,384) diff --git a/common/eth2_network_config/built_in_network_configs/pyrmont/config.yaml b/common/eth2_network_config/built_in_network_configs/pyrmont/config.yaml index 4a3581c31..352a4e918 100644 --- a/common/eth2_network_config/built_in_network_configs/pyrmont/config.yaml +++ b/common/eth2_network_config/built_in_network_configs/pyrmont/config.yaml @@ -3,6 +3,14 @@ # Extends the mainnet preset PRESET_BASE: 'mainnet' +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-2**10 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129638912 +# By default, don't use these params +TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000 +TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551615 + # Genesis # --------------------------------------------------------------- # `2**14` (= 16,384) diff --git a/consensus/types/src/chain_spec.rs b/consensus/types/src/chain_spec.rs index fbc3739f6..e5eabec20 100644 --- a/consensus/types/src/chain_spec.rs +++ b/consensus/types/src/chain_spec.rs @@ -533,7 +533,11 @@ impl ChainSpec { merge_fork_epoch: None, terminal_total_difficulty: Uint256::MAX .checked_sub(Uint256::from(2u64.pow(10))) - .expect("calculation does not overflow"), + .expect("subtraction does not overflow") + // Add 1 since the spec declares `2**256 - 2**10` and we use + // `Uint256::MAX` which is `2*256- 1`. + .checked_add(Uint256::one()) + .expect("addition does not overflow"), terminal_block_hash: Hash256::zero(), terminal_block_hash_activation_epoch: Epoch::new(u64::MAX), @@ -605,6 +609,11 @@ pub struct Config { #[serde(default)] pub preset_base: String, + #[serde(with = "eth2_serde_utils::quoted_u256")] + pub terminal_total_difficulty: Uint256, + pub terminal_block_hash: Hash256, + pub terminal_block_hash_activation_epoch: Epoch, + #[serde(with = "eth2_serde_utils::quoted_u64")] min_genesis_active_validator_count: u64, #[serde(with = "eth2_serde_utils::quoted_u64")] @@ -707,6 +716,10 @@ impl Config { Self { preset_base: T::spec_name().to_string(), + terminal_total_difficulty: spec.terminal_total_difficulty, + terminal_block_hash: spec.terminal_block_hash, + terminal_block_hash_activation_epoch: spec.terminal_block_hash_activation_epoch, + min_genesis_active_validator_count: spec.min_genesis_active_validator_count, min_genesis_time: spec.min_genesis_time, genesis_fork_version: spec.genesis_fork_version, @@ -750,6 +763,9 @@ impl Config { // Pattern match here to avoid missing any fields. let &Config { ref preset_base, + terminal_total_difficulty, + terminal_block_hash, + terminal_block_hash_activation_epoch, min_genesis_active_validator_count, min_genesis_time, genesis_fork_version, @@ -799,6 +815,9 @@ impl Config { deposit_chain_id, deposit_network_id, deposit_contract_address, + terminal_total_difficulty, + terminal_block_hash, + terminal_block_hash_activation_epoch, ..chain_spec.clone() }) } diff --git a/lighthouse/environment/src/lib.rs b/lighthouse/environment/src/lib.rs index d44031981..e536d3c95 100644 --- a/lighthouse/environment/src/lib.rs +++ b/lighthouse/environment/src/lib.rs @@ -249,7 +249,7 @@ impl EnvironmentBuilder { log: self.log.ok_or("Cannot build environment without log")?, eth_spec_instance: self.eth_spec_instance, eth2_config: self.eth2_config, - eth2_network_config: self.eth2_network_config, + eth2_network_config: self.eth2_network_config.map(Arc::new), }) } } @@ -263,6 +263,7 @@ pub struct RuntimeContext { pub executor: TaskExecutor, pub eth_spec_instance: E, pub eth2_config: Eth2Config, + pub eth2_network_config: Option>, } impl RuntimeContext { @@ -274,6 +275,7 @@ impl RuntimeContext { executor: self.executor.clone_with_name(service_name), eth_spec_instance: self.eth_spec_instance.clone(), eth2_config: self.eth2_config.clone(), + eth2_network_config: self.eth2_network_config.clone(), } } @@ -301,7 +303,7 @@ pub struct Environment { log: Logger, eth_spec_instance: E, pub eth2_config: Eth2Config, - pub eth2_network_config: Option, + pub eth2_network_config: Option>, } impl Environment { @@ -324,6 +326,7 @@ impl Environment { ), eth_spec_instance: self.eth_spec_instance.clone(), eth2_config: self.eth2_config.clone(), + eth2_network_config: self.eth2_network_config.clone(), } } @@ -338,6 +341,7 @@ impl Environment { ), eth_spec_instance: self.eth_spec_instance.clone(), eth2_config: self.eth2_config.clone(), + eth2_network_config: self.eth2_network_config.clone(), } } diff --git a/lighthouse/environment/tests/testnet_dir/config.yaml b/lighthouse/environment/tests/testnet_dir/config.yaml index 7d0105cca..c06e89653 100644 --- a/lighthouse/environment/tests/testnet_dir/config.yaml +++ b/lighthouse/environment/tests/testnet_dir/config.yaml @@ -3,6 +3,14 @@ # Extends the mainnet preset PRESET_BASE: 'mainnet' +# Transition +# --------------------------------------------------------------- +# TBD, 2**256-2**10 is a placeholder +TERMINAL_TOTAL_DIFFICULTY: 115792089237316195423570985008687907853269984665640564039457584007913129638912 +# By default, don't use these params +TERMINAL_BLOCK_HASH: 0x0000000000000000000000000000000000000000000000000000000000000000 +TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH: 18446744073709551615 + # Genesis # --------------------------------------------------------------- # CUSTOMISED FOR TEST diff --git a/lighthouse/src/main.rs b/lighthouse/src/main.rs index 49a778e65..75447d35a 100644 --- a/lighthouse/src/main.rs +++ b/lighthouse/src/main.rs @@ -2,9 +2,9 @@ mod metrics; -use beacon_node::{get_eth2_network_config, ProductionBeaconNode}; +use beacon_node::ProductionBeaconNode; use clap::{App, Arg, ArgMatches}; -use clap_utils::{flags::DISABLE_MALLOC_TUNING_FLAG, parse_optional}; +use clap_utils::{flags::DISABLE_MALLOC_TUNING_FLAG, get_eth2_network_config}; use directory::{parse_path_or_default, DEFAULT_BEACON_NODE_DIR, DEFAULT_VALIDATOR_DIR}; use env_logger::{Builder, Env}; use environment::{EnvironmentBuilder, LoggerConfig}; @@ -211,6 +211,45 @@ fn main() { ) .global(true), ) + .arg( + Arg::with_name("terminal-total-difficulty-override") + .long("terminal-total-difficulty-override") + .value_name("INTEGER") + .help("Used to coordinate manual overrides to the TERMINAL_TOTAL_DIFFICULTY parameter. \ + Accepts a 256-bit decimal integer (not a hex value). \ + This flag should only be used if the user has a clear understanding that \ + the broad Ethereum community has elected to override the terminal difficulty. \ + Incorrect use of this flag will cause your node to experience a consensus + failure. Be extremely careful with this flag.") + .takes_value(true) + .global(true) + ) + .arg( + Arg::with_name("terminal-block-hash-override") + .long("terminal-block-hash-override") + .value_name("TERMINAL_BLOCK_HASH") + .help("Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH parameter. \ + This flag should only be used if the user has a clear understanding that \ + the broad Ethereum community has elected to override the terminal PoW block. \ + Incorrect use of this flag will cause your node to experience a consensus + failure. Be extremely careful with this flag.") + .requires("terminal-block-hash-epoch-override") + .takes_value(true) + .global(true) + ) + .arg( + Arg::with_name("terminal-block-hash-epoch-override") + .long("terminal-block-hash-epoch-override") + .value_name("EPOCH") + .help("Used to coordinate manual overrides to the TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH \ + parameter. This flag should only be used if the user has a clear understanding \ + that the broad Ethereum community has elected to override the terminal PoW block. \ + Incorrect use of this flag will cause your node to experience a consensus + failure. Be extremely careful with this flag.") + .requires("terminal-block-hash-override") + .takes_value(true) + .global(true) + ) .subcommand(beacon_node::cli_app()) .subcommand(boot_node::cli_app()) .subcommand(validator_client::cli_app()) @@ -250,7 +289,13 @@ fn main() { .expect("Debug-level must be present") .into(); - boot_node::run(&matches, bootnode_matches, eth_spec_id, debug_info); + boot_node::run( + &matches, + bootnode_matches, + eth_spec_id, + ð2_network_config, + debug_info, + ); return Ok(()); } @@ -424,11 +469,7 @@ fn run( let context = environment.core_context(); let log = context.log().clone(); let executor = context.executor.clone(); - let config = beacon_node::get_config::( - matches, - &context.eth2_config().spec, - context.log().clone(), - )?; + let config = beacon_node::get_config::(matches, &context)?; let shutdown_flag = matches.is_present("immediate-shutdown"); if let Some(dump_path) = clap_utils::parse_optional::(matches, "dump-config")? { diff --git a/lighthouse/tests/beacon_node.rs b/lighthouse/tests/beacon_node.rs index 14b15c04c..b8dd31beb 100644 --- a/lighthouse/tests/beacon_node.rs +++ b/lighthouse/tests/beacon_node.rs @@ -11,7 +11,7 @@ use std::process::Command; use std::str::FromStr; use std::string::ToString; use tempfile::TempDir; -use types::{Checkpoint, Epoch, Hash256, Uint256}; +use types::{Checkpoint, Epoch, Hash256}; const DEFAULT_ETH1_ENDPOINT: &str = "http://localhost:8545/"; @@ -817,83 +817,6 @@ pub fn malloc_tuning_flag() { }); } #[test] -pub fn ttd_override_decimal() { - CommandLineTest::new().run().with_config(|config| { - assert!(config.terminal_total_difficulty_override.is_none()); - }); - - CommandLineTest::new() - .flag("merge", None) - .flag( - "terminal-total-difficulty-override", - Some("31,841,035,257,753,085,493,511"), - ) - .run() - .with_config(|config| { - assert_eq!( - config.terminal_total_difficulty_override.unwrap(), - Uint256::from_dec_str(&"31841035257753085493511").unwrap() - ); - }); - - CommandLineTest::new() - .flag("merge", None) - .flag( - "terminal-total-difficulty-override", - Some("31841035257753085493511"), - ) - .run() - .with_config(|config| { - assert_eq!( - config.terminal_total_difficulty_override.unwrap(), - Uint256::from_dec_str(&"31841035257753085493511").unwrap() - ); - }); - - CommandLineTest::new() - .flag("merge", None) - .flag("terminal-total-difficulty-override", Some("1234")) - .run() - .with_config(|config| { - assert_eq!( - config.terminal_total_difficulty_override.unwrap(), - Uint256::from(1234) - ); - }); - - CommandLineTest::new() - .flag("merge", None) - .flag("terminal-total-difficulty-override", Some("1,234")) - .run() - .with_config(|config| { - assert_eq!( - config.terminal_total_difficulty_override.unwrap(), - Uint256::from(1234) - ); - }); -} -#[test] -#[should_panic] -pub fn ttd_override_without_merge() { - CommandLineTest::new() - .flag("terminal-total-difficulty-override", Some("1234")) - .run(); -} -#[test] -#[should_panic] -pub fn ttd_override_hex() { - CommandLineTest::new() - .flag("terminal-total-difficulty-override", Some("0xabcd")) - .run(); -} -#[test] -#[should_panic] -pub fn ttd_override_none() { - CommandLineTest::new() - .flag("terminal-total-difficulty-override", None) - .run(); -} -#[test] #[should_panic] fn ensure_panic_on_failed_launch() { CommandLineTest::new() diff --git a/lighthouse/tests/boot_node.rs b/lighthouse/tests/boot_node.rs index 04437aca9..ac23002c3 100644 --- a/lighthouse/tests/boot_node.rs +++ b/lighthouse/tests/boot_node.rs @@ -1,8 +1,8 @@ use boot_node::config::BootNodeConfigSerialization; use crate::exec::{CommandLineTestExec, CompletedTest}; -use beacon_node::get_eth2_network_config; use clap::ArgMatches; +use clap_utils::get_eth2_network_config; use lighthouse_network::discovery::ENR_FILENAME; use lighthouse_network::Enr; use std::fs::File;