2019-01-24 06:05:48 +00:00
|
|
|
mod attestation_targets;
|
|
|
|
mod block_graph;
|
2019-01-25 00:30:06 +00:00
|
|
|
pub mod block_processing;
|
2019-01-24 06:05:48 +00:00
|
|
|
pub mod block_production;
|
|
|
|
mod canonical_head;
|
2019-01-25 20:20:58 +00:00
|
|
|
pub mod dump;
|
2019-01-26 03:50:56 +00:00
|
|
|
pub mod epoch_processing;
|
2019-01-25 00:30:06 +00:00
|
|
|
mod finalized_head;
|
2019-01-24 06:05:48 +00:00
|
|
|
mod info;
|
2019-01-22 22:33:04 +00:00
|
|
|
mod lmd_ghost;
|
2019-01-23 08:25:05 +00:00
|
|
|
mod state_transition;
|
2018-12-30 01:59:24 +00:00
|
|
|
|
2019-01-24 06:05:48 +00:00
|
|
|
use self::attestation_targets::AttestationTargets;
|
|
|
|
use self::block_graph::BlockGraph;
|
2018-12-30 01:59:24 +00:00
|
|
|
use db::{
|
|
|
|
stores::{BeaconBlockStore, BeaconStateStore},
|
|
|
|
ClientDB, DBError,
|
|
|
|
};
|
|
|
|
use genesis::{genesis_beacon_block, genesis_beacon_state, GenesisError};
|
2019-01-04 07:12:32 +00:00
|
|
|
use slot_clock::SlotClock;
|
2018-12-30 01:59:24 +00:00
|
|
|
use ssz::ssz_encode;
|
2019-01-24 06:05:48 +00:00
|
|
|
use std::sync::{Arc, RwLock};
|
2019-01-25 02:52:21 +00:00
|
|
|
use types::{BeaconBlock, BeaconState, ChainSpec, Hash256};
|
2018-12-30 01:59:24 +00:00
|
|
|
|
2019-01-22 22:33:04 +00:00
|
|
|
pub use self::block_processing::Outcome as BlockProcessingOutcome;
|
|
|
|
|
2018-12-30 01:59:24 +00:00
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum BeaconChainError {
|
|
|
|
InsufficientValidators,
|
|
|
|
GenesisError(GenesisError),
|
|
|
|
DBError(String),
|
|
|
|
}
|
|
|
|
|
2019-01-24 06:05:48 +00:00
|
|
|
pub struct CheckPoint {
|
|
|
|
beacon_block: BeaconBlock,
|
|
|
|
beacon_block_root: Hash256,
|
|
|
|
beacon_state: BeaconState,
|
|
|
|
beacon_state_root: Hash256,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CheckPoint {
|
|
|
|
pub fn new(
|
|
|
|
beacon_block: BeaconBlock,
|
|
|
|
beacon_block_root: Hash256,
|
|
|
|
beacon_state: BeaconState,
|
|
|
|
beacon_state_root: Hash256,
|
|
|
|
) -> Self {
|
|
|
|
Self {
|
|
|
|
beacon_block,
|
|
|
|
beacon_block_root,
|
|
|
|
beacon_state,
|
|
|
|
beacon_state_root,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn update(
|
|
|
|
&mut self,
|
|
|
|
beacon_block: BeaconBlock,
|
|
|
|
beacon_block_root: Hash256,
|
|
|
|
beacon_state: BeaconState,
|
|
|
|
beacon_state_root: Hash256,
|
|
|
|
) {
|
|
|
|
self.beacon_block = beacon_block;
|
|
|
|
self.beacon_block_root = beacon_block_root;
|
|
|
|
self.beacon_state = beacon_state;
|
|
|
|
self.beacon_state_root = beacon_state_root;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-30 01:59:24 +00:00
|
|
|
pub struct BeaconChain<T: ClientDB + Sized, U: SlotClock> {
|
|
|
|
pub block_store: Arc<BeaconBlockStore<T>>,
|
|
|
|
pub state_store: Arc<BeaconStateStore<T>>,
|
|
|
|
pub slot_clock: U,
|
2019-01-24 06:05:48 +00:00
|
|
|
pub block_graph: BlockGraph,
|
|
|
|
canonical_head: RwLock<CheckPoint>,
|
|
|
|
finalized_head: RwLock<CheckPoint>,
|
|
|
|
pub latest_attestation_targets: RwLock<AttestationTargets>,
|
2018-12-30 01:59:24 +00:00
|
|
|
pub spec: ChainSpec,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T, U> BeaconChain<T, U>
|
|
|
|
where
|
|
|
|
T: ClientDB,
|
|
|
|
U: SlotClock,
|
|
|
|
{
|
|
|
|
pub fn genesis(
|
|
|
|
state_store: Arc<BeaconStateStore<T>>,
|
|
|
|
block_store: Arc<BeaconBlockStore<T>>,
|
|
|
|
slot_clock: U,
|
|
|
|
spec: ChainSpec,
|
|
|
|
) -> Result<Self, BeaconChainError> {
|
|
|
|
if spec.initial_validators.is_empty() {
|
|
|
|
return Err(BeaconChainError::InsufficientValidators);
|
|
|
|
}
|
|
|
|
|
|
|
|
let genesis_state = genesis_beacon_state(&spec)?;
|
|
|
|
let state_root = genesis_state.canonical_root();
|
|
|
|
state_store.put(&state_root, &ssz_encode(&genesis_state)[..])?;
|
|
|
|
|
|
|
|
let genesis_block = genesis_beacon_block(state_root, &spec);
|
|
|
|
let block_root = genesis_block.canonical_root();
|
|
|
|
block_store.put(&block_root, &ssz_encode(&genesis_block)[..])?;
|
|
|
|
|
2019-01-24 06:05:48 +00:00
|
|
|
let block_graph = BlockGraph::new();
|
|
|
|
block_graph.add_leaf(&Hash256::zero(), block_root.clone());
|
|
|
|
|
|
|
|
let finalized_head = RwLock::new(CheckPoint::new(
|
|
|
|
genesis_block.clone(),
|
|
|
|
block_root.clone(),
|
|
|
|
genesis_state.clone(),
|
|
|
|
state_root.clone(),
|
|
|
|
));
|
|
|
|
let canonical_head = RwLock::new(CheckPoint::new(
|
|
|
|
genesis_block.clone(),
|
|
|
|
block_root.clone(),
|
|
|
|
genesis_state.clone(),
|
|
|
|
state_root.clone(),
|
|
|
|
));
|
2018-12-30 01:59:24 +00:00
|
|
|
|
2019-01-24 06:05:48 +00:00
|
|
|
let latest_attestation_targets = RwLock::new(AttestationTargets::new());
|
2019-01-22 22:33:04 +00:00
|
|
|
|
2018-12-30 01:59:24 +00:00
|
|
|
Ok(Self {
|
|
|
|
block_store,
|
|
|
|
state_store,
|
|
|
|
slot_clock,
|
2019-01-24 06:05:48 +00:00
|
|
|
block_graph,
|
|
|
|
finalized_head,
|
|
|
|
canonical_head,
|
|
|
|
latest_attestation_targets,
|
|
|
|
spec: spec,
|
2018-12-30 01:59:24 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<DBError> for BeaconChainError {
|
|
|
|
fn from(e: DBError) -> BeaconChainError {
|
|
|
|
BeaconChainError::DBError(e.message)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<GenesisError> for BeaconChainError {
|
|
|
|
fn from(e: GenesisError) -> BeaconChainError {
|
|
|
|
BeaconChainError::GenesisError(e)
|
|
|
|
}
|
|
|
|
}
|