From 08b1808745a844b30e1bfc0ef58f603f4344b39e Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Sun, 31 Mar 2019 18:57:48 +1100 Subject: [PATCH] Modify runtime to allow memory or disk db DiskDB is not working yet, but we'll get there! --- beacon_node/Cargo.toml | 1 + beacon_node/beacon_chain/src/initialise.rs | 43 +++++++++++++++++++++- beacon_node/client/src/client_config.rs | 6 +++ beacon_node/client/src/client_types.rs | 20 ++++++++-- beacon_node/src/main.rs | 9 +++++ beacon_node/src/run.rs | 41 ++++++++++++++++----- 6 files changed, 107 insertions(+), 13 deletions(-) diff --git a/beacon_node/Cargo.toml b/beacon_node/Cargo.toml index 37d96a497..da31bfa77 100644 --- a/beacon_node/Cargo.toml +++ b/beacon_node/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" [dependencies] types = { path = "../eth2/types" } +db = { path = "./db" } client = { path = "client" } version = { path = "version" } clap = "2.32.0" diff --git a/beacon_node/beacon_chain/src/initialise.rs b/beacon_node/beacon_chain/src/initialise.rs index 0951e06fb..44cef5fe1 100644 --- a/beacon_node/beacon_chain/src/initialise.rs +++ b/beacon_node/beacon_chain/src/initialise.rs @@ -61,7 +61,7 @@ pub fn initialise_beacon_chain( } /// Initialisation of a test beacon chain, uses an in memory db with fixed genesis time. -pub fn initialise_test_beacon_chain( +pub fn initialise_test_beacon_chain_with_memory_db( spec: &ChainSpec, _db_name: Option<&PathBuf>, ) -> Arc>> { @@ -100,3 +100,44 @@ pub fn initialise_test_beacon_chain( .expect("Terminate if beacon chain generation fails"), ) } + +/// Initialisation of a test beacon chain, uses an in memory db with fixed genesis time. +pub fn initialise_test_beacon_chain_with_disk_db( + spec: &ChainSpec, + db_name: Option<&PathBuf>, +) -> Arc>> { + let db = Arc::new(DiskDB::open(db_name.expect("Must have DB path"), None)); + let block_store = Arc::new(BeaconBlockStore::new(db.clone())); + let state_store = Arc::new(BeaconStateStore::new(db.clone())); + + let state_builder = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(8, spec); + let (genesis_state, _keypairs) = state_builder.build(); + + let mut genesis_block = BeaconBlock::empty(spec); + genesis_block.state_root = Hash256::from_slice(&genesis_state.hash_tree_root()); + + // Slot clock + let slot_clock = SystemTimeSlotClock::new( + spec.genesis_slot, + genesis_state.genesis_time, + spec.seconds_per_slot, + ) + .expect("Unable to load SystemTimeSlotClock"); + // Choose the fork choice + let fork_choice = BitwiseLMDGhost::new(block_store.clone(), state_store.clone()); + + // Genesis chain + //TODO: Handle error correctly + Arc::new( + BeaconChain::from_genesis( + state_store.clone(), + block_store.clone(), + slot_clock, + genesis_state, + genesis_block, + spec.clone(), + fork_choice, + ) + .expect("Terminate if beacon chain generation fails"), + ) +} diff --git a/beacon_node/client/src/client_config.rs b/beacon_node/client/src/client_config.rs index cad287f2c..c32379522 100644 --- a/beacon_node/client/src/client_config.rs +++ b/beacon_node/client/src/client_config.rs @@ -119,6 +119,12 @@ impl ClientConfig { } } + match args.value_of("db") { + Some("rocks") => config.db_type = DBType::RocksDB, + Some("memory") => config.db_type = DBType::Memory, + _ => unreachable!(), // clap prevents this. + }; + Ok(config) } } diff --git a/beacon_node/client/src/client_types.rs b/beacon_node/client/src/client_types.rs index f5abc77ce..1d2f1d6ec 100644 --- a/beacon_node/client/src/client_types.rs +++ b/beacon_node/client/src/client_types.rs @@ -34,9 +34,9 @@ impl ClientTypes for StandardClientType { } } -pub struct TestingClientType; +pub struct MemoryDBTestingClientType; -impl ClientTypes for TestingClientType { +impl ClientTypes for MemoryDBTestingClientType { type DB = MemoryDB; type SlotClock = SystemTimeSlotClock; type ForkChoice = BitwiseLMDGhost; @@ -44,6 +44,20 @@ impl ClientTypes for TestingClientType { fn initialise_beacon_chain( config: &ClientConfig, ) -> Arc> { - initialise::initialise_test_beacon_chain(&config.spec, None) + initialise::initialise_test_beacon_chain_with_memory_db(&config.spec, None) + } +} + +pub struct DiskDBTestingClientType; + +impl ClientTypes for DiskDBTestingClientType { + type DB = DiskDB; + type SlotClock = SystemTimeSlotClock; + type ForkChoice = BitwiseLMDGhost; + + fn initialise_beacon_chain( + config: &ClientConfig, + ) -> Arc> { + initialise::initialise_test_beacon_chain_with_disk_db(&config.spec, Some(&config.db_name)) } } diff --git a/beacon_node/src/main.rs b/beacon_node/src/main.rs index ea74c7376..8aa6da7d5 100644 --- a/beacon_node/src/main.rs +++ b/beacon_node/src/main.rs @@ -58,6 +58,15 @@ fn main() { .help("Listen port for RPC endpoint.") .takes_value(true), ) + .arg( + Arg::with_name("db") + .long("db") + .value_name("DB") + .help("Type of database to use.") + .takes_value(true) + .possible_values(&["rocks", "memory"]) + .default_value("memory"), + ) .get_matches(); // invalid arguments, panic diff --git a/beacon_node/src/run.rs b/beacon_node/src/run.rs index 1d9156124..1afeb5408 100644 --- a/beacon_node/src/run.rs +++ b/beacon_node/src/run.rs @@ -1,15 +1,18 @@ -use client::client_types::TestingClientType; +use client::client_types::{DiskDBTestingClientType, MemoryDBTestingClientType}; use client::error; -use client::{notifier, Client, ClientConfig}; +use client::{notifier, Client, ClientConfig, ClientTypes}; +use db::DBType; use futures::sync::oneshot; use futures::Future; use slog::info; use std::cell::RefCell; use tokio::runtime::Builder; +use tokio::runtime::Runtime; +use tokio::runtime::TaskExecutor; use tokio_timer::clock::Clock; pub fn run_beacon_node(config: ClientConfig, log: &slog::Logger) -> error::Result<()> { - let mut runtime = Builder::new() + let runtime = Builder::new() .name_prefix("main-") .clock(Clock::system()) .build() @@ -20,8 +23,32 @@ pub fn run_beacon_node(config: ClientConfig, log: &slog::Logger) -> error::Resul "data_dir" => &config.data_dir.to_str(), "port" => &config.net_conf.listen_port); + let executor = runtime.executor(); + + match config.db_type { + DBType::RocksDB => { + let client: Client = + Client::new(config, log.clone(), &executor)?; + + run(client, executor, runtime, log) + } + DBType::Memory => { + let client: Client = + Client::new(config, log.clone(), &executor)?; + + run(client, executor, runtime, log) + } + } +} + +pub fn run( + client: Client, + executor: TaskExecutor, + mut runtime: Runtime, + log: &slog::Logger, +) -> error::Result<()> { // run service until ctrl-c - let (ctrlc_send, ctrlc) = oneshot::channel(); + let (ctrlc_send, ctrlc_oneshot) = oneshot::channel(); let ctrlc_send_c = RefCell::new(Some(ctrlc_send)); ctrlc::set_handler(move || { if let Some(ctrlc_send) = ctrlc_send_c.try_borrow_mut().unwrap().take() { @@ -32,14 +59,10 @@ pub fn run_beacon_node(config: ClientConfig, log: &slog::Logger) -> error::Resul let (exit_signal, exit) = exit_future::signal(); - let executor = runtime.executor(); - - // currently testing - using TestingClientType - let client: Client = Client::new(config, log.clone(), &executor)?; notifier::run(&client, executor, exit); runtime - .block_on(ctrlc) + .block_on(ctrlc_oneshot) .map_err(|e| format!("Ctrlc oneshot failed: {:?}", e))?; // perform global shutdown operations.