110 lines
4.1 KiB
Rust
110 lines
4.1 KiB
Rust
//! This crate stores the various implementations of fork-choice rules that can be used for the
|
|
//! beacon blockchain.
|
|
//!
|
|
//! There are three implementations. One is the naive longest chain rule (primarily for testing
|
|
//! purposes). The other two are proposed implementations of the LMD-GHOST fork-choice rule with various forms of optimisation.
|
|
//!
|
|
//! The current implementations are:
|
|
//! - [`longest-chain`]: Simplistic longest-chain fork choice - primarily for testing, **not for
|
|
//! production**.
|
|
//! - [`slow_lmd_ghost`]: This is a simple and very inefficient implementation given in the ethereum 2.0
|
|
//! specifications (https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#get_block_root).
|
|
//! - [`bitwise_lmd_ghost`]: This is an optimised version of bitwise LMD-GHOST as proposed
|
|
//! by Vitalik. The reference implementation can be found at: https://github.com/ethereum/research/blob/master/ghost/ghost.py
|
|
//!
|
|
//! [`longest-chain`]: struct.LongestChain.html
|
|
//! [`slow_lmd_ghost`]: struct.SlowLmdGhost.html
|
|
//! [`bitwise_lmd_ghost`]: struct.OptimisedLmdGhost.html
|
|
|
|
extern crate db;
|
|
extern crate ssz;
|
|
extern crate types;
|
|
|
|
pub mod bitwise_lmd_ghost;
|
|
pub mod longest_chain;
|
|
pub mod optimized_lmd_ghost;
|
|
pub mod slow_lmd_ghost;
|
|
|
|
use db::stores::BeaconBlockAtSlotError;
|
|
use db::DBError;
|
|
use types::{BeaconBlock, ChainSpec, Hash256};
|
|
|
|
pub use bitwise_lmd_ghost::BitwiseLMDGhost;
|
|
pub use longest_chain::LongestChain;
|
|
pub use optimized_lmd_ghost::OptimizedLMDGhost;
|
|
pub use slow_lmd_ghost::SlowLMDGhost;
|
|
|
|
/// Defines the interface for Fork Choices. Each Fork choice will define their own data structures
|
|
/// which can be built in block processing through the `add_block` and `add_attestation` functions.
|
|
/// The main fork choice algorithm is specified in `find_head
|
|
pub trait ForkChoice: Send + Sync {
|
|
/// Called when a block has been added. Allows generic block-level data structures to be
|
|
/// built for a given fork-choice.
|
|
fn add_block(
|
|
&mut self,
|
|
block: &BeaconBlock,
|
|
block_hash: &Hash256,
|
|
spec: &ChainSpec,
|
|
) -> Result<(), ForkChoiceError>;
|
|
/// Called when an attestation has been added. Allows generic attestation-level data structures to be built for a given fork choice.
|
|
// This can be generalised to a full attestation if required later.
|
|
fn add_attestation(
|
|
&mut self,
|
|
validator_index: u64,
|
|
target_block_hash: &Hash256,
|
|
spec: &ChainSpec,
|
|
) -> Result<(), ForkChoiceError>;
|
|
/// The fork-choice algorithm to find the current canonical head of the chain.
|
|
// TODO: Remove the justified_start_block parameter and make it internal
|
|
fn find_head(
|
|
&mut self,
|
|
justified_start_block: &Hash256,
|
|
spec: &ChainSpec,
|
|
) -> Result<Hash256, ForkChoiceError>;
|
|
}
|
|
|
|
/// Possible fork choice errors that can occur.
|
|
#[derive(Debug, PartialEq)]
|
|
pub enum ForkChoiceError {
|
|
MissingBeaconBlock(Hash256),
|
|
MissingBeaconState(Hash256),
|
|
IncorrectBeaconState(Hash256),
|
|
CannotFindBestChild,
|
|
ChildrenNotFound,
|
|
StorageError(String),
|
|
HeadNotFound,
|
|
}
|
|
|
|
impl From<DBError> for ForkChoiceError {
|
|
fn from(e: DBError) -> ForkChoiceError {
|
|
ForkChoiceError::StorageError(e.message)
|
|
}
|
|
}
|
|
|
|
impl From<BeaconBlockAtSlotError> for ForkChoiceError {
|
|
fn from(e: BeaconBlockAtSlotError) -> ForkChoiceError {
|
|
match e {
|
|
BeaconBlockAtSlotError::UnknownBeaconBlock(hash) => {
|
|
ForkChoiceError::MissingBeaconBlock(hash)
|
|
}
|
|
BeaconBlockAtSlotError::InvalidBeaconBlock(hash) => {
|
|
ForkChoiceError::MissingBeaconBlock(hash)
|
|
}
|
|
BeaconBlockAtSlotError::DBError(string) => ForkChoiceError::StorageError(string),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Fork choice options that are currently implemented.
|
|
#[derive(Debug, Clone)]
|
|
pub enum ForkChoiceAlgorithm {
|
|
/// Chooses the longest chain becomes the head. Not for production.
|
|
LongestChain,
|
|
/// A simple and highly inefficient implementation of LMD ghost.
|
|
SlowLMDGhost,
|
|
/// An optimised version of bitwise LMD-GHOST by Vitalik.
|
|
BitwiseLMDGhost,
|
|
/// An optimised implementation of LMD ghost.
|
|
OptimizedLMDGhost,
|
|
}
|