Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beacon Node Syncing, Network Infrastructure and Core Services #286

Merged
merged 58 commits into from
Mar 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
19a64f9
Initial beacon node setup.
AgeManning Feb 27, 2019
2e020a3
Implement the basic structure of the beacon node.
AgeManning Mar 1, 2019
3b8f29a
[Temp Commit] Implements more basic skeleton code.
AgeManning Mar 4, 2019
b68adc1
Implement skeleton network/sync framework.
AgeManning Mar 4, 2019
ac639c6
Add libp2p transport - tcp/ws/secio and multiplexing.
AgeManning Mar 6, 2019
e8e4c4a
Adds basic structure for swarm behaviour and topology.
AgeManning Mar 7, 2019
9f13731
Implements a basic libp2p tcp,secio,mplex,gossipsub swarm.
AgeManning Mar 7, 2019
3c51769
Node listens on default port and connects to bootnodes.
AgeManning Mar 8, 2019
c5a7c62
Updates to latest master.
AgeManning Mar 8, 2019
2103233
Adds bootnodes to chainspec. Handles type correctly
AgeManning Mar 8, 2019
ae983a9
Basic networking service with channel
AgeManning Mar 12, 2019
8ee3523
Transition to secp256k1 default peer id
AgeManning Mar 13, 2019
23a8fbf
Add default topics and initial topic subscription
AgeManning Mar 13, 2019
c06e8ff
Initial Libp2p RPC implementation.
AgeManning Mar 14, 2019
24c7f18
Update rpc event handling.
AgeManning Mar 14, 2019
7b6a653
Add RPC protocol to lh network behaviour.
AgeManning Mar 14, 2019
2871ad5
Correct listening addresses and associated log
AgeManning Mar 17, 2019
7370306
Rename RPC reqeusts, correct RPC internals
AgeManning Mar 17, 2019
9803ab3
Propagate RPC through network service.
AgeManning Mar 17, 2019
2e0c8e2
Handle peer dials and propagate to message handler
AgeManning Mar 17, 2019
bbad4bf
Starts initialisation of beacon chain in the client
AgeManning Mar 18, 2019
6b5debe
Organize beacon_chain typing
AgeManning Mar 18, 2019
2d52d29
Modify testnet spec to have few validators
AgeManning Mar 18, 2019
66f09e1
Updates network branch to v0.5.0
AgeManning Mar 18, 2019
6a89da4
Cleanup network shutdown messages
AgeManning Mar 18, 2019
be712f5
Add network id to chainspec
AgeManning Mar 18, 2019
0625bb6
Add network channel into message handler
AgeManning Mar 18, 2019
8ec0688
Implements RPC call functionality
AgeManning Mar 18, 2019
41abdb7
Remove sync crate, move into network crate
AgeManning Mar 18, 2019
dfdec78
Implements hello generation in sync module
AgeManning Mar 18, 2019
495348f
Adds RPC request send framework in message handler
AgeManning Mar 19, 2019
31333e8
Add send rpc in message handler
AgeManning Mar 19, 2019
2657dc1
Builds RPC infrastructure to handle RPC responses
AgeManning Mar 19, 2019
67c0902
Initial handling RPC responses
AgeManning Mar 19, 2019
5ae8079
Basic node handshake
AgeManning Mar 19, 2019
752c784
Initial handling of RPC HELLO requests
AgeManning Mar 19, 2019
c0bc45f
Implement node connection validation structure
AgeManning Mar 19, 2019
6e10ce9
Tidy message handler
AgeManning Mar 19, 2019
b30d725
Add logger to sync module
AgeManning Mar 19, 2019
0a8b006
Add peer validation and successful handshake
AgeManning Mar 19, 2019
dc014d0
Enable syncing state when new peer connects
AgeManning Mar 19, 2019
e7f8711
Tidy networking crates
AgeManning Mar 19, 2019
4b57d32
Apply clippy suggestions
AgeManning Mar 19, 2019
d2f12b7
Add standard RPC service
AgeManning Mar 19, 2019
037c3b8
Update config and cli for rpc
AgeManning Mar 19, 2019
4be2eeb
Correct cli rpc parameters
AgeManning Mar 19, 2019
d229bc9
Stub possible fields in HandlerMessage
AgeManning Mar 19, 2019
0e8b174
Implement Goodbye libp2p rpc request
AgeManning Mar 19, 2019
8acfb26
Implement RequestBeaconBlockRoots RPC method
AgeManning Mar 19, 2019
450b2cf
Rename RequestBeaconBlockRoots to BeaconBlockRoots for consistency
AgeManning Mar 19, 2019
8fa70f6
Implement BeaconBlockHeaders RPC method
AgeManning Mar 19, 2019
fd04431
Implement BeaconBlockBody RPC method
AgeManning Mar 19, 2019
ae1a7a2
Implement BeaconChainState RPC method
AgeManning Mar 19, 2019
9db36f1
Tidy RPC Methods
AgeManning Mar 19, 2019
4105b86
Fix all matches relating to new RPC methods
AgeManning Mar 19, 2019
4310f35
Merge branch 'master' into network-server
AgeManning Mar 20, 2019
7c7f81d
Fix issue with merging v0.5.0
AgeManning Mar 20, 2019
e080f63
Rename libp2p to eth2-libp2p
AgeManning Mar 20, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ members = [
"eth2/utils/test_random_derive",
"beacon_node",
"beacon_node/db",
"beacon_node/client",
"beacon_node/network",
"beacon_node/eth2-libp2p",
"beacon_node/rpc",
"beacon_node/version",
"beacon_node/beacon_chain",
"beacon_node/beacon_chain/test_harness",
"protos",
Expand Down
22 changes: 8 additions & 14 deletions beacon_node/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
[package]
name = "beacon_node"
version = "0.1.0"
authors = ["Paul Hauner <paul@paulhauner.com>"]
authors = ["Paul Hauner <paul@paulhauner.com>", "Age Manning <Age@AgeManning.com"]
edition = "2018"

[dependencies]
bls = { path = "../eth2/utils/bls" }
beacon_chain = { path = "beacon_chain" }
grpcio = { version = "0.4", default-features = false, features = ["protobuf-codec"] }
protobuf = "2.0.2"
protos = { path = "../protos" }
types = { path = "../eth2/types" }
client = { path = "client" }
version = { path = "version" }
clap = "2.32.0"
db = { path = "db" }
dirs = "1.0.3"
futures = "0.1.23"
fork_choice = { path = "../eth2/fork_choice" }
slog = "^2.2.3"
slot_clock = { path = "../eth2/utils/slot_clock" }
slog-term = "^2.4.0"
slog-async = "^2.3.0"
ctrlc = { version = "3.1.1", features = ["termination"] }
tokio = "0.1.15"
futures = "0.1.25"
exit-future = "0.1.3"
state_processing = { path = "../eth2/state_processing" }
types = { path = "../eth2/types" }
ssz = { path = "../eth2/utils/ssz" }
tokio = "0.1"
2 changes: 1 addition & 1 deletion beacon_node/beacon_chain/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "beacon_chain"
version = "0.1.0"
authors = ["Paul Hauner <paul@paulhauner.com>"]
authors = ["Paul Hauner <paul@paulhauner.com>", "Age Manning <Age@AgeManning.com>"]
edition = "2018"

[dependencies]
Expand Down
94 changes: 94 additions & 0 deletions beacon_node/beacon_chain/src/initialise.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Initialisation functions to generate a new BeaconChain.
// Note: A new version of ClientTypes may need to be implemented for the lighthouse
// testnet. These are examples. Also. there is code duplication which can/should be cleaned up.

use crate::BeaconChain;
use db::stores::{BeaconBlockStore, BeaconStateStore};
use db::{DiskDB, MemoryDB};
use fork_choice::BitwiseLMDGhost;
use slot_clock::SystemTimeSlotClock;
use ssz::TreeHash;
use std::path::PathBuf;
use std::sync::Arc;
use types::test_utils::TestingBeaconStateBuilder;
use types::{BeaconBlock, ChainSpec, Hash256};

//TODO: Correct this for prod
//TODO: Account for historical db
pub fn initialise_beacon_chain(
spec: &ChainSpec,
db_name: Option<&PathBuf>,
) -> Arc<BeaconChain<DiskDB, SystemTimeSlotClock, BitwiseLMDGhost<DiskDB>>> {
// set up the db
let db = Arc::new(DiskDB::open(
db_name.expect("Database directory must be included"),
None,
));

let block_store = Arc::new(BeaconBlockStore::new(db.clone()));
let state_store = Arc::new(BeaconStateStore::new(db.clone()));

let state_builder = TestingBeaconStateBuilder::from_deterministic_keypairs(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(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"),
)
}

/// Initialisation of a test beacon chain, uses an in memory db with fixed genesis time.
pub fn initialise_test_beacon_chain(
spec: &ChainSpec,
_db_name: Option<&PathBuf>,
) -> Arc<BeaconChain<MemoryDB, SystemTimeSlotClock, BitwiseLMDGhost<MemoryDB>>> {
let db = Arc::new(MemoryDB::open());
let block_store = Arc::new(BeaconBlockStore::new(db.clone()));
let state_store = Arc::new(BeaconStateStore::new(db.clone()));

let state_builder = TestingBeaconStateBuilder::from_deterministic_keypairs(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(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"),
)
}
7 changes: 6 additions & 1 deletion beacon_node/beacon_chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ mod attestation_aggregator;
mod beacon_chain;
mod checkpoint;
mod errors;
pub mod initialise;

pub use self::beacon_chain::{BeaconChain, BlockProcessingOutcome, InvalidBlock, ValidBlock};
pub use self::checkpoint::CheckPoint;
pub use self::errors::BeaconChainError;
pub use fork_choice::{ForkChoice, ForkChoiceAlgorithm, ForkChoiceError};
pub use db;
pub use fork_choice;
pub use parking_lot;
pub use slot_clock;
pub use types;
21 changes: 21 additions & 0 deletions beacon_node/client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "client"
version = "0.1.0"
authors = ["Age Manning <Age@AgeManning.com>"]
edition = "2018"

[dependencies]
beacon_chain = { path = "../beacon_chain" }
network = { path = "../network" }
db = { path = "../db" }
rpc = { path = "../rpc" }
fork_choice = { path = "../../eth2/fork_choice" }
types = { path = "../../eth2/types" }
slot_clock = { path = "../../eth2/utils/slot_clock" }
error-chain = "0.12.0"
slog = "^2.2.3"
tokio = "0.1.15"
clap = "2.32.0"
dirs = "1.0.3"
exit-future = "0.1.3"
futures = "0.1.25"
124 changes: 124 additions & 0 deletions beacon_node/client/src/client_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
use clap::ArgMatches;
use db::DBType;
use fork_choice::ForkChoiceAlgorithm;
use network::NetworkConfig;
use slog::error;
use std::fs;
use std::net::SocketAddr;
use std::net::{IpAddr, Ipv4Addr};
use std::path::PathBuf;
use types::multiaddr::Protocol;
use types::multiaddr::ToMultiaddr;
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::NetworkConfig,
pub fork_choice: ForkChoiceAlgorithm,
pub db_type: DBType,
pub db_name: PathBuf,
pub rpc_conf: rpc::RPCConfig,
//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));

let default_spec = ChainSpec::lighthouse_testnet();
let default_net_conf = NetworkConfig::new(default_spec.boot_nodes.clone());

Self {
data_dir: data_dir.clone(),
// default to foundation for chain specs
spec: default_spec,
net_conf: default_net_conf,
// 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"),
rpc_conf: rpc::RPCConfig::default(),
}
}
}

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 arguments */

// 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 = port;
// update the listening multiaddrs
for address in &mut config.net_conf.listen_addresses {
address.pop();
address.append(Protocol::Tcp(port));
}
} else {
error!(log, "Invalid port"; "port" => port_str);
return Err("Invalid port");
}
}
// 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::<IpAddr>() {
let multiaddr = SocketAddr::new(listen_address, config.net_conf.listen_port)
.to_multiaddr()
.expect("Invalid listen address format");
config.net_conf.listen_addresses = vec![multiaddr];
} else {
error!(log, "Invalid IP Address"; "Address" => listen_address_str);
return Err("Invalid IP Address");
}
}

