Add new
fns to ForkChoice
and SlotClock
This commit is contained in:
parent
9922ed2239
commit
76602a65fc
@ -82,7 +82,7 @@ impl BlockProcessingOutcome {
|
|||||||
pub trait BeaconChainTypes {
|
pub trait BeaconChainTypes {
|
||||||
type Store: store::Store;
|
type Store: store::Store;
|
||||||
type SlotClock: slot_clock::SlotClock;
|
type SlotClock: slot_clock::SlotClock;
|
||||||
type ForkChoice: fork_choice::ForkChoice;
|
type ForkChoice: fork_choice::ForkChoice<Self::Store>;
|
||||||
type EthSpec: types::EthSpec;
|
type EthSpec: types::EthSpec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ use beacon_chain::{
|
|||||||
store::{DiskStore, MemoryStore, Store},
|
store::{DiskStore, MemoryStore, Store},
|
||||||
BeaconChain, BeaconChainTypes,
|
BeaconChain, BeaconChainTypes,
|
||||||
};
|
};
|
||||||
|
use fork_choice::ForkChoice;
|
||||||
|
use slot_clock::SlotClock;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tree_hash::TreeHash;
|
use tree_hash::TreeHash;
|
||||||
use types::{
|
use types::{
|
||||||
@ -36,7 +38,7 @@ where
|
|||||||
>,
|
>,
|
||||||
{
|
{
|
||||||
fn initialise_beacon_chain(_config: &ClientConfig) -> BeaconChain<T> {
|
fn initialise_beacon_chain(_config: &ClientConfig) -> BeaconChain<T> {
|
||||||
initialize_chain(MemoryStore::open())
|
initialize_chain::<_, _, FewValidatorsEthSpec>(MemoryStore::open())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,18 +64,15 @@ where
|
|||||||
fn initialise_beacon_chain(config: &ClientConfig) -> BeaconChain<T> {
|
fn initialise_beacon_chain(config: &ClientConfig) -> BeaconChain<T> {
|
||||||
let store = DiskStore::open(&config.db_name).expect("Unable to open DB.");
|
let store = DiskStore::open(&config.db_name).expect("Unable to open DB.");
|
||||||
|
|
||||||
initialize_chain(store)
|
initialize_chain::<_, _, FewValidatorsEthSpec>(store)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Produces a `BeaconChain` given some pre-initialized `Store`.
|
/// Produces a `BeaconChain` given some pre-initialized `Store`.
|
||||||
fn initialize_chain<T, U: Store, V: EthSpec>(store: U) -> BeaconChain<T>
|
fn initialize_chain<T, U: Store, V: EthSpec>(store: U) -> BeaconChain<T>
|
||||||
where
|
where
|
||||||
T: BeaconChainTypes<
|
T: BeaconChainTypes<Store = U>,
|
||||||
Store = U,
|
T::ForkChoice: ForkChoice<U>,
|
||||||
SlotClock = SystemTimeSlotClock,
|
|
||||||
ForkChoice = BitwiseLMDGhost<U, V>,
|
|
||||||
>,
|
|
||||||
{
|
{
|
||||||
let spec = T::EthSpec::spec();
|
let spec = T::EthSpec::spec();
|
||||||
|
|
||||||
@ -86,14 +85,13 @@ where
|
|||||||
genesis_block.state_root = Hash256::from_slice(&genesis_state.tree_hash_root());
|
genesis_block.state_root = Hash256::from_slice(&genesis_state.tree_hash_root());
|
||||||
|
|
||||||
// Slot clock
|
// Slot clock
|
||||||
let slot_clock = SystemTimeSlotClock::new(
|
let slot_clock = T::SlotClock::new(
|
||||||
spec.genesis_slot,
|
spec.genesis_slot,
|
||||||
genesis_state.genesis_time,
|
genesis_state.genesis_time,
|
||||||
spec.seconds_per_slot,
|
spec.seconds_per_slot,
|
||||||
)
|
);
|
||||||
.expect("Unable to load SystemTimeSlotClock");
|
|
||||||
// Choose the fork choice
|
// Choose the fork choice
|
||||||
let fork_choice = BitwiseLMDGhost::new(store.clone());
|
let fork_choice = T::ForkChoice::new(store.clone());
|
||||||
|
|
||||||
// Genesis chain
|
// Genesis chain
|
||||||
//TODO: Handle error correctly
|
//TODO: Handle error correctly
|
||||||
|
@ -48,18 +48,6 @@ pub struct BitwiseLMDGhost<T, E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Store, E: EthSpec> BitwiseLMDGhost<T, E> {
|
impl<T: Store, E: EthSpec> BitwiseLMDGhost<T, E> {
|
||||||
pub fn new(store: Arc<T>) -> Self {
|
|
||||||
BitwiseLMDGhost {
|
|
||||||
cache: HashMap::new(),
|
|
||||||
ancestors: vec![HashMap::new(); 16],
|
|
||||||
latest_attestation_targets: HashMap::new(),
|
|
||||||
children: HashMap::new(),
|
|
||||||
max_known_height: SlotHeight::new(0),
|
|
||||||
store,
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finds the latest votes weighted by validator balance. Returns a hashmap of block_hash to
|
/// Finds the latest votes weighted by validator balance. Returns a hashmap of block_hash to
|
||||||
/// weighted votes.
|
/// weighted votes.
|
||||||
pub fn get_latest_votes(
|
pub fn get_latest_votes(
|
||||||
@ -229,7 +217,19 @@ impl<T: Store, E: EthSpec> BitwiseLMDGhost<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Store, E: EthSpec> ForkChoice for BitwiseLMDGhost<T, E> {
|
impl<T: Store, E: EthSpec> ForkChoice<T> for BitwiseLMDGhost<T, E> {
|
||||||
|
fn new(store: Arc<T>) -> Self {
|
||||||
|
BitwiseLMDGhost {
|
||||||
|
cache: HashMap::new(),
|
||||||
|
ancestors: vec![HashMap::new(); 16],
|
||||||
|
latest_attestation_targets: HashMap::new(),
|
||||||
|
children: HashMap::new(),
|
||||||
|
max_known_height: SlotHeight::new(0),
|
||||||
|
store,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn add_block(
|
fn add_block(
|
||||||
&mut self,
|
&mut self,
|
||||||
block: &BeaconBlock,
|
block: &BeaconBlock,
|
||||||
|
@ -21,8 +21,7 @@ pub mod longest_chain;
|
|||||||
pub mod optimized_lmd_ghost;
|
pub mod optimized_lmd_ghost;
|
||||||
pub mod slow_lmd_ghost;
|
pub mod slow_lmd_ghost;
|
||||||
|
|
||||||
// use store::stores::BeaconBlockAtSlotError;
|
use std::sync::Arc;
|
||||||
// use store::DBError;
|
|
||||||
use store::Error as DBError;
|
use store::Error as DBError;
|
||||||
use types::{BeaconBlock, ChainSpec, Hash256};
|
use types::{BeaconBlock, ChainSpec, Hash256};
|
||||||
|
|
||||||
@ -34,7 +33,10 @@ pub use slow_lmd_ghost::SlowLMDGhost;
|
|||||||
/// Defines the interface for Fork Choices. Each Fork choice will define their own data structures
|
/// 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.
|
/// 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
|
/// The main fork choice algorithm is specified in `find_head
|
||||||
pub trait ForkChoice: Send + Sync {
|
pub trait ForkChoice<T>: Send + Sync {
|
||||||
|
/// Create a new `ForkChoice` which reads from `store`.
|
||||||
|
fn new(store: Arc<T>) -> Self;
|
||||||
|
|
||||||
/// Called when a block has been added. Allows generic block-level data structures to be
|
/// Called when a block has been added. Allows generic block-level data structures to be
|
||||||
/// built for a given fork-choice.
|
/// built for a given fork-choice.
|
||||||
fn add_block(
|
fn add_block(
|
||||||
@ -78,22 +80,6 @@ impl From<DBError> for ForkChoiceError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
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.
|
/// Fork choice options that are currently implemented.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ForkChoiceAlgorithm {
|
pub enum ForkChoiceAlgorithm {
|
||||||
|
@ -10,16 +10,14 @@ pub struct LongestChain<T> {
|
|||||||
store: Arc<T>,
|
store: Arc<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Store> LongestChain<T> {
|
impl<T: Store> ForkChoice<T> for LongestChain<T> {
|
||||||
pub fn new(store: Arc<T>) -> Self {
|
fn new(store: Arc<T>) -> Self {
|
||||||
LongestChain {
|
LongestChain {
|
||||||
head_block_hashes: Vec::new(),
|
head_block_hashes: Vec::new(),
|
||||||
store,
|
store,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Store> ForkChoice for LongestChain<T> {
|
|
||||||
fn add_block(
|
fn add_block(
|
||||||
&mut self,
|
&mut self,
|
||||||
block: &BeaconBlock,
|
block: &BeaconBlock,
|
||||||
|
@ -48,18 +48,6 @@ pub struct OptimizedLMDGhost<T, E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Store, E: EthSpec> OptimizedLMDGhost<T, E> {
|
impl<T: Store, E: EthSpec> OptimizedLMDGhost<T, E> {
|
||||||
pub fn new(store: Arc<T>) -> Self {
|
|
||||||
OptimizedLMDGhost {
|
|
||||||
cache: HashMap::new(),
|
|
||||||
ancestors: vec![HashMap::new(); 16],
|
|
||||||
latest_attestation_targets: HashMap::new(),
|
|
||||||
children: HashMap::new(),
|
|
||||||
max_known_height: SlotHeight::new(0),
|
|
||||||
store,
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finds the latest votes weighted by validator balance. Returns a hashmap of block_hash to
|
/// Finds the latest votes weighted by validator balance. Returns a hashmap of block_hash to
|
||||||
/// weighted votes.
|
/// weighted votes.
|
||||||
pub fn get_latest_votes(
|
pub fn get_latest_votes(
|
||||||
@ -200,7 +188,19 @@ impl<T: Store, E: EthSpec> OptimizedLMDGhost<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Store, E: EthSpec> ForkChoice for OptimizedLMDGhost<T, E> {
|
impl<T: Store, E: EthSpec> ForkChoice<T> for OptimizedLMDGhost<T, E> {
|
||||||
|
fn new(store: Arc<T>) -> Self {
|
||||||
|
OptimizedLMDGhost {
|
||||||
|
cache: HashMap::new(),
|
||||||
|
ancestors: vec![HashMap::new(); 16],
|
||||||
|
latest_attestation_targets: HashMap::new(),
|
||||||
|
children: HashMap::new(),
|
||||||
|
max_known_height: SlotHeight::new(0),
|
||||||
|
store,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn add_block(
|
fn add_block(
|
||||||
&mut self,
|
&mut self,
|
||||||
block: &BeaconBlock,
|
block: &BeaconBlock,
|
||||||
|
@ -20,15 +20,6 @@ pub struct SlowLMDGhost<T, E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Store, E: EthSpec> SlowLMDGhost<T, E> {
|
impl<T: Store, E: EthSpec> SlowLMDGhost<T, E> {
|
||||||
pub fn new(store: Arc<T>) -> Self {
|
|
||||||
SlowLMDGhost {
|
|
||||||
latest_attestation_targets: HashMap::new(),
|
|
||||||
children: HashMap::new(),
|
|
||||||
store,
|
|
||||||
_phantom: PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finds the latest votes weighted by validator balance. Returns a hashmap of block_hash to
|
/// Finds the latest votes weighted by validator balance. Returns a hashmap of block_hash to
|
||||||
/// weighted votes.
|
/// weighted votes.
|
||||||
pub fn get_latest_votes(
|
pub fn get_latest_votes(
|
||||||
@ -94,7 +85,16 @@ impl<T: Store, E: EthSpec> SlowLMDGhost<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Store, E: EthSpec> ForkChoice for SlowLMDGhost<T, E> {
|
impl<T: Store, E: EthSpec> ForkChoice<T> for SlowLMDGhost<T, E> {
|
||||||
|
fn new(store: Arc<T>) -> Self {
|
||||||
|
SlowLMDGhost {
|
||||||
|
latest_attestation_targets: HashMap::new(),
|
||||||
|
children: HashMap::new(),
|
||||||
|
store,
|
||||||
|
_phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Process when a block is added
|
/// Process when a block is added
|
||||||
fn add_block(
|
fn add_block(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -6,9 +6,14 @@ pub use crate::testing_slot_clock::{Error as TestingSlotClockError, TestingSlotC
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
pub use types::Slot;
|
pub use types::Slot;
|
||||||
|
|
||||||
pub trait SlotClock: Send + Sync {
|
pub trait SlotClock: Send + Sync + Sized {
|
||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
|
/// Create a new `SlotClock`.
|
||||||
|
///
|
||||||
|
/// Returns an Error if `slot_duration_seconds == 0`.
|
||||||
|
fn new(genesis_slot: Slot, genesis_seconds: u64, slot_duration_seconds: u64) -> Self;
|
||||||
|
|
||||||
fn present_slot(&self) -> Result<Option<Slot>, Self::Error>;
|
fn present_slot(&self) -> Result<Option<Slot>, Self::Error>;
|
||||||
|
|
||||||
fn duration_to_next_slot(&self) -> Result<Option<Duration>, Self::Error>;
|
fn duration_to_next_slot(&self) -> Result<Option<Duration>, Self::Error>;
|
||||||
|
@ -18,31 +18,25 @@ pub struct SystemTimeSlotClock {
|
|||||||
slot_duration_seconds: u64,
|
slot_duration_seconds: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SystemTimeSlotClock {
|
|
||||||
/// Create a new `SystemTimeSlotClock`.
|
|
||||||
///
|
|
||||||
/// Returns an Error if `slot_duration_seconds == 0`.
|
|
||||||
pub fn new(
|
|
||||||
genesis_slot: Slot,
|
|
||||||
genesis_seconds: u64,
|
|
||||||
slot_duration_seconds: u64,
|
|
||||||
) -> Result<SystemTimeSlotClock, Error> {
|
|
||||||
if slot_duration_seconds == 0 {
|
|
||||||
Err(Error::SlotDurationIsZero)
|
|
||||||
} else {
|
|
||||||
Ok(Self {
|
|
||||||
genesis_slot,
|
|
||||||
genesis_seconds,
|
|
||||||
slot_duration_seconds,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SlotClock for SystemTimeSlotClock {
|
impl SlotClock for SystemTimeSlotClock {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
|
/// Create a new `SystemTimeSlotClock`.
|
||||||
|
///
|
||||||
|
/// Returns an Error if `slot_duration_seconds == 0`.
|
||||||
|
fn new(genesis_slot: Slot, genesis_seconds: u64, slot_duration_seconds: u64) -> Self {
|
||||||
|
Self {
|
||||||
|
genesis_slot,
|
||||||
|
genesis_seconds,
|
||||||
|
slot_duration_seconds,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn present_slot(&self) -> Result<Option<Slot>, Error> {
|
fn present_slot(&self) -> Result<Option<Slot>, Error> {
|
||||||
|
if self.slot_duration_seconds == 0 {
|
||||||
|
return Err(Error::SlotDurationIsZero);
|
||||||
|
}
|
||||||
|
|
||||||
let syslot_time = SystemTime::now();
|
let syslot_time = SystemTime::now();
|
||||||
let duration_since_epoch = syslot_time.duration_since(SystemTime::UNIX_EPOCH)?;
|
let duration_since_epoch = syslot_time.duration_since(SystemTime::UNIX_EPOCH)?;
|
||||||
let duration_since_genesis =
|
let duration_since_genesis =
|
||||||
|
@ -8,30 +8,28 @@ pub enum Error {}
|
|||||||
|
|
||||||
/// Determines the present slot based upon the present system time.
|
/// Determines the present slot based upon the present system time.
|
||||||
pub struct TestingSlotClock {
|
pub struct TestingSlotClock {
|
||||||
slot: RwLock<u64>,
|
slot: RwLock<Slot>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestingSlotClock {
|
impl TestingSlotClock {
|
||||||
/// Create a new `TestingSlotClock`.
|
|
||||||
///
|
|
||||||
/// Returns an Error if `slot_duration_seconds == 0`.
|
|
||||||
pub fn new(slot: u64) -> TestingSlotClock {
|
|
||||||
TestingSlotClock {
|
|
||||||
slot: RwLock::new(slot),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_slot(&self, slot: u64) {
|
pub fn set_slot(&self, slot: u64) {
|
||||||
*self.slot.write().expect("TestingSlotClock poisoned.") = slot;
|
*self.slot.write().expect("TestingSlotClock poisoned.") = Slot::from(slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SlotClock for TestingSlotClock {
|
impl SlotClock for TestingSlotClock {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
||||||
|
/// Create a new `TestingSlotClock` at `genesis_slot`.
|
||||||
|
fn new(genesis_slot: Slot, _genesis_seconds: u64, _slot_duration_seconds: u64) -> Self {
|
||||||
|
TestingSlotClock {
|
||||||
|
slot: RwLock::new(genesis_slot),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn present_slot(&self) -> Result<Option<Slot>, Error> {
|
fn present_slot(&self) -> Result<Option<Slot>, Error> {
|
||||||
let slot = *self.slot.read().expect("TestingSlotClock poisoned.");
|
let slot = *self.slot.read().expect("TestingSlotClock poisoned.");
|
||||||
Ok(Some(Slot::new(slot)))
|
Ok(Some(slot))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Always returns a duration of 1 second.
|
/// Always returns a duration of 1 second.
|
||||||
@ -46,7 +44,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_slot_now() {
|
fn test_slot_now() {
|
||||||
let clock = TestingSlotClock::new(10);
|
let null = 0;
|
||||||
|
|
||||||
|
let clock = TestingSlotClock::new(Slot::new(10), null, null);
|
||||||
assert_eq!(clock.present_slot(), Ok(Some(Slot::new(10))));
|
assert_eq!(clock.present_slot(), Ok(Some(Slot::new(10))));
|
||||||
clock.set_slot(123);
|
clock.set_slot(123);
|
||||||
assert_eq!(clock.present_slot(), Ok(Some(Slot::new(123))));
|
assert_eq!(clock.present_slot(), Ok(Some(Slot::new(123))));
|
||||||
|
@ -155,8 +155,7 @@ impl<B: BeaconNodeDuties + 'static, S: Signer + 'static> Service<B, S> {
|
|||||||
|
|
||||||
// build the validator slot clock
|
// build the validator slot clock
|
||||||
let slot_clock =
|
let slot_clock =
|
||||||
SystemTimeSlotClock::new(genesis_slot, genesis_time, config.spec.seconds_per_slot)
|
SystemTimeSlotClock::new(genesis_slot, genesis_time, config.spec.seconds_per_slot);
|
||||||
.expect("Unable to instantiate SystemTimeSlotClock.");
|
|
||||||
|
|
||||||
let current_slot = slot_clock
|
let current_slot = slot_clock
|
||||||
.present_slot()
|
.present_slot()
|
||||||
|
Loading…
Reference in New Issue
Block a user