2019-03-06 21:37:13 +00:00
|
|
|
use crate::*;
|
2019-04-28 21:34:01 +00:00
|
|
|
use tree_hash::SignedRoot;
|
2019-03-18 05:53:59 +00:00
|
|
|
use types::*;
|
2019-03-06 21:37:13 +00:00
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum Error {
|
|
|
|
BeaconStateError(BeaconStateError),
|
|
|
|
EpochProcessingError(EpochProcessingError),
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Advances a state forward by one slot, performing per-epoch processing if required.
|
|
|
|
///
|
2019-04-15 00:51:20 +00:00
|
|
|
/// Spec v0.5.1
|
2019-04-08 04:37:01 +00:00
|
|
|
pub fn per_slot_processing(state: &mut BeaconState, spec: &ChainSpec) -> Result<(), Error> {
|
|
|
|
cache_state(state, spec)?;
|
2019-03-18 05:53:59 +00:00
|
|
|
|
2019-03-06 21:37:13 +00:00
|
|
|
if (state.slot + 1) % spec.slots_per_epoch == 0 {
|
|
|
|
per_epoch_processing(state, spec)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
state.slot += 1;
|
|
|
|
|
2019-03-18 05:53:59 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2019-04-08 04:37:01 +00:00
|
|
|
fn cache_state(state: &mut BeaconState, spec: &ChainSpec) -> Result<(), Error> {
|
2019-04-28 01:33:48 +00:00
|
|
|
let previous_slot_state_root = state.update_tree_hash_cache()?;
|
2019-03-18 05:53:59 +00:00
|
|
|
|
|
|
|
// Note: increment the state slot here to allow use of our `state_root` and `block_root`
|
|
|
|
// getter/setter functions.
|
|
|
|
//
|
|
|
|
// This is a bit hacky, however it gets the job safely without lots of code.
|
|
|
|
let previous_slot = state.slot;
|
|
|
|
state.slot += 1;
|
|
|
|
|
|
|
|
// Store the previous slot's post-state transition root.
|
|
|
|
if state.latest_block_header.state_root == spec.zero_hash {
|
|
|
|
state.latest_block_header.state_root = previous_slot_state_root
|
|
|
|
}
|
|
|
|
|
2019-04-17 07:17:43 +00:00
|
|
|
// Store the previous slot's post state transition root.
|
|
|
|
state.set_state_root(previous_slot, previous_slot_state_root, spec)?;
|
|
|
|
|
2019-04-17 01:59:40 +00:00
|
|
|
let latest_block_root = Hash256::from_slice(&state.latest_block_header.signed_root()[..]);
|
2019-03-18 05:53:59 +00:00
|
|
|
state.set_block_root(previous_slot, latest_block_root, spec)?;
|
|
|
|
|
|
|
|
// Set the state slot back to what it should be.
|
|
|
|
state.slot -= 1;
|
|
|
|
|
2019-03-06 21:37:13 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<BeaconStateError> for Error {
|
|
|
|
fn from(e: BeaconStateError) -> Error {
|
|
|
|
Error::BeaconStateError(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<EpochProcessingError> for Error {
|
|
|
|
fn from(e: EpochProcessingError) -> Error {
|
|
|
|
Error::EpochProcessingError(e)
|
|
|
|
}
|
|
|
|
}
|