Migrate fork_choice over to new DB

This commit is contained in:
Paul Hauner 2019-05-21 12:58:51 +10:00
parent f8c425d6b4
commit 2128d411bc
No known key found for this signature in database
GPG Key ID: 5E2CFF9B75FA63DF
5 changed files with 65 additions and 99 deletions

View File

@ -3,10 +3,7 @@ extern crate bit_vec;
use crate::{ForkChoice, ForkChoiceError}; use crate::{ForkChoice, ForkChoiceError};
use bit_vec::BitVec; use bit_vec::BitVec;
use db::{ use db::Store;
stores::{BeaconBlockStore, BeaconStateStore},
ClientDB,
};
use log::{debug, trace}; use log::{debug, trace};
use std::collections::HashMap; use std::collections::HashMap;
use std::marker::PhantomData; use std::marker::PhantomData;
@ -34,7 +31,7 @@ fn power_of_2_below(x: u64) -> u64 {
} }
/// Stores the necessary data structures to run the optimised bitwise lmd ghost algorithm. /// Stores the necessary data structures to run the optimised bitwise lmd ghost algorithm.
pub struct BitwiseLMDGhost<T: ClientDB + Sized, E> { pub struct BitwiseLMDGhost<T, E> {
/// A cache of known ancestors at given heights for a specific block. /// A cache of known ancestors at given heights for a specific block.
//TODO: Consider FnvHashMap //TODO: Consider FnvHashMap
cache: HashMap<CacheKey<u64>, Hash256>, cache: HashMap<CacheKey<u64>, Hash256>,
@ -46,30 +43,21 @@ pub struct BitwiseLMDGhost<T: ClientDB + Sized, E> {
/// The latest attestation targets as a map of validator index to block hash. /// The latest attestation targets as a map of validator index to block hash.
//TODO: Could this be a fixed size vec //TODO: Could this be a fixed size vec
latest_attestation_targets: HashMap<u64, Hash256>, latest_attestation_targets: HashMap<u64, Hash256>,
/// Block storage access. /// Block and state storage.
block_store: Arc<BeaconBlockStore<T>>, store: Arc<T>,
/// State storage access.
state_store: Arc<BeaconStateStore<T>>,
max_known_height: SlotHeight, max_known_height: SlotHeight,
_phantom: PhantomData<E>, _phantom: PhantomData<E>,
} }
impl<T, E: EthSpec> BitwiseLMDGhost<T, E> impl<T: Store, E: EthSpec> BitwiseLMDGhost<T, E> {
where pub fn new(store: Arc<T>) -> Self {
T: ClientDB + Sized,
{
pub fn new(
block_store: Arc<BeaconBlockStore<T>>,
state_store: Arc<BeaconStateStore<T>>,
) -> Self {
BitwiseLMDGhost { BitwiseLMDGhost {
cache: HashMap::new(), cache: HashMap::new(),
ancestors: vec![HashMap::new(); 16], ancestors: vec![HashMap::new(); 16],
latest_attestation_targets: HashMap::new(), latest_attestation_targets: HashMap::new(),
children: HashMap::new(), children: HashMap::new(),
max_known_height: SlotHeight::new(0), max_known_height: SlotHeight::new(0),
block_store, store,
state_store,
_phantom: PhantomData, _phantom: PhantomData,
} }
} }
@ -89,8 +77,8 @@ where
let mut latest_votes: HashMap<Hash256, u64> = HashMap::new(); let mut latest_votes: HashMap<Hash256, u64> = HashMap::new();
// gets the current weighted votes // gets the current weighted votes
let current_state: BeaconState<E> = self let current_state: BeaconState<E> = self
.state_store .store
.get_deserialized(&state_root)? .get(&state_root)?
.ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?;
let active_validator_indices = let active_validator_indices =
@ -121,8 +109,8 @@ where
// return None if we can't get the block from the db. // return None if we can't get the block from the db.
let block_height = { let block_height = {
let block_slot = self let block_slot = self
.block_store .store
.get_deserialized(&block_hash) .get::<BeaconBlock>(&block_hash)
.ok()? .ok()?
.expect("Should have returned already if None") .expect("Should have returned already if None")
.slot; .slot;
@ -243,7 +231,7 @@ where
} }
} }
impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for BitwiseLMDGhost<T, E> { impl<T: Store, E: EthSpec> ForkChoice for BitwiseLMDGhost<T, E> {
fn add_block( fn add_block(
&mut self, &mut self,
block: &BeaconBlock, block: &BeaconBlock,
@ -252,8 +240,8 @@ impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for BitwiseLMDGhost<T, E> {
) -> Result<(), ForkChoiceError> { ) -> Result<(), ForkChoiceError> {
// get the height of the parent // get the height of the parent
let parent_height = self let parent_height = self
.block_store .store
.get_deserialized(&block.previous_block_root)? .get::<BeaconBlock>(&block.previous_block_root)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(block.previous_block_root))? .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(block.previous_block_root))?
.slot .slot
.height(spec.genesis_slot); .height(spec.genesis_slot);
@ -304,16 +292,16 @@ impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for BitwiseLMDGhost<T, E> {
trace!("Old attestation found: {:?}", attestation_target); trace!("Old attestation found: {:?}", attestation_target);
// get the height of the target block // get the height of the target block
let block_height = self let block_height = self
.block_store .store
.get_deserialized(&target_block_root)? .get::<BeaconBlock>(&target_block_root)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*target_block_root))? .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*target_block_root))?
.slot .slot
.height(spec.genesis_slot); .height(spec.genesis_slot);
// get the height of the past target block // get the height of the past target block
let past_block_height = self let past_block_height = self
.block_store .store
.get_deserialized(&attestation_target)? .get::<BeaconBlock>(&attestation_target)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*attestation_target))? .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*attestation_target))?
.slot .slot
.height(spec.genesis_slot); .height(spec.genesis_slot);
@ -337,8 +325,8 @@ impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for BitwiseLMDGhost<T, E> {
justified_block_start justified_block_start
); );
let block = self let block = self
.block_store .store
.get_deserialized(&justified_block_start)? .get::<BeaconBlock>(&justified_block_start)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*justified_block_start))?; .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*justified_block_start))?;
let block_slot = block.slot; let block_slot = block.slot;
@ -429,8 +417,8 @@ impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for BitwiseLMDGhost<T, E> {
// didn't find head yet, proceed to next iteration // didn't find head yet, proceed to next iteration
// update block height // update block height
block_height = self block_height = self
.block_store .store
.get_deserialized(&current_head)? .get::<BeaconBlock>(&current_head)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(current_head))? .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(current_head))?
.slot .slot
.height(spec.genesis_slot); .height(spec.genesis_slot);

