Remove iter mod from beacon chain
Now the iter mod in store is the only implementation
This commit is contained in:
parent
952e08ba38
commit
55196dff64
@ -1,7 +1,6 @@
|
|||||||
use crate::checkpoint::CheckPoint;
|
use crate::checkpoint::CheckPoint;
|
||||||
use crate::errors::{BeaconChainError as Error, BlockProductionError};
|
use crate::errors::{BeaconChainError as Error, BlockProductionError};
|
||||||
use crate::fork_choice::{Error as ForkChoiceError, ForkChoice};
|
use crate::fork_choice::{Error as ForkChoiceError, ForkChoice};
|
||||||
use crate::iter::{BlockIterator, BlockRootsIterator};
|
|
||||||
use crate::metrics::Metrics;
|
use crate::metrics::Metrics;
|
||||||
use crate::persisted_beacon_chain::{PersistedBeaconChain, BEACON_CHAIN_DB_KEY};
|
use crate::persisted_beacon_chain::{PersistedBeaconChain, BEACON_CHAIN_DB_KEY};
|
||||||
use lmd_ghost::LmdGhost;
|
use lmd_ghost::LmdGhost;
|
||||||
@ -19,6 +18,7 @@ use state_processing::{
|
|||||||
per_slot_processing, BlockProcessingError,
|
per_slot_processing, BlockProcessingError,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use store::iter::{BlockIterator, BlockRootsIterator, StateRootsIterator};
|
||||||
use store::{Error as DBError, Store};
|
use store::{Error as DBError, Store};
|
||||||
use tree_hash::TreeHash;
|
use tree_hash::TreeHash;
|
||||||
use types::*;
|
use types::*;
|
||||||
@ -203,7 +203,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
///
|
///
|
||||||
/// Contains duplicate headers when skip slots are encountered.
|
/// Contains duplicate headers when skip slots are encountered.
|
||||||
pub fn rev_iter_blocks(&self, slot: Slot) -> BlockIterator<T::EthSpec, T::Store> {
|
pub fn rev_iter_blocks(&self, slot: Slot) -> BlockIterator<T::EthSpec, T::Store> {
|
||||||
BlockIterator::new(self.store.clone(), self.state.read().clone(), slot)
|
BlockIterator::owned(self.store.clone(), self.state.read().clone(), slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterates in reverse (highest to lowest slot) through all block roots from `slot` through to
|
/// Iterates in reverse (highest to lowest slot) through all block roots from `slot` through to
|
||||||
@ -213,7 +213,15 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
///
|
///
|
||||||
/// Contains duplicate roots when skip slots are encountered.
|
/// Contains duplicate roots when skip slots are encountered.
|
||||||
pub fn rev_iter_block_roots(&self, slot: Slot) -> BlockRootsIterator<T::EthSpec, T::Store> {
|
pub fn rev_iter_block_roots(&self, slot: Slot) -> BlockRootsIterator<T::EthSpec, T::Store> {
|
||||||
BlockRootsIterator::new(self.store.clone(), self.state.read().clone(), slot)
|
BlockRootsIterator::owned(self.store.clone(), self.state.read().clone(), slot)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Iterates in reverse (highest to lowest slot) through all state roots from `slot` through to
|
||||||
|
/// genesis.
|
||||||
|
///
|
||||||
|
/// Returns `None` for roots prior to genesis or when there is an error reading from `Store`.
|
||||||
|
pub fn rev_iter_state_roots(&self, slot: Slot) -> StateRootsIterator<T::EthSpec, T::Store> {
|
||||||
|
StateRootsIterator::owned(self.store.clone(), self.state.read().clone(), slot)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the block at the given root, if any.
|
/// Returns the block at the given root, if any.
|
||||||
|
@ -1,133 +0,0 @@
|
|||||||
use std::sync::Arc;
|
|
||||||
use store::Store;
|
|
||||||
use types::{BeaconBlock, BeaconState, BeaconStateError, EthSpec, Hash256, Slot};
|
|
||||||
|
|
||||||
/// Extends `BlockRootsIterator`, returning `BeaconBlock` instances, instead of their roots.
|
|
||||||
pub struct BlockIterator<T: EthSpec, U> {
|
|
||||||
roots: BlockRootsIterator<T, U>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: EthSpec, U: Store> BlockIterator<T, U> {
|
|
||||||
/// Create a new iterator over all blocks in the given `beacon_state` and prior states.
|
|
||||||
pub fn new(store: Arc<U>, beacon_state: BeaconState<T>, start_slot: Slot) -> Self {
|
|
||||||
Self {
|
|
||||||
roots: BlockRootsIterator::new(store, beacon_state, start_slot),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: EthSpec, U: Store> Iterator for BlockIterator<T, U> {
|
|
||||||
type Item = BeaconBlock;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
let root = self.roots.next()?;
|
|
||||||
self.roots.store.get(&root).ok()?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Iterates backwards through block roots.
|
|
||||||
///
|
|
||||||
/// Uses the `latest_block_roots` field of `BeaconState` to as the source of block roots and will
|
|
||||||
/// perform a lookup on the `Store` for a prior `BeaconState` if `latest_block_roots` has been
|
|
||||||
/// exhausted.
|
|
||||||
///
|
|
||||||
/// Returns `None` for roots prior to genesis or when there is an error reading from `Store`.
|
|
||||||
pub struct BlockRootsIterator<T: EthSpec, U> {
|
|
||||||
store: Arc<U>,
|
|
||||||
beacon_state: BeaconState<T>,
|
|
||||||
slot: Slot,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: EthSpec, U: Store> BlockRootsIterator<T, U> {
|
|
||||||
/// Create a new iterator over all block roots in the given `beacon_state` and prior states.
|
|
||||||
pub fn new(store: Arc<U>, beacon_state: BeaconState<T>, start_slot: Slot) -> Self {
|
|
||||||
Self {
|
|
||||||
slot: start_slot,
|
|
||||||
beacon_state,
|
|
||||||
store,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: EthSpec, U: Store> Iterator for BlockRootsIterator<T, U> {
|
|
||||||
type Item = Hash256;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
if (self.slot == 0) || (self.slot > self.beacon_state.slot) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.slot -= 1;
|
|
||||||
|
|
||||||
match self.beacon_state.get_block_root(self.slot) {
|
|
||||||
Ok(root) => Some(*root),
|
|
||||||
Err(BeaconStateError::SlotOutOfBounds) => {
|
|
||||||
// Read a `BeaconState` from the store that has access to prior historical root.
|
|
||||||
self.beacon_state = {
|
|
||||||
// Load the earlier state from disk. Skip forward one slot, because a state
|
|
||||||
// doesn't return it's own state root.
|
|
||||||
let new_state_root = self.beacon_state.get_state_root(self.slot + 1).ok()?;
|
|
||||||
|
|
||||||
self.store.get(&new_state_root).ok()?
|
|
||||||
}?;
|
|
||||||
|
|
||||||
self.beacon_state.get_block_root(self.slot).ok().cloned()
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
use store::MemoryStore;
|
|
||||||
use types::{test_utils::TestingBeaconStateBuilder, Keypair, MainnetEthSpec};
|
|
||||||
|
|
||||||
fn get_state<T: EthSpec>() -> BeaconState<T> {
|
|
||||||
let builder = TestingBeaconStateBuilder::from_single_keypair(
|
|
||||||
0,
|
|
||||||
&Keypair::random(),
|
|
||||||
&T::default_spec(),
|
|
||||||
);
|
|
||||||
let (state, _keypairs) = builder.build();
|
|
||||||
state
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn root_iter() {
|
|
||||||
let store = Arc::new(MemoryStore::open());
|
|
||||||
let slots_per_historical_root = MainnetEthSpec::slots_per_historical_root();
|
|
||||||
|
|
||||||
let mut state_a: BeaconState<MainnetEthSpec> = get_state();
|
|
||||||
let mut state_b: BeaconState<MainnetEthSpec> = get_state();
|
|
||||||
|
|
||||||
state_a.slot = Slot::from(slots_per_historical_root);
|
|
||||||
state_b.slot = Slot::from(slots_per_historical_root * 2);
|
|
||||||
|
|
||||||
let mut hashes = (0..).into_iter().map(|i| Hash256::from(i));
|
|
||||||
|
|
||||||
for root in &mut state_a.latest_block_roots[..] {
|
|
||||||
*root = hashes.next().unwrap()
|
|
||||||
}
|
|
||||||
for root in &mut state_b.latest_block_roots[..] {
|
|
||||||
*root = hashes.next().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
let state_a_root = hashes.next().unwrap();
|
|
||||||
state_b.latest_state_roots[0] = state_a_root;
|
|
||||||
store.put(&state_a_root, &state_a).unwrap();
|
|
||||||
|
|
||||||
let iter = BlockRootsIterator::new(store.clone(), state_b.clone(), state_b.slot - 1);
|
|
||||||
let mut collected: Vec<Hash256> = iter.collect();
|
|
||||||
collected.reverse();
|
|
||||||
|
|
||||||
let expected_len = 2 * MainnetEthSpec::slots_per_historical_root() - 1;
|
|
||||||
|
|
||||||
assert_eq!(collected.len(), expected_len);
|
|
||||||
|
|
||||||
for i in 0..expected_len {
|
|
||||||
assert_eq!(collected[i], Hash256::from(i as u64));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,7 +2,6 @@ mod beacon_chain;
|
|||||||
mod checkpoint;
|
mod checkpoint;
|
||||||
mod errors;
|
mod errors;
|
||||||
mod fork_choice;
|
mod fork_choice;
|
||||||
pub mod iter;
|
|
||||||
mod metrics;
|
mod metrics;
|
||||||
mod persisted_beacon_chain;
|
mod persisted_beacon_chain;
|
||||||
pub mod test_utils;
|
pub mod test_utils;
|
||||||
|
@ -11,7 +11,6 @@ pub struct StateRootsIterator<'a, T: EthSpec, U> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: EthSpec, U: Store> StateRootsIterator<'a, T, U> {
|
impl<'a, T: EthSpec, U: Store> StateRootsIterator<'a, T, U> {
|
||||||
/// Create a new iterator over all blocks in the given `beacon_state` and prior states.
|
|
||||||
pub fn new(store: Arc<U>, beacon_state: &'a BeaconState<T>, start_slot: Slot) -> Self {
|
pub fn new(store: Arc<U>, beacon_state: &'a BeaconState<T>, start_slot: Slot) -> Self {
|
||||||
Self {
|
Self {
|
||||||
store,
|
store,
|
||||||
@ -19,6 +18,14 @@ impl<'a, T: EthSpec, U: Store> StateRootsIterator<'a, T, U> {
|
|||||||
slot: start_slot,
|
slot: start_slot,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn owned(store: Arc<U>, beacon_state: BeaconState<T>, start_slot: Slot) -> Self {
|
||||||
|
Self {
|
||||||
|
slot: start_slot,
|
||||||
|
beacon_state: Cow::Owned(beacon_state),
|
||||||
|
store,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: EthSpec, U: Store> Iterator for StateRootsIterator<'a, T, U> {
|
impl<'a, T: EthSpec, U: Store> Iterator for StateRootsIterator<'a, T, U> {
|
||||||
@ -65,6 +72,13 @@ impl<'a, T: EthSpec, U: Store> BlockIterator<'a, T, U> {
|
|||||||
roots: BlockRootsIterator::new(store, beacon_state, start_slot),
|
roots: BlockRootsIterator::new(store, beacon_state, start_slot),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new iterator over all blocks in the given `beacon_state` and prior states.
|
||||||
|
pub fn owned(store: Arc<U>, beacon_state: BeaconState<T>, start_slot: Slot) -> Self {
|
||||||
|
Self {
|
||||||
|
roots: BlockRootsIterator::owned(store, beacon_state, start_slot),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: EthSpec, U: Store> Iterator for BlockIterator<'a, T, U> {
|
impl<'a, T: EthSpec, U: Store> Iterator for BlockIterator<'a, T, U> {
|
||||||
@ -99,6 +113,15 @@ impl<'a, T: EthSpec, U: Store> BlockRootsIterator<'a, T, U> {
|
|||||||
store,
|
store,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new iterator over all block roots in the given `beacon_state` and prior states.
|
||||||
|
pub fn owned(store: Arc<U>, beacon_state: BeaconState<T>, start_slot: Slot) -> Self {
|
||||||
|
Self {
|
||||||
|
slot: start_slot,
|
||||||
|
beacon_state: Cow::Owned(beacon_state),
|
||||||
|
store,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: EthSpec, U: Store> Iterator for BlockRootsIterator<'a, T, U> {
|
impl<'a, T: EthSpec, U: Store> Iterator for BlockRootsIterator<'a, T, U> {
|
||||||
|
@ -496,7 +496,7 @@ where
|
|||||||
let block = self.get_block(child)?;
|
let block = self.get_block(child)?;
|
||||||
let state = self.get_state(block.state_root)?;
|
let state = self.get_state(block.state_root)?;
|
||||||
|
|
||||||
Ok(BlockRootsIterator::new(
|
Ok(BlockRootsIterator::owned(
|
||||||
self.store.clone(),
|
self.store.clone(),
|
||||||
state,
|
state,
|
||||||
block.slot,
|
block.slot,
|
||||||
|
Loading…
Reference in New Issue
Block a user