diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 41a718655..2bbb6901c 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -83,30 +83,31 @@ impl BlockProcessingOutcome { } } -pub struct BeaconChain { +pub struct BeaconChain { pub block_store: Arc>, pub state_store: Arc>, pub slot_clock: U, - pub op_pool: OperationPool, - canonical_head: RwLock, - finalized_head: RwLock, - pub state: RwLock, + pub op_pool: OperationPool, + canonical_head: RwLock>, + finalized_head: RwLock>, + pub state: RwLock>, pub spec: ChainSpec, pub fork_choice: RwLock, } -impl BeaconChain +impl BeaconChain where T: ClientDB, U: SlotClock, F: ForkChoice, + B: BeaconStateTypes, { /// Instantiate a new Beacon Chain, from genesis. pub fn from_genesis( state_store: Arc>, block_store: Arc>, slot_clock: U, - mut genesis_state: BeaconState, + mut genesis_state: BeaconState, genesis_block: BeaconBlock, spec: ChainSpec, fork_choice: F, @@ -218,7 +219,7 @@ where // // If we get `SlotOutOfBounds` error, load the oldest available historic // state from the DB. - match state.get_block_root(slot, spec) { + match state.get_block_root(slot) { Ok(root) => { if slot < earliest_slot { break; @@ -230,9 +231,9 @@ where Err(BeaconStateError::SlotOutOfBounds) => { // Read the earliest historic state in the current slot. let earliest_historic_slot = - state.slot - Slot::from(spec.slots_per_historical_root); + state.slot - Slot::from(B::SlotsPerHistoricalRoot::to_usize()); // Load the earlier state from disk. - let new_state_root = state.get_state_root(earliest_historic_slot, spec)?; + let new_state_root = state.get_state_root(earliest_historic_slot)?; // Break if the DB is unable to load the state. state = match self.state_store.get_deserialized(&new_state_root) { @@ -270,7 +271,7 @@ where &self, new_beacon_block: BeaconBlock, new_beacon_block_root: Hash256, - new_beacon_state: BeaconState, + new_beacon_state: BeaconState, new_beacon_state_root: Hash256, ) { debug!( @@ -292,7 +293,7 @@ where /// It is important to note that the `beacon_state` returned may not match the present slot. It /// is the state as it was when the head block was received, which could be some slots prior to /// now. - pub fn head(&self) -> RwLockReadGuard { + pub fn head(&self) -> RwLockReadGuard> { self.canonical_head.read() } @@ -302,7 +303,7 @@ where /// state and calling `catchup_state` as it will not result in an old state being installed and /// then having it iteratively updated -- in such a case it's possible for another thread to /// find the state at an old slot. - pub fn update_state(&self, mut state: BeaconState) -> Result<(), Error> { + pub fn update_state(&self, mut state: BeaconState) -> Result<(), Error> { let present_slot = match self.slot_clock.present_slot() { Ok(Some(slot)) => slot, _ => return Err(Error::UnableToReadSlot), @@ -357,7 +358,7 @@ where &self, new_beacon_block: BeaconBlock, new_beacon_block_root: Hash256, - new_beacon_state: BeaconState, + new_beacon_state: BeaconState, new_beacon_state_root: Hash256, ) { let mut finalized_head = self.finalized_head.write(); @@ -371,7 +372,7 @@ where /// Returns a read-lock guarded `CheckPoint` struct for reading the justified head (as chosen, /// indirectly, by the fork-choice rule). - pub fn finalized_head(&self) -> RwLockReadGuard { + pub fn finalized_head(&self) -> RwLockReadGuard> { self.finalized_head.read() } @@ -493,17 +494,14 @@ where } else { // If the current head block is not from this slot, use the slot from the previous // epoch. - *self.state.read().get_block_root( - current_epoch_start_slot - self.spec.slots_per_epoch, - &self.spec, - )? + *self + .state + .read() + .get_block_root(current_epoch_start_slot - self.spec.slots_per_epoch)? } } else { // If we're not on the first slot of the epoch. - *self - .state - .read() - .get_block_root(current_epoch_start_slot, &self.spec)? + *self.state.read().get_block_root(current_epoch_start_slot)? }; Ok(AttestationData { @@ -667,7 +665,7 @@ where pub fn produce_block( &self, randao_reveal: Signature, - ) -> Result<(BeaconBlock, BeaconState), BlockProductionError> { + ) -> Result<(BeaconBlock, BeaconState), BlockProductionError> { debug!("Producing block at slot {}...", self.state.read().slot); let mut state = self.state.read().clone(); @@ -677,7 +675,7 @@ where trace!("Finding attestations for new block..."); let previous_block_root = *state - .get_block_root(state.slot - 1, &self.spec) + .get_block_root(state.slot - 1) .map_err(|_| BlockProductionError::UnableToGetBlockRootFromState)?; let (proposer_slashings, attester_slashings) = @@ -762,7 +760,7 @@ where /// /// This could be a very expensive operation and should only be done in testing/analysis /// activities. - pub fn chain_dump(&self) -> Result, Error> { + pub fn chain_dump(&self) -> Result>, Error> { let mut dump = vec![]; let mut last_slot = CheckPoint { diff --git a/beacon_node/beacon_chain/src/checkpoint.rs b/beacon_node/beacon_chain/src/checkpoint.rs index 78227e5c8..c3757949f 100644 --- a/beacon_node/beacon_chain/src/checkpoint.rs +++ b/beacon_node/beacon_chain/src/checkpoint.rs @@ -1,22 +1,22 @@ use serde_derive::Serialize; -use types::{BeaconBlock, BeaconState, Hash256}; +use types::{BeaconBlock, BeaconState, BeaconStateTypes, Hash256}; /// Represents some block and it's associated state. Generally, this will be used for tracking the /// head, justified head and finalized head. #[derive(Clone, Serialize, PartialEq, Debug)] -pub struct CheckPoint { +pub struct CheckPoint { pub beacon_block: BeaconBlock, pub beacon_block_root: Hash256, - pub beacon_state: BeaconState, + pub beacon_state: BeaconState, pub beacon_state_root: Hash256, } -impl CheckPoint { +impl CheckPoint { /// Create a new checkpoint. pub fn new( beacon_block: BeaconBlock, beacon_block_root: Hash256, - beacon_state: BeaconState, + beacon_state: BeaconState, beacon_state_root: Hash256, ) -> Self { Self { @@ -32,7 +32,7 @@ impl CheckPoint { &mut self, beacon_block: BeaconBlock, beacon_block_root: Hash256, - beacon_state: BeaconState, + beacon_state: BeaconState, beacon_state_root: Hash256, ) { self.beacon_block = beacon_block; diff --git a/beacon_node/beacon_chain/src/initialise.rs b/beacon_node/beacon_chain/src/initialise.rs index c66dd63b1..284393c02 100644 --- a/beacon_node/beacon_chain/src/initialise.rs +++ b/beacon_node/beacon_chain/src/initialise.rs @@ -11,14 +11,21 @@ use std::path::PathBuf; use std::sync::Arc; use tree_hash::TreeHash; use types::test_utils::TestingBeaconStateBuilder; -use types::{BeaconBlock, ChainSpec, Hash256}; +use types::{BeaconBlock, ChainSpec, FewValidatorsStateTypes, FoundationStateTypes, Hash256}; //TODO: Correct this for prod //TODO: Account for historical db pub fn initialise_beacon_chain( spec: &ChainSpec, db_name: Option<&PathBuf>, -) -> Arc>> { +) -> Arc< + BeaconChain< + DiskDB, + SystemTimeSlotClock, + BitwiseLMDGhost, + FoundationStateTypes, + >, +> { // set up the db let db = Arc::new(DiskDB::open( db_name.expect("Database directory must be included"), @@ -64,7 +71,14 @@ pub fn initialise_beacon_chain( pub fn initialise_test_beacon_chain( spec: &ChainSpec, _db_name: Option<&PathBuf>, -) -> Arc>> { +) -> Arc< + BeaconChain< + MemoryDB, + SystemTimeSlotClock, + BitwiseLMDGhost, + FewValidatorsStateTypes, + >, +> { let db = Arc::new(MemoryDB::open()); let block_store = Arc::new(BeaconBlockStore::new(db.clone())); let state_store = Arc::new(BeaconStateStore::new(db.clone())); diff --git a/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs b/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs index d174670c0..9f9838ae7 100644 --- a/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs +++ b/beacon_node/beacon_chain/src/test_utils/testing_beacon_chain_builder.rs @@ -7,17 +7,18 @@ use fork_choice::BitwiseLMDGhost; use slot_clock::TestingSlotClock; use std::sync::Arc; use tree_hash::TreeHash; -use types::test_utils::TestingBeaconStateBuilder; use types::*; +use types::{test_utils::TestingBeaconStateBuilder, BeaconStateTypes, FewValidatorsStateTypes}; -type TestingBeaconChain = BeaconChain>; +type TestingBeaconChain = + BeaconChain, B>; -pub struct TestingBeaconChainBuilder { - state_builder: TestingBeaconStateBuilder, +pub struct TestingBeaconChainBuilder { + state_builder: TestingBeaconStateBuilder, } -impl TestingBeaconChainBuilder { - pub fn build(self, spec: &ChainSpec) -> TestingBeaconChain { +impl TestingBeaconChainBuilder { + pub fn build(self, spec: &ChainSpec) -> TestingBeaconChain { let db = Arc::new(MemoryDB::open()); let block_store = Arc::new(BeaconBlockStore::new(db.clone())); let state_store = Arc::new(BeaconStateStore::new(db.clone())); @@ -43,8 +44,8 @@ impl TestingBeaconChainBuilder { } } -impl From for TestingBeaconChainBuilder { - fn from(state_builder: TestingBeaconStateBuilder) -> TestingBeaconChainBuilder { +impl From> for TestingBeaconChainBuilder { + fn from(state_builder: TestingBeaconStateBuilder) -> TestingBeaconChainBuilder { TestingBeaconChainBuilder { state_builder } } } diff --git a/eth2/fork_choice/src/bitwise_lmd_ghost.rs b/eth2/fork_choice/src/bitwise_lmd_ghost.rs index 8ae0251d2..66100dbc1 100644 --- a/eth2/fork_choice/src/bitwise_lmd_ghost.rs +++ b/eth2/fork_choice/src/bitwise_lmd_ghost.rs @@ -9,8 +9,9 @@ use db::{ }; use log::{debug, trace}; use std::collections::HashMap; +use std::marker::PhantomData; use std::sync::Arc; -use types::{BeaconBlock, ChainSpec, Hash256, Slot, SlotHeight}; +use types::{BeaconBlock, BeaconState, BeaconStateTypes, ChainSpec, Hash256, Slot, SlotHeight}; //TODO: Pruning - Children //TODO: Handle Syncing @@ -33,7 +34,7 @@ fn power_of_2_below(x: u64) -> u64 { } /// Stores the necessary data structures to run the optimised bitwise lmd ghost algorithm. -pub struct BitwiseLMDGhost { +pub struct BitwiseLMDGhost { /// A cache of known ancestors at given heights for a specific block. //TODO: Consider FnvHashMap cache: HashMap, Hash256>, @@ -50,9 +51,10 @@ pub struct BitwiseLMDGhost { /// State storage access. state_store: Arc>, max_known_height: SlotHeight, + _phantom: PhantomData, } -impl BitwiseLMDGhost +impl BitwiseLMDGhost where T: ClientDB + Sized, { @@ -68,6 +70,7 @@ where max_known_height: SlotHeight::new(0), block_store, state_store, + _phantom: PhantomData, } } @@ -85,7 +88,7 @@ where // build a hashmap of block_hash to weighted votes let mut latest_votes: HashMap = HashMap::new(); // gets the current weighted votes - let current_state = self + let current_state: BeaconState = self .state_store .get_deserialized(&state_root)? .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; @@ -240,7 +243,7 @@ where } } -impl ForkChoice for BitwiseLMDGhost { +impl ForkChoice for BitwiseLMDGhost { fn add_block( &mut self, block: &BeaconBlock, diff --git a/eth2/fork_choice/src/optimized_lmd_ghost.rs b/eth2/fork_choice/src/optimized_lmd_ghost.rs index ee2919e85..3e43e2153 100644 --- a/eth2/fork_choice/src/optimized_lmd_ghost.rs +++ b/eth2/fork_choice/src/optimized_lmd_ghost.rs @@ -9,8 +9,9 @@ use db::{ use log::{debug, trace}; use std::cmp::Ordering; use std::collections::HashMap; +use std::marker::PhantomData; use std::sync::Arc; -use types::{BeaconBlock, ChainSpec, Hash256, Slot, SlotHeight}; +use types::{BeaconBlock, BeaconState, BeaconStateTypes, ChainSpec, Hash256, Slot, SlotHeight}; //TODO: Pruning - Children //TODO: Handle Syncing @@ -33,7 +34,7 @@ fn power_of_2_below(x: u64) -> u64 { } /// Stores the necessary data structures to run the optimised lmd ghost algorithm. -pub struct OptimizedLMDGhost { +pub struct OptimizedLMDGhost { /// A cache of known ancestors at given heights for a specific block. //TODO: Consider FnvHashMap cache: HashMap, Hash256>, @@ -50,9 +51,10 @@ pub struct OptimizedLMDGhost { /// State storage access. state_store: Arc>, max_known_height: SlotHeight, + _phantom: PhantomData, } -impl OptimizedLMDGhost +impl OptimizedLMDGhost where T: ClientDB + Sized, { @@ -68,6 +70,7 @@ where max_known_height: SlotHeight::new(0), block_store, state_store, + _phantom: PhantomData, } } @@ -85,7 +88,7 @@ where // build a hashmap of block_hash to weighted votes let mut latest_votes: HashMap = HashMap::new(); // gets the current weighted votes - let current_state = self + let current_state: BeaconState = self .state_store .get_deserialized(&state_root)? .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; @@ -211,7 +214,7 @@ where } } -impl ForkChoice for OptimizedLMDGhost { +impl ForkChoice for OptimizedLMDGhost { fn add_block( &mut self, block: &BeaconBlock, diff --git a/eth2/fork_choice/src/slow_lmd_ghost.rs b/eth2/fork_choice/src/slow_lmd_ghost.rs index 4b236cba4..c621870d1 100644 --- a/eth2/fork_choice/src/slow_lmd_ghost.rs +++ b/eth2/fork_choice/src/slow_lmd_ghost.rs @@ -7,12 +7,13 @@ use db::{ }; use log::{debug, trace}; use std::collections::HashMap; +use std::marker::PhantomData; use std::sync::Arc; -use types::{BeaconBlock, ChainSpec, Hash256, Slot}; +use types::{BeaconBlock, BeaconState, BeaconStateTypes, ChainSpec, Hash256, Slot}; //TODO: Pruning and syncing -pub struct SlowLMDGhost { +pub struct SlowLMDGhost { /// The latest attestation targets as a map of validator index to block hash. //TODO: Could this be a fixed size vec latest_attestation_targets: HashMap, @@ -22,9 +23,10 @@ pub struct SlowLMDGhost { block_store: Arc>, /// State storage access. state_store: Arc>, + _phantom: PhantomData, } -impl SlowLMDGhost +impl SlowLMDGhost where T: ClientDB + Sized, { @@ -37,6 +39,7 @@ where children: HashMap::new(), block_store, state_store, + _phantom: PhantomData, } } @@ -54,7 +57,7 @@ where // build a hashmap of block_hash to weighted votes let mut latest_votes: HashMap = HashMap::new(); // gets the current weighted votes - let current_state = self + let current_state: BeaconState = self .state_store .get_deserialized(&state_root)? .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; @@ -105,7 +108,7 @@ where } } -impl ForkChoice for SlowLMDGhost { +impl ForkChoice for SlowLMDGhost { /// Process when a block is added fn add_block( &mut self, diff --git a/eth2/types/src/beacon_state/beacon_state_types.rs b/eth2/types/src/beacon_state/beacon_state_types.rs index 4d296feed..5012ebb37 100644 --- a/eth2/types/src/beacon_state/beacon_state_types.rs +++ b/eth2/types/src/beacon_state/beacon_state_types.rs @@ -1,12 +1,13 @@ use crate::*; use fixed_len_vec::typenum::{Unsigned, U1024, U8, U8192}; +use std::fmt::Debug; -pub trait BeaconStateTypes: Default { - type ShardCount: Unsigned + Clone + Sync + Send; - type SlotsPerHistoricalRoot: Unsigned + Clone + Sync + Send; - type LatestRandaoMixesLength: Unsigned + Clone + Sync + Send; - type LatestActiveIndexRootsLength: Unsigned + Clone + Sync + Send; - type LatestSlashedExitLength: Unsigned + Clone + Sync + Send; +pub trait BeaconStateTypes: Default + Sync + Send + Clone + Debug + PartialEq { + type ShardCount: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type SlotsPerHistoricalRoot: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type LatestRandaoMixesLength: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type LatestActiveIndexRootsLength: Unsigned + Clone + Sync + Send + Debug + PartialEq; + type LatestSlashedExitLength: Unsigned + Clone + Sync + Send + Debug + PartialEq; fn spec() -> ChainSpec; }