From 3b8f29a9141e337738937c2efe23c496621ed90b Mon Sep 17 00:00:00 2001 From: Age Manning Date: Mon, 4 Mar 2019 16:39:37 +1100 Subject: [PATCH] [Temp Commit] Implements more basic skeleton code. --- beacon_node/beacon_chain/Cargo.toml | 2 +- beacon_node/beacon_chain/src/initialize.rs | 56 +++++++++++++++ beacon_node/client/src/client_config.rs | 13 ++-- beacon_node/client/src/lib.rs | 21 ++++-- beacon_node/client/src/notifier.rs | 2 +- beacon_node/libp2p/Cargo.toml | 7 ++ beacon_node/libp2p/src/lib.rs | 11 +++ beacon_node/libp2p/src/service.rs | 0 beacon_node/network/Cargo.toml | 4 +- beacon_node/network/src/error.rs | 8 +++ beacon_node/network/src/lib.rs | 6 +- beacon_node/network/src/message_handler.rs | 18 +++++ beacon_node/network/src/messages.rs | 27 +++++++ ...ork_configuration.rs => network_config.rs} | 15 ++-- beacon_node/network/src/service.rs | 0 beacon_node/src/run.rs | 1 + beacon_node/sync/Cargo.toml | 3 +- beacon_node/sync/src/lib.rs | 72 ++----------------- beacon_node/sync/src/simple_syncer.rs | 22 ++++++ 19 files changed, 195 insertions(+), 93 deletions(-) create mode 100644 beacon_node/beacon_chain/src/initialize.rs mode change 100755 => 100644 beacon_node/client/src/notifier.rs create mode 100644 beacon_node/libp2p/Cargo.toml create mode 100644 beacon_node/libp2p/src/lib.rs create mode 100644 beacon_node/libp2p/src/service.rs create mode 100644 beacon_node/network/src/error.rs create mode 100644 beacon_node/network/src/message_handler.rs create mode 100644 beacon_node/network/src/messages.rs rename beacon_node/network/src/{network_configuration.rs => network_config.rs} (75%) create mode 100644 beacon_node/network/src/service.rs create mode 100644 beacon_node/sync/src/simple_syncer.rs diff --git a/beacon_node/beacon_chain/Cargo.toml b/beacon_node/beacon_chain/Cargo.toml index 4ce894477d..b5471be5fa 100644 --- a/beacon_node/beacon_chain/Cargo.toml +++ b/beacon_node/beacon_chain/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "beacon_chain" version = "0.1.0" -authors = ["Paul Hauner "] +authors = ["Paul Hauner ", "Age Manning "] edition = "2018" [dependencies] diff --git a/beacon_node/beacon_chain/src/initialize.rs b/beacon_node/beacon_chain/src/initialize.rs new file mode 100644 index 0000000000..14d0f81a67 --- /dev/null +++ b/beacon_node/beacon_chain/src/initialize.rs @@ -0,0 +1,56 @@ +// Initialisation functions to generate a new BeaconChain. + +pub fn initialise_test_chain( + config: &ClientConfig, +) -> Arc> { + let spec = config.spec; + // Slot clock + let genesis_time = 1_549_935_547; // 12th Feb 2018 (arbitrary value in the past). + let slot_clock = SystemTimeSlotClock::new(genesis_time, spec.slot_duration) + .expect("Unable to load SystemTimeSlotClock"); + // Choose the fork choice + let fork_choice = BitwiseLMDGhost::new(block_store.clone(), state_store.clone()); + + /* + * Generate some random data to start a chain with. + * + * This is will need to be replace for production usage. + */ + let latest_eth1_data = Eth1Data { + deposit_root: Hash256::zero(), + block_hash: Hash256::zero(), + }; + let keypairs: Vec = (0..10) + .collect::>() + .iter() + .map(|_| Keypair::random()) + .collect(); + let initial_validator_deposits = keypairs + .iter() + .map(|keypair| Deposit { + branch: vec![], // branch verification is not specified. + index: 0, // index verification is not specified. + deposit_data: DepositData { + amount: 32_000_000_000, // 32 ETH (in Gwei) + timestamp: genesis_time - 1, + deposit_input: DepositInput { + pubkey: keypair.pk.clone(), + withdrawal_credentials: Hash256::zero(), // Withdrawal not possible. + proof_of_possession: create_proof_of_possession(&keypair), + }, + }, + }) + .collect(); + + // Genesis chain + Arc::new(BeaconChain::genesis( + state_store.clone(), + block_store.clone(), + slot_clock, + genesis_time, + latest_eth1_data, + initial_validator_deposits, + spec, + fork_choice, + )); +} diff --git a/beacon_node/client/src/client_config.rs b/beacon_node/client/src/client_config.rs index c1580aa9fe..8943e783d0 100644 --- a/beacon_node/client/src/client_config.rs +++ b/beacon_node/client/src/client_config.rs @@ -1,7 +1,7 @@ use clap::ArgMatches; use db::DBType; use fork_choice::ForkChoiceAlgorithm; -use network::NetworkConfiguration; +use network::NetworkConfig; use slog::error; use std::fs; use std::net::IpAddr; @@ -13,7 +13,7 @@ use types::ChainSpec; pub struct ClientConfig { pub data_dir: PathBuf, pub spec: ChainSpec, - pub net_conf: network::NetworkConfiguration, + pub net_conf: network::NetworkConfig, pub fork_choice: ForkChoiceAlgorithm, pub db_type: DBType, pub db_name: PathBuf, @@ -34,7 +34,7 @@ impl Default for ClientConfig { data_dir: data_dir.clone(), // default to foundation for chain specs spec: ChainSpec::foundation(), - net_conf: NetworkConfiguration::default(), + net_conf: NetworkConfig::default(), // default to bitwise LMD Ghost fork_choice: ForkChoiceAlgorithm::BitwiseLMDGhost, // default to memory db for now @@ -53,12 +53,13 @@ impl ClientConfig { // Network related args // Custom listening address ipv4/ipv6 + // TODO: Handle list of addresses if let Some(listen_address_str) = args.value_of("listen_address") { if let Ok(listen_address) = listen_address_str.parse::() { - config.net_conf.listen_address = Some(listen_address); + config.net_conf.listen_address = Some(Vec::new(listen_address)); } else { - error!(log, "Invalid Ip Address"; "Address" => listen_address_str); - return Err("Invalid Ip Address"); + error!(log, "Invalid IP Address"; "Address" => listen_address_str); + return Err("Invalid IP Address"); } } // Custom p2p listen port diff --git a/beacon_node/client/src/lib.rs b/beacon_node/client/src/lib.rs index 3bfde0e9de..5ea6ba4a67 100644 --- a/beacon_node/client/src/lib.rs +++ b/beacon_node/client/src/lib.rs @@ -13,14 +13,15 @@ pub use client_types::ClientTypes; use exit_future::{Exit, Signal}; use std::marker::PhantomData; //use std::sync::Arc; +use network::NetworkService; use tokio::runtime::TaskExecutor; -//use network::NetworkService; - +/// Main beacon node client service. This provides the connection and initialisation of the clients +/// sub-services in multiple threads. pub struct Client { config: ClientConfig, // beacon_chain: Arc>, - // network: Option>, + network: Option>, exit: exit_future::Exit, exit_signal: Option, log: slog::Logger, @@ -28,6 +29,7 @@ pub struct Client { } impl Client { + /// Generate an instance of the client. Spawn and link all internal subprocesses. pub fn new( config: ClientConfig, log: slog::Logger, @@ -35,16 +37,21 @@ impl Client { ) -> error::Result { let (exit_signal, exit) = exit_future::signal(); + // TODO: generate a beacon_chain service. + + // start the network service, libp2p and syncing threads + // TODO: Add beacon_chain reference to network parameters + let network_config = config.net_config; + let network_logger = client.log.new(o!("Service" => "Network")); + let (network, network_send) = NetworkService::new(network_config, network_logger); + Ok(Client { config, exit, exit_signal: Some(exit_signal), log, + network: Some(network), phantom: PhantomData, }) } - - pub fn logger(&self) -> slog::Logger { - self.log.clone() - } } diff --git a/beacon_node/client/src/notifier.rs b/beacon_node/client/src/notifier.rs old mode 100755 new mode 100644 index 3edf93bf68..68d93e7358 --- a/beacon_node/client/src/notifier.rs +++ b/beacon_node/client/src/notifier.rs @@ -17,7 +17,7 @@ pub fn run(client: &Client, executor: TaskExecutor, exit: Exi // notification heartbeat let interval = Interval::new(Instant::now(), Duration::from_secs(5)); - let log = client.logger(); + let log = client.log.new(o!("Service" => "Notifier")); // build heartbeat logic here let heartbeat = move |_| { diff --git a/beacon_node/libp2p/Cargo.toml b/beacon_node/libp2p/Cargo.toml new file mode 100644 index 0000000000..f35ae4d430 --- /dev/null +++ b/beacon_node/libp2p/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "libp2p" +version = "0.1.0" +authors = ["Age Manning "] +edition = "2018" + +[dependencies] diff --git a/beacon_node/libp2p/src/lib.rs b/beacon_node/libp2p/src/lib.rs new file mode 100644 index 0000000000..e20eb055f8 --- /dev/null +++ b/beacon_node/libp2p/src/lib.rs @@ -0,0 +1,11 @@ +/// This crate contains the main link for lighthouse to rust-libp2p. It therefore re-exports +/// all required libp2p functionality. +/// +/// This crate builds and manages the libp2p services required by the beacon node. +extern crate libp2p; + +mod libp2p_service; + +pub use libp2p::{GossipsubConfig, PeerId}; + +pub use libp2p_service::LibP2PService; diff --git a/beacon_node/libp2p/src/service.rs b/beacon_node/libp2p/src/service.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/beacon_node/network/Cargo.toml b/beacon_node/network/Cargo.toml index 57f75e2739..31fc9eab6c 100644 --- a/beacon_node/network/Cargo.toml +++ b/beacon_node/network/Cargo.toml @@ -5,6 +5,6 @@ authors = ["Age Manning "] edition = "2018" [dependencies] -# SigP repository until PR is merged -libp2p = { git = "https://github.com/SigP/rust-libp2p", branch = "gossipsub" } +libp2p = { git = "../libp2p" } version = { path = "../version" } +types = { path = "../../eth2/types" } diff --git a/beacon_node/network/src/error.rs b/beacon_node/network/src/error.rs new file mode 100644 index 0000000000..163fe575d2 --- /dev/null +++ b/beacon_node/network/src/error.rs @@ -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! {} diff --git a/beacon_node/network/src/lib.rs b/beacon_node/network/src/lib.rs index 1dc56ec4fb..3bc555dd66 100644 --- a/beacon_node/network/src/lib.rs +++ b/beacon_node/network/src/lib.rs @@ -1,4 +1,6 @@ /// This crate provides the network server for Lighthouse. -mod network_configuration; +mod network_config; +mod service; -pub use network_configuration::NetworkConfiguration; +pub use network_config::NetworkConfig; +pub use service::NetworkService; diff --git a/beacon_node/network/src/message_handler.rs b/beacon_node/network/src/message_handler.rs new file mode 100644 index 0000000000..66a7b58159 --- /dev/null +++ b/beacon_node/network/src/message_handler.rs @@ -0,0 +1,18 @@ +use crate::node_message::NodeMessage; + +/// Handles messages received from the network and client and organises syncing. +pub struct MessageHandler { + sync: Syncer, + //TODO: Implement beacon chain + //chain: BeaconChain +} + +/// Types of messages the handler can receive. +pub enum HandlerMessage { + /// Peer has connected. + PeerConnected(PeerId), + /// Peer has disconnected, + PeerDisconnected(PeerId), + /// A Node message has been received. + Message(Peer, NodeMessage), +} diff --git a/beacon_node/network/src/messages.rs b/beacon_node/network/src/messages.rs new file mode 100644 index 0000000000..5f9a666e06 --- /dev/null +++ b/beacon_node/network/src/messages.rs @@ -0,0 +1,27 @@ +use types::{H256,Slot} + +/// Messages between nodes across the network. +pub enum NodeMessage { + + Status(Status), + BlockRequest, +} + +pub struct Status { + /// Current node version. + version: u8 + /// Genesis Hash. + genesis_hash: H256 + /// Best known slot number. + best_slot: Slot + /// Best known slot hash. + best_slot_hash: H256 +} + +/// Types of messages that the network service can receive. +pub enum NetworkMessage { + /// Send a message to libp2p service. + //TODO: Define typing for messages accross the wire + Send(Node, Message), +} + diff --git a/beacon_node/network/src/network_configuration.rs b/beacon_node/network/src/network_config.rs similarity index 75% rename from beacon_node/network/src/network_configuration.rs rename to beacon_node/network/src/network_config.rs index 64d763287b..98347e122b 100644 --- a/beacon_node/network/src/network_configuration.rs +++ b/beacon_node/network/src/network_config.rs @@ -4,10 +4,10 @@ use version; #[derive(Debug, Clone)] /// Network configuration for lighthouse. -pub struct NetworkConfiguration { +pub struct NetworkConfig { //TODO: stubbing networking initial params, change in the future /// IP address to listen on. - pub listen_address: Option, + pub listen_addresses: Option>, /// Listen port UDP/TCP. pub listen_port: Option, /// Gossipsub configuration parameters. @@ -16,14 +16,13 @@ pub struct NetworkConfiguration { pub boot_nodes: Vec, /// Client version pub client_version: String, - //TODO: more to be added } -impl Default for NetworkConfiguration { +impl Default for NetworkConfig { /// Generate a default network configuration. fn default() -> Self { - NetworkConfiguration { - listen_address: None, + NetworkConfig { + listen_addresses: None, listen_port: None, gs_config: GossipsubConfigBuilder::new().build(), boot_nodes: Vec::new(), @@ -32,8 +31,8 @@ impl Default for NetworkConfiguration { } } -impl NetworkConfiguration { +impl NetworkConfig { pub fn new() -> Self { - NetworkConfiguration::default() + NetworkConfig::default() } } diff --git a/beacon_node/network/src/service.rs b/beacon_node/network/src/service.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/beacon_node/src/run.rs b/beacon_node/src/run.rs index 3207ce43de..f2a703cbcf 100644 --- a/beacon_node/src/run.rs +++ b/beacon_node/src/run.rs @@ -37,6 +37,7 @@ pub fn run_beacon_node(config: ClientConfig, log: slog::Logger) -> error::Result runtime.block_on(ctrlc); + // perform global shutdown operations. info!(log, "Shutting down.."); exit_signal.fire(); drop(client); diff --git a/beacon_node/sync/Cargo.toml b/beacon_node/sync/Cargo.toml index 347506bf06..4997cd094b 100644 --- a/beacon_node/sync/Cargo.toml +++ b/beacon_node/sync/Cargo.toml @@ -5,4 +5,5 @@ authors = ["Age Manning "] edition = "2018" [dependencies] - +types = { path = "../../eth2/types" } +libp2p = { git = "../libp2p/" } diff --git a/beacon_node/sync/src/lib.rs b/beacon_node/sync/src/lib.rs index f520e9e094..a901344f51 100644 --- a/beacon_node/sync/src/lib.rs +++ b/beacon_node/sync/src/lib.rs @@ -1,68 +1,10 @@ -// /// Syncing for lighthouse. +/// Syncing for lighthouse. +/// +/// Stores the various syncing methods for the beacon chain. +mod simple_sync; -/* -// for initial testing and setup, to be replaced. -pub fn sync_server(config: Config) { - // Set up database - let db = match config.db_type { - _ => Arc::new(MemoryDB::open()), - //TODO: Box db - //DBType::Memory => Arc::new(Box::new(MemoryDB::open())), - //DBType::RocksDB => Arc::new(Box::new(DiskDB::open(&config.db_name, None))), - }; +pub use crate::SimpleSync; - // build block - let block_store = Arc::new(BeaconBlockStore::new(db.clone())); - let state_store = Arc::new(BeaconStateStore::new(db.clone())); - - // Slot clock - let genesis_time = 1_549_935_547; // 12th Feb 2018 (arbitrary value in the past). - let slot_clock = SystemTimeSlotClock::new(genesis_time, spec.slot_duration) - .expect("Unable to load SystemTimeSlotClock"); - // Choose the fork choice - let fork_choice = BitwiseLMDGhost::new(block_store.clone(), state_store.clone()); - - /* - * Generate some random data to start a chain with. - * - * This is will need to be replace for production usage. - */ -let latest_eth1_data = Eth1Data { -deposit_root: Hash256::zero(), -block_hash: Hash256::zero(), -}; -let keypairs: Vec = (0..10) -.collect::>() -.iter() -.map(|_| Keypair::random()) -.collect(); -let initial_validator_deposits = keypairs -.iter() -.map(|keypair| Deposit { -branch: vec![], // branch verification is not specified. -index: 0, // index verification is not specified. -deposit_data: DepositData { -amount: 32_000_000_000, // 32 ETH (in Gwei) -timestamp: genesis_time - 1, -deposit_input: DepositInput { -pubkey: keypair.pk.clone(), -withdrawal_credentials: Hash256::zero(), // Withdrawal not possible. -proof_of_possession: create_proof_of_possession(&keypair), -}, -}, -}) -.collect(); - -// Genesis chain -let _chain_result = BeaconChain::genesis( -state_store.clone(), -block_store.clone(), -slot_clock, -genesis_time, -latest_eth1_data, -initial_validator_deposits, -spec, -fork_choice, -); +pub enum SyncMethod { + SimpleSync, } -*/ diff --git a/beacon_node/sync/src/simple_syncer.rs b/beacon_node/sync/src/simple_syncer.rs new file mode 100644 index 0000000000..f1d0a52195 --- /dev/null +++ b/beacon_node/sync/src/simple_syncer.rs @@ -0,0 +1,22 @@ +use std::collections::HashMap; +use types::{Slot, H256}; + +/// Keeps track of syncing information for known connected peers. +pub struct PeerSyncInfo { + best_slot: Slot, + best_slot_hash: H256, +} + +/// The current syncing state. +pub enum SyncState { + Idle, + Downloading, + Stopped, +} + +/// Simple Syncing protocol. +pub struct SimpleSync { + genesis_hash: H256, + known_peers: HashMap, + state: SyncState, +}