View File

@ -16,11 +16,9 @@
//! [`slow_lmd_ghost`]: struct.SlowLmdGhost.html //! [`slow_lmd_ghost`]: struct.SlowLmdGhost.html
//! [`bitwise_lmd_ghost`]: struct.OptimisedLmdGhost.html //! [`bitwise_lmd_ghost`]: struct.OptimisedLmdGhost.html
/*
pub mod bitwise_lmd_ghost; pub mod bitwise_lmd_ghost;
pub mod longest_chain; 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 db::stores::BeaconBlockAtSlotError; // use db::stores::BeaconBlockAtSlotError;
@ -28,11 +26,9 @@ pub mod slow_lmd_ghost;
use db::Error as DBError; use db::Error as DBError;
use types::{BeaconBlock, ChainSpec, Hash256}; use types::{BeaconBlock, ChainSpec, Hash256};
/*
pub use bitwise_lmd_ghost::BitwiseLMDGhost; pub use bitwise_lmd_ghost::BitwiseLMDGhost;
pub use longest_chain::LongestChain; pub use longest_chain::LongestChain;
pub use optimized_lmd_ghost::OptimizedLMDGhost; pub use optimized_lmd_ghost::OptimizedLMDGhost;
*/
pub use slow_lmd_ghost::SlowLMDGhost; 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

