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
This commit is contained in:
parent
47db682d7e
commit
afe59afacd
152
Cargo.lock
generated
152
Cargo.lock
generated
@ -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]]
|
||||
|
@ -2893,7 +2893,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
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 {
|
||||
|
@ -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)?;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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(),
|
||||
|
@ -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<Vec<SensitiveUrl>>,
|
||||
pub terminal_total_difficulty_override: Option<Uint256>,
|
||||
pub terminal_block_hash_override: Option<Hash256>,
|
||||
pub terminal_block_hash_epoch_override: Option<Epoch>,
|
||||
pub fee_recipient: Option<Address>,
|
||||
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(),
|
||||
|
@ -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<ApiError> for Error {
|
||||
|
||||
struct Inner {
|
||||
engines: Engines<HttpJsonRpc>,
|
||||
terminal_total_difficulty: Uint256,
|
||||
terminal_block_hash: Hash256,
|
||||
fee_recipient: Option<Address>,
|
||||
execution_blocks: Mutex<LruCache<Hash256, ExecutionBlock>>,
|
||||
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<SensitiveUrl>,
|
||||
terminal_total_difficulty: Uint256,
|
||||
terminal_block_hash: Hash256,
|
||||
fee_recipient: Option<Address>,
|
||||
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<Address, Error> {
|
||||
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<Option<Hash256>, Error> {
|
||||
pub async fn get_terminal_pow_block_hash(
|
||||
&self,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Option<Hash256>, 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<HttpJsonRpc>,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<Option<Hash256>, 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<Option<bool>, 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
|
||||
|
@ -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<Arc<tokio::runtime::Runtime>>,
|
||||
@ -50,6 +50,7 @@ pub struct MockExecutionLayer<T: EthSpec> {
|
||||
pub server: MockServer<T>,
|
||||
pub el: ExecutionLayer,
|
||||
pub el_runtime: ExecutionLayerRuntime,
|
||||
pub spec: ChainSpec,
|
||||
}
|
||||
|
||||
impl<T: EthSpec> MockExecutionLayer<T> {
|
||||
@ -58,6 +59,7 @@ impl<T: EthSpec> MockExecutionLayer<T> {
|
||||
DEFAULT_TERMINAL_DIFFICULTY.into(),
|
||||
DEFAULT_TERMINAL_BLOCK,
|
||||
Hash256::zero(),
|
||||
Epoch::new(0),
|
||||
)
|
||||
}
|
||||
|
||||
@ -65,10 +67,16 @@ impl<T: EthSpec> MockExecutionLayer<T> {
|
||||
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<T: EthSpec> MockExecutionLayer<T> {
|
||||
|
||||
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<T: EthSpec> MockExecutionLayer<T> {
|
||||
server,
|
||||
el,
|
||||
el_runtime,
|
||||
spec,
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,7 +178,7 @@ impl<T: EthSpec> MockExecutionLayer<T> {
|
||||
|
||||
pub async fn with_terminal_block<'a, U, V>(self, func: U) -> Self
|
||||
where
|
||||
U: Fn(ExecutionLayer, Option<ExecutionBlock>) -> V,
|
||||
U: Fn(ChainSpec, ExecutionLayer, Option<ExecutionBlock>) -> V,
|
||||
V: Future<Output = ()>,
|
||||
{
|
||||
let terminal_block_number = self
|
||||
@ -183,7 +190,7 @@ impl<T: EthSpec> MockExecutionLayer<T> {
|
||||
.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
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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<E: EthSpec>(
|
||||
cli_args: &ArgMatches,
|
||||
spec: &ChainSpec,
|
||||
log: Logger,
|
||||
context: &RuntimeContext<E>,
|
||||
) -> Result<ClientConfig, String> {
|
||||
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<E: EthSpec>(
|
||||
&mut client_config.network,
|
||||
cli_args,
|
||||
&client_config.data_dir,
|
||||
&log,
|
||||
log,
|
||||
false,
|
||||
)?;
|
||||
|
||||
@ -242,32 +242,7 @@ pub fn get_config<E: EthSpec>(
|
||||
client_config.execution_endpoints = Some(client_config.eth1.endpoints.clone());
|
||||
}
|
||||
|
||||
if let Some(string) =
|
||||
clap_utils::parse_optional::<String>(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<E: EthSpec>(
|
||||
/*
|
||||
* 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<E: EthSpec>(
|
||||
|
||||
// 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<Eth2NetworkConfig, String> {
|
||||
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
|
||||
|
@ -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<E: EthSpec> ProductionBeaconNode<E> {
|
||||
context: RuntimeContext<E>,
|
||||
matches: ArgMatches<'static>,
|
||||
) -> Result<Self, String> {
|
||||
let client_config =
|
||||
get_config::<E>(&matches, &context.eth2_config().spec, context.log().clone())?;
|
||||
let client_config = get_config::<E>(&matches, &context)?;
|
||||
Self::new(context, client_config).await
|
||||
}
|
||||
|
||||
|
@ -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" }
|
||||
|
@ -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<T: EthSpec> {
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: EthSpec> TryFrom<&ArgMatches<'_>> for BootNodeConfig<T> {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(matches: &ArgMatches<'_>) -> Result<Self, Self::Error> {
|
||||
impl<T: EthSpec> BootNodeConfig<T> {
|
||||
pub fn new(
|
||||
matches: &ArgMatches<'_>,
|
||||
eth2_network_config: &Eth2NetworkConfig,
|
||||
) -> Result<Self, String> {
|
||||
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 = {
|
||||
|
@ -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::<types::MinimalEthSpec>(lh_matches, bn_matches, log),
|
||||
EthSpecId::Mainnet => main::<types::MainnetEthSpec>(lh_matches, bn_matches, log),
|
||||
EthSpecId::Minimal => {
|
||||
main::<types::MinimalEthSpec>(lh_matches, bn_matches, eth2_network_config, log)
|
||||
}
|
||||
EthSpecId::Mainnet => {
|
||||
main::<types::MainnetEthSpec>(lh_matches, bn_matches, eth2_network_config, log)
|
||||
}
|
||||
} {
|
||||
slog::crit!(slog_scope::logger(), "{}", e);
|
||||
}
|
||||
@ -66,6 +71,7 @@ pub fn run(
|
||||
fn main<T: EthSpec>(
|
||||
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<T: EthSpec>(
|
||||
.build()
|
||||
.map_err(|e| format!("Failed to build runtime: {}", e))?;
|
||||
|
||||
// Parse the CLI args into a useable config
|
||||
let config: BootNodeConfig<T> = BootNodeConfig::try_from(bn_matches)?;
|
||||
// parse the CLI args into a useable config
|
||||
let config: BootNodeConfig<T> = BootNodeConfig::new(bn_matches, eth2_network_config)?;
|
||||
|
||||
// Dump config if `dump-config` flag is set
|
||||
let dump_config = clap_utils::parse_optional::<PathBuf>(lh_matches, "dump-config")?;
|
||||
|
@ -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"
|
||||
|
@ -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<Eth2NetworkConfig, String> {
|
||||
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::<String>(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(
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
})
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ impl<E: EthSpec> EnvironmentBuilder<E> {
|
||||
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<E: EthSpec> {
|
||||
pub executor: TaskExecutor,
|
||||
pub eth_spec_instance: E,
|
||||
pub eth2_config: Eth2Config,
|
||||
pub eth2_network_config: Option<Arc<Eth2NetworkConfig>>,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> RuntimeContext<E> {
|
||||
@ -274,6 +275,7 @@ impl<E: EthSpec> RuntimeContext<E> {
|
||||
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<E: EthSpec> {
|
||||
log: Logger,
|
||||
eth_spec_instance: E,
|
||||
pub eth2_config: Eth2Config,
|
||||
pub eth2_network_config: Option<Eth2NetworkConfig>,
|
||||
pub eth2_network_config: Option<Arc<Eth2NetworkConfig>>,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> Environment<E> {
|
||||
@ -324,6 +326,7 @@ impl<E: EthSpec> Environment<E> {
|
||||
),
|
||||
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<E: EthSpec> Environment<E> {
|
||||
),
|
||||
eth_spec_instance: self.eth_spec_instance.clone(),
|
||||
eth2_config: self.eth2_config.clone(),
|
||||
eth2_network_config: self.eth2_network_config.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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<E: EthSpec>(
|
||||
let context = environment.core_context();
|
||||
let log = context.log().clone();
|
||||
let executor = context.executor.clone();
|
||||
let config = beacon_node::get_config::<E>(
|
||||
matches,
|
||||
&context.eth2_config().spec,
|
||||
context.log().clone(),
|
||||
)?;
|
||||
let config = beacon_node::get_config::<E>(matches, &context)?;
|
||||
let shutdown_flag = matches.is_present("immediate-shutdown");
|
||||
if let Some(dump_path) = clap_utils::parse_optional::<PathBuf>(matches, "dump-config")?
|
||||
{
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user