Merge branch 'master' into disk-db

This commit is contained in:
Paul Hauner
2019-05-20 16:56:04 +10:00
203 changed files with 3893 additions and 19921 deletions

View File

@@ -83,30 +83,31 @@ impl BlockProcessingOutcome {
}
}
pub struct BeaconChain<T: ClientDB + Sized, U: SlotClock, F: ForkChoice> {
pub struct BeaconChain<T: ClientDB + Sized, U: SlotClock, F: ForkChoice, E: EthSpec> {
pub block_store: Arc<BeaconBlockStore<T>>,
pub state_store: Arc<BeaconStateStore<T>>,
pub slot_clock: U,
pub op_pool: OperationPool,
canonical_head: RwLock<CheckPoint>,
finalized_head: RwLock<CheckPoint>,
pub state: RwLock<BeaconState>,
pub op_pool: OperationPool<E>,
canonical_head: RwLock<CheckPoint<E>>,
finalized_head: RwLock<CheckPoint<E>>,
pub state: RwLock<BeaconState<E>>,
pub spec: ChainSpec,
pub fork_choice: RwLock<F>,
}
impl<T, U, F> BeaconChain<T, U, F>
impl<T, U, F, E> BeaconChain<T, U, F, E>
where
T: ClientDB,
U: SlotClock,
F: ForkChoice,
E: EthSpec,
{
/// Instantiate a new Beacon Chain, from genesis.
pub fn from_genesis(
state_store: Arc<BeaconStateStore<T>>,
block_store: Arc<BeaconBlockStore<T>>,
slot_clock: U,
mut genesis_state: BeaconState,
mut genesis_state: BeaconState<E>,
genesis_block: BeaconBlock,
spec: ChainSpec,
fork_choice: F,
@@ -190,7 +191,6 @@ where
count: usize,
skip: usize,
) -> Result<Vec<Hash256>, Error> {
let spec = &self.spec;
let step_by = Slot::from(skip + 1);
let mut roots: Vec<Hash256> = vec![];
@@ -218,7 +218,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 +230,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(E::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 +270,7 @@ where
&self,
new_beacon_block: BeaconBlock,
new_beacon_block_root: Hash256,
new_beacon_state: BeaconState,
new_beacon_state: BeaconState<E>,
new_beacon_state_root: Hash256,
) {
debug!(
@@ -292,7 +292,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<CheckPoint> {
pub fn head(&self) -> RwLockReadGuard<CheckPoint<E>> {
self.canonical_head.read()
}
@@ -302,7 +302,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<E>) -> Result<(), Error> {
let present_slot = match self.slot_clock.present_slot() {
Ok(Some(slot)) => slot,
_ => return Err(Error::UnableToReadSlot),
@@ -357,7 +357,7 @@ where
&self,
new_beacon_block: BeaconBlock,
new_beacon_block_root: Hash256,
new_beacon_state: BeaconState,
new_beacon_state: BeaconState<E>,
new_beacon_state_root: Hash256,
) {
let mut finalized_head = self.finalized_head.write();
@@ -371,7 +371,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<CheckPoint> {
pub fn finalized_head(&self) -> RwLockReadGuard<CheckPoint<E>> {
self.finalized_head.read()
}
@@ -493,17 +493,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 +664,7 @@ where
pub fn produce_block(
&self,
randao_reveal: Signature,
) -> Result<(BeaconBlock, BeaconState), BlockProductionError> {
) -> Result<(BeaconBlock, BeaconState<E>), BlockProductionError> {
debug!("Producing block at slot {}...", self.state.read().slot);
let mut state = self.state.read().clone();
@@ -677,7 +674,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 +759,7 @@ where
///
/// This could be a very expensive operation and should only be done in testing/analysis
/// activities.
pub fn chain_dump(&self) -> Result<Vec<CheckPoint>, Error> {
pub fn chain_dump(&self) -> Result<Vec<CheckPoint<E>>, Error> {
let mut dump = vec![];
let mut last_slot = CheckPoint {

View File

@@ -1,22 +1,22 @@
use serde_derive::Serialize;
use types::{BeaconBlock, BeaconState, Hash256};
use types::{BeaconBlock, BeaconState, EthSpec, 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<E: EthSpec> {
pub beacon_block: BeaconBlock,
pub beacon_block_root: Hash256,
pub beacon_state: BeaconState,
pub beacon_state: BeaconState<E>,
pub beacon_state_root: Hash256,
}
impl CheckPoint {
impl<E: EthSpec> CheckPoint<E> {
/// Create a new checkpoint.
pub fn new(
beacon_block: BeaconBlock,
beacon_block_root: Hash256,
beacon_state: BeaconState,
beacon_state: BeaconState<E>,
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<E>,
beacon_state_root: Hash256,
) {
self.beacon_block = beacon_block;

View File

@@ -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, FewValidatorsEthSpec, FoundationEthSpec, Hash256};
//TODO: Correct this for prod
//TODO: Account for historical db
pub fn initialise_beacon_chain(
spec: &ChainSpec,
db_name: Option<&PathBuf>,
) -> Arc<BeaconChain<DiskDB, SystemTimeSlotClock, BitwiseLMDGhost<DiskDB>>> {
) -> Arc<
BeaconChain<
DiskDB,
SystemTimeSlotClock,
BitwiseLMDGhost<DiskDB, FoundationEthSpec>,
FoundationEthSpec,
>,
> {
// 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_with_memory_db(
spec: &ChainSpec,
_db_name: Option<&PathBuf>,
) -> Arc<BeaconChain<MemoryDB, SystemTimeSlotClock, BitwiseLMDGhost<MemoryDB>>> {
) -> Arc<
BeaconChain<
MemoryDB,
SystemTimeSlotClock,
BitwiseLMDGhost<MemoryDB, FewValidatorsEthSpec>,
FewValidatorsEthSpec,
>,
> {
let db = Arc::new(MemoryDB::open());
let block_store = Arc::new(BeaconBlockStore::new(db.clone()));
let state_store = Arc::new(BeaconStateStore::new(db.clone()));

View File

@@ -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, EthSpec, FewValidatorsEthSpec};
type TestingBeaconChain = BeaconChain<MemoryDB, TestingSlotClock, BitwiseLMDGhost<MemoryDB>>;
type TestingBeaconChain<E> =
BeaconChain<MemoryDB, TestingSlotClock, BitwiseLMDGhost<MemoryDB, FewValidatorsEthSpec>, E>;
pub struct TestingBeaconChainBuilder {
state_builder: TestingBeaconStateBuilder,
pub struct TestingBeaconChainBuilder<E: EthSpec> {
state_builder: TestingBeaconStateBuilder<E>,
}
impl TestingBeaconChainBuilder {
pub fn build(self, spec: &ChainSpec) -> TestingBeaconChain {
impl<E: EthSpec> TestingBeaconChainBuilder<E> {
pub fn build(self, spec: &ChainSpec) -> TestingBeaconChain<E> {
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<TestingBeaconStateBuilder> for TestingBeaconChainBuilder {
fn from(state_builder: TestingBeaconStateBuilder) -> TestingBeaconChainBuilder {
impl<E: EthSpec> From<TestingBeaconStateBuilder<E>> for TestingBeaconChainBuilder<E> {
fn from(state_builder: TestingBeaconStateBuilder<E>) -> TestingBeaconChainBuilder<E> {
TestingBeaconChainBuilder { state_builder }
}
}