Add skip slot support to BeaconChain fns
This commit is contained in:
parent
a57a7c2394
commit
3eae7b3fc5
@ -142,7 +142,38 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns beacon block roots for `count` slots, starting from `start_slot`.
|
/// Returns the beacon block body for each beacon block root in `roots`.
|
||||||
|
///
|
||||||
|
/// Fails if any root in `roots` does not have a corresponding block.
|
||||||
|
pub fn get_block_bodies(&self, roots: &[Hash256]) -> Result<Vec<BeaconBlockBody>, Error> {
|
||||||
|
let bodies: Result<Vec<BeaconBlockBody>, _> = roots
|
||||||
|
.iter()
|
||||||
|
.map(|root| match self.get_block(root)? {
|
||||||
|
Some(block) => Ok(block.body),
|
||||||
|
None => Err(Error::DBInconsistent("Missing block".into())),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(bodies?)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the beacon block header for each beacon block root in `roots`.
|
||||||
|
///
|
||||||
|
/// Fails if any root in `roots` does not have a corresponding block.
|
||||||
|
pub fn get_block_headers(&self, roots: &[Hash256]) -> Result<Vec<BeaconBlockHeader>, Error> {
|
||||||
|
let headers: Result<Vec<BeaconBlockHeader>, _> = roots
|
||||||
|
.iter()
|
||||||
|
.map(|root| match self.get_block(root)? {
|
||||||
|
Some(block) => Ok(block.block_header()),
|
||||||
|
None => Err(Error::DBInconsistent("Missing block".into())),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(headers?)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `count `beacon block roots, starting from `start_slot` with an
|
||||||
|
/// interval of `skip` slots between each root.
|
||||||
///
|
///
|
||||||
/// ## Errors:
|
/// ## Errors:
|
||||||
///
|
///
|
||||||
@ -152,40 +183,45 @@ where
|
|||||||
/// - Other: BeaconState` is inconsistent.
|
/// - Other: BeaconState` is inconsistent.
|
||||||
pub fn get_block_roots(
|
pub fn get_block_roots(
|
||||||
&self,
|
&self,
|
||||||
start_slot: Slot,
|
earliest_slot: Slot,
|
||||||
count: Slot,
|
count: usize,
|
||||||
) -> Result<Vec<Hash256>, BeaconStateError> {
|
skip: usize,
|
||||||
|
) -> Result<Vec<Hash256>, Error> {
|
||||||
let spec = &self.spec;
|
let spec = &self.spec;
|
||||||
|
let step_by = Slot::from(skip + 1);
|
||||||
|
|
||||||
let mut roots: Vec<Hash256> = vec![];
|
let mut roots: Vec<Hash256> = vec![];
|
||||||
|
|
||||||
|
// The state for reading block roots. Will be updated with an older state if slots go too
|
||||||
|
// far back in history.
|
||||||
let mut state = self.state.read().clone();
|
let mut state = self.state.read().clone();
|
||||||
let mut slot = start_slot + count - 1;
|
|
||||||
|
// The final slot in this series, will be reduced by `skip` each loop iteration.
|
||||||
|
let mut slot = earliest_slot + Slot::from(count * (skip + 1)) - 1;
|
||||||
|
|
||||||
|
// If the highest slot requested is that of the current state insert the root of the
|
||||||
|
// head block, unless the head block's slot is not matching.
|
||||||
|
if slot == state.slot && self.head().beacon_block.slot == slot {
|
||||||
|
roots.push(self.head().beacon_block_root);
|
||||||
|
|
||||||
|
slot -= step_by;
|
||||||
|
} else if slot >= state.slot {
|
||||||
|
return Err(BeaconStateError::SlotOutOfBounds.into());
|
||||||
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// If the highest slot requested is that of the current state insert the root of the
|
|
||||||
// head block, unless the head block's slot is not matching.
|
|
||||||
if slot == state.slot && self.head().beacon_block.slot == slot {
|
|
||||||
roots.push(self.head().beacon_block_root);
|
|
||||||
|
|
||||||
slot -= 1;
|
|
||||||
continue;
|
|
||||||
} else if slot >= state.slot {
|
|
||||||
return Err(BeaconStateError::SlotOutOfBounds);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the slot is within the range of the current state's block roots, append the root
|
// If the slot is within the range of the current state's block roots, append the root
|
||||||
// to the output vec.
|
// to the output vec.
|
||||||
//
|
//
|
||||||
// If we get `SlotOutOfBounds` error, load the oldest known state to the present state
|
// If we get `SlotOutOfBounds` error, load the oldest available historic
|
||||||
// from the DB.
|
// state from the DB.
|
||||||
match state.get_block_root(slot, spec) {
|
match state.get_block_root(slot, spec) {
|
||||||
Ok(root) => {
|
Ok(root) => {
|
||||||
roots.push(*root);
|
if slot < earliest_slot {
|
||||||
|
|
||||||
if slot == start_slot {
|
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
slot -= 1;
|
roots.push(*root);
|
||||||
|
slot -= step_by;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(BeaconStateError::SlotOutOfBounds) => {
|
Err(BeaconStateError::SlotOutOfBounds) => {
|
||||||
@ -201,18 +237,19 @@ where
|
|||||||
_ => break,
|
_ => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e.into()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slot == start_slot) && (roots.len() == count.as_usize()) {
|
// Return the results if they pass a sanity check.
|
||||||
|
if (slot <= earliest_slot) && (roots.len() == count) {
|
||||||
// Reverse the ordering of the roots. We extracted them in reverse order to make it
|
// Reverse the ordering of the roots. We extracted them in reverse order to make it
|
||||||
// simpler to lookup historic states.
|
// simpler to lookup historic states.
|
||||||
//
|
//
|
||||||
// This is a potential optimisation target.
|
// This is a potential optimisation target.
|
||||||
Ok(roots.iter().rev().cloned().collect())
|
Ok(roots.iter().rev().cloned().collect())
|
||||||
} else {
|
} else {
|
||||||
Err(BeaconStateError::SlotOutOfBounds)
|
Err(BeaconStateError::SlotOutOfBounds.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ use beacon_chain::{
|
|||||||
CheckPoint,
|
CheckPoint,
|
||||||
};
|
};
|
||||||
use eth2_libp2p::HelloMessage;
|
use eth2_libp2p::HelloMessage;
|
||||||
use types::{BeaconBlock, BeaconStateError, Epoch, Hash256, Slot};
|
use types::{BeaconBlock, BeaconBlockBody, BeaconBlockHeader, Epoch, Hash256, Slot};
|
||||||
|
|
||||||
pub use beacon_chain::{BeaconChainError, BlockProcessingOutcome};
|
pub use beacon_chain::{BeaconChainError, BlockProcessingOutcome};
|
||||||
|
|
||||||
@ -40,8 +40,19 @@ pub trait BeaconChain: Send + Sync {
|
|||||||
fn get_block_roots(
|
fn get_block_roots(
|
||||||
&self,
|
&self,
|
||||||
start_slot: Slot,
|
start_slot: Slot,
|
||||||
count: Slot,
|
count: usize,
|
||||||
) -> Result<Vec<Hash256>, BeaconStateError>;
|
skip: usize,
|
||||||
|
) -> Result<Vec<Hash256>, BeaconChainError>;
|
||||||
|
|
||||||
|
fn get_block_headers(
|
||||||
|
&self,
|
||||||
|
start_slot: Slot,
|
||||||
|
count: usize,
|
||||||
|
skip: usize,
|
||||||
|
) -> Result<Vec<BeaconBlockHeader>, BeaconChainError>;
|
||||||
|
|
||||||
|
fn get_block_bodies(&self, roots: &[Hash256])
|
||||||
|
-> Result<Vec<BeaconBlockBody>, BeaconChainError>;
|
||||||
|
|
||||||
fn is_new_block_root(&self, beacon_block_root: &Hash256) -> Result<bool, BeaconChainError>;
|
fn is_new_block_root(&self, beacon_block_root: &Hash256) -> Result<bool, BeaconChainError>;
|
||||||
}
|
}
|
||||||
@ -111,9 +122,27 @@ where
|
|||||||
fn get_block_roots(
|
fn get_block_roots(
|
||||||
&self,
|
&self,
|
||||||
start_slot: Slot,
|
start_slot: Slot,
|
||||||
count: Slot,
|
count: usize,
|
||||||
) -> Result<Vec<Hash256>, BeaconStateError> {
|
skip: usize,
|
||||||
self.get_block_roots(start_slot, count)
|
) -> Result<Vec<Hash256>, BeaconChainError> {
|
||||||
|
self.get_block_roots(start_slot, count, skip)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_block_headers(
|
||||||
|
&self,
|
||||||
|
start_slot: Slot,
|
||||||
|
count: usize,
|
||||||
|
skip: usize,
|
||||||
|
) -> Result<Vec<BeaconBlockHeader>, BeaconChainError> {
|
||||||
|
let roots = self.get_block_roots(start_slot, count, skip)?;
|
||||||
|
self.get_block_headers(&roots)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_block_bodies(
|
||||||
|
&self,
|
||||||
|
roots: &[Hash256],
|
||||||
|
) -> Result<Vec<BeaconBlockBody>, BeaconChainError> {
|
||||||
|
self.get_block_bodies(roots)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_new_block_root(&self, beacon_block_root: &Hash256) -> Result<bool, BeaconChainError> {
|
fn is_new_block_root(&self, beacon_block_root: &Hash256) -> Result<bool, BeaconChainError> {
|
||||||
|
Loading…
Reference in New Issue
Block a user