/* Filesystem related arguments */

// Custom datadir
if let Some(dir) = args.value_of("datadir") {
config.data_dir = PathBuf::from(dir.to_string());
};

/* RPC related arguments */

if args.is_present("rpc") {
config.rpc_conf.enabled = true;
}

if let Some(rpc_address) = args.value_of("rpc-address") {
if let Ok(listen_address) = rpc_address.parse::<Ipv4Addr>() {
config.rpc_conf.listen_address = listen_address;
} else {
error!(log, "Invalid RPC listen address"; "Address" => rpc_address);
return Err("Invalid RPC listen address");
}
}

if let Some(rpc_port) = args.value_of("rpc-port") {
if let Ok(port) = rpc_port.parse::<u16>() {
config.rpc_conf.port = port;
} else {
error!(log, "Invalid RPC port"; "port" => rpc_port);
return Err("Invalid RPC port");
}
}

Ok(config)
}
}
49 changes: 49 additions & 0 deletions beacon_node/client/src/client_types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use crate::ClientConfig;
use beacon_chain::{
db::{ClientDB, DiskDB, MemoryDB},
fork_choice::BitwiseLMDGhost,
initialise,
slot_clock::{SlotClock, SystemTimeSlotClock},
BeaconChain,
};
use fork_choice::ForkChoice;

