Fix beacon chain block iters

This commit is contained in:
Paul Hauner 2019-06-07 02:48:26 -04:00
parent 591c8ae219
commit 4cecf05198
No known key found for this signature in database
GPG Key ID: 303E4494BB28068C
2 changed files with 21 additions and 20 deletions

View File

@ -57,28 +57,21 @@ impl<T: EthSpec, U: Store> Iterator for BlockRootsIterator<T, U> {
return None; return None;
} }
let slot = self.slot - 1; self.slot = self.slot - 1;
match self.beacon_state.get_block_root(slot) { match self.beacon_state.get_block_root(self.slot) {
Ok(root) => Some(*root), Ok(root) => Some(*root),
Err(BeaconStateError::SlotOutOfBounds) => { Err(BeaconStateError::SlotOutOfBounds) => {
// Read a `BeaconState` from the store that has access to prior historical root. // Read a `BeaconState` from the store that has access to prior historical root.
self.beacon_state = { self.beacon_state = {
// Read the earliest historic state in the current slot. // Load the earlier state from disk. Skip forward one slot, because a state
let earliest_historic_slot = // doesn't return it's own state root.
self.beacon_state.slot - Slot::from(T::slots_per_historical_root()); let new_state_root = self.beacon_state.get_state_root(self.slot + 1).ok()?;
// Load the earlier state from disk. self.store.get(&new_state_root).ok()?
let new_state_root = self }?;
.beacon_state
.get_state_root(earliest_historic_slot)
.ok()?;
let state_option = self.store.get(&new_state_root).ok()?; self.beacon_state.get_block_root(self.slot).ok().cloned()
state_option?
};
self.beacon_state.get_block_root(slot).ok().cloned()
} }
_ => return None, _ => return None,
} }
@ -101,10 +94,14 @@ mod test {
#[test] #[test]
fn root_iter() { fn root_iter() {
let store = Arc::new(MemoryStore::open()); let store = Arc::new(MemoryStore::open());
let slots_per_historical_root = FoundationEthSpec::slots_per_historical_root();
let mut state_a: BeaconState<FoundationEthSpec> = get_state(); let mut state_a: BeaconState<FoundationEthSpec> = get_state();
let mut state_b: BeaconState<FoundationEthSpec> = get_state(); let mut state_b: BeaconState<FoundationEthSpec> = 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)); let mut hashes = (0..).into_iter().map(|i| Hash256::from(i));
for root in &mut state_a.latest_block_roots[..] { for root in &mut state_a.latest_block_roots[..] {
@ -118,12 +115,16 @@ mod test {
state_b.latest_state_roots[0] = state_a_root; state_b.latest_state_roots[0] = state_a_root;
store.put(&state_a_root, &state_a).unwrap(); store.put(&state_a_root, &state_a).unwrap();
let iter = BlockRootsIterator::new(store.clone(), state_b.clone(), state_b.slot); let iter = BlockRootsIterator::new(store.clone(), state_b.clone(), state_b.slot - 1);
let mut collected: Vec<Hash256> = iter.collect(); let mut collected: Vec<Hash256> = iter.collect();
collected.reverse(); collected.reverse();
for (i, item) in collected.iter().enumerate() { let expected_len = 2 * FoundationEthSpec::slots_per_historical_root() - 1;
assert_eq!(*item, Hash256::from(i as u64));
assert_eq!(collected.len(), expected_len);
for i in 0..expected_len {
assert_eq!(collected[i], Hash256::from(i as u64));
} }
} }
} }

View File

@ -172,8 +172,8 @@ pub struct BeaconBlockRootsResponse {
impl BeaconBlockRootsResponse { impl BeaconBlockRootsResponse {
/// Returns `true` if each `self.roots.slot[i]` is higher than the preceeding `i`. /// Returns `true` if each `self.roots.slot[i]` is higher than the preceeding `i`.
pub fn slots_are_ascending(&self) -> bool { pub fn slots_are_ascending(&self) -> bool {
for i in 1..self.roots.len() { for window in self.roots.windows(2) {
if self.roots[i - 1].slot >= self.roots[i].slot { if window[0].slot >= window[1].slot {
return false; return false;
} }
} }