Add --testnet mainnet and start HTTP server before genesis (#1862)
## Issue Addressed NA ## Proposed Changes - Adds support for `--testnet mainnet` - Start HTTP server prior to genesis ## Additional Info **Note: This is an incomplete work-in-progress. Use Lighthouse for mainnet at your own risk.** With this PR, you can check the deposits: ```bash lighthouse --testnet mainnet bn --http ``` ```bash curl localhost:5052/lighthouse/eth1/deposit_cache | jq ``` ```json { "data": [ { "deposit_data": { "pubkey": "0x854980aa9bf2e84723e1fa6ef682e3537257984cc9cb1daea2ce6b268084b414f0bb43206e9fa6fd7a202357d6eb2b0d", "withdrawal_credentials": "0x00cacf703c658b802d55baa2a5c1777500ef5051fc084330d2761bcb6ab6182b", "amount": "32000000000", "signature": "0xace226cdfd9da6b1d827c3a6ab93f91f53e8e090eb6ca5ee7c7c5fe3acc75558240ca9291684a2a7af5cac67f0558d1109cc95309f5cdf8c125185ec9dcd22635f900d791316924aed7c40cff2ffccdac0d44cf496853db678c8c53745b3545b" }, "block_number": 3492981, "index": 0, "signature_is_valid": true }, { "deposit_data": { "pubkey": "0x93da03a71bc4ed163c2f91c8a54ea3ba2461383dd615388fd494670f8ce571b46e698fc8d04b49e4a8ffe653f581806b", "withdrawal_credentials": "0x006ebfbb7c8269a78018c8b810492979561d0404d74ba9c234650baa7524dcc4", "amount": "32000000000", "signature": "0x8d1f4a1683f798a76effcc6e2cdb8c3eed5a79123d201c5ecd4ab91f768a03c30885455b8a952aeec3c02110457f97ae0a60724187b6d4129d7c352f2e1ac19b4210daacd892fe4629ad3260ce2911dceae3890b04ed28267b2d8cb831f6a92d" }, "block_number": 3493427, "index": 1, "signature_is_valid": true }, ```
This commit is contained in:
parent
b3fc48e887
commit
2f9999752e
@ -16,14 +16,15 @@ use eth2_libp2p::NetworkGlobals;
|
||||
use genesis::{interop_genesis_state, Eth1GenesisService};
|
||||
use network::{NetworkConfig, NetworkMessage, NetworkService};
|
||||
use parking_lot::Mutex;
|
||||
use slog::{debug, info};
|
||||
use slog::{debug, info, warn};
|
||||
use ssz::Decode;
|
||||
use std::net::SocketAddr;
|
||||
use std::net::TcpListener;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use timer::spawn_timer;
|
||||
use tokio::sync::mpsc::UnboundedSender;
|
||||
use tokio::sync::{mpsc::UnboundedSender, oneshot};
|
||||
use types::{
|
||||
test_utils::generate_deterministic_keypairs, BeaconState, ChainSpec, EthSpec,
|
||||
SignedBeaconBlockHash,
|
||||
@ -202,6 +203,53 @@ where
|
||||
context.eth2_config().spec.clone(),
|
||||
);
|
||||
|
||||
// If the HTTP API server is enabled, start an instance of it where it only
|
||||
// contains a reference to the eth1 service (all non-eth1 endpoints will fail
|
||||
// gracefully).
|
||||
//
|
||||
// Later in this function we will shutdown this temporary "waiting for genesis"
|
||||
// server so the real one can be started later.
|
||||
let (exit_tx, exit_rx) = oneshot::channel::<()>();
|
||||
let http_listen_opt = if self.http_api_config.enabled {
|
||||
#[allow(clippy::type_complexity)]
|
||||
let ctx: Arc<
|
||||
http_api::Context<
|
||||
Witness<
|
||||
TSlotClock,
|
||||
TEth1Backend,
|
||||
TEthSpec,
|
||||
TEventHandler,
|
||||
THotStore,
|
||||
TColdStore,
|
||||
>,
|
||||
>,
|
||||
> = Arc::new(http_api::Context {
|
||||
config: self.http_api_config.clone(),
|
||||
chain: None,
|
||||
network_tx: None,
|
||||
network_globals: None,
|
||||
eth1_service: Some(genesis_service.eth1_service.clone()),
|
||||
log: context.log().clone(),
|
||||
});
|
||||
|
||||
// Discard the error from the oneshot.
|
||||
let exit_future = async {
|
||||
let _ = exit_rx.await;
|
||||
};
|
||||
|
||||
let (listen_addr, server) = http_api::serve(ctx, exit_future)
|
||||
.map_err(|e| format!("Unable to start HTTP API server: {:?}", e))?;
|
||||
|
||||
context
|
||||
.clone()
|
||||
.executor
|
||||
.spawn_without_exit(async move { server.await }, "http-api");
|
||||
|
||||
Some(listen_addr)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let genesis_state = genesis_service
|
||||
.wait_for_genesis_state(
|
||||
Duration::from_millis(ETH1_GENESIS_UPDATE_INTERVAL_MILLIS),
|
||||
@ -209,6 +257,22 @@ where
|
||||
)
|
||||
.await?;
|
||||
|
||||
let _ = exit_tx.send(());
|
||||
|
||||
if let Some(http_listen) = http_listen_opt {
|
||||
// This is a bit of a hack to ensure that the HTTP server has indeed shutdown.
|
||||
//
|
||||
// We will restart it again after we've finished setting up for genesis.
|
||||
while TcpListener::bind(http_listen).is_err() {
|
||||
warn!(
|
||||
context.log(),
|
||||
"Waiting for HTTP server port to open";
|
||||
"port" => http_listen
|
||||
);
|
||||
tokio::time::delay_for(Duration::from_secs(1)).await;
|
||||
}
|
||||
}
|
||||
|
||||
builder
|
||||
.genesis_state(genesis_state)
|
||||
.map(|v| (v, Some(genesis_service.into_core_service())))?
|
||||
|
@ -79,6 +79,7 @@ impl<E: EthSpec> ProductionBeaconNode<E> {
|
||||
let builder = ClientBuilder::new(context.eth_spec_instance.clone())
|
||||
.runtime_context(context)
|
||||
.chain_spec(spec)
|
||||
.http_api_config(client_config.http_api.clone())
|
||||
.disk_store(&db_path, &freezer_db_path_res?, store_config)?;
|
||||
|
||||
let builder = builder
|
||||
@ -123,7 +124,6 @@ impl<E: EthSpec> ProductionBeaconNode<E> {
|
||||
.network(&client_config.network)
|
||||
.await?
|
||||
.notifier()?
|
||||
.http_api_config(client_config.http_api.clone())
|
||||
.http_metrics_config(client_config.http_metrics.clone())
|
||||
.build()
|
||||
.map(Self)
|
||||
|
@ -122,6 +122,8 @@ define_net!(spadina, include_spadina_file, "spadina", true);
|
||||
|
||||
define_net!(zinken, include_zinken_file, "zinken", true);
|
||||
|
||||
define_net!(mainnet, include_mainnet_file, "mainnet", false);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
1
common/eth2_testnet_config/.gitignore
vendored
1
common/eth2_testnet_config/.gitignore
vendored
@ -3,3 +3,4 @@ schlesi-*
|
||||
witti-*
|
||||
/altona*
|
||||
built_in_testnet_configs/*/genesis.ssz
|
||||
!built_in_testnet_configs/mainnet/genesis.ssz
|
||||
|
@ -0,0 +1 @@
|
||||
[]
|
@ -0,0 +1,155 @@
|
||||
# Mainnet preset
|
||||
|
||||
CONFIG_NAME: "mainnet"
|
||||
|
||||
# Misc
|
||||
# ---------------------------------------------------------------
|
||||
# 2**6 (= 64)
|
||||
MAX_COMMITTEES_PER_SLOT: 64
|
||||
# 2**7 (= 128)
|
||||
TARGET_COMMITTEE_SIZE: 128
|
||||
# 2**11 (= 2,048)
|
||||
MAX_VALIDATORS_PER_COMMITTEE: 2048
|
||||
# 2**2 (= 4)
|
||||
MIN_PER_EPOCH_CHURN_LIMIT: 4
|
||||
# 2**16 (= 65,536)
|
||||
CHURN_LIMIT_QUOTIENT: 65536
|
||||
# See issue 563
|
||||
SHUFFLE_ROUND_COUNT: 90
|
||||
# `2**14` (= 16,384)
|
||||
MIN_GENESIS_ACTIVE_VALIDATOR_COUNT: 16384
|
||||
# Dec 1, 2020, 12pm UTC
|
||||
MIN_GENESIS_TIME: 1606824000
|
||||
# 4
|
||||
HYSTERESIS_QUOTIENT: 4
|
||||
# 1 (minus 0.25)
|
||||
HYSTERESIS_DOWNWARD_MULTIPLIER: 1
|
||||
# 5 (plus 1.25)
|
||||
HYSTERESIS_UPWARD_MULTIPLIER: 5
|
||||
|
||||
|
||||
# Fork Choice
|
||||
# ---------------------------------------------------------------
|
||||
# 2**3 (= 8)
|
||||
SAFE_SLOTS_TO_UPDATE_JUSTIFIED: 8
|
||||
|
||||
|
||||
# Validator
|
||||
# ---------------------------------------------------------------
|
||||
# 2**11 (= 2,048)
|
||||
ETH1_FOLLOW_DISTANCE: 2048
|
||||
# 2**4 (= 16)
|
||||
TARGET_AGGREGATORS_PER_COMMITTEE: 16
|
||||
# 2**0 (= 1)
|
||||
RANDOM_SUBNETS_PER_VALIDATOR: 1
|
||||
# 2**8 (= 256)
|
||||
EPOCHS_PER_RANDOM_SUBNET_SUBSCRIPTION: 256
|
||||
# 14 (estimate from Eth1 mainnet)
|
||||
SECONDS_PER_ETH1_BLOCK: 14
|
||||
|
||||
|
||||
# Deposit contract
|
||||
# ---------------------------------------------------------------
|
||||
# Ethereum PoW Mainnet
|
||||
DEPOSIT_CHAIN_ID: 1
|
||||
DEPOSIT_NETWORK_ID: 1
|
||||
# **TBD**
|
||||
DEPOSIT_CONTRACT_ADDRESS: 0x00000000219ab540356cBB839Cbe05303d7705Fa
|
||||
|
||||
|
||||
# Gwei values
|
||||
# ---------------------------------------------------------------
|
||||
# 2**0 * 10**9 (= 1,000,000,000) Gwei
|
||||
MIN_DEPOSIT_AMOUNT: 1000000000
|
||||
# 2**5 * 10**9 (= 32,000,000,000) Gwei
|
||||
MAX_EFFECTIVE_BALANCE: 32000000000
|
||||
# 2**4 * 10**9 (= 16,000,000,000) Gwei
|
||||
EJECTION_BALANCE: 16000000000
|
||||
# 2**0 * 10**9 (= 1,000,000,000) Gwei
|
||||
EFFECTIVE_BALANCE_INCREMENT: 1000000000
|
||||
|
||||
|
||||
# Initial values
|
||||
# ---------------------------------------------------------------
|
||||
# Mainnet initial fork version, recommend altering for testnets
|
||||
GENESIS_FORK_VERSION: 0x00000000
|
||||
BLS_WITHDRAWAL_PREFIX: 0x00
|
||||
|
||||
|
||||
# Time parameters
|
||||
# ---------------------------------------------------------------
|
||||
# 604800 seconds (7 days)
|
||||
GENESIS_DELAY: 604800
|
||||
# 12 seconds
|
||||
SECONDS_PER_SLOT: 12
|
||||
# 2**0 (= 1) slots 12 seconds
|
||||
MIN_ATTESTATION_INCLUSION_DELAY: 1
|
||||
# 2**5 (= 32) slots 6.4 minutes
|
||||
SLOTS_PER_EPOCH: 32
|
||||
# 2**0 (= 1) epochs 6.4 minutes
|
||||
MIN_SEED_LOOKAHEAD: 1
|
||||
# 2**2 (= 4) epochs 25.6 minutes
|
||||
MAX_SEED_LOOKAHEAD: 4
|
||||
# 2**6 (= 64) epochs ~6.8 hours
|
||||
EPOCHS_PER_ETH1_VOTING_PERIOD: 64
|
||||
# 2**13 (= 8,192) slots ~13 hours
|
||||
SLOTS_PER_HISTORICAL_ROOT: 8192
|
||||
# 2**8 (= 256) epochs ~27 hours
|
||||
MIN_VALIDATOR_WITHDRAWABILITY_DELAY: 256
|
||||
# 2**8 (= 256) epochs ~27 hours
|
||||
SHARD_COMMITTEE_PERIOD: 256
|
||||
# 2**2 (= 4) epochs 25.6 minutes
|
||||
MIN_EPOCHS_TO_INACTIVITY_PENALTY: 4
|
||||
|
||||
|
||||
# State vector lengths
|
||||
# ---------------------------------------------------------------
|
||||
# 2**16 (= 65,536) epochs ~0.8 years
|
||||
EPOCHS_PER_HISTORICAL_VECTOR: 65536
|
||||
# 2**13 (= 8,192) epochs ~36 days
|
||||
EPOCHS_PER_SLASHINGS_VECTOR: 8192
|
||||
# 2**24 (= 16,777,216) historical roots, ~26,131 years
|
||||
HISTORICAL_ROOTS_LIMIT: 16777216
|
||||
# 2**40 (= 1,099,511,627,776) validator spots
|
||||
VALIDATOR_REGISTRY_LIMIT: 1099511627776
|
||||
|
||||
|
||||
# Reward and penalty quotients
|
||||
# ---------------------------------------------------------------
|
||||
# 2**6 (= 64)
|
||||
BASE_REWARD_FACTOR: 64
|
||||
# 2**9 (= 512)
|
||||
WHISTLEBLOWER_REWARD_QUOTIENT: 512
|
||||
# 2**3 (= 8)
|
||||
PROPOSER_REWARD_QUOTIENT: 8
|
||||
# 2**26 (= 67,108,864)
|
||||
INACTIVITY_PENALTY_QUOTIENT: 67108864
|
||||
# 2**7 (= 128) (lower safety margin at Phase 0 genesis)
|
||||
MIN_SLASHING_PENALTY_QUOTIENT: 128
|
||||
# 1 (lower safety margin at Phase 0 genesis)
|
||||
PROPORTIONAL_SLASHING_MULTIPLIER: 1
|
||||
|
||||
|
||||
# Max operations per block
|
||||
# ---------------------------------------------------------------
|
||||
# 2**4 (= 16)
|
||||
MAX_PROPOSER_SLASHINGS: 16
|
||||
# 2**1 (= 2)
|
||||
MAX_ATTESTER_SLASHINGS: 2
|
||||
# 2**7 (= 128)
|
||||
MAX_ATTESTATIONS: 128
|
||||
# 2**4 (= 16)
|
||||
MAX_DEPOSITS: 16
|
||||
# 2**4 (= 16)
|
||||
MAX_VOLUNTARY_EXITS: 16
|
||||
|
||||
|
||||
# Signature domains
|
||||
# ---------------------------------------------------------------
|
||||
DOMAIN_BEACON_PROPOSER: 0x00000000
|
||||
DOMAIN_BEACON_ATTESTER: 0x01000000
|
||||
DOMAIN_RANDAO: 0x02000000
|
||||
DOMAIN_DEPOSIT: 0x03000000
|
||||
DOMAIN_VOLUNTARY_EXIT: 0x04000000
|
||||
DOMAIN_SELECTION_PROOF: 0x05000000
|
||||
DOMAIN_AGGREGATE_AND_PROOF: 0x06000000
|
@ -0,0 +1 @@
|
||||
11184524
|
@ -0,0 +1 @@
|
||||
0x00000000219ab540356cBB839Cbe05303d7705Fa
|
@ -8,8 +8,8 @@
|
||||
//! https://github.com/sigp/lighthouse/pull/605
|
||||
//!
|
||||
use eth2_config::{
|
||||
include_altona_file, include_medalla_file, include_spadina_file, include_zinken_file,
|
||||
testnets_dir,
|
||||
include_altona_file, include_mainnet_file, include_medalla_file, include_spadina_file,
|
||||
include_zinken_file, testnets_dir,
|
||||
};
|
||||
|
||||
use enr::{CombinedKey, Enr};
|
||||
@ -56,8 +56,9 @@ const ALTONA: HardcodedNet = define_net!(altona, include_altona_file);
|
||||
const MEDALLA: HardcodedNet = define_net!(medalla, include_medalla_file);
|
||||
const SPADINA: HardcodedNet = define_net!(spadina, include_spadina_file);
|
||||
const ZINKEN: HardcodedNet = define_net!(zinken, include_zinken_file);
|
||||
const MAINNET: HardcodedNet = define_net!(mainnet, include_mainnet_file);
|
||||
|
||||
const HARDCODED_NETS: &[HardcodedNet] = &[ALTONA, MEDALLA, SPADINA, ZINKEN];
|
||||
const HARDCODED_NETS: &[HardcodedNet] = &[ALTONA, MEDALLA, SPADINA, ZINKEN, MAINNET];
|
||||
pub const DEFAULT_HARDCODED_TESTNET: &str = "medalla";
|
||||
|
||||
/// Specifies an Eth2 testnet.
|
||||
@ -66,6 +67,8 @@ pub const DEFAULT_HARDCODED_TESTNET: &str = "medalla";
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
pub struct Eth2TestnetConfig {
|
||||
pub deposit_contract_address: String,
|
||||
/// Note: instead of the block where the contract is deployed, it is acceptable to set this
|
||||
/// value to be the block number where the first deposit occurs.
|
||||
pub deposit_contract_deploy_block: u64,
|
||||
pub boot_enr: Option<Vec<Enr<CombinedKey>>>,
|
||||
pub genesis_state_bytes: Option<Vec<u8>>,
|
||||
@ -239,7 +242,8 @@ impl Eth2TestnetConfig {
|
||||
file.read_to_end(&mut bytes)
|
||||
.map_err(|e| format!("Unable to read {:?}: {:?}", file, e))
|
||||
})?;
|
||||
Some(bytes)
|
||||
|
||||
Some(bytes).filter(|bytes| !bytes.is_empty())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -269,7 +273,7 @@ mod tests {
|
||||
use super::*;
|
||||
use ssz::Encode;
|
||||
use tempdir::TempDir;
|
||||
use types::{Eth1Data, Hash256, V012LegacyEthSpec, YamlConfig};
|
||||
use types::{Eth1Data, Hash256, MainnetEthSpec, V012LegacyEthSpec, YamlConfig};
|
||||
|
||||
type E = V012LegacyEthSpec;
|
||||
|
||||
@ -279,13 +283,23 @@ mod tests {
|
||||
let config =
|
||||
Eth2TestnetConfig::from_hardcoded_net(net).expect(&format!("{:?}", net.name));
|
||||
|
||||
if net.name == "mainnet" {
|
||||
// Ensure we can parse the YAML config to a chain spec.
|
||||
config
|
||||
.yaml_config
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.apply_to_chain_spec::<E>(&E::default_spec())
|
||||
.apply_to_chain_spec::<MainnetEthSpec>(&E::default_spec())
|
||||
.unwrap();
|
||||
} else {
|
||||
// Ensure we can parse the YAML config to a chain spec.
|
||||
config
|
||||
.yaml_config
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.apply_to_chain_spec::<V012LegacyEthSpec>(&E::default_spec())
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
config.genesis_state_bytes.is_some(),
|
||||
|
@ -115,7 +115,7 @@ fn main() {
|
||||
.long("testnet")
|
||||
.value_name("testnet")
|
||||
.help("Name of network lighthouse will connect to")
|
||||
.possible_values(&["medalla", "altona", "spadina", "zinken"])
|
||||
.possible_values(&["medalla", "altona", "spadina", "zinken", "mainnet"])
|
||||
.conflicts_with("testnet-dir")
|
||||
.takes_value(true)
|
||||
.global(true)
|
||||
@ -265,15 +265,22 @@ fn run<E: EthSpec>(
|
||||
|
||||
warn!(
|
||||
log,
|
||||
"Ethereum 2.0 is pre-release. This software is experimental."
|
||||
"Ethereum 2.0 is pre-release. This software is experimental"
|
||||
);
|
||||
info!(log, "Lighthouse started"; "version" => VERSION);
|
||||
info!(
|
||||
log,
|
||||
"Configured for testnet";
|
||||
"name" => testnet_name
|
||||
"name" => &testnet_name
|
||||
);
|
||||
|
||||
if testnet_name == "mainnet" {
|
||||
warn!(
|
||||
log,
|
||||
"The mainnet specification is being used. This not recommended (yet)."
|
||||
)
|
||||
}
|
||||
|
||||
match matches.subcommand() {
|
||||
("beacon_node", Some(matches)) => {
|
||||
let context = environment.core_context();
|
||||
|
Loading…
Reference in New Issue
Block a user