Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Add --testnet mainnet and start HTTP server before genesis #1862

Closed
wants to merge 12 commits into from
68 changes: 66 additions & 2 deletions beacon_node/client/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -202,13 +203,76 @@ 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),
context.eth2_config().spec.clone(),
)
.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())))?
Expand Down
2 changes: 1 addition & 1 deletion beacon_node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions common/eth2_config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down
1 change: 1 addition & 0 deletions common/eth2_testnet_config/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ schlesi-*
witti-*
/altona*
built_in_testnet_configs/*/genesis.ssz
!built_in_testnet_configs/mainnet/genesis.ssz
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
11184524
michaelsproul marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0x00000000219ab540356cBB839Cbe05303d7705Fa
Empty file.
38 changes: 26 additions & 12 deletions common/eth2_testnet_config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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.
Expand All @@ -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>>,
Expand Down Expand Up @@ -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
};
Expand Down Expand Up @@ -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;

Expand All @@ -279,13 +283,23 @@ mod tests {
let config =
Eth2TestnetConfig::from_hardcoded_net(net).expect(&format!("{:?}", net.name));

// 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())
.unwrap();
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::<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(),
Expand Down
Loading