use std::sync::Arc;

pub trait ClientTypes {
type DB: ClientDB + 'static;
type SlotClock: SlotClock + 'static;
type ForkChoice: ForkChoice + 'static;

fn initialise_beacon_chain(
config: &ClientConfig,
) -> Arc<BeaconChain<Self::DB, Self::SlotClock, Self::ForkChoice>>;
}

pub struct StandardClientType;

impl ClientTypes for StandardClientType {
type DB = DiskDB;
type SlotClock = SystemTimeSlotClock;
type ForkChoice = BitwiseLMDGhost<DiskDB>;

fn initialise_beacon_chain(
config: &ClientConfig,
) -> Arc<BeaconChain<Self::DB, Self::SlotClock, Self::ForkChoice>> {
initialise::initialise_beacon_chain(&config.spec, Some(&config.db_name))
}
}

pub struct TestingClientType;

impl ClientTypes for TestingClientType {
type DB = MemoryDB;
type SlotClock = SystemTimeSlotClock;
type ForkChoice = BitwiseLMDGhost<MemoryDB>;

fn initialise_beacon_chain(
config: &ClientConfig,
) -> Arc<BeaconChain<Self::DB, Self::SlotClock, Self::ForkChoice>> {
initialise::initialise_test_beacon_chain(&config.spec, None)
}
}
14 changes: 14 additions & 0 deletions beacon_node/client/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// generates error types
use network;

use error_chain::{
error_chain, error_chain_processing, impl_error_chain_kind, impl_error_chain_processed,
impl_extract_backtrace,
};

error_chain! {
links {
Network(network::error::Error, network::error::ErrorKind);
}

}
Loading