mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-14 18:32:42 +00:00
Implement the basic structure of the beacon node.
This commit is contained in:
@@ -1,85 +0,0 @@
|
||||
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 core configuration for this Lighthouse instance.
|
||||
/// This struct is general, other components may implement more
|
||||
/// specialized configuration structs.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Config {
|
||||
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 Config {
|
||||
/// 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 Config {
|
||||
/// Parses the CLI arguments into a `Config` struct.
|
||||
pub fn parse_args(args: ArgMatches, log: &slog::Logger) -> Result<Self, &'static str> {
|
||||
let mut config = Config::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)
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
// generates error types
|
||||
|
||||
use error_chain::{
|
||||
error_chain, error_chain_processing, impl_error_chain_kind, impl_error_chain_processed,
|
||||
impl_extract_backtrace,
|
||||
};
|
||||
|
||||
error_chain! {}
|
||||
@@ -1,12 +1,9 @@
|
||||
extern crate slog;
|
||||
|
||||
mod config;
|
||||
mod error;
|
||||
mod rpc;
|
||||
mod run;
|
||||
|
||||
use clap::{App, Arg};
|
||||
use config::Config;
|
||||
use client::ClientConfig;
|
||||
use slog::{o, Drain};
|
||||
|
||||
fn main() {
|
||||
@@ -43,7 +40,7 @@ fn main() {
|
||||
.get_matches();
|
||||
|
||||
// invalid arguments, panic
|
||||
let config = Config::parse_args(matches, &logger).unwrap();
|
||||
let config = ClientConfig::parse_args(matches, &logger).unwrap();
|
||||
|
||||
run::run_beacon_node(config, &logger);
|
||||
run::run_beacon_node(config, logger);
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
use futures::Future;
|
||||
use grpcio::{RpcContext, UnarySink};
|
||||
use protos::services::{
|
||||
BeaconBlock as BeaconBlockProto, ProduceBeaconBlockRequest, ProduceBeaconBlockResponse,
|
||||
PublishBeaconBlockRequest, PublishBeaconBlockResponse,
|
||||
};
|
||||
use protos::services_grpc::BeaconBlockService;
|
||||
use slog::Logger;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BeaconBlockServiceInstance {
|
||||
pub log: Logger,
|
||||
}
|
||||
|
||||
impl BeaconBlockService for BeaconBlockServiceInstance {
|
||||
/// Produce a `BeaconBlock` for signing by a validator.
|
||||
fn produce_beacon_block(
|
||||
&mut self,
|
||||
ctx: RpcContext,
|
||||
req: ProduceBeaconBlockRequest,
|
||||
sink: UnarySink<ProduceBeaconBlockResponse>,
|
||||
) {
|
||||
println!("producing at slot {}", req.get_slot());
|
||||
|
||||
// TODO: build a legit block.
|
||||
let mut block = BeaconBlockProto::new();
|
||||
block.set_slot(req.get_slot());
|
||||
block.set_block_root(b"cats".to_vec());
|
||||
|
||||
let mut resp = ProduceBeaconBlockResponse::new();
|
||||
resp.set_block(block);
|
||||
|
||||
let f = sink
|
||||
.success(resp)
|
||||
.map_err(move |e| println!("failed to reply {:?}: {:?}", req, e));
|
||||
ctx.spawn(f)
|
||||
}
|
||||
|
||||
/// Accept some fully-formed `BeaconBlock`, process and publish it.
|
||||
fn publish_beacon_block(
|
||||
&mut self,
|
||||
ctx: RpcContext,
|
||||
req: PublishBeaconBlockRequest,
|
||||
sink: UnarySink<PublishBeaconBlockResponse>,
|
||||
) {
|
||||
println!("publishing {:?}", req.get_block());
|
||||
|
||||
// TODO: actually process the block.
|
||||
let mut resp = PublishBeaconBlockResponse::new();
|
||||
resp.set_success(true);
|
||||
|
||||
let f = sink
|
||||
.success(resp)
|
||||
.map_err(move |e| println!("failed to reply {:?}: {:?}", req, e));
|
||||
ctx.spawn(f)
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
mod beacon_block;
|
||||
mod validator;
|
||||
|
||||
use self::beacon_block::BeaconBlockServiceInstance;
|
||||
use self::validator::ValidatorServiceInstance;
|
||||
use grpcio::{Environment, Server, ServerBuilder};
|
||||
use protos::services_grpc::{create_beacon_block_service, create_validator_service};
|
||||
use std::sync::Arc;
|
||||
|
||||
use slog::{info, Logger};
|
||||
|
||||
pub fn start_server(log: Logger) -> Server {
|
||||
let log_clone = log.clone();
|
||||
let env = Arc::new(Environment::new(1));
|
||||
|
||||
let beacon_block_service = {
|
||||
let instance = BeaconBlockServiceInstance { log: log.clone() };
|
||||
create_beacon_block_service(instance)
|
||||
};
|
||||
let validator_service = {
|
||||
let instance = ValidatorServiceInstance { log: log.clone() };
|
||||
create_validator_service(instance)
|
||||
};
|
||||
|
||||
let mut server = ServerBuilder::new(env)
|
||||
.register_service(beacon_block_service)
|
||||
.register_service(validator_service)
|
||||
.bind("127.0.0.1", 50_051)
|
||||
.build()
|
||||
.unwrap();
|
||||
server.start();
|
||||
for &(ref host, port) in server.bind_addrs() {
|
||||
info!(log_clone, "gRPC listening on {}:{}", host, port);
|
||||
}
|
||||
server
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
use bls::PublicKey;
|
||||
use futures::Future;
|
||||
use grpcio::{RpcContext, RpcStatus, RpcStatusCode, UnarySink};
|
||||
use protos::services::{
|
||||
IndexResponse, ProposeBlockSlotRequest, ProposeBlockSlotResponse, PublicKey as PublicKeyRequest,
|
||||
};
|
||||
use protos::services_grpc::ValidatorService;
|
||||
use slog::{debug, Logger};
|
||||
use ssz::Decodable;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ValidatorServiceInstance {
|
||||
pub log: Logger,
|
||||
}
|
||||
|
||||
impl ValidatorService for ValidatorServiceInstance {
|
||||
fn validator_index(
|
||||
&mut self,
|
||||
ctx: RpcContext,
|
||||
req: PublicKeyRequest,
|
||||
sink: UnarySink<IndexResponse>,
|
||||
) {
|
||||
if let Ok((public_key, _)) = PublicKey::ssz_decode(req.get_public_key(), 0) {
|
||||
debug!(self.log, "RPC request"; "endpoint" => "ValidatorIndex", "public_key" => public_key.concatenated_hex_id());
|
||||
|
||||
let mut resp = IndexResponse::new();
|
||||
|
||||
// TODO: return a legit value.
|
||||
resp.set_index(1);
|
||||
|
||||
let f = sink
|
||||
.success(resp)
|
||||
.map_err(move |e| println!("failed to reply {:?}: {:?}", req, e));
|
||||
ctx.spawn(f)
|
||||
} else {
|
||||
let f = sink
|
||||
.fail(RpcStatus::new(
|
||||
RpcStatusCode::InvalidArgument,
|
||||
Some("Invalid public_key".to_string()),
|
||||
))
|
||||
.map_err(move |e| println!("failed to reply {:?}: {:?}", req, e));
|
||||
ctx.spawn(f)
|
||||
}
|
||||
}
|
||||
|
||||
fn propose_block_slot(
|
||||
&mut self,
|
||||
ctx: RpcContext,
|
||||
req: ProposeBlockSlotRequest,
|
||||
sink: UnarySink<ProposeBlockSlotResponse>,
|
||||
) {
|
||||
debug!(self.log, "RPC request"; "endpoint" => "ProposeBlockSlot", "epoch" => req.get_epoch(), "validator_index" => req.get_validator_index());
|
||||
|
||||
let mut resp = ProposeBlockSlotResponse::new();
|
||||
|
||||
// TODO: return a legit value.
|
||||
resp.set_slot(1);
|
||||
|
||||
let f = sink
|
||||
.success(resp)
|
||||
.map_err(move |e| println!("failed to reply {:?}: {:?}", req, e));
|
||||
ctx.spawn(f)
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,13 @@
|
||||
use crate::config::Config;
|
||||
use crate::error;
|
||||
use crate::rpc::start_server;
|
||||
use beacon_chain::BeaconChain;
|
||||
use bls::create_proof_of_possession;
|
||||
use db::{
|
||||
stores::{BeaconBlockStore, BeaconStateStore},
|
||||
ClientDB, DBType, DiskDB, MemoryDB,
|
||||
};
|
||||
use fork_choice::{BitwiseLMDGhost, ForkChoiceAlgorithm};
|
||||
use client::client_types::{StandardClientType, TestingClientType};
|
||||
use client::error;
|
||||
use client::{notifier, Client, ClientConfig};
|
||||
use futures::sync::oneshot;
|
||||
use network::NetworkConfiguration;
|
||||
use slog::{error, info};
|
||||
use slot_clock::SystemTimeSlotClock;
|
||||
use futures::Future;
|
||||
use slog::info;
|
||||
use std::cell::RefCell;
|
||||
use std::sync::Arc;
|
||||
use tokio::runtime::{Builder, Runtime, TaskExecutor};
|
||||
use types::{ChainSpec, Deposit, DepositData, DepositInput, Eth1Data, Hash256, Keypair};
|
||||
use tokio::runtime::Builder;
|
||||
|
||||
pub fn run_beacon_node(config: Config, log: &slog::Logger) -> error::Result<()> {
|
||||
pub fn run_beacon_node(config: ClientConfig, log: slog::Logger) -> error::Result<()> {
|
||||
let mut runtime = Builder::new()
|
||||
.name_prefix("main-")
|
||||
.build()
|
||||
@@ -33,22 +23,23 @@ pub fn run_beacon_node(config: Config, log: &slog::Logger) -> error::Result<()>
|
||||
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() {
|
||||
ctrlc_send
|
||||
.send(())
|
||||
.expect("Error sending termination message");
|
||||
ctrlc_send.send(()).expect("Error sending ctrl-c message");
|
||||
}
|
||||
});
|
||||
|
||||
let (exit_signal, exit) = exit_future::signal();
|
||||
|
||||
let executor = runtime.executor();
|
||||
|
||||
start(config, log, executor);
|
||||
// currently testing - using TestingNode type
|
||||
let client: Client<TestingClientType> = Client::new(config, log.clone(), executor.clone())?;
|
||||
notifier::run(&client, executor, exit);
|
||||
|
||||
runtime.block_on(ctrlc);
|
||||
|
||||
info!(log, "Shutting down.");
|
||||
//TODO: handle shutdown of processes gracefully
|
||||
|
||||
info!(log, "Shutting down..");
|
||||
exit_signal.fire();
|
||||
drop(client);
|
||||
runtime.shutdown_on_idle().wait().unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn start(config: Config, log: &slog::Logger, executor: TaskExecutor) {}
|
||||
|
||||
Reference in New Issue
Block a user