Implement the basic structure of the beacon node.

This commit is contained in:
Age Manning
2019-03-01 12:45:01 +11:00
parent 19a64f906e
commit 2e020a3efa
14 changed files with 188 additions and 56 deletions

View File

@@ -0,0 +1,83 @@
use clap::ArgMatches;
use db::DBType;
use fork_choice::ForkChoiceAlgorithm;
use network::NetworkConfiguration;
use slog::error;
use std::fs;
use std::net::IpAddr;
use std::path::PathBuf;
use types::ChainSpec;
/// Stores the client configuration for this Lighthouse instance.
#[derive(Debug, Clone)]
pub struct ClientConfig {
pub data_dir: PathBuf,
pub spec: ChainSpec,
pub net_conf: network::NetworkConfiguration,
pub fork_choice: ForkChoiceAlgorithm,
pub db_type: DBType,
pub db_name: PathBuf,
//pub rpc_conf:
//pub ipc_conf:
}
impl Default for ClientConfig {
/// Build a new lighthouse configuration from defaults.
fn default() -> Self {
let data_dir = {
let home = dirs::home_dir().expect("Unable to determine home dir.");
home.join(".lighthouse/")
};
fs::create_dir_all(&data_dir)
.unwrap_or_else(|_| panic!("Unable to create {:?}", &data_dir));
Self {
data_dir: data_dir.clone(),
// default to foundation for chain specs
spec: ChainSpec::foundation(),
net_conf: NetworkConfiguration::default(),
// default to bitwise LMD Ghost
fork_choice: ForkChoiceAlgorithm::BitwiseLMDGhost,
// default to memory db for now
db_type: DBType::Memory,
// default db name for disk-based dbs
db_name: data_dir.join("chain.db"),
}
}
}
impl ClientConfig {
/// Parses the CLI arguments into a `Config` struct.
pub fn parse_args(args: ArgMatches, log: &slog::Logger) -> Result<Self, &'static str> {
let mut config = ClientConfig::default();
// Network related args
// Custom listening address ipv4/ipv6
if let Some(listen_address_str) = args.value_of("listen_address") {
if let Ok(listen_address) = listen_address_str.parse::<IpAddr>() {
config.net_conf.listen_address = Some(listen_address);
} else {
error!(log, "Invalid Ip Address"; "Address" => listen_address_str);
return Err("Invalid Ip Address");
}
}
// Custom p2p listen port
if let Some(port_str) = args.value_of("port") {
if let Ok(port) = port_str.parse::<u16>() {
config.net_conf.listen_port = Some(port);
} else {
error!(log, "Invalid port"; "port" => port_str);
return Err("Invalid port");
}
}
// filesystem args
// Custom datadir
if let Some(dir) = args.value_of("datadir") {
config.data_dir = PathBuf::from(dir.to_string());
};
Ok(config)
}
}

View File

@@ -0,0 +1,25 @@
use db::{ClientDB, DiskDB, MemoryDB};
use fork_choice::{BitwiseLMDGhost, ForkChoice};
use slot_clock::{SlotClock, SystemTimeSlotClock, TestingSlotClock};
pub trait ClientTypes {
type ForkChoice: ForkChoice;
type DB: ClientDB;
type SlotClock: SlotClock;
}
pub struct StandardClientType {}
impl ClientTypes for StandardClientType {
type DB = DiskDB;
type ForkChoice = BitwiseLMDGhost<DiskDB>;
type SlotClock = SystemTimeSlotClock;
}
pub struct TestingClientType {}
impl ClientTypes for TestingClientType {
type DB = MemoryDB;
type SlotClock = TestingSlotClock;
type ForkChoice = BitwiseLMDGhost<MemoryDB>;
}

View File

@@ -0,0 +1,8 @@
// generates error types
use error_chain::{
error_chain, error_chain_processing, impl_error_chain_kind, impl_error_chain_processed,
impl_extract_backtrace,
};
error_chain! {}

View File

@@ -0,0 +1,50 @@
extern crate slog;
mod client_config;
pub mod client_types;
pub mod error;
pub mod notifier;
pub use client_config::ClientConfig;
pub use client_types::ClientTypes;
//use beacon_chain::BeaconChain;
use exit_future::{Exit, Signal};
use std::marker::PhantomData;
//use std::sync::Arc;
use tokio::runtime::TaskExecutor;
//use network::NetworkService;
pub struct Client<T: ClientTypes> {
config: ClientConfig,
// beacon_chain: Arc<BeaconChain<T, U, F>>,
// network: Option<Arc<NetworkService>>,
exit: exit_future::Exit,
exit_signal: Option<Signal>,
log: slog::Logger,
phantom: PhantomData<T>,
}
impl<T: ClientTypes> Client<T> {
pub fn new(
config: ClientConfig,
log: slog::Logger,
executor: TaskExecutor,
) -> error::Result<Self> {
let (exit_signal, exit) = exit_future::signal();
Ok(Client {
config,
exit,
exit_signal: Some(exit_signal),
log,
phantom: PhantomData,
})
}
pub fn logger(&self) -> slog::Logger {
self.log.clone()
}
}

View File

@@ -0,0 +1,35 @@
use crate::Client;
use crate::ClientTypes;
use db::ClientDB;
use exit_future::Exit;
use fork_choice::ForkChoice;
use futures::{Future, Stream};
use slog::{debug, info};
use slot_clock::SlotClock;
use std::sync::Arc;
use std::time::{Duration, Instant};
use tokio::runtime::TaskExecutor;
use tokio::timer::Interval;
/// Thread that monitors the client and reports useful statistics to the user.
pub fn run<T: ClientTypes>(client: &Client<T>, executor: TaskExecutor, exit: Exit) {
// notification heartbeat
let interval = Interval::new(Instant::now(), Duration::from_secs(5));
let log = client.logger();
// build heartbeat logic here
let heartbeat = move |_| {
info!(log, "Temp heartbeat output");
Ok(())
};
// map error and spawn
let log = client.logger();
let heartbeat_interval = interval
.map_err(move |e| debug!(log, "Timer error {}", e))
.for_each(heartbeat);
executor.spawn(exit.until(heartbeat_interval).map(|_| ()));
}