diff --git a/beacon_node/Cargo.toml b/beacon_node/Cargo.toml index 3107068d9..47abb6c6d 100644 --- a/beacon_node/Cargo.toml +++ b/beacon_node/Cargo.toml @@ -10,7 +10,6 @@ types = { path = "../eth2/types" } toml = "^0.5" store = { path = "./store" } client = { path = "client" } -fork_choice = { path = "../eth2/fork_choice" } version = { path = "version" } clap = "2.32.0" slog = { version = "^2.2.3" , features = ["max_level_trace", "release_max_level_debug"] } diff --git a/beacon_node/client/src/beacon_chain_types.rs b/beacon_node/client/src/beacon_chain_types.rs index 133ebcc94..c55c04b44 100644 --- a/beacon_node/client/src/beacon_chain_types.rs +++ b/beacon_node/client/src/beacon_chain_types.rs @@ -1,18 +1,14 @@ use beacon_chain::{ - fork_choice::OptimizedLMDGhost, - slot_clock::SystemTimeSlotClock, - store::{DiskStore, MemoryStore, Store}, - BeaconChain, BeaconChainTypes, + fork_choice::OptimizedLMDGhost, slot_clock::SystemTimeSlotClock, store::Store, BeaconChain, + BeaconChainTypes, }; use fork_choice::ForkChoice; use slog::{info, Logger}; use slot_clock::SlotClock; +use std::marker::PhantomData; use std::sync::Arc; use tree_hash::TreeHash; -use types::{ - test_utils::TestingBeaconStateBuilder, BeaconBlock, ChainSpec, EthSpec, Hash256, - MinimalEthSpec, -}; +use types::{test_utils::TestingBeaconStateBuilder, BeaconBlock, ChainSpec, EthSpec, Hash256}; /// The number initial validators when starting the `Minimal`. const TESTNET_VALIDATOR_COUNT: usize = 16; @@ -28,27 +24,19 @@ pub trait InitialiseBeaconChain { } } -/// A testnet-suitable BeaconChainType, using `MemoryStore`. #[derive(Clone)] -pub struct TestnetMemoryBeaconChainTypes; -impl BeaconChainTypes for TestnetMemoryBeaconChainTypes { - type Store = MemoryStore; - type SlotClock = SystemTimeSlotClock; - type ForkChoice = OptimizedLMDGhost; - type EthSpec = MinimalEthSpec; +pub struct ClientType { + _phantom_t: PhantomData, + _phantom_u: PhantomData, } -impl InitialiseBeaconChain for TestnetMemoryBeaconChainTypes {} -/// A testnet-suitable BeaconChainType, using `DiskStore`. -#[derive(Clone)] -pub struct TestnetDiskBeaconChainTypes; -impl BeaconChainTypes for TestnetDiskBeaconChainTypes { - type Store = DiskStore; +impl BeaconChainTypes for ClientType { + type Store = S; type SlotClock = SystemTimeSlotClock; - type ForkChoice = OptimizedLMDGhost; - type EthSpec = MinimalEthSpec; + type ForkChoice = OptimizedLMDGhost; + type EthSpec = E; } -impl InitialiseBeaconChain for TestnetDiskBeaconChainTypes {} +impl InitialiseBeaconChain for ClientType {} /// Loads a `BeaconChain` from `store`, if it exists. Otherwise, create a new chain from genesis. fn maybe_load_from_store_for_testnet( diff --git a/beacon_node/client/src/lib.rs b/beacon_node/client/src/lib.rs index ae28858c5..c4e1c2558 100644 --- a/beacon_node/client/src/lib.rs +++ b/beacon_node/client/src/lib.rs @@ -19,8 +19,8 @@ use tokio::runtime::TaskExecutor; use tokio::timer::Interval; pub use beacon_chain::BeaconChainTypes; +pub use beacon_chain_types::ClientType; pub use beacon_chain_types::InitialiseBeaconChain; -pub use beacon_chain_types::{TestnetDiskBeaconChainTypes, TestnetMemoryBeaconChainTypes}; pub use client_config::ClientConfig; /// Main beacon node client service. This provides the connection and initialisation of the clients diff --git a/beacon_node/rpc/src/lib.rs b/beacon_node/rpc/src/lib.rs index f2f1b2abf..11de6eb6a 100644 --- a/beacon_node/rpc/src/lib.rs +++ b/beacon_node/rpc/src/lib.rs @@ -27,7 +27,8 @@ pub fn start_server( network_chan: crossbeam_channel::Sender, beacon_chain: Arc>, log: &slog::Logger, -) -> exit_future::Signal { +) -> exit_future::Signal +{ let log = log.new(o!("Service"=>"RPC")); let env = Arc::new(Environment::new(1)); diff --git a/beacon_node/src/run.rs b/beacon_node/src/run.rs index 0638e9ec9..4e2ea0876 100644 --- a/beacon_node/src/run.rs +++ b/beacon_node/src/run.rs @@ -1,10 +1,9 @@ use client::{ - error, notifier, BeaconChainTypes, Client, ClientConfig, InitialiseBeaconChain, - TestnetDiskBeaconChainTypes, TestnetMemoryBeaconChainTypes, + error, notifier, BeaconChainTypes, Client, ClientConfig, ClientType, InitialiseBeaconChain, }; use futures::sync::oneshot; use futures::Future; -use slog::{error, info}; +use slog::{warn, error, info}; use std::cell::RefCell; use std::path::Path; use std::path::PathBuf; @@ -13,6 +12,7 @@ use tokio::runtime::Builder; use tokio::runtime::Runtime; use tokio::runtime::TaskExecutor; use tokio_timer::clock::Clock; +use types::{MainnetEthSpec, MinimalEthSpec}; pub fn run_beacon_node(config: ClientConfig, log: &slog::Logger) -> error::Result<()> { let runtime = Builder::new() @@ -27,16 +27,22 @@ pub fn run_beacon_node(config: ClientConfig, log: &slog::Logger) -> error::Resul .db_path() .ok_or_else::(|| "Unable to access database path".into())?; let db_type = &config.db_type; - let spec_constants = &config.spec_constants; + let spec_constants = config.spec_constants.clone(); let other_config = config.clone(); let result = match (db_type.as_str(), spec_constants.as_str()) { - ("disk", "testnet") => { - run::(&db_path, config, executor, runtime, log) + ("disk", "minimal") => { + run::>(&db_path, config, executor, runtime, log) } - ("memory", "testnet") => { - run::(&db_path, config, executor, runtime, log) + ("memory", "minimal") => { + run::>(&db_path, config, executor, runtime, log) + } + ("disk", "mainnet") => { + run::>(&db_path, config, executor, runtime, log) + } + ("memory", "mainnet") => { + run::>(&db_path, config, executor, runtime, log) } (db_type, spec) => { error!(log, "Unknown runtime configuration"; "spec" => spec, "db_type" => db_type); @@ -53,6 +59,23 @@ pub fn run_beacon_node(config: ClientConfig, log: &slog::Logger) -> error::Resul "spec_constants" => &other_config.spec_constants, "db_type" => &other_config.db_type, ); + + // `SHUFFLE_ROUND_COUNT == 10` in minimal, this is not considered safe. + if spec_constants.as_str() == "minimal" { + warn!( + log, + "The minimal specification does not use cryptographically secure committee selection." + ) + } + + // Mainnet is not really complete, it still generates determinitic, unsafe initial + // validators. + if spec_constants.as_str() == "mainnet" { + warn!( + log, + "The mainnet specification uses unsafe validator keypairs." + ) + } } result @@ -66,7 +89,7 @@ pub fn run( log: &slog::Logger, ) -> error::Result<()> where - T: BeaconChainTypes + InitialiseBeaconChain + Send + Sync + 'static + Clone, + T: BeaconChainTypes + InitialiseBeaconChain + Clone + Send + Sync + 'static, T::Store: OpenDatabase, { let store = T::Store::open_database(&db_path)?; diff --git a/beacon_node/store/src/leveldb_store.rs b/beacon_node/store/src/leveldb_store.rs index 09aec46fa..699861e3a 100644 --- a/beacon_node/store/src/leveldb_store.rs +++ b/beacon_node/store/src/leveldb_store.rs @@ -5,10 +5,14 @@ use leveldb::database::Database; use leveldb::error::Error as LevelDBError; use leveldb::options::{Options, ReadOptions, WriteOptions}; use std::path::Path; +use std::sync::Arc; /// A wrapped leveldb database. +#[derive(Clone)] pub struct LevelDB { - db: Database, + // Note: this `Arc` is only included because of an artificial constraint by gRPC. Hopefully we + // can remove this one day. + db: Arc>, } impl LevelDB { @@ -18,7 +22,7 @@ impl LevelDB { options.create_if_missing = true; - let db = Database::open(path, options)?; + let db = Arc::new(Database::open(path, options)?); Ok(Self { db }) } diff --git a/beacon_node/store/src/memory_store.rs b/beacon_node/store/src/memory_store.rs index 086a16c26..048c054f5 100644 --- a/beacon_node/store/src/memory_store.rs +++ b/beacon_node/store/src/memory_store.rs @@ -1,19 +1,23 @@ use super::{Error, Store}; use parking_lot::RwLock; use std::collections::HashMap; +use std::sync::Arc; type DBHashMap = HashMap, Vec>; /// A thread-safe `HashMap` wrapper. +#[derive(Clone)] pub struct MemoryStore { - db: RwLock, + // Note: this `Arc` is only included because of an artificial constraint by gRPC. Hopefully we + // can remove this one day. + db: Arc>, } impl MemoryStore { /// Create a new, empty database. pub fn open() -> Self { Self { - db: RwLock::new(HashMap::new()), + db: Arc::new(RwLock::new(HashMap::new())), } }