mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-09 11:41:51 +00:00
109
beacon_node/client/src/beacon_chain_types.rs
Normal file
109
beacon_node/client/src/beacon_chain_types.rs
Normal file
@@ -0,0 +1,109 @@
|
||||
use crate::ClientConfig;
|
||||
use beacon_chain::{
|
||||
fork_choice::BitwiseLMDGhost,
|
||||
slot_clock::SystemTimeSlotClock,
|
||||
store::{DiskStore, MemoryStore, Store},
|
||||
BeaconChain, BeaconChainTypes,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use tree_hash::TreeHash;
|
||||
use types::{
|
||||
test_utils::TestingBeaconStateBuilder, BeaconBlock, EthSpec, FewValidatorsEthSpec, Hash256,
|
||||
};
|
||||
|
||||
/// Provides a new, initialized `BeaconChain`
|
||||
pub trait InitialiseBeaconChain<T: BeaconChainTypes> {
|
||||
fn initialise_beacon_chain(config: &ClientConfig) -> BeaconChain<T>;
|
||||
}
|
||||
|
||||
/// A testnet-suitable BeaconChainType, using `MemoryStore`.
|
||||
#[derive(Clone)]
|
||||
pub struct TestnetMemoryBeaconChainTypes;
|
||||
|
||||
impl BeaconChainTypes for TestnetMemoryBeaconChainTypes {
|
||||
type Store = MemoryStore;
|
||||
type SlotClock = SystemTimeSlotClock;
|
||||
type ForkChoice = BitwiseLMDGhost<Self::Store, Self::EthSpec>;
|
||||
type EthSpec = FewValidatorsEthSpec;
|
||||
}
|
||||
|
||||
impl<T> InitialiseBeaconChain<T> for TestnetMemoryBeaconChainTypes
|
||||
where
|
||||
T: BeaconChainTypes<
|
||||
Store = MemoryStore,
|
||||
SlotClock = SystemTimeSlotClock,
|
||||
ForkChoice = BitwiseLMDGhost<MemoryStore, FewValidatorsEthSpec>,
|
||||
>,
|
||||
{
|
||||
fn initialise_beacon_chain(_config: &ClientConfig) -> BeaconChain<T> {
|
||||
initialize_chain(MemoryStore::open())
|
||||
}
|
||||
}
|
||||
|
||||
/// A testnet-suitable BeaconChainType, using `DiskStore`.
|
||||
#[derive(Clone)]
|
||||
pub struct TestnetDiskBeaconChainTypes;
|
||||
|
||||
impl BeaconChainTypes for TestnetDiskBeaconChainTypes {
|
||||
type Store = DiskStore;
|
||||
type SlotClock = SystemTimeSlotClock;
|
||||
type ForkChoice = BitwiseLMDGhost<Self::Store, Self::EthSpec>;
|
||||
type EthSpec = FewValidatorsEthSpec;
|
||||
}
|
||||
|
||||
impl<T> InitialiseBeaconChain<T> for TestnetDiskBeaconChainTypes
|
||||
where
|
||||
T: BeaconChainTypes<
|
||||
Store = DiskStore,
|
||||
SlotClock = SystemTimeSlotClock,
|
||||
ForkChoice = BitwiseLMDGhost<DiskStore, FewValidatorsEthSpec>,
|
||||
>,
|
||||
{
|
||||
fn initialise_beacon_chain(config: &ClientConfig) -> BeaconChain<T> {
|
||||
let store = DiskStore::open(&config.db_name).expect("Unable to open DB.");
|
||||
|
||||
initialize_chain(store)
|
||||
}
|
||||
}
|
||||
|
||||
/// Produces a `BeaconChain` given some pre-initialized `Store`.
|
||||
fn initialize_chain<T, U: Store, V: EthSpec>(store: U) -> BeaconChain<T>
|
||||
where
|
||||
T: BeaconChainTypes<
|
||||
Store = U,
|
||||
SlotClock = SystemTimeSlotClock,
|
||||
ForkChoice = BitwiseLMDGhost<U, V>,
|
||||
>,
|
||||
{
|
||||
let spec = T::EthSpec::spec();
|
||||
|
||||
let store = Arc::new(store);
|
||||
|
||||
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.tree_hash_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(store.clone());
|
||||
|
||||
// Genesis chain
|
||||
//TODO: Handle error correctly
|
||||
BeaconChain::from_genesis(
|
||||
store,
|
||||
slot_clock,
|
||||
genesis_state,
|
||||
genesis_block,
|
||||
spec.clone(),
|
||||
fork_choice,
|
||||
)
|
||||
.expect("Terminate if beacon chain generation fails")
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
use clap::ArgMatches;
|
||||
use fork_choice::ForkChoiceAlgorithm;
|
||||
use http_server::HttpServerConfig;
|
||||
use network::NetworkConfig;
|
||||
use slog::error;
|
||||
use std::fs;
|
||||
@@ -27,7 +28,7 @@ pub struct ClientConfig {
|
||||
pub db_type: DBType,
|
||||
pub db_name: PathBuf,
|
||||
pub rpc_conf: rpc::RPCConfig,
|
||||
//pub ipc_conf:
|
||||
pub http_conf: HttpServerConfig, //pub ipc_conf:
|
||||
}
|
||||
|
||||
impl Default for ClientConfig {
|
||||
@@ -55,6 +56,7 @@ impl Default for ClientConfig {
|
||||
// default db name for disk-based dbs
|
||||
db_name: data_dir.join("chain_db"),
|
||||
rpc_conf: rpc::RPCConfig::default(),
|
||||
http_conf: HttpServerConfig::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
use crate::{ArcBeaconChain, ClientConfig};
|
||||
use beacon_chain::{
|
||||
fork_choice::BitwiseLMDGhost,
|
||||
initialise,
|
||||
slot_clock::{SlotClock, SystemTimeSlotClock},
|
||||
store::{DiskStore, MemoryStore, Store},
|
||||
};
|
||||
use fork_choice::ForkChoice;
|
||||
use types::{EthSpec, FewValidatorsEthSpec, FoundationEthSpec};
|
||||
|
||||
pub trait ClientTypes {
|
||||
type DB: Store + 'static;
|
||||
type SlotClock: SlotClock + 'static;
|
||||
type ForkChoice: ForkChoice + 'static;
|
||||
type EthSpec: EthSpec + 'static;
|
||||
|
||||
fn initialise_beacon_chain(
|
||||
config: &ClientConfig,
|
||||
) -> ArcBeaconChain<Self::DB, Self::SlotClock, Self::ForkChoice, Self::EthSpec>;
|
||||
}
|
||||
|
||||
pub struct StandardClientType;
|
||||
|
||||
impl ClientTypes for StandardClientType {
|
||||
type DB = DiskStore;
|
||||
type SlotClock = SystemTimeSlotClock;
|
||||
type ForkChoice = BitwiseLMDGhost<Self::DB, Self::EthSpec>;
|
||||
type EthSpec = FoundationEthSpec;
|
||||
|
||||
fn initialise_beacon_chain(
|
||||
config: &ClientConfig,
|
||||
) -> ArcBeaconChain<Self::DB, Self::SlotClock, Self::ForkChoice, Self::EthSpec> {
|
||||
initialise::initialise_beacon_chain(&config.spec, Some(&config.db_name))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MemoryStoreTestingClientType;
|
||||
|
||||
impl ClientTypes for MemoryStoreTestingClientType {
|
||||
type DB = MemoryStore;
|
||||
type SlotClock = SystemTimeSlotClock;
|
||||
type ForkChoice = BitwiseLMDGhost<Self::DB, Self::EthSpec>;
|
||||
type EthSpec = FewValidatorsEthSpec;
|
||||
|
||||
fn initialise_beacon_chain(
|
||||
config: &ClientConfig,
|
||||
) -> ArcBeaconChain<Self::DB, Self::SlotClock, Self::ForkChoice, Self::EthSpec> {
|
||||
initialise::initialise_test_beacon_chain_with_memory_db(&config.spec, None)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DiskStoreTestingClientType;
|
||||
|
||||
impl ClientTypes for DiskStoreTestingClientType {
|
||||
type DB = DiskStore;
|
||||
type SlotClock = SystemTimeSlotClock;
|
||||
type ForkChoice = BitwiseLMDGhost<Self::DB, Self::EthSpec>;
|
||||
type EthSpec = FewValidatorsEthSpec;
|
||||
|
||||
fn initialise_beacon_chain(
|
||||
config: &ClientConfig,
|
||||
) -> ArcBeaconChain<Self::DB, Self::SlotClock, Self::ForkChoice, Self::EthSpec> {
|
||||
initialise::initialise_test_beacon_chain_with_disk_db(&config.spec, Some(&config.db_name))
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,13 @@
|
||||
extern crate slog;
|
||||
|
||||
mod beacon_chain_types;
|
||||
mod client_config;
|
||||
pub mod client_types;
|
||||
pub mod error;
|
||||
pub mod notifier;
|
||||
|
||||
use beacon_chain::BeaconChain;
|
||||
pub use client_config::{ClientConfig, DBType};
|
||||
pub use client_types::ClientTypes;
|
||||
use beacon_chain_types::InitialiseBeaconChain;
|
||||
use exit_future::Signal;
|
||||
use fork_choice::ForkChoice;
|
||||
use futures::{future::Future, Stream};
|
||||
use network::Service as NetworkService;
|
||||
use slog::{error, info, o};
|
||||
@@ -17,24 +15,26 @@ use slot_clock::SlotClock;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
use store::Store;
|
||||
use tokio::runtime::TaskExecutor;
|
||||
use tokio::timer::Interval;
|
||||
use types::EthSpec;
|
||||
|
||||
type ArcBeaconChain<D, S, F, B> = Arc<BeaconChain<D, S, F, B>>;
|
||||
pub use beacon_chain::BeaconChainTypes;
|
||||
pub use beacon_chain_types::{TestnetDiskBeaconChainTypes, TestnetMemoryBeaconChainTypes};
|
||||
pub use client_config::{ClientConfig, DBType};
|
||||
|
||||
/// Main beacon node client service. This provides the connection and initialisation of the clients
|
||||
/// sub-services in multiple threads.
|
||||
pub struct Client<T: ClientTypes> {
|
||||
pub struct Client<T: BeaconChainTypes> {
|
||||
/// Configuration for the lighthouse client.
|
||||
_config: ClientConfig,
|
||||
/// The beacon chain for the running client.
|
||||
_beacon_chain: ArcBeaconChain<T::DB, T::SlotClock, T::ForkChoice, T::EthSpec>,
|
||||
_beacon_chain: Arc<BeaconChain<T>>,
|
||||
/// Reference to the network service.
|
||||
pub network: Arc<NetworkService<T::EthSpec>>,
|
||||
pub network: Arc<NetworkService<T>>,
|
||||
/// Signal to terminate the RPC server.
|
||||
pub rpc_exit_signal: Option<Signal>,
|
||||
/// Signal to terminate the HTTP server.
|
||||
pub http_exit_signal: Option<Signal>,
|
||||
/// Signal to terminate the slot timer.
|
||||
pub slot_timer_exit_signal: Option<Signal>,
|
||||
/// The clients logger.
|
||||
@@ -43,7 +43,10 @@ pub struct Client<T: ClientTypes> {
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<TClientType: ClientTypes> Client<TClientType> {
|
||||
impl<T> Client<T>
|
||||
where
|
||||
T: BeaconChainTypes + InitialiseBeaconChain<T> + Clone + 'static,
|
||||
{
|
||||
/// Generate an instance of the client. Spawn and link all internal sub-processes.
|
||||
pub fn new(
|
||||
config: ClientConfig,
|
||||
@@ -51,7 +54,7 @@ impl<TClientType: ClientTypes> Client<TClientType> {
|
||||
executor: &TaskExecutor,
|
||||
) -> error::Result<Self> {
|
||||
// generate a beacon chain
|
||||
let beacon_chain = TClientType::initialise_beacon_chain(&config);
|
||||
let beacon_chain = Arc::new(T::initialise_beacon_chain(&config));
|
||||
|
||||
if beacon_chain.read_slot_clock().is_none() {
|
||||
panic!("Cannot start client before genesis!")
|
||||
@@ -98,7 +101,7 @@ impl<TClientType: ClientTypes> Client<TClientType> {
|
||||
Some(rpc::start_server(
|
||||
&config.rpc_conf,
|
||||
executor,
|
||||
network_send,
|
||||
network_send.clone(),
|
||||
beacon_chain.clone(),
|
||||
&log,
|
||||
))
|
||||
@@ -106,6 +109,17 @@ impl<TClientType: ClientTypes> Client<TClientType> {
|
||||
None
|
||||
};
|
||||
|
||||
// Start the `http_server` service.
|
||||
//
|
||||
// Note: presently we are ignoring the config and _always_ starting a HTTP server.
|
||||
let http_exit_signal = Some(http_server::start_service(
|
||||
&config.http_conf,
|
||||
executor,
|
||||
network_send,
|
||||
beacon_chain.clone(),
|
||||
&log,
|
||||
));
|
||||
|
||||
let (slot_timer_exit_signal, exit) = exit_future::signal();
|
||||
if let Ok(Some(duration_to_next_slot)) = beacon_chain.slot_clock.duration_to_next_slot() {
|
||||
// set up the validator work interval - start at next slot and proceed every slot
|
||||
@@ -135,6 +149,7 @@ impl<TClientType: ClientTypes> Client<TClientType> {
|
||||
Ok(Client {
|
||||
_config: config,
|
||||
_beacon_chain: beacon_chain,
|
||||
http_exit_signal,
|
||||
rpc_exit_signal,
|
||||
slot_timer_exit_signal: Some(slot_timer_exit_signal),
|
||||
log,
|
||||
@@ -144,13 +159,7 @@ impl<TClientType: ClientTypes> Client<TClientType> {
|
||||
}
|
||||
}
|
||||
|
||||
fn do_state_catchup<T, U, F, E>(chain: &Arc<BeaconChain<T, U, F, E>>, log: &slog::Logger)
|
||||
where
|
||||
T: Store,
|
||||
U: SlotClock,
|
||||
F: ForkChoice,
|
||||
E: EthSpec,
|
||||
{
|
||||
fn do_state_catchup<T: BeaconChainTypes>(chain: &Arc<BeaconChain<T>>, log: &slog::Logger) {
|
||||
if let Some(genesis_height) = chain.slots_since_genesis() {
|
||||
let result = chain.catchup_state();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::Client;
|
||||
use crate::ClientTypes;
|
||||
use beacon_chain::BeaconChainTypes;
|
||||
use exit_future::Exit;
|
||||
use futures::{Future, Stream};
|
||||
use slog::{debug, o};
|
||||
@@ -10,7 +10,11 @@ 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) {
|
||||
pub fn run<T: BeaconChainTypes + Send + Sync + 'static>(
|
||||
client: &Client<T>,
|
||||
executor: TaskExecutor,
|
||||
exit: Exit,
|
||||
) {
|
||||
// notification heartbeat
|
||||
let interval = Interval::new(Instant::now(), Duration::from_secs(5));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user