View File

@ -1,31 +1,25 @@
use crate::{ForkChoice, ForkChoiceError}; use crate::{ForkChoice, ForkChoiceError};
use db::{stores::BeaconBlockStore, ClientDB}; use db::Store;
use std::sync::Arc; use std::sync::Arc;
use types::{BeaconBlock, ChainSpec, Hash256, Slot}; use types::{BeaconBlock, ChainSpec, Hash256, Slot};
pub struct LongestChain<T> pub struct LongestChain<T> {
where
T: ClientDB + Sized,
{
/// List of head block hashes /// List of head block hashes
head_block_hashes: Vec<Hash256>, head_block_hashes: Vec<Hash256>,
/// Block storage access. /// Block storage.
block_store: Arc<BeaconBlockStore<T>>, store: Arc<T>,
} }
impl<T> LongestChain<T> impl<T: Store> LongestChain<T> {
where pub fn new(store: Arc<T>) -> Self {
T: ClientDB + Sized,
{
pub fn new(block_store: Arc<BeaconBlockStore<T>>) -> Self {
LongestChain { LongestChain {
head_block_hashes: Vec::new(), head_block_hashes: Vec::new(),
block_store, store,
} }
} }
} }
impl<T: ClientDB + Sized> ForkChoice for LongestChain<T> { impl<T: Store> ForkChoice for LongestChain<T> {
fn add_block( fn add_block(
&mut self, &mut self,
block: &BeaconBlock, block: &BeaconBlock,
@ -55,9 +49,9 @@ impl<T: ClientDB + Sized> ForkChoice for LongestChain<T> {
* Load all the head_block hashes from the DB as SszBeaconBlocks. * Load all the head_block hashes from the DB as SszBeaconBlocks.
*/ */
for (index, block_hash) in self.head_block_hashes.iter().enumerate() { for (index, block_hash) in self.head_block_hashes.iter().enumerate() {
let block = self let block: BeaconBlock = self
.block_store .store
.get_deserialized(&block_hash)? .get(&block_hash)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*block_hash))?; .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*block_hash))?;
head_blocks.push((index, block)); head_blocks.push((index, block));
} }

View File

@ -2,10 +2,7 @@
extern crate bit_vec; extern crate bit_vec;
use crate::{ForkChoice, ForkChoiceError}; use crate::{ForkChoice, ForkChoiceError};
use db::{ use db::Store;
stores::{BeaconBlockStore, BeaconStateStore},
ClientDB,
};
use log::{debug, trace}; use log::{debug, trace};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::collections::HashMap; use std::collections::HashMap;
@ -34,7 +31,7 @@ fn power_of_2_below(x: u64) -> u64 {
} }
/// Stores the necessary data structures to run the optimised lmd ghost algorithm. /// Stores the necessary data structures to run the optimised lmd ghost algorithm.
pub struct OptimizedLMDGhost<T: ClientDB + Sized, E> { pub struct OptimizedLMDGhost<T, E> {
/// A cache of known ancestors at given heights for a specific block. /// A cache of known ancestors at given heights for a specific block.
//TODO: Consider FnvHashMap //TODO: Consider FnvHashMap
cache: HashMap<CacheKey<u64>, Hash256>, cache: HashMap<CacheKey<u64>, Hash256>,
@ -46,30 +43,21 @@ pub struct OptimizedLMDGhost<T: ClientDB + Sized, E> {
/// The latest attestation targets as a map of validator index to block hash. /// The latest attestation targets as a map of validator index to block hash.
//TODO: Could this be a fixed size vec //TODO: Could this be a fixed size vec
latest_attestation_targets: HashMap<u64, Hash256>, latest_attestation_targets: HashMap<u64, Hash256>,
/// Block storage access. /// Block and state storage.
block_store: Arc<BeaconBlockStore<T>>, store: Arc<T>,
/// State storage access.
state_store: Arc<BeaconStateStore<T>>,
max_known_height: SlotHeight, max_known_height: SlotHeight,
_phantom: PhantomData<E>, _phantom: PhantomData<E>,
} }
impl<T, E: EthSpec> OptimizedLMDGhost<T, E> impl<T: Store, E: EthSpec> OptimizedLMDGhost<T, E> {
where pub fn new(store: Arc<T>) -> Self {
T: ClientDB + Sized,
{
pub fn new(
block_store: Arc<BeaconBlockStore<T>>,
state_store: Arc<BeaconStateStore<T>>,
) -> Self {
OptimizedLMDGhost { OptimizedLMDGhost {
cache: HashMap::new(), cache: HashMap::new(),
ancestors: vec![HashMap::new(); 16], ancestors: vec![HashMap::new(); 16],
latest_attestation_targets: HashMap::new(), latest_attestation_targets: HashMap::new(),
children: HashMap::new(), children: HashMap::new(),
max_known_height: SlotHeight::new(0), max_known_height: SlotHeight::new(0),
block_store, store,
state_store,
_phantom: PhantomData, _phantom: PhantomData,
} }
} }
@ -89,8 +77,8 @@ where
let mut latest_votes: HashMap<Hash256, u64> = HashMap::new(); let mut latest_votes: HashMap<Hash256, u64> = HashMap::new();
// gets the current weighted votes // gets the current weighted votes
let current_state: BeaconState<E> = self let current_state: BeaconState<E> = self
.state_store .store
.get_deserialized(&state_root)? .get(&state_root)?
.ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?; .ok_or_else(|| ForkChoiceError::MissingBeaconState(*state_root))?;
let active_validator_indices = let active_validator_indices =
@ -121,8 +109,8 @@ where
// return None if we can't get the block from the db. // return None if we can't get the block from the db.
let block_height = { let block_height = {
let block_slot = self let block_slot = self
.block_store .store
.get_deserialized(&block_hash) .get::<BeaconBlock>(&block_hash)
.ok()? .ok()?
.expect("Should have returned already if None") .expect("Should have returned already if None")
.slot; .slot;
@ -214,7 +202,7 @@ where
} }
} }
impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for OptimizedLMDGhost<T, E> { impl<T: Store, E: EthSpec> ForkChoice for OptimizedLMDGhost<T, E> {
fn add_block( fn add_block(
&mut self, &mut self,
block: &BeaconBlock, block: &BeaconBlock,
@ -223,8 +211,8 @@ impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for OptimizedLMDGhost<T, E> {
) -> Result<(), ForkChoiceError> { ) -> Result<(), ForkChoiceError> {
// get the height of the parent // get the height of the parent
let parent_height = self let parent_height = self
.block_store .store
.get_deserialized(&block.previous_block_root)? .get::<BeaconBlock>(&block.previous_block_root)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(block.previous_block_root))? .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(block.previous_block_root))?
.slot .slot
.height(spec.genesis_slot); .height(spec.genesis_slot);
@ -275,16 +263,16 @@ impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for OptimizedLMDGhost<T, E> {
trace!("Old attestation found: {:?}", attestation_target); trace!("Old attestation found: {:?}", attestation_target);
// get the height of the target block // get the height of the target block
let block_height = self let block_height = self
.block_store .store
.get_deserialized(&target_block_root)? .get::<BeaconBlock>(&target_block_root)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*target_block_root))? .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*target_block_root))?
.slot .slot
.height(spec.genesis_slot); .height(spec.genesis_slot);
// get the height of the past target block // get the height of the past target block
let past_block_height = self let past_block_height = self
.block_store .store
.get_deserialized(&attestation_target)? .get::<BeaconBlock>(&attestation_target)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*attestation_target))? .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*attestation_target))?
.slot .slot
.height(spec.genesis_slot); .height(spec.genesis_slot);
@ -308,8 +296,8 @@ impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for OptimizedLMDGhost<T, E> {
justified_block_start justified_block_start
); );
let block = self let block = self
.block_store .store
.get_deserialized(&justified_block_start)? .get::<BeaconBlock>(&justified_block_start)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*justified_block_start))?; .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*justified_block_start))?;
let block_slot = block.slot; let block_slot = block.slot;
@ -400,8 +388,8 @@ impl<T: ClientDB + Sized, E: EthSpec> ForkChoice for OptimizedLMDGhost<T, E> {
// didn't find head yet, proceed to next iteration // didn't find head yet, proceed to next iteration
// update block height // update block height
block_height = self block_height = self
.block_store .store
.get_deserialized(&current_head)? .get::<BeaconBlock>(&current_head)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(current_head))? .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(current_head))?
.slot .slot
.height(spec.genesis_slot); .height(spec.genesis_slot);

