Partially update BeaconState to v0.5.0

- Uses new ssz attributes to remove manual impl of ssz.
- Updates struct def to v0.5.0
- Does not update all methods
This commit is contained in:
Paul Hauner 2019-03-15 18:36:55 +11:00
parent b37cf3a269
commit 49d3f3d1d6
No known key found for this signature in database
GPG Key ID: D362883A9218FCC6

View File

@ -8,9 +8,11 @@ use log::{debug, error, trace};
use pubkey_cache::PubkeyCache; use pubkey_cache::PubkeyCache;
use rand::RngCore; use rand::RngCore;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use ssz::{hash, Decodable, DecodeError, Encodable, SignedRoot, SszStream, TreeHash}; use ssz::{hash, Decodable, SignedRoot, TreeHash};
use ssz_derive::{Decode, Encode, TreeHash};
use std::collections::HashMap; use std::collections::HashMap;
use swap_or_not_shuffle::shuffle_list; use swap_or_not_shuffle::shuffle_list;
use test_random_derive::TestRandom;
pub use builder::BeaconStateBuilder; pub use builder::BeaconStateBuilder;
@ -72,7 +74,10 @@ macro_rules! safe_sub_assign {
}; };
} }
#[derive(Debug, PartialEq, Clone, Default, Serialize, Deserialize)] /// The state of the `BeaconChain` at some slot.
///
/// Spec v0.5.0
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, TestRandom, Encode, Decode, TreeHash)]
pub struct BeaconState { pub struct BeaconState {
// Misc // Misc
pub slot: Slot, pub slot: Slot,
@ -94,18 +99,24 @@ pub struct BeaconState {
pub current_shuffling_seed: Hash256, pub current_shuffling_seed: Hash256,
// Finality // Finality
pub previous_epoch_attestations: Vec<PendingAttestation>,
pub current_epoch_attestations: Vec<PendingAttestation>,
pub previous_justified_epoch: Epoch, pub previous_justified_epoch: Epoch,
pub justified_epoch: Epoch, pub current_justified_epoch: Epoch,
pub previous_justified_root: Hash256,
pub current_justified_root: Hash256,
pub justification_bitfield: u64, pub justification_bitfield: u64,
pub finalized_epoch: Epoch, pub finalized_epoch: Epoch,
pub finalized_root: Hash256,
// Recent state // Recent state
pub latest_crosslinks: Vec<Crosslink>, pub latest_crosslinks: Vec<Crosslink>,
pub latest_block_roots: Vec<Hash256>, pub latest_block_roots: Vec<Hash256>,
pub latest_state_roots: Vec<Hash256>,
pub latest_active_index_roots: Vec<Hash256>, pub latest_active_index_roots: Vec<Hash256>,
pub latest_slashed_balances: Vec<u64>, pub latest_slashed_balances: Vec<u64>,
pub latest_attestations: Vec<PendingAttestation>, pub latest_block_header: BeaconBlockHeader,
pub batched_block_roots: Vec<Hash256>, pub historical_roots: Vec<Hash256>,
// Ethereum 1.0 chain data // Ethereum 1.0 chain data
pub latest_eth1_data: Eth1Data, pub latest_eth1_data: Eth1Data,
@ -113,10 +124,19 @@ pub struct BeaconState {
pub deposit_index: u64, pub deposit_index: u64,
// Caching (not in the spec) // Caching (not in the spec)
#[serde(default)]
#[ssz(skip_serializing)]
#[ssz(skip_deserializing)]
#[tree_hash(skip_hashing)]
pub cache_index_offset: usize, pub cache_index_offset: usize,
#[ssz(skip_serializing)]
#[ssz(skip_deserializing)]
#[tree_hash(skip_hashing)]
pub caches: [EpochCache; CACHED_EPOCHS],
#[serde(default)] #[serde(default)]
pub caches: Vec<EpochCache>, #[ssz(skip_serializing)]
#[serde(default)] #[ssz(skip_deserializing)]
#[tree_hash(skip_hashing)]
pub pubkey_cache: PubkeyCache, pub pubkey_cache: PubkeyCache,
} }
@ -126,7 +146,7 @@ impl BeaconState {
/// This does not fully build a genesis beacon state, it omits processing of initial validator /// This does not fully build a genesis beacon state, it omits processing of initial validator
/// deposits. To obtain a full genesis beacon state, use the `BeaconStateBuilder`. /// deposits. To obtain a full genesis beacon state, use the `BeaconStateBuilder`.
/// ///
/// Spec v0.4.0 /// Spec v0.5.0
pub fn genesis(genesis_time: u64, latest_eth1_data: Eth1Data, spec: &ChainSpec) -> BeaconState { pub fn genesis(genesis_time: u64, latest_eth1_data: Eth1Data, spec: &ChainSpec) -> BeaconState {
let initial_crosslink = Crosslink { let initial_crosslink = Crosslink {
epoch: spec.genesis_epoch, epoch: spec.genesis_epoch,
@ -134,23 +154,17 @@ impl BeaconState {
}; };
BeaconState { BeaconState {
/* // Misc
* Misc
*/
slot: spec.genesis_slot, slot: spec.genesis_slot,
genesis_time, genesis_time,
fork: Fork::genesis(spec), fork: Fork::genesis(spec),
/* // Validator registry
* Validator registry
*/
validator_registry: vec![], // Set later in the function. validator_registry: vec![], // Set later in the function.
validator_balances: vec![], // Set later in the function. validator_balances: vec![], // Set later in the function.
validator_registry_update_epoch: spec.genesis_epoch, validator_registry_update_epoch: spec.genesis_epoch,
/* // Randomness and committees
* Randomness and committees
*/
latest_randao_mixes: vec![spec.zero_hash; spec.latest_randao_mixes_length as usize], latest_randao_mixes: vec![spec.zero_hash; spec.latest_randao_mixes_length as usize],
previous_shuffling_start_shard: spec.genesis_start_shard, previous_shuffling_start_shard: spec.genesis_start_shard,
current_shuffling_start_shard: spec.genesis_start_shard, current_shuffling_start_shard: spec.genesis_start_shard,
@ -159,26 +173,25 @@ impl BeaconState {
previous_shuffling_seed: spec.zero_hash, previous_shuffling_seed: spec.zero_hash,
current_shuffling_seed: spec.zero_hash, current_shuffling_seed: spec.zero_hash,
/* // Finality
* Finality previous_epoch_attestations: vec![],
*/ current_epoch_attestations: vec![],
previous_justified_epoch: spec.genesis_epoch, previous_justified_epoch: spec.genesis_epoch,
justified_epoch: spec.genesis_epoch, current_justified_epoch: spec.genesis_epoch,
previous_justified_root: spec.zero_hash,
current_justified_root: spec.zero_hash,
justification_bitfield: 0, justification_bitfield: 0,
finalized_epoch: spec.genesis_epoch, finalized_epoch: spec.genesis_epoch,
finalized_root: spec.zero_hash,
/* // Recent state
* Recent state
*/
latest_crosslinks: vec![initial_crosslink; spec.shard_count as usize], latest_crosslinks: vec![initial_crosslink; spec.shard_count as usize],
latest_block_roots: vec![spec.zero_hash; spec.latest_block_roots_length as usize], latest_block_roots: vec![spec.zero_hash; spec.slots_per_historical_root],
latest_active_index_roots: vec![ latest_state_roots: vec![spec.zero_hash; spec.slots_per_historical_root],
spec.zero_hash; latest_active_index_roots: vec![spec.zero_hash; spec.latest_active_index_roots_length],
spec.latest_active_index_roots_length as usize latest_slashed_balances: vec![0; spec.latest_slashed_exit_length],
], latest_block_header: BeaconBlock::empty(spec).into_temporary_header(spec),
latest_slashed_balances: vec![0; spec.latest_slashed_exit_length as usize], historical_roots: vec![],
latest_attestations: vec![],
batched_block_roots: vec![],
/* /*
* PoW receipt root * PoW receipt root
@ -191,18 +204,26 @@ impl BeaconState {
* Caching (not in spec) * Caching (not in spec)
*/ */
cache_index_offset: 0, cache_index_offset: 0,
caches: vec![EpochCache::default(); CACHED_EPOCHS], caches: [
EpochCache::default(),
EpochCache::default(),
EpochCache::default(),
],
pubkey_cache: PubkeyCache::default(), pubkey_cache: PubkeyCache::default(),
} }
} }
/*
/// Returns the `hash_tree_root` of the state. /// Returns the `hash_tree_root` of the state.
/// ///
/// Spec v0.4.0 /// Spec v0.5.0
pub fn canonical_root(&self) -> Hash256 { pub fn canonical_root(&self) -> Hash256 {
Hash256::from_slice(&self.hash_tree_root()[..]) Hash256::from_slice(&self.hash_tree_root()[..])
} }
*/
/// Build an epoch cache, unless it is has already been built. /// Build an epoch cache, unless it is has already been built.
pub fn build_epoch_cache( pub fn build_epoch_cache(
&mut self, &mut self,
@ -426,11 +447,11 @@ impl BeaconState {
/// Return the block root at a recent `slot`. /// Return the block root at a recent `slot`.
/// ///
/// Spec v0.4.0 /// Spec v0.5.0
pub fn get_block_root(&self, slot: Slot, spec: &ChainSpec) -> Option<&Hash256> { pub fn get_block_root(&self, slot: Slot, spec: &ChainSpec) -> Option<&Hash256> {
if (self.slot <= slot + spec.latest_block_roots_length as u64) && (slot < self.slot) { if (self.slot <= slot + spec.slots_per_historical_root as u64) && (slot < self.slot) {
self.latest_block_roots self.latest_block_roots
.get(slot.as_usize() % spec.latest_block_roots_length) .get(slot.as_usize() % spec.slots_per_historical_root)
} else { } else {
None None
} }
@ -1135,169 +1156,3 @@ impl BeaconState {
Ok(all_participants) Ok(all_participants)
} }
} }
impl Encodable for BeaconState {
fn ssz_append(&self, s: &mut SszStream) {
s.append(&self.slot);
s.append(&self.genesis_time);
s.append(&self.fork);
s.append(&self.validator_registry);
s.append(&self.validator_balances);
s.append(&self.validator_registry_update_epoch);
s.append(&self.latest_randao_mixes);
s.append(&self.previous_shuffling_start_shard);
s.append(&self.current_shuffling_start_shard);
s.append(&self.previous_shuffling_epoch);
s.append(&self.current_shuffling_epoch);
s.append(&self.previous_shuffling_seed);
s.append(&self.current_shuffling_seed);
s.append(&self.previous_justified_epoch);
s.append(&self.justified_epoch);
s.append(&self.justification_bitfield);
s.append(&self.finalized_epoch);
s.append(&self.latest_crosslinks);
s.append(&self.latest_block_roots);
s.append(&self.latest_active_index_roots);
s.append(&self.latest_slashed_balances);
s.append(&self.latest_attestations);
s.append(&self.batched_block_roots);
s.append(&self.latest_eth1_data);
s.append(&self.eth1_data_votes);
s.append(&self.deposit_index);
}
}
impl Decodable for BeaconState {
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
let (slot, i) = <_>::ssz_decode(bytes, i)?;
let (genesis_time, i) = <_>::ssz_decode(bytes, i)?;
let (fork, i) = <_>::ssz_decode(bytes, i)?;
let (validator_registry, i) = <_>::ssz_decode(bytes, i)?;
let (validator_balances, i) = <_>::ssz_decode(bytes, i)?;
let (validator_registry_update_epoch, i) = <_>::ssz_decode(bytes, i)?;
let (latest_randao_mixes, i) = <_>::ssz_decode(bytes, i)?;
let (previous_shuffling_start_shard, i) = <_>::ssz_decode(bytes, i)?;
let (current_shuffling_start_shard, i) = <_>::ssz_decode(bytes, i)?;
let (previous_shuffling_epoch, i) = <_>::ssz_decode(bytes, i)?;
let (current_shuffling_epoch, i) = <_>::ssz_decode(bytes, i)?;
let (previous_shuffling_seed, i) = <_>::ssz_decode(bytes, i)?;
let (current_shuffling_seed, i) = <_>::ssz_decode(bytes, i)?;
let (previous_justified_epoch, i) = <_>::ssz_decode(bytes, i)?;
let (justified_epoch, i) = <_>::ssz_decode(bytes, i)?;
let (justification_bitfield, i) = <_>::ssz_decode(bytes, i)?;
let (finalized_epoch, i) = <_>::ssz_decode(bytes, i)?;
let (latest_crosslinks, i) = <_>::ssz_decode(bytes, i)?;
let (latest_block_roots, i) = <_>::ssz_decode(bytes, i)?;
let (latest_active_index_roots, i) = <_>::ssz_decode(bytes, i)?;
let (latest_slashed_balances, i) = <_>::ssz_decode(bytes, i)?;
let (latest_attestations, i) = <_>::ssz_decode(bytes, i)?;
let (batched_block_roots, i) = <_>::ssz_decode(bytes, i)?;
let (latest_eth1_data, i) = <_>::ssz_decode(bytes, i)?;
let (eth1_data_votes, i) = <_>::ssz_decode(bytes, i)?;
let (deposit_index, i) = <_>::ssz_decode(bytes, i)?;
Ok((
Self {
slot,
genesis_time,
fork,
validator_registry,
validator_balances,
validator_registry_update_epoch,
latest_randao_mixes,
previous_shuffling_start_shard,
current_shuffling_start_shard,
previous_shuffling_epoch,
current_shuffling_epoch,
previous_shuffling_seed,
current_shuffling_seed,
previous_justified_epoch,
justified_epoch,
justification_bitfield,
finalized_epoch,
latest_crosslinks,
latest_block_roots,
latest_active_index_roots,
latest_slashed_balances,
latest_attestations,
batched_block_roots,
latest_eth1_data,
eth1_data_votes,
deposit_index,
cache_index_offset: 0,
caches: vec![EpochCache::default(); CACHED_EPOCHS],
pubkey_cache: PubkeyCache::default(),
},
i,
))
}
}
impl TreeHash for BeaconState {
fn hash_tree_root(&self) -> Vec<u8> {
let mut result: Vec<u8> = vec![];
result.append(&mut self.slot.hash_tree_root());
result.append(&mut self.genesis_time.hash_tree_root());
result.append(&mut self.fork.hash_tree_root());
result.append(&mut self.validator_registry.hash_tree_root());
result.append(&mut self.validator_balances.hash_tree_root());
result.append(&mut self.validator_registry_update_epoch.hash_tree_root());
result.append(&mut self.latest_randao_mixes.hash_tree_root());
result.append(&mut self.previous_shuffling_start_shard.hash_tree_root());
result.append(&mut self.current_shuffling_start_shard.hash_tree_root());
result.append(&mut self.previous_shuffling_epoch.hash_tree_root());
result.append(&mut self.current_shuffling_epoch.hash_tree_root());
result.append(&mut self.previous_shuffling_seed.hash_tree_root());
result.append(&mut self.current_shuffling_seed.hash_tree_root());
result.append(&mut self.previous_justified_epoch.hash_tree_root());
result.append(&mut self.justified_epoch.hash_tree_root());
result.append(&mut self.justification_bitfield.hash_tree_root());
result.append(&mut self.finalized_epoch.hash_tree_root());
result.append(&mut self.latest_crosslinks.hash_tree_root());
result.append(&mut self.latest_block_roots.hash_tree_root());
result.append(&mut self.latest_active_index_roots.hash_tree_root());
result.append(&mut self.latest_slashed_balances.hash_tree_root());
result.append(&mut self.latest_attestations.hash_tree_root());
result.append(&mut self.batched_block_roots.hash_tree_root());
result.append(&mut self.latest_eth1_data.hash_tree_root());
result.append(&mut self.eth1_data_votes.hash_tree_root());
result.append(&mut self.deposit_index.hash_tree_root());
hash(&result)
}
}
impl<T: RngCore> TestRandom<T> for BeaconState {
fn random_for_test(rng: &mut T) -> Self {
Self {
slot: <_>::random_for_test(rng),
genesis_time: <_>::random_for_test(rng),
fork: <_>::random_for_test(rng),
validator_registry: <_>::random_for_test(rng),
validator_balances: <_>::random_for_test(rng),
validator_registry_update_epoch: <_>::random_for_test(rng),
latest_randao_mixes: <_>::random_for_test(rng),
previous_shuffling_start_shard: <_>::random_for_test(rng),
current_shuffling_start_shard: <_>::random_for_test(rng),
previous_shuffling_epoch: <_>::random_for_test(rng),
current_shuffling_epoch: <_>::random_for_test(rng),
previous_shuffling_seed: <_>::random_for_test(rng),
current_shuffling_seed: <_>::random_for_test(rng),
previous_justified_epoch: <_>::random_for_test(rng),
justified_epoch: <_>::random_for_test(rng),
justification_bitfield: <_>::random_for_test(rng),
finalized_epoch: <_>::random_for_test(rng),
latest_crosslinks: <_>::random_for_test(rng),
latest_block_roots: <_>::random_for_test(rng),
latest_active_index_roots: <_>::random_for_test(rng),
latest_slashed_balances: <_>::random_for_test(rng),
latest_attestations: <_>::random_for_test(rng),
batched_block_roots: <_>::random_for_test(rng),
latest_eth1_data: <_>::random_for_test(rng),
eth1_data_votes: <_>::random_for_test(rng),
deposit_index: <_>::random_for_test(rng),
cache_index_offset: 0,
caches: vec![EpochCache::default(); CACHED_EPOCHS],
pubkey_cache: PubkeyCache::default(),
}
}
}