Files
lighthouse/beacon_node/src/lib.rs
Michael Sproul 36bd4d87f0 Update to spec v1.0.0-rc.0 and BLSv4 (#1765)
## Issue Addressed

Closes #1504 
Closes #1505
Replaces #1703
Closes #1707

## Proposed Changes

* Update BLST and Milagro to versions compatible with BLSv4 spec
* Update Lighthouse to spec v1.0.0-rc.0, and update EF test vectors
* Use the v1.0.0 constants for `MainnetEthSpec`.
* Rename `InteropEthSpec` -> `V012LegacyEthSpec`
    * Change all constants to suit the mainnet `v0.12.3` specification (i.e., Medalla).
* Deprecate the `--spec` flag for the `lighthouse` binary
    * This value is now obtained from the `config_name` field of the `YamlConfig`.
        * Built in testnet YAML files have been updated.
    * Ignore the `--spec` value, if supplied, log a warning that it will be deprecated
    * `lcli` still has the spec flag, that's fine because it's dev tooling.
* Remove the `E: EthSpec` from `YamlConfig`
    * This means we need to deser the genesis `BeaconState` on-demand, but this is fine.
* Swap the old "minimal", "mainnet" strings over to the new `EthSpecId` enum.
* Always require a `CONFIG_NAME` field in `YamlConfig` (it used to have a default).

## Additional Info

Lots of breaking changes, do not merge! ~~We will likely need a Lighthouse v0.4.0 branch, and possibly a long-term v0.3.0 branch to keep Medalla alive~~.

Co-authored-by: Kirk Baird <baird.k@outlook.com>
Co-authored-by: Paul Hauner <paul@paulhauner.com>
2020-10-28 22:19:38 +00:00

160 lines
5.1 KiB
Rust

#[macro_use]
extern crate clap;
mod cli;
mod config;
pub use beacon_chain;
pub use cli::cli_app;
pub use client::{Client, ClientBuilder, ClientConfig, ClientGenesis};
pub use config::{get_config, get_data_dir, get_eth2_testnet_config, set_network_config};
pub use eth2_config::Eth2Config;
use beacon_chain::events::TeeEventHandler;
use beacon_chain::store::LevelDB;
use beacon_chain::{
builder::Witness, eth1_chain::CachingEth1Backend, slot_clock::SystemTimeSlotClock,
};
use clap::ArgMatches;
use environment::RuntimeContext;
use slog::{info, warn};
use std::ops::{Deref, DerefMut};
use types::EthSpec;
/// A type-alias to the tighten the definition of a production-intended `Client`.
pub type ProductionClient<E> = Client<
Witness<
SystemTimeSlotClock,
CachingEth1Backend<E>,
E,
TeeEventHandler<E>,
LevelDB<E>,
LevelDB<E>,
>,
>;
/// The beacon node `Client` that will be used in production.
///
/// Generic over some `EthSpec`.
///
/// ## Notes:
///
/// Despite being titled `Production...`, this code is not ready for production. The name
/// demonstrates an intention, not a promise.
pub struct ProductionBeaconNode<E: EthSpec>(ProductionClient<E>);
impl<E: EthSpec> ProductionBeaconNode<E> {
/// Starts a new beacon node `Client` in the given `environment`.
///
/// Identical to `start_from_client_config`, however the `client_config` is generated from the
/// given `matches` and potentially configuration files on the local filesystem or other
/// configurations hosted remotely.
pub async fn new_from_cli(
context: RuntimeContext<E>,
matches: ArgMatches<'static>,
) -> Result<Self, String> {
let client_config =
get_config::<E>(&matches, &context.eth2_config().spec, context.log().clone())?;
Self::new(context, client_config).await
}
/// Starts a new beacon node `Client` in the given `environment`.
///
/// Client behaviour is defined by the given `client_config`.
pub async fn new(
context: RuntimeContext<E>,
mut client_config: ClientConfig,
) -> Result<Self, String> {
let spec = context.eth2_config().spec.clone();
let client_config_1 = client_config.clone();
let client_genesis = client_config.genesis.clone();
let store_config = client_config.store.clone();
let log = context.log().clone();
let db_path = client_config.create_db_path()?;
let freezer_db_path_res = client_config.create_freezer_db_path();
let executor = context.executor.clone();
let builder = ClientBuilder::new(context.eth_spec_instance.clone())
.runtime_context(context)
.chain_spec(spec)
.disk_store(&db_path, &freezer_db_path_res?, store_config)?;
let builder = builder
.beacon_chain_builder(client_genesis, client_config_1)
.await?;
let builder = if client_config.sync_eth1_chain && !client_config.dummy_eth1_backend {
info!(
log,
"Block production enabled";
"endpoint" => &client_config.eth1.endpoint,
"method" => "json rpc via http"
);
builder
.caching_eth1_backend(client_config.eth1.clone())
.await?
} else if client_config.dummy_eth1_backend {
warn!(
log,
"Block production impaired";
"reason" => "dummy eth1 backend is enabled"
);
builder.dummy_eth1_backend()?
} else {
info!(
log,
"Block production disabled";
"reason" => "no eth1 backend configured"
);
builder.no_eth1_backend()?
};
let (builder, _events) = builder
.system_time_slot_clock()?
.tee_event_handler(client_config.websocket_server.clone())?;
// Inject the executor into the discv5 network config.
let discv5_executor = Discv5Executor(executor);
client_config.network.discv5_config.executor = Some(Box::new(discv5_executor));
builder
.build_beacon_chain()?
.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)
}
pub fn into_inner(self) -> ProductionClient<E> {
self.0
}
}
impl<E: EthSpec> Deref for ProductionBeaconNode<E> {
type Target = ProductionClient<E>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<E: EthSpec> DerefMut for ProductionBeaconNode<E> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
// Implements the Discv5 Executor trait over our global executor
#[derive(Clone)]
struct Discv5Executor(task_executor::TaskExecutor);
impl eth2_libp2p::discv5::Executor for Discv5Executor {
fn spawn(&self, future: std::pin::Pin<Box<dyn std::future::Future<Output = ()> + Send>>) {
self.0.spawn(future, "discv5")
}
}