mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-21 22:04:44 +00:00
Create BeaconChainTypes, thread through runtime
This commit is contained in:
@@ -79,32 +79,33 @@ impl BlockProcessingOutcome {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BeaconChain<T, U, F, E: EthSpec> {
|
||||
pub store: Arc<T>,
|
||||
pub slot_clock: U,
|
||||
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>,
|
||||
pub trait BeaconChainTypes {
|
||||
type Store: store::Store;
|
||||
type SlotClock: slot_clock::SlotClock;
|
||||
type ForkChoice: fork_choice::ForkChoice;
|
||||
type EthSpec: types::EthSpec;
|
||||
}
|
||||
|
||||
impl<T, U, F, E> BeaconChain<T, U, F, E>
|
||||
where
|
||||
T: Store,
|
||||
U: SlotClock,
|
||||
F: ForkChoice,
|
||||
E: EthSpec,
|
||||
{
|
||||
pub struct BeaconChain<T: BeaconChainTypes> {
|
||||
pub store: Arc<T::Store>,
|
||||
pub slot_clock: T::SlotClock,
|
||||
pub op_pool: OperationPool<T::EthSpec>,
|
||||
canonical_head: RwLock<CheckPoint<T::EthSpec>>,
|
||||
finalized_head: RwLock<CheckPoint<T::EthSpec>>,
|
||||
pub state: RwLock<BeaconState<T::EthSpec>>,
|
||||
pub spec: ChainSpec,
|
||||
pub fork_choice: RwLock<T::ForkChoice>,
|
||||
}
|
||||
|
||||
impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
/// Instantiate a new Beacon Chain, from genesis.
|
||||
pub fn from_genesis(
|
||||
store: Arc<T>,
|
||||
slot_clock: U,
|
||||
mut genesis_state: BeaconState<E>,
|
||||
store: Arc<T::Store>,
|
||||
slot_clock: T::SlotClock,
|
||||
mut genesis_state: BeaconState<T::EthSpec>,
|
||||
genesis_block: BeaconBlock,
|
||||
spec: ChainSpec,
|
||||
fork_choice: F,
|
||||
fork_choice: T::ForkChoice,
|
||||
) -> Result<Self, Error> {
|
||||
let state_root = genesis_state.canonical_root();
|
||||
store.put(&state_root, &genesis_state)?;
|
||||
@@ -223,7 +224,7 @@ where
|
||||
Err(BeaconStateError::SlotOutOfBounds) => {
|
||||
// Read the earliest historic state in the current slot.
|
||||
let earliest_historic_slot =
|
||||
state.slot - Slot::from(E::SlotsPerHistoricalRoot::to_usize());
|
||||
state.slot - Slot::from(T::EthSpec::slots_per_historical_root());
|
||||
// Load the earlier state from disk.
|
||||
let new_state_root = state.get_state_root(earliest_historic_slot)?;
|
||||
|
||||
@@ -263,7 +264,7 @@ where
|
||||
&self,
|
||||
new_beacon_block: BeaconBlock,
|
||||
new_beacon_block_root: Hash256,
|
||||
new_beacon_state: BeaconState<E>,
|
||||
new_beacon_state: BeaconState<T::EthSpec>,
|
||||
new_beacon_state_root: Hash256,
|
||||
) {
|
||||
debug!(
|
||||
@@ -285,7 +286,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<E>> {
|
||||
pub fn head(&self) -> RwLockReadGuard<CheckPoint<T::EthSpec>> {
|
||||
self.canonical_head.read()
|
||||
}
|
||||
|
||||
@@ -295,7 +296,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<E>) -> Result<(), Error> {
|
||||
pub fn update_state(&self, mut state: BeaconState<T::EthSpec>) -> Result<(), Error> {
|
||||
let present_slot = match self.slot_clock.present_slot() {
|
||||
Ok(Some(slot)) => slot,
|
||||
_ => return Err(Error::UnableToReadSlot),
|
||||
@@ -350,7 +351,7 @@ where
|
||||
&self,
|
||||
new_beacon_block: BeaconBlock,
|
||||
new_beacon_block_root: Hash256,
|
||||
new_beacon_state: BeaconState<E>,
|
||||
new_beacon_state: BeaconState<T::EthSpec>,
|
||||
new_beacon_state_root: Hash256,
|
||||
) {
|
||||
let mut finalized_head = self.finalized_head.write();
|
||||
@@ -364,7 +365,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<E>> {
|
||||
pub fn finalized_head(&self) -> RwLockReadGuard<CheckPoint<T::EthSpec>> {
|
||||
self.finalized_head.read()
|
||||
}
|
||||
|
||||
@@ -602,7 +603,7 @@ where
|
||||
// significantly lower exposure surface to DoS attacks.
|
||||
|
||||
// Transition the parent state to the block slot.
|
||||
let mut state: BeaconState<E> = parent_state;
|
||||
let mut state: BeaconState<T::EthSpec> = parent_state;
|
||||
for _ in state.slot.as_u64()..block.slot.as_u64() {
|
||||
if let Err(e) = per_slot_processing(&mut state, &self.spec) {
|
||||
return Ok(BlockProcessingOutcome::InvalidBlock(
|
||||
@@ -657,7 +658,7 @@ where
|
||||
pub fn produce_block(
|
||||
&self,
|
||||
randao_reveal: Signature,
|
||||
) -> Result<(BeaconBlock, BeaconState<E>), BlockProductionError> {
|
||||
) -> Result<(BeaconBlock, BeaconState<T::EthSpec>), BlockProductionError> {
|
||||
debug!("Producing block at slot {}...", self.state.read().slot);
|
||||
|
||||
let mut state = self.state.read().clone();
|
||||
@@ -728,7 +729,7 @@ where
|
||||
.ok_or_else(|| Error::MissingBeaconBlock(new_head))?;
|
||||
let block_root = block.canonical_root();
|
||||
|
||||
let state: BeaconState<E> = self
|
||||
let state: BeaconState<T::EthSpec> = self
|
||||
.store
|
||||
.get(&block.state_root)?
|
||||
.ok_or_else(|| Error::MissingBeaconState(block.state_root))?;
|
||||
@@ -752,7 +753,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<E>>, Error> {
|
||||
pub fn chain_dump(&self) -> Result<Vec<CheckPoint<T::EthSpec>>, Error> {
|
||||
let mut dump = vec![];
|
||||
|
||||
let mut last_slot = CheckPoint {
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
// Initialisation functions to generate a new BeaconChain.
|
||||
// Note: A new version of ClientTypes may need to be implemented for the lighthouse
|
||||
// testnet. These are examples. Also. there is code duplication which can/should be cleaned up.
|
||||
|
||||
use crate::BeaconChain;
|
||||
use fork_choice::BitwiseLMDGhost;
|
||||
use slot_clock::SystemTimeSlotClock;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use store::{DiskStore, MemoryStore};
|
||||
use tree_hash::TreeHash;
|
||||
use types::test_utils::TestingBeaconStateBuilder;
|
||||
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<
|
||||
DiskStore,
|
||||
SystemTimeSlotClock,
|
||||
BitwiseLMDGhost<DiskStore, FoundationEthSpec>,
|
||||
FoundationEthSpec,
|
||||
>,
|
||||
> {
|
||||
let path = db_name.expect("db_name cannot be None.");
|
||||
let store = DiskStore::open(path).expect("Unable to open DB.");
|
||||
let store = Arc::new(store);
|
||||
|
||||
let state_builder = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(8, &spec);
|
||||
let (genesis_state, _keypairs) = state_builder.build();
|
||||
|
||||
let mut genesis_block = BeaconBlock::empty(&spec);
|
||||
genesis_block.state_root = Hash256::from_slice(&genesis_state.tree_hash_root());
|
||||
|
||||
// Slot clock
|
||||
let slot_clock = SystemTimeSlotClock::new(
|
||||
spec.genesis_slot,
|
||||
genesis_state.genesis_time,
|
||||
spec.seconds_per_slot,
|
||||
)
|
||||
.expect("Unable to load SystemTimeSlotClock");
|
||||
// Choose the fork choice
|
||||
let fork_choice = BitwiseLMDGhost::new(store.clone());
|
||||
|
||||
// Genesis chain
|
||||
//TODO: Handle error correctly
|
||||
Arc::new(
|
||||
BeaconChain::from_genesis(
|
||||
store,
|
||||
slot_clock,
|
||||
genesis_state,
|
||||
genesis_block,
|
||||
spec.clone(),
|
||||
fork_choice,
|
||||
)
|
||||
.expect("Terminate if beacon chain generation fails"),
|
||||
)
|
||||
}
|
||||
|
||||
/// Initialisation of a test beacon chain, uses an in memory db with fixed genesis time.
|
||||
pub fn initialise_test_beacon_chain_with_memory_db(
|
||||
spec: &ChainSpec,
|
||||
_db_name: Option<&PathBuf>,
|
||||
) -> Arc<
|
||||
BeaconChain<
|
||||
MemoryStore,
|
||||
SystemTimeSlotClock,
|
||||
BitwiseLMDGhost<MemoryStore, FewValidatorsEthSpec>,
|
||||
FewValidatorsEthSpec,
|
||||
>,
|
||||
> {
|
||||
let store = Arc::new(MemoryStore::open());
|
||||
|
||||
let state_builder = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(8, spec);
|
||||
let (genesis_state, _keypairs) = state_builder.build();
|
||||
|
||||
let mut genesis_block = BeaconBlock::empty(spec);
|
||||
genesis_block.state_root = Hash256::from_slice(&genesis_state.tree_hash_root());
|
||||
|
||||
// Slot clock
|
||||
let slot_clock = SystemTimeSlotClock::new(
|
||||
spec.genesis_slot,
|
||||
genesis_state.genesis_time,
|
||||
spec.seconds_per_slot,
|
||||
)
|
||||
.expect("Unable to load SystemTimeSlotClock");
|
||||
// Choose the fork choice
|
||||
let fork_choice = BitwiseLMDGhost::new(store.clone());
|
||||
|
||||
// Genesis chain
|
||||
//TODO: Handle error correctly
|
||||
Arc::new(
|
||||
BeaconChain::from_genesis(
|
||||
store,
|
||||
slot_clock,
|
||||
genesis_state,
|
||||
genesis_block,
|
||||
spec.clone(),
|
||||
fork_choice,
|
||||
)
|
||||
.expect("Terminate if beacon chain generation fails"),
|
||||
)
|
||||
}
|
||||
|
||||
/// Initialisation of a test beacon chain, uses an in memory db with fixed genesis time.
|
||||
pub fn initialise_test_beacon_chain_with_disk_db(
|
||||
spec: &ChainSpec,
|
||||
db_name: Option<&PathBuf>,
|
||||
) -> Arc<
|
||||
BeaconChain<
|
||||
DiskStore,
|
||||
SystemTimeSlotClock,
|
||||
BitwiseLMDGhost<DiskStore, FewValidatorsEthSpec>,
|
||||
FewValidatorsEthSpec,
|
||||
>,
|
||||
> {
|
||||
let path = db_name.expect("db_name cannot be None.");
|
||||
let store = DiskStore::open(path).expect("Unable to open DB.");
|
||||
let store = Arc::new(store);
|
||||
|
||||
let state_builder = TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(8, spec);
|
||||
let (genesis_state, _keypairs) = state_builder.build();
|
||||
|
||||
let mut genesis_block = BeaconBlock::empty(spec);
|
||||
genesis_block.state_root = Hash256::from_slice(&genesis_state.tree_hash_root());
|
||||
|
||||
// Slot clock
|
||||
let slot_clock = SystemTimeSlotClock::new(
|
||||
spec.genesis_slot,
|
||||
genesis_state.genesis_time,
|
||||
spec.seconds_per_slot,
|
||||
)
|
||||
.expect("Unable to load SystemTimeSlotClock");
|
||||
// Choose the fork choice
|
||||
let fork_choice = BitwiseLMDGhost::new(store.clone());
|
||||
|
||||
// Genesis chain
|
||||
//TODO: Handle error correctly
|
||||
Arc::new(
|
||||
BeaconChain::from_genesis(
|
||||
store,
|
||||
slot_clock,
|
||||
genesis_state,
|
||||
genesis_block,
|
||||
spec.clone(),
|
||||
fork_choice,
|
||||
)
|
||||
.expect("Terminate if beacon chain generation fails"),
|
||||
)
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
mod beacon_chain;
|
||||
mod checkpoint;
|
||||
mod errors;
|
||||
pub mod initialise;
|
||||
pub mod test_utils;
|
||||
|
||||
pub use self::beacon_chain::{BeaconChain, BlockProcessingOutcome, InvalidBlock, ValidBlock};
|
||||
pub use self::beacon_chain::{
|
||||
BeaconChain, BeaconChainTypes, BlockProcessingOutcome, InvalidBlock, ValidBlock,
|
||||
};
|
||||
pub use self::checkpoint::CheckPoint;
|
||||
pub use self::errors::{BeaconChainError, BlockProductionError};
|
||||
pub use fork_choice;
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
mod testing_beacon_chain_builder;
|
||||
|
||||
pub use testing_beacon_chain_builder::TestingBeaconChainBuilder;
|
||||
@@ -1,49 +0,0 @@
|
||||
pub use crate::{BeaconChain, BeaconChainError, CheckPoint};
|
||||
use fork_choice::BitwiseLMDGhost;
|
||||
use slot_clock::TestingSlotClock;
|
||||
use std::sync::Arc;
|
||||
use store::MemoryStore;
|
||||
use tree_hash::TreeHash;
|
||||
use types::*;
|
||||
use types::{test_utils::TestingBeaconStateBuilder, EthSpec, FewValidatorsEthSpec};
|
||||
|
||||
type TestingBeaconChain<E> = BeaconChain<
|
||||
MemoryStore,
|
||||
TestingSlotClock,
|
||||
BitwiseLMDGhost<MemoryStore, FewValidatorsEthSpec>,
|
||||
E,
|
||||
>;
|
||||
|
||||
pub struct TestingBeaconChainBuilder<E: EthSpec> {
|
||||
state_builder: TestingBeaconStateBuilder<E>,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> TestingBeaconChainBuilder<E> {
|
||||
pub fn build(self, spec: &ChainSpec) -> TestingBeaconChain<E> {
|
||||
let store = Arc::new(MemoryStore::open());
|
||||
let slot_clock = TestingSlotClock::new(spec.genesis_slot.as_u64());
|
||||
let fork_choice = BitwiseLMDGhost::new(store.clone());
|
||||
|
||||
let (genesis_state, _keypairs) = self.state_builder.build();
|
||||
|
||||
let mut genesis_block = BeaconBlock::empty(&spec);
|
||||
genesis_block.state_root = Hash256::from_slice(&genesis_state.tree_hash_root());
|
||||
|
||||
// Create the Beacon Chain
|
||||
BeaconChain::from_genesis(
|
||||
store,
|
||||
slot_clock,
|
||||
genesis_state,
|
||||
genesis_block,
|
||||
spec.clone(),
|
||||
fork_choice,
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> From<TestingBeaconStateBuilder<E>> for TestingBeaconChainBuilder<E> {
|
||||
fn from(state_builder: TestingBeaconStateBuilder<E>) -> TestingBeaconChainBuilder<E> {
|
||||
TestingBeaconChainBuilder { state_builder }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user