View File

@ -1,7 +1,7 @@
extern crate db; extern crate db;
use crate::{ForkChoice, ForkChoiceError}; use crate::{ForkChoice, ForkChoiceError};
use db::{Store, StoreItem}; use db::Store;
use log::{debug, trace}; use log::{debug, trace};
use std::collections::HashMap; use std::collections::HashMap;
use std::marker::PhantomData; use std::marker::PhantomData;
@ -16,7 +16,7 @@ pub struct SlowLMDGhost<T, E> {
latest_attestation_targets: HashMap<u64, Hash256>, latest_attestation_targets: HashMap<u64, Hash256>,
/// Stores the children for any given parent. /// Stores the children for any given parent.
children: HashMap<Hash256, Vec<Hash256>>, children: HashMap<Hash256, Vec<Hash256>>,
/// Persistent storage /// Block and state storage.
store: Arc<T>, store: Arc<T>,
_phantom: PhantomData<E>, _phantom: PhantomData<E>,
} }
@ -85,8 +85,8 @@ impl<T: Store, E: EthSpec> SlowLMDGhost<T, E> {
for (vote_hash, votes) in latest_votes.iter() { for (vote_hash, votes) in latest_votes.iter() {
let (root_at_slot, _) = self let (root_at_slot, _) = self
.block_store .store
.block_at_slot(&vote_hash, block_slot)? .get_block_at_preceeding_slot(*vote_hash, block_slot)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*block_root))?; .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*block_root))?;
if root_at_slot == *block_root { if root_at_slot == *block_root {
count += votes; count += votes;
@ -138,16 +138,16 @@ impl<T: Store, E: EthSpec> ForkChoice for SlowLMDGhost<T, E> {
trace!("Old attestation found: {:?}", attestation_target); trace!("Old attestation found: {:?}", attestation_target);
// get the height of the target block // get the height of the target block
let block_height = self let block_height = self
.block_store .store
.get_deserialized(&target_block_root)? .get::<BeaconBlock>(&target_block_root)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*target_block_root))? .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*target_block_root))?
.slot .slot
.height(spec.genesis_slot); .height(spec.genesis_slot);
// get the height of the past target block // get the height of the past target block
let past_block_height = self let past_block_height = self
.block_store .store
.get_deserialized(&attestation_target)? .get::<BeaconBlock>(&attestation_target)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*attestation_target))? .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*attestation_target))?
.slot .slot
.height(spec.genesis_slot); .height(spec.genesis_slot);
@ -168,8 +168,8 @@ impl<T: Store, E: EthSpec> ForkChoice for SlowLMDGhost<T, E> {
) -> Result<Hash256, ForkChoiceError> { ) -> Result<Hash256, ForkChoiceError> {
debug!("Running LMD Ghost Fork-choice rule"); debug!("Running LMD Ghost Fork-choice rule");
let start = self let start = self
.block_store .store
.get_deserialized(&justified_block_start)? .get::<BeaconBlock>(&justified_block_start)?
.ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*justified_block_start))?; .ok_or_else(|| ForkChoiceError::MissingBeaconBlock(*justified_block_start))?;
let start_state_root = start.state_root; let start_state_root = start.state_root;