From d80d9dba4c62d9b81b9fd233460cdc5e47d23c5b Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Tue, 3 Sep 2019 16:40:53 +1000 Subject: [PATCH] Add flag for web3 server --- beacon_node/beacon_chain/src/eth1_chain.rs | 8 ++- beacon_node/beacon_chain/src/lib.rs | 2 +- beacon_node/client/src/config.rs | 18 +++++ beacon_node/client/src/lib.rs | 13 ++-- beacon_node/src/config.rs | 15 ++++- beacon_node/src/main.rs | 10 +++ beacon_node/src/run.rs | 76 ++++++++-------------- 7 files changed, 85 insertions(+), 57 deletions(-) diff --git a/beacon_node/beacon_chain/src/eth1_chain.rs b/beacon_node/beacon_chain/src/eth1_chain.rs index 8e578ea9a..e4ccee3ba 100644 --- a/beacon_node/beacon_chain/src/eth1_chain.rs +++ b/beacon_node/beacon_chain/src/eth1_chain.rs @@ -48,7 +48,9 @@ pub enum Error { BackendError(String), } -pub trait Eth1ChainBackend { +pub trait Eth1ChainBackend: Sized + Send + Sync { + fn new(server: String) -> Result; + /// Returns the `Eth1Data` that should be included in a block being produced for the given /// `state`. fn eth1_data(&self, beacon_state: &BeaconState) -> Result; @@ -68,6 +70,10 @@ pub struct InteropEth1ChainBackend { } impl Eth1ChainBackend for InteropEth1ChainBackend { + fn new(_server: String) -> Result { + Ok(Self::default()) + } + fn eth1_data(&self, state: &BeaconState) -> Result { let current_epoch = state.current_epoch(); let slots_per_voting_period = T::slots_per_eth1_voting_period() as u64; diff --git a/beacon_node/beacon_chain/src/lib.rs b/beacon_node/beacon_chain/src/lib.rs index 7883019d7..036172348 100644 --- a/beacon_node/beacon_chain/src/lib.rs +++ b/beacon_node/beacon_chain/src/lib.rs @@ -19,7 +19,7 @@ pub use self::beacon_chain::{ pub use self::checkpoint::CheckPoint; pub use self::errors::{BeaconChainError, BlockProductionError}; pub use beacon_chain_builder::BeaconChainBuilder; -pub use eth1_chain::InteropEth1ChainBackend; +pub use eth1_chain::{Eth1ChainBackend, InteropEth1ChainBackend}; pub use lmd_ghost; pub use metrics::scrape_for_metrics; pub use parking_lot; diff --git a/beacon_node/client/src/config.rs b/beacon_node/client/src/config.rs index f9b366eb1..5b0553c5b 100644 --- a/beacon_node/client/src/config.rs +++ b/beacon_node/client/src/config.rs @@ -23,6 +23,7 @@ pub struct Config { /// files. It can only be configured via the CLI. #[serde(skip)] pub beacon_chain_start_method: BeaconChainStartMethod, + pub eth1_backend_method: Eth1BackendMethod, pub network: network::NetworkConfig, pub rpc: rpc::RPCConfig, pub rest_api: rest_api::ApiConfig, @@ -69,6 +70,22 @@ impl Default for BeaconChainStartMethod { } } +/// Defines which Eth1 backend the client should use. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(tag = "type")] +pub enum Eth1BackendMethod { + /// Use the mocked eth1 backend used in interop testing + Interop, + /// Use a web3 connection to a running Eth1 node. + Web3 { server: String }, +} + +impl Default for Eth1BackendMethod { + fn default() -> Self { + Eth1BackendMethod::Interop + } +} + impl Default for Config { fn default() -> Self { Self { @@ -81,6 +98,7 @@ impl Default for Config { rest_api: <_>::default(), spec_constants: TESTNET_SPEC_CONSTANTS.into(), beacon_chain_start_method: <_>::default(), + eth1_backend_method: <_>::default(), } } } diff --git a/beacon_node/client/src/lib.rs b/beacon_node/client/src/lib.rs index e14da2af9..33f27f253 100644 --- a/beacon_node/client/src/lib.rs +++ b/beacon_node/client/src/lib.rs @@ -21,14 +21,14 @@ use tokio::runtime::TaskExecutor; use tokio::timer::Interval; use types::EthSpec; -pub use beacon_chain::BeaconChainTypes; -pub use config::{BeaconChainStartMethod, Config as ClientConfig}; +pub use beacon_chain::{BeaconChainTypes, Eth1ChainBackend, InteropEth1ChainBackend}; +pub use config::{BeaconChainStartMethod, Config as ClientConfig, Eth1BackendMethod}; pub use eth2_config::Eth2Config; #[derive(Clone)] pub struct ClientType { - _phantom_t: PhantomData, - _phantom_u: PhantomData, + _phantom_s: PhantomData, + _phantom_e: PhantomData, } impl BeaconChainTypes for ClientType @@ -39,6 +39,7 @@ where type Store = S; type SlotClock = SystemTimeSlotClock; type LmdGhost = ThreadSafeReducedTree; + type Eth1Chain = InteropEth1ChainBackend; type EthSpec = E; } @@ -168,9 +169,11 @@ where } }; + let eth1_backend = T::Eth1Chain::new(String::new()).map_err(|e| format!("{:?}", e))?; + let beacon_chain: Arc> = Arc::new( beacon_chain_builder - .build(store) + .build(store, eth1_backend) .map_err(error::Error::from)?, ); diff --git a/beacon_node/src/config.rs b/beacon_node/src/config.rs index 4a3f6b6a7..47b877ecb 100644 --- a/beacon_node/src/config.rs +++ b/beacon_node/src/config.rs @@ -1,5 +1,5 @@ use clap::ArgMatches; -use client::{BeaconChainStartMethod, ClientConfig, Eth2Config}; +use client::{BeaconChainStartMethod, ClientConfig, Eth1BackendMethod, Eth2Config}; use eth2_config::{read_from_file, write_to_file}; use lighthouse_bootstrap::Bootstrapper; use rand::{distributions::Alphanumeric, Rng}; @@ -25,6 +25,14 @@ type Config = (ClientConfig, Eth2Config); pub fn get_configs(cli_args: &ArgMatches, log: &Logger) -> Result { let mut builder = ConfigBuilder::new(cli_args, log)?; + if let Some(server) = cli_args.value_of("eth1-server") { + builder.set_eth1_backend_method(Eth1BackendMethod::Web3 { + server: server.into(), + }) + } else { + builder.set_eth1_backend_method(Eth1BackendMethod::Interop) + } + match cli_args.subcommand() { ("testnet", Some(sub_cmd_args)) => { process_testnet_subcommand(&mut builder, sub_cmd_args, log)? @@ -288,6 +296,11 @@ impl<'a> ConfigBuilder<'a> { self.client_config.beacon_chain_start_method = method; } + /// Sets the method for starting the beacon chain. + pub fn set_eth1_backend_method(&mut self, method: Eth1BackendMethod) { + self.client_config.eth1_backend_method = method; + } + /// Import the libp2p address for `server` into the list of bootnodes in `self`. /// /// If `port` is `Some`, it is used as the port for the `Multiaddr`. If `port` is `None`, diff --git a/beacon_node/src/main.rs b/beacon_node/src/main.rs index b914be549..fab75ea4e 100644 --- a/beacon_node/src/main.rs +++ b/beacon_node/src/main.rs @@ -162,6 +162,16 @@ fn main() { .takes_value(true), ) + /* + * Eth1 Integration + */ + .arg( + Arg::with_name("eth1-server") + .long("eth1-server") + .value_name("SERVER") + .help("Specifies the server for a web3 connection to the Eth1 chain.") + .takes_value(true) + ) /* * Database parameters. */ diff --git a/beacon_node/src/run.rs b/beacon_node/src/run.rs index 26225cc92..d036ef0c4 100644 --- a/beacon_node/src/run.rs +++ b/beacon_node/src/run.rs @@ -1,4 +1,7 @@ -use client::{error, notifier, BeaconChainTypes, Client, ClientConfig, ClientType, Eth2Config}; +use client::{ + error, notifier, BeaconChainTypes, Client, ClientConfig, ClientType, Eth1BackendMethod, + Eth2Config, +}; use futures::sync::oneshot; use futures::Future; use slog::{error, info}; @@ -47,55 +50,30 @@ pub fn run_beacon_node( "spec_constants" => &spec_constants, ); + macro_rules! run_client { + ($store: ty, $eth_spec: ty) => { + run::>( + &db_path, + client_config, + eth2_config, + executor, + runtime, + log, + ) + }; + } + + if let Eth1BackendMethod::Web3 { .. } = client_config.eth1_backend_method { + return Err("Starting from web3 backend is not supported for interop.".into()); + } + match (db_type.as_str(), spec_constants.as_str()) { - ("disk", "minimal") => run::>( - &db_path, - client_config, - eth2_config, - executor, - runtime, - log, - ), - ("memory", "minimal") => run::>( - &db_path, - client_config, - eth2_config, - executor, - runtime, - log, - ), - ("disk", "mainnet") => run::>( - &db_path, - client_config, - eth2_config, - executor, - runtime, - log, - ), - ("memory", "mainnet") => run::>( - &db_path, - client_config, - eth2_config, - executor, - runtime, - log, - ), - ("disk", "interop") => run::>( - &db_path, - client_config, - eth2_config, - executor, - runtime, - log, - ), - ("memory", "interop") => run::>( - &db_path, - client_config, - eth2_config, - executor, - runtime, - log, - ), + ("disk", "minimal") => run_client!(DiskStore, MinimalEthSpec), + ("disk", "mainnet") => run_client!(DiskStore, MainnetEthSpec), + ("disk", "interop") => run_client!(DiskStore, InteropEthSpec), + ("memory", "minimal") => run_client!(MemoryStore, MinimalEthSpec), + ("memory", "mainnet") => run_client!(MemoryStore, MainnetEthSpec), + ("memory", "interop") => run_client!(MemoryStore, InteropEthSpec), (db_type, spec) => { error!(log, "Unknown runtime configuration"; "spec_constants" => spec, "db_type" => db_type); Err("Unknown specification and/or db_type.".into())