Merge branch 'fixed-vec' into sos
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use super::{AggregateSignature, AttestationData, Bitfield};
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{Crosslink, Epoch, Hash256, Slot};
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use super::AttestationData;
|
||||
use crate::test_utils::TestRandom;
|
||||
|
||||
use rand::RngCore;
|
||||
use serde_derive::Serialize;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
@@ -14,8 +15,8 @@ pub struct AttestationDataAndCustodyBit {
|
||||
pub custody_bit: bool,
|
||||
}
|
||||
|
||||
impl<T: RngCore> TestRandom<T> for AttestationDataAndCustodyBit {
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
impl TestRandom for AttestationDataAndCustodyBit {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
Self {
|
||||
data: <_>::random_for_test(rng),
|
||||
custody_bit: <_>::random_for_test(rng),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{test_utils::TestRandom, SlashableAttestation};
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use bls::Signature;
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use bls::Signature;
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -5,7 +5,8 @@ use cached_tree_hash::{Error as TreeHashCacheError, TreeHashCache};
|
||||
use hashing::hash;
|
||||
use int_to_bytes::int_to_bytes32;
|
||||
use pubkey_cache::PubkeyCache;
|
||||
use rand::RngCore;
|
||||
|
||||
use fixed_len_vec::{typenum::Unsigned, FixedLenVec};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::ssz_encode;
|
||||
use ssz_derive::{Decode, Encode};
|
||||
@@ -13,6 +14,9 @@ use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
pub use beacon_state_types::*;
|
||||
|
||||
mod beacon_state_types;
|
||||
mod epoch_cache;
|
||||
mod pubkey_cache;
|
||||
mod tests;
|
||||
@@ -62,7 +66,10 @@ pub enum Error {
|
||||
TreeHash,
|
||||
CachedTreeHash,
|
||||
)]
|
||||
pub struct BeaconState {
|
||||
pub struct BeaconState<T>
|
||||
where
|
||||
T: EthSpec,
|
||||
{
|
||||
// Misc
|
||||
pub slot: Slot,
|
||||
pub genesis_time: u64,
|
||||
@@ -74,7 +81,7 @@ pub struct BeaconState {
|
||||
pub validator_registry_update_epoch: Epoch,
|
||||
|
||||
// Randomness and committees
|
||||
pub latest_randao_mixes: TreeHashVector<Hash256>,
|
||||
pub latest_randao_mixes: FixedLenVec<Hash256, T::LatestRandaoMixesLength>,
|
||||
pub previous_shuffling_start_shard: u64,
|
||||
pub current_shuffling_start_shard: u64,
|
||||
pub previous_shuffling_epoch: Epoch,
|
||||
@@ -94,11 +101,11 @@ pub struct BeaconState {
|
||||
pub finalized_root: Hash256,
|
||||
|
||||
// Recent state
|
||||
pub latest_crosslinks: TreeHashVector<Crosslink>,
|
||||
pub latest_block_roots: TreeHashVector<Hash256>,
|
||||
latest_state_roots: TreeHashVector<Hash256>,
|
||||
latest_active_index_roots: TreeHashVector<Hash256>,
|
||||
latest_slashed_balances: TreeHashVector<u64>,
|
||||
pub latest_crosslinks: FixedLenVec<Crosslink, T::ShardCount>,
|
||||
pub latest_block_roots: FixedLenVec<Hash256, T::SlotsPerHistoricalRoot>,
|
||||
latest_state_roots: FixedLenVec<Hash256, T::SlotsPerHistoricalRoot>,
|
||||
latest_active_index_roots: FixedLenVec<Hash256, T::LatestActiveIndexRootsLength>,
|
||||
latest_slashed_balances: FixedLenVec<u64, T::LatestSlashedExitLength>,
|
||||
pub latest_block_header: BeaconBlockHeader,
|
||||
pub historical_roots: Vec<Hash256>,
|
||||
|
||||
@@ -134,14 +141,18 @@ pub struct BeaconState {
|
||||
pub tree_hash_cache: TreeHashCache,
|
||||
}
|
||||
|
||||
impl BeaconState {
|
||||
impl<T: EthSpec> BeaconState<T> {
|
||||
/// Produce the first state of the Beacon Chain.
|
||||
///
|
||||
/// 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`.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
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<T> {
|
||||
let initial_crosslink = Crosslink {
|
||||
epoch: spec.genesis_epoch,
|
||||
crosslink_data_root: spec.zero_hash,
|
||||
@@ -159,8 +170,10 @@ impl BeaconState {
|
||||
validator_registry_update_epoch: spec.genesis_epoch,
|
||||
|
||||
// Randomness and committees
|
||||
latest_randao_mixes: vec![spec.zero_hash; spec.latest_randao_mixes_length as usize]
|
||||
.into(),
|
||||
latest_randao_mixes: FixedLenVec::from(vec![
|
||||
spec.zero_hash;
|
||||
T::LatestRandaoMixesLength::to_usize()
|
||||
]),
|
||||
previous_shuffling_start_shard: spec.genesis_start_shard,
|
||||
current_shuffling_start_shard: spec.genesis_start_shard,
|
||||
previous_shuffling_epoch: spec.genesis_epoch,
|
||||
@@ -181,11 +194,21 @@ impl BeaconState {
|
||||
|
||||
// Recent state
|
||||
latest_crosslinks: vec![initial_crosslink; spec.shard_count as usize].into(),
|
||||
latest_block_roots: vec![spec.zero_hash; spec.slots_per_historical_root].into(),
|
||||
latest_state_roots: vec![spec.zero_hash; spec.slots_per_historical_root].into(),
|
||||
latest_active_index_roots: vec![spec.zero_hash; spec.latest_active_index_roots_length]
|
||||
.into(),
|
||||
latest_slashed_balances: vec![0; spec.latest_slashed_exit_length].into(),
|
||||
latest_block_roots: FixedLenVec::from(vec![
|
||||
spec.zero_hash;
|
||||
T::SlotsPerHistoricalRoot::to_usize()
|
||||
]),
|
||||
latest_state_roots: FixedLenVec::from(vec![
|
||||
spec.zero_hash;
|
||||
T::SlotsPerHistoricalRoot::to_usize()
|
||||
]),
|
||||
latest_active_index_roots: FixedLenVec::from(
|
||||
vec![spec.zero_hash; T::LatestActiveIndexRootsLength::to_usize()],
|
||||
),
|
||||
latest_slashed_balances: FixedLenVec::from(vec![
|
||||
0;
|
||||
T::LatestSlashedExitLength::to_usize()
|
||||
]),
|
||||
latest_block_header: BeaconBlock::empty(spec).temporary_block_header(spec),
|
||||
historical_roots: vec![],
|
||||
|
||||
@@ -218,7 +241,7 @@ impl BeaconState {
|
||||
Hash256::from_slice(&self.tree_hash_root()[..])
|
||||
}
|
||||
|
||||
pub fn historical_batch(&self) -> HistoricalBatch {
|
||||
pub fn historical_batch(&self) -> HistoricalBatch<T> {
|
||||
HistoricalBatch {
|
||||
block_roots: self.latest_block_roots.clone(),
|
||||
state_roots: self.latest_state_roots.clone(),
|
||||
@@ -376,14 +399,9 @@ impl BeaconState {
|
||||
/// Safely obtains the index for latest block roots, given some `slot`.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
fn get_latest_block_roots_index(&self, slot: Slot, spec: &ChainSpec) -> Result<usize, Error> {
|
||||
if (slot < self.slot) && (self.slot <= slot + spec.slots_per_historical_root as u64) {
|
||||
let i = slot.as_usize() % spec.slots_per_historical_root;
|
||||
if i >= self.latest_block_roots.len() {
|
||||
Err(Error::InsufficientStateRoots)
|
||||
} else {
|
||||
Ok(i)
|
||||
}
|
||||
fn get_latest_block_roots_index(&self, slot: Slot) -> Result<usize, Error> {
|
||||
if (slot < self.slot) && (self.slot <= slot + self.latest_block_roots.len() as u64) {
|
||||
Ok(slot.as_usize() % self.latest_block_roots.len())
|
||||
} else {
|
||||
Err(BeaconStateError::SlotOutOfBounds)
|
||||
}
|
||||
@@ -392,12 +410,8 @@ impl BeaconState {
|
||||
/// Return the block root at a recent `slot`.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
pub fn get_block_root(
|
||||
&self,
|
||||
slot: Slot,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<&Hash256, BeaconStateError> {
|
||||
let i = self.get_latest_block_roots_index(slot, spec)?;
|
||||
pub fn get_block_root(&self, slot: Slot) -> Result<&Hash256, BeaconStateError> {
|
||||
let i = self.get_latest_block_roots_index(slot)?;
|
||||
Ok(&self.latest_block_roots[i])
|
||||
}
|
||||
|
||||
@@ -408,9 +422,8 @@ impl BeaconState {
|
||||
&mut self,
|
||||
slot: Slot,
|
||||
block_root: Hash256,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), BeaconStateError> {
|
||||
let i = self.get_latest_block_roots_index(slot, spec)?;
|
||||
let i = self.get_latest_block_roots_index(slot)?;
|
||||
self.latest_block_roots[i] = block_root;
|
||||
Ok(())
|
||||
}
|
||||
@@ -420,16 +433,10 @@ impl BeaconState {
|
||||
/// Spec v0.5.1
|
||||
fn get_randao_mix_index(&self, epoch: Epoch, spec: &ChainSpec) -> Result<usize, Error> {
|
||||
let current_epoch = self.current_epoch(spec);
|
||||
let len = T::LatestRandaoMixesLength::to_u64();
|
||||
|
||||
if (current_epoch - (spec.latest_randao_mixes_length as u64) < epoch)
|
||||
& (epoch <= current_epoch)
|
||||
{
|
||||
let i = epoch.as_usize() % spec.latest_randao_mixes_length;
|
||||
if i < self.latest_randao_mixes.len() {
|
||||
Ok(i)
|
||||
} else {
|
||||
Err(Error::InsufficientRandaoMixes)
|
||||
}
|
||||
if (current_epoch - len < epoch) & (epoch <= current_epoch) {
|
||||
Ok(epoch.as_usize() % len as usize)
|
||||
} else {
|
||||
Err(Error::EpochOutOfBounds)
|
||||
}
|
||||
@@ -448,7 +455,7 @@ impl BeaconState {
|
||||
signature: &Signature,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
let i = epoch.as_usize() % spec.latest_randao_mixes_length;
|
||||
let i = epoch.as_usize() % T::LatestRandaoMixesLength::to_usize();
|
||||
|
||||
let signature_hash = Hash256::from_slice(&hash(&ssz_encode(signature)));
|
||||
|
||||
@@ -485,17 +492,12 @@ impl BeaconState {
|
||||
fn get_active_index_root_index(&self, epoch: Epoch, spec: &ChainSpec) -> Result<usize, Error> {
|
||||
let current_epoch = self.current_epoch(spec);
|
||||
|
||||
if (current_epoch - spec.latest_active_index_roots_length as u64
|
||||
if (current_epoch - self.latest_active_index_roots.len() as u64
|
||||
+ spec.activation_exit_delay
|
||||
< epoch)
|
||||
& (epoch <= current_epoch + spec.activation_exit_delay)
|
||||
{
|
||||
let i = epoch.as_usize() % spec.latest_active_index_roots_length;
|
||||
if i < self.latest_active_index_roots.len() {
|
||||
Ok(i)
|
||||
} else {
|
||||
Err(Error::InsufficientIndexRoots)
|
||||
}
|
||||
Ok(epoch.as_usize() % self.latest_active_index_roots.len())
|
||||
} else {
|
||||
Err(Error::EpochOutOfBounds)
|
||||
}
|
||||
@@ -526,22 +528,17 @@ impl BeaconState {
|
||||
/// Replace `active_index_roots` with clones of `index_root`.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
pub fn fill_active_index_roots_with(&mut self, index_root: Hash256, spec: &ChainSpec) {
|
||||
pub fn fill_active_index_roots_with(&mut self, index_root: Hash256) {
|
||||
self.latest_active_index_roots =
|
||||
vec![index_root; spec.latest_active_index_roots_length as usize].into()
|
||||
vec![index_root; self.latest_active_index_roots.len() as usize].into()
|
||||
}
|
||||
|
||||
/// Safely obtains the index for latest state roots, given some `slot`.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
fn get_latest_state_roots_index(&self, slot: Slot, spec: &ChainSpec) -> Result<usize, Error> {
|
||||
if (slot < self.slot) && (self.slot <= slot + spec.slots_per_historical_root as u64) {
|
||||
let i = slot.as_usize() % spec.slots_per_historical_root;
|
||||
if i >= self.latest_state_roots.len() {
|
||||
Err(Error::InsufficientStateRoots)
|
||||
} else {
|
||||
Ok(i)
|
||||
}
|
||||
fn get_latest_state_roots_index(&self, slot: Slot) -> Result<usize, Error> {
|
||||
if (slot < self.slot) && (self.slot <= slot + self.latest_state_roots.len() as u64) {
|
||||
Ok(slot.as_usize() % self.latest_state_roots.len())
|
||||
} else {
|
||||
Err(BeaconStateError::SlotOutOfBounds)
|
||||
}
|
||||
@@ -550,21 +547,16 @@ impl BeaconState {
|
||||
/// Gets the state root for some slot.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
pub fn get_state_root(&mut self, slot: Slot, spec: &ChainSpec) -> Result<&Hash256, Error> {
|
||||
let i = self.get_latest_state_roots_index(slot, spec)?;
|
||||
pub fn get_state_root(&mut self, slot: Slot) -> Result<&Hash256, Error> {
|
||||
let i = self.get_latest_state_roots_index(slot)?;
|
||||
Ok(&self.latest_state_roots[i])
|
||||
}
|
||||
|
||||
/// Sets the latest state root for slot.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
pub fn set_state_root(
|
||||
&mut self,
|
||||
slot: Slot,
|
||||
state_root: Hash256,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
let i = self.get_latest_state_roots_index(slot, spec)?;
|
||||
pub fn set_state_root(&mut self, slot: Slot, state_root: Hash256) -> Result<(), Error> {
|
||||
let i = self.get_latest_state_roots_index(slot)?;
|
||||
self.latest_state_roots[i] = state_root;
|
||||
Ok(())
|
||||
}
|
||||
@@ -572,8 +564,8 @@ impl BeaconState {
|
||||
/// Safely obtains the index for `latest_slashed_balances`, given some `epoch`.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
fn get_slashed_balance_index(&self, epoch: Epoch, spec: &ChainSpec) -> Result<usize, Error> {
|
||||
let i = epoch.as_usize() % spec.latest_slashed_exit_length;
|
||||
fn get_slashed_balance_index(&self, epoch: Epoch) -> Result<usize, Error> {
|
||||
let i = epoch.as_usize() % self.latest_slashed_balances.len();
|
||||
|
||||
// NOTE: the validity of the epoch is not checked. It is not in the spec but it's probably
|
||||
// useful to have.
|
||||
@@ -587,21 +579,16 @@ impl BeaconState {
|
||||
/// Gets the total slashed balances for some epoch.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
pub fn get_slashed_balance(&self, epoch: Epoch, spec: &ChainSpec) -> Result<u64, Error> {
|
||||
let i = self.get_slashed_balance_index(epoch, spec)?;
|
||||
pub fn get_slashed_balance(&self, epoch: Epoch) -> Result<u64, Error> {
|
||||
let i = self.get_slashed_balance_index(epoch)?;
|
||||
Ok(self.latest_slashed_balances[i])
|
||||
}
|
||||
|
||||
/// Sets the total slashed balances for some epoch.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
pub fn set_slashed_balance(
|
||||
&mut self,
|
||||
epoch: Epoch,
|
||||
balance: u64,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<(), Error> {
|
||||
let i = self.get_slashed_balance_index(epoch, spec)?;
|
||||
pub fn set_slashed_balance(&mut self, epoch: Epoch, balance: u64) -> Result<(), Error> {
|
||||
let i = self.get_slashed_balance_index(epoch)?;
|
||||
self.latest_slashed_balances[i] = balance;
|
||||
Ok(())
|
||||
}
|
||||
@@ -831,7 +818,7 @@ impl BeaconState {
|
||||
self.tree_hash_cache
|
||||
.tree_hash_root()
|
||||
.and_then(|b| Ok(Hash256::from_slice(b)))
|
||||
.map_err(|e| e.into())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
use crate::*;
|
||||
use fixed_len_vec::typenum::{Unsigned, U1024, U8, U8192};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub trait EthSpec:
|
||||
'static + Default + Sync + Send + Clone + Debug + PartialEq + serde::de::DeserializeOwned
|
||||
{
|
||||
type ShardCount: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
type SlotsPerHistoricalRoot: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
type LatestRandaoMixesLength: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
type LatestActiveIndexRootsLength: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
type LatestSlashedExitLength: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
|
||||
fn spec() -> ChainSpec;
|
||||
|
||||
/// Returns the `SHARD_COUNT` constant for this specification.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
fn shard_count() -> usize {
|
||||
Self::ShardCount::to_usize()
|
||||
}
|
||||
|
||||
/// Returns the `SLOTS_PER_HISTORICAL_ROOT` constant for this specification.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
fn slots_per_historical_root() -> usize {
|
||||
Self::SlotsPerHistoricalRoot::to_usize()
|
||||
}
|
||||
|
||||
/// Returns the `LATEST_RANDAO_MIXES_LENGTH` constant for this specification.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
fn latest_randao_mixes_length() -> usize {
|
||||
Self::LatestRandaoMixesLength::to_usize()
|
||||
}
|
||||
|
||||
/// Returns the `LATEST_ACTIVE_INDEX_ROOTS` constant for this specification.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
fn latest_active_index_roots() -> usize {
|
||||
Self::LatestActiveIndexRootsLength::to_usize()
|
||||
}
|
||||
|
||||
/// Returns the `LATEST_SLASHED_EXIT_LENGTH` constant for this specification.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
fn latest_slashed_exit_length() -> usize {
|
||||
Self::LatestSlashedExitLength::to_usize()
|
||||
}
|
||||
}
|
||||
|
||||
/// Ethereum Foundation specifications.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)]
|
||||
pub struct FoundationEthSpec;
|
||||
|
||||
impl EthSpec for FoundationEthSpec {
|
||||
type ShardCount = U1024;
|
||||
type SlotsPerHistoricalRoot = U8192;
|
||||
type LatestRandaoMixesLength = U8192;
|
||||
type LatestActiveIndexRootsLength = U8192;
|
||||
type LatestSlashedExitLength = U8192;
|
||||
|
||||
fn spec() -> ChainSpec {
|
||||
ChainSpec::foundation()
|
||||
}
|
||||
}
|
||||
|
||||
pub type FoundationBeaconState = BeaconState<FoundationEthSpec>;
|
||||
|
||||
/// Ethereum Foundation specifications, modified to be suitable for < 1000 validators.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)]
|
||||
pub struct FewValidatorsEthSpec;
|
||||
|
||||
impl EthSpec for FewValidatorsEthSpec {
|
||||
type ShardCount = U8;
|
||||
type SlotsPerHistoricalRoot = U8192;
|
||||
type LatestRandaoMixesLength = U8192;
|
||||
type LatestActiveIndexRootsLength = U8192;
|
||||
type LatestSlashedExitLength = U8192;
|
||||
|
||||
fn spec() -> ChainSpec {
|
||||
ChainSpec::few_validators()
|
||||
}
|
||||
}
|
||||
|
||||
pub type FewValidatorsBeaconState = BeaconState<FewValidatorsEthSpec>;
|
||||
|
||||
/// Specifications suitable for a small-scale (< 1000 validators) lighthouse testnet.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)]
|
||||
pub struct LighthouseTestnetEthSpec;
|
||||
|
||||
impl EthSpec for LighthouseTestnetEthSpec {
|
||||
type ShardCount = U8;
|
||||
type SlotsPerHistoricalRoot = U8192;
|
||||
type LatestRandaoMixesLength = U8192;
|
||||
type LatestActiveIndexRootsLength = U8192;
|
||||
type LatestSlashedExitLength = U8192;
|
||||
|
||||
fn spec() -> ChainSpec {
|
||||
ChainSpec::lighthouse_testnet()
|
||||
}
|
||||
}
|
||||
|
||||
pub type LighthouseTestnetBeaconState = BeaconState<LighthouseTestnetEthSpec>;
|
||||
@@ -28,8 +28,8 @@ pub struct EpochCache {
|
||||
|
||||
impl EpochCache {
|
||||
/// Return a new, fully initialized cache.
|
||||
pub fn initialized(
|
||||
state: &BeaconState,
|
||||
pub fn initialized<T: EthSpec>(
|
||||
state: &BeaconState<T>,
|
||||
relative_epoch: RelativeEpoch,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<EpochCache, Error> {
|
||||
@@ -200,8 +200,8 @@ pub struct EpochCrosslinkCommitteesBuilder {
|
||||
|
||||
impl EpochCrosslinkCommitteesBuilder {
|
||||
/// Instantiates a builder that will build for the `state`'s previous epoch.
|
||||
pub fn for_previous_epoch(
|
||||
state: &BeaconState,
|
||||
pub fn for_previous_epoch<T: EthSpec>(
|
||||
state: &BeaconState<T>,
|
||||
active_validator_indices: Vec<usize>,
|
||||
spec: &ChainSpec,
|
||||
) -> Self {
|
||||
@@ -215,8 +215,8 @@ impl EpochCrosslinkCommitteesBuilder {
|
||||
}
|
||||
|
||||
/// Instantiates a builder that will build for the `state`'s next epoch.
|
||||
pub fn for_current_epoch(
|
||||
state: &BeaconState,
|
||||
pub fn for_current_epoch<T: EthSpec>(
|
||||
state: &BeaconState<T>,
|
||||
active_validator_indices: Vec<usize>,
|
||||
spec: &ChainSpec,
|
||||
) -> Self {
|
||||
@@ -233,8 +233,8 @@ impl EpochCrosslinkCommitteesBuilder {
|
||||
///
|
||||
/// Note: there are two possible epoch builds for the next epoch, one where there is a registry
|
||||
/// change and one where there is not.
|
||||
pub fn for_next_epoch(
|
||||
state: &BeaconState,
|
||||
pub fn for_next_epoch<T: EthSpec>(
|
||||
state: &BeaconState<T>,
|
||||
active_validator_indices: Vec<usize>,
|
||||
registry_change: bool,
|
||||
spec: &ChainSpec,
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#![cfg(test)]
|
||||
|
||||
use super::*;
|
||||
use crate::beacon_state::FewValidatorsEthSpec;
|
||||
use crate::test_utils::*;
|
||||
use swap_or_not_shuffle::shuffle_list;
|
||||
|
||||
fn do_sane_cache_test(
|
||||
state: BeaconState,
|
||||
fn do_sane_cache_test<T: EthSpec>(
|
||||
state: BeaconState<T>,
|
||||
epoch: Epoch,
|
||||
relative_epoch: RelativeEpoch,
|
||||
validator_count: usize,
|
||||
@@ -64,7 +65,7 @@ fn do_sane_cache_test(
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_sane_cache_test(validator_count: usize, spec: &ChainSpec) -> BeaconState {
|
||||
fn setup_sane_cache_test<T: EthSpec>(validator_count: usize, spec: &ChainSpec) -> BeaconState<T> {
|
||||
let mut builder =
|
||||
TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(validator_count, spec);
|
||||
|
||||
@@ -98,10 +99,13 @@ fn setup_sane_cache_test(validator_count: usize, spec: &ChainSpec) -> BeaconStat
|
||||
|
||||
#[test]
|
||||
fn builds_sane_current_epoch_cache() {
|
||||
let mut spec = ChainSpec::few_validators();
|
||||
let mut spec = FewValidatorsEthSpec::spec();
|
||||
spec.shard_count = 4;
|
||||
let validator_count = (spec.shard_count * spec.target_committee_size) + 1;
|
||||
let state = setup_sane_cache_test(validator_count as usize, &spec);
|
||||
|
||||
let state: BeaconState<FewValidatorsEthSpec> =
|
||||
setup_sane_cache_test(validator_count as usize, &spec);
|
||||
|
||||
do_sane_cache_test(
|
||||
state.clone(),
|
||||
state.current_epoch(&spec),
|
||||
@@ -115,10 +119,13 @@ fn builds_sane_current_epoch_cache() {
|
||||
|
||||
#[test]
|
||||
fn builds_sane_previous_epoch_cache() {
|
||||
let mut spec = ChainSpec::few_validators();
|
||||
let mut spec = FewValidatorsEthSpec::spec();
|
||||
spec.shard_count = 2;
|
||||
let validator_count = (spec.shard_count * spec.target_committee_size) + 1;
|
||||
let state = setup_sane_cache_test(validator_count as usize, &spec);
|
||||
|
||||
let state: BeaconState<FewValidatorsEthSpec> =
|
||||
setup_sane_cache_test(validator_count as usize, &spec);
|
||||
|
||||
do_sane_cache_test(
|
||||
state.clone(),
|
||||
state.previous_epoch(&spec),
|
||||
@@ -132,10 +139,13 @@ fn builds_sane_previous_epoch_cache() {
|
||||
|
||||
#[test]
|
||||
fn builds_sane_next_without_update_epoch_cache() {
|
||||
let mut spec = ChainSpec::few_validators();
|
||||
let mut spec = FewValidatorsEthSpec::spec();
|
||||
spec.shard_count = 2;
|
||||
let validator_count = (spec.shard_count * spec.target_committee_size) + 1;
|
||||
let mut state = setup_sane_cache_test(validator_count as usize, &spec);
|
||||
|
||||
let mut state: BeaconState<FewValidatorsEthSpec> =
|
||||
setup_sane_cache_test(validator_count as usize, &spec);
|
||||
|
||||
state.validator_registry_update_epoch = state.slot.epoch(spec.slots_per_epoch);
|
||||
do_sane_cache_test(
|
||||
state.clone(),
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
#![cfg(test)]
|
||||
use super::*;
|
||||
use crate::beacon_state::FewValidatorsEthSpec;
|
||||
use crate::test_utils::*;
|
||||
|
||||
ssz_tests!(BeaconState);
|
||||
cached_tree_hash_tests!(BeaconState);
|
||||
ssz_tests!(FoundationBeaconState);
|
||||
cached_tree_hash_tests!(FoundationBeaconState);
|
||||
|
||||
/// Test that
|
||||
///
|
||||
/// 1. Using the cache before it's built fails.
|
||||
/// 2. Using the cache after it's build passes.
|
||||
/// 3. Using the cache after it's dropped fails.
|
||||
fn test_cache_initialization<'a>(
|
||||
state: &'a mut BeaconState,
|
||||
fn test_cache_initialization<'a, T: EthSpec>(
|
||||
state: &'a mut BeaconState<T>,
|
||||
relative_epoch: RelativeEpoch,
|
||||
spec: &ChainSpec,
|
||||
) {
|
||||
@@ -45,9 +46,11 @@ fn test_cache_initialization<'a>(
|
||||
|
||||
#[test]
|
||||
fn cache_initialization() {
|
||||
let spec = ChainSpec::few_validators();
|
||||
let (mut state, _keypairs) =
|
||||
TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(16, &spec).build();
|
||||
let spec = FewValidatorsEthSpec::spec();
|
||||
|
||||
let builder: TestingBeaconStateBuilder<FewValidatorsEthSpec> =
|
||||
TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(16, &spec);
|
||||
let (mut state, _keypairs) = builder.build();
|
||||
|
||||
state.slot = (spec.genesis_epoch + 1).start_slot(spec.slots_per_epoch);
|
||||
|
||||
@@ -64,7 +67,7 @@ fn tree_hash_cache() {
|
||||
|
||||
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||
|
||||
let mut state = BeaconState::random_for_test(&mut rng);
|
||||
let mut state: FoundationBeaconState = BeaconState::random_for_test(&mut rng);
|
||||
|
||||
let root = state.update_tree_hash_cache().unwrap();
|
||||
|
||||
|
||||
@@ -70,17 +70,9 @@ pub struct ChainSpec {
|
||||
pub min_seed_lookahead: Epoch,
|
||||
pub activation_exit_delay: u64,
|
||||
pub epochs_per_eth1_voting_period: u64,
|
||||
pub slots_per_historical_root: usize,
|
||||
pub min_validator_withdrawability_delay: Epoch,
|
||||
pub persistent_committee_period: u64,
|
||||
|
||||
/*
|
||||
* State list lengths
|
||||
*/
|
||||
pub latest_randao_mixes_length: usize,
|
||||
pub latest_active_index_roots_length: usize,
|
||||
pub latest_slashed_exit_length: usize,
|
||||
|
||||
/*
|
||||
* Reward and penalty quotients
|
||||
*/
|
||||
@@ -162,7 +154,7 @@ impl ChainSpec {
|
||||
/// Returns a `ChainSpec` compatible with the Ethereum Foundation specification.
|
||||
///
|
||||
/// Spec v0.5.1
|
||||
pub fn foundation() -> Self {
|
||||
pub(crate) fn foundation() -> Self {
|
||||
let genesis_slot = Slot::new(2_u64.pow(32));
|
||||
let slots_per_epoch = 64;
|
||||
let genesis_epoch = genesis_slot.epoch(slots_per_epoch);
|
||||
@@ -213,17 +205,9 @@ impl ChainSpec {
|
||||
min_seed_lookahead: Epoch::new(1),
|
||||
activation_exit_delay: 4,
|
||||
epochs_per_eth1_voting_period: 16,
|
||||
slots_per_historical_root: 8_192,
|
||||
min_validator_withdrawability_delay: Epoch::new(256),
|
||||
persistent_committee_period: 2_048,
|
||||
|
||||
/*
|
||||
* State list lengths
|
||||
*/
|
||||
latest_randao_mixes_length: 8_192,
|
||||
latest_active_index_roots_length: 8_192,
|
||||
latest_slashed_exit_length: 8_192,
|
||||
|
||||
/*
|
||||
* Reward and penalty quotients
|
||||
*/
|
||||
@@ -264,7 +248,7 @@ impl ChainSpec {
|
||||
/// Returns a `ChainSpec` compatible with the Lighthouse testnet specification.
|
||||
///
|
||||
/// Spec v0.4.0
|
||||
pub fn lighthouse_testnet() -> Self {
|
||||
pub(crate) fn lighthouse_testnet() -> Self {
|
||||
/*
|
||||
* Lighthouse testnet bootnodes
|
||||
*/
|
||||
@@ -280,7 +264,7 @@ impl ChainSpec {
|
||||
}
|
||||
|
||||
/// Returns a `ChainSpec` compatible with the specification suitable for 8 validators.
|
||||
pub fn few_validators() -> Self {
|
||||
pub(crate) fn few_validators() -> Self {
|
||||
let genesis_slot = Slot::new(2_u64.pow(32));
|
||||
let slots_per_epoch = 8;
|
||||
let genesis_epoch = genesis_slot.epoch(slots_per_epoch);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{Epoch, Hash256};
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use super::{DepositData, Hash256, TreeHashVector};
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
use crate::*;
|
||||
use fixed_len_vec::typenum::U32;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
@@ -22,7 +23,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
TestRandom,
|
||||
)]
|
||||
pub struct Deposit {
|
||||
pub proof: TreeHashVector<Hash256>,
|
||||
pub proof: FixedLenVec<Hash256, U32>,
|
||||
pub index: u64,
|
||||
pub deposit_data: DepositData,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::DepositInput;
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
use bls::{PublicKey, Signature};
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::Hash256;
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::Eth1Data;
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::{
|
||||
ChainSpec, Epoch,
|
||||
};
|
||||
use int_to_bytes::int_to_bytes4;
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{Hash256, TreeHashVector};
|
||||
use rand::RngCore;
|
||||
use crate::*;
|
||||
|
||||
use fixed_len_vec::FixedLenVec;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
@@ -21,15 +22,17 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
CachedTreeHash,
|
||||
TestRandom,
|
||||
)]
|
||||
pub struct HistoricalBatch {
|
||||
pub block_roots: TreeHashVector<Hash256>,
|
||||
pub state_roots: TreeHashVector<Hash256>,
|
||||
pub struct HistoricalBatch<T: EthSpec> {
|
||||
pub block_roots: FixedLenVec<Hash256, T::SlotsPerHistoricalRoot>,
|
||||
pub state_roots: FixedLenVec<Hash256, T::SlotsPerHistoricalRoot>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
ssz_tests!(HistoricalBatch);
|
||||
cached_tree_hash_tests!(HistoricalBatch);
|
||||
pub type FoundationHistoricalBatch = HistoricalBatch<FoundationEthSpec>;
|
||||
|
||||
ssz_tests!(FoundationHistoricalBatch);
|
||||
cached_tree_hash_tests!(FoundationHistoricalBatch);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ pub mod pending_attestation;
|
||||
pub mod proposer_slashing;
|
||||
pub mod slashable_attestation;
|
||||
pub mod transfer;
|
||||
pub mod tree_hash_vector;
|
||||
// pub mod tree_hash_vector;
|
||||
pub mod voluntary_exit;
|
||||
#[macro_use]
|
||||
pub mod slot_epoch_macros;
|
||||
@@ -47,7 +47,7 @@ pub use crate::attester_slashing::AttesterSlashing;
|
||||
pub use crate::beacon_block::BeaconBlock;
|
||||
pub use crate::beacon_block_body::BeaconBlockBody;
|
||||
pub use crate::beacon_block_header::BeaconBlockHeader;
|
||||
pub use crate::beacon_state::{BeaconState, Error as BeaconStateError};
|
||||
pub use crate::beacon_state::{Error as BeaconStateError, *};
|
||||
pub use crate::chain_spec::{ChainSpec, Domain};
|
||||
pub use crate::crosslink::Crosslink;
|
||||
pub use crate::crosslink_committee::CrosslinkCommittee;
|
||||
@@ -66,7 +66,7 @@ pub use crate::slashable_attestation::SlashableAttestation;
|
||||
pub use crate::slot_epoch::{Epoch, Slot};
|
||||
pub use crate::slot_height::SlotHeight;
|
||||
pub use crate::transfer::Transfer;
|
||||
pub use crate::tree_hash_vector::TreeHashVector;
|
||||
// pub use crate::tree_hash_vector::TreeHashVector;
|
||||
pub use crate::validator::Validator;
|
||||
pub use crate::voluntary_exit::VoluntaryExit;
|
||||
|
||||
@@ -87,6 +87,7 @@ pub type AttesterMap = HashMap<(u64, u64), Vec<usize>>;
|
||||
pub type ProposerMap = HashMap<u64, usize>;
|
||||
|
||||
pub use bls::{AggregatePublicKey, AggregateSignature, Keypair, PublicKey, SecretKey, Signature};
|
||||
pub use fixed_len_vec::{typenum::Unsigned, FixedLenVec};
|
||||
pub use libp2p::floodsub::{Topic, TopicBuilder, TopicHash};
|
||||
pub use libp2p::multiaddr;
|
||||
pub use libp2p::Multiaddr;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::{Attestation, AttestationData, Bitfield, Slot};
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::BeaconBlockHeader;
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{test_utils::TestRandom, AggregateSignature, AttestationData, Bitfield, ChainSpec};
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
//! The `Slot` and `Epoch` types are defined as newtypes over u64 to enforce type-safety between
|
||||
//! the two types.
|
||||
//!
|
||||
//! `Slot` and `Epoch` have implementations which permit conversion, comparison and math operations
|
||||
//! between each and `u64`, however specifically not between each other.
|
||||
//!
|
||||
//! All math operations on `Slot` and `Epoch` are saturating, they never wrap.
|
||||
//!
|
||||
//! It would be easy to define `PartialOrd` and other traits generically across all types which
|
||||
//! implement `Into<u64>`, however this would allow operations between `Slots` and `Epochs` which
|
||||
//! may lead to programming errors which are not detected by the compiler.
|
||||
|
||||
use crate::slot_height::SlotHeight;
|
||||
/// The `Slot` and `Epoch` types are defined as newtypes over u64 to enforce type-safety between
|
||||
/// the two types.
|
||||
///
|
||||
/// `Slot` and `Epoch` have implementations which permit conversion, comparison and math operations
|
||||
/// between each and `u64`, however specifically not between each other.
|
||||
///
|
||||
/// All math operations on `Slot` and `Epoch` are saturating, they never wrap.
|
||||
///
|
||||
/// It would be easy to define `PartialOrd` and other traits generically across all types which
|
||||
/// implement `Into<u64>`, however this would allow operations between `Slots` and `Epochs` which
|
||||
/// may lead to programming errors which are not detected by the compiler.
|
||||
use crate::test_utils::TestRandom;
|
||||
use rand::RngCore;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
@@ -258,8 +258,8 @@ macro_rules! impl_ssz {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RngCore> TestRandom<T> for $type {
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
impl TestRandom for $type {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
$type::from(u64::random_for_test(rng))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::slot_epoch::{Epoch, Slot};
|
||||
use crate::test_utils::TestRandom;
|
||||
|
||||
use rand::RngCore;
|
||||
use serde_derive::Serialize;
|
||||
use ssz::{ssz_encode, Decodable, DecodeError, Encodable};
|
||||
|
||||
@@ -18,13 +18,17 @@ pub fn generate_deterministic_keypairs(validator_count: usize) -> Vec<Keypair> {
|
||||
let keypairs: Vec<Keypair> = (0..validator_count)
|
||||
.collect::<Vec<usize>>()
|
||||
.par_iter()
|
||||
.map(|&i| {
|
||||
let secret = int_to_bytes48(i as u64 + 1000);
|
||||
let sk = SecretKey::from_bytes(&secret).unwrap();
|
||||
let pk = PublicKey::from_secret_key(&sk);
|
||||
Keypair { sk, pk }
|
||||
})
|
||||
.map(|&i| generate_deterministic_keypair(i))
|
||||
.collect();
|
||||
|
||||
keypairs
|
||||
}
|
||||
|
||||
/// Generates a single deterministic keypair, where the secret key is `validator_index`.
|
||||
///
|
||||
/// This is used for testing only, and not to be used in production!
|
||||
pub fn generate_deterministic_keypair(validator_index: usize) -> Keypair {
|
||||
let secret = int_to_bytes48(validator_index as u64 + 1000);
|
||||
let sk = SecretKey::from_bytes(&secret).unwrap();
|
||||
let pk = PublicKey::from_secret_key(&sk);
|
||||
Keypair { sk, pk }
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ mod testing_proposer_slashing_builder;
|
||||
mod testing_transfer_builder;
|
||||
mod testing_voluntary_exit_builder;
|
||||
|
||||
pub use generate_deterministic_keypairs::generate_deterministic_keypair;
|
||||
pub use generate_deterministic_keypairs::generate_deterministic_keypairs;
|
||||
pub use keypairs_file::KeypairsFile;
|
||||
pub use rand::{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use crate::*;
|
||||
use fixed_len_vec::typenum::Unsigned;
|
||||
use rand::RngCore;
|
||||
|
||||
mod address;
|
||||
@@ -8,42 +10,39 @@ mod public_key;
|
||||
mod secret_key;
|
||||
mod signature;
|
||||
|
||||
pub trait TestRandom<T>
|
||||
where
|
||||
T: RngCore,
|
||||
{
|
||||
fn random_for_test(rng: &mut T) -> Self;
|
||||
pub trait TestRandom {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self;
|
||||
}
|
||||
|
||||
impl<T: RngCore> TestRandom<T> for bool {
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
impl TestRandom for bool {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
(rng.next_u32() % 2) == 1
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RngCore> TestRandom<T> for u64 {
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
impl TestRandom for u64 {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
rng.next_u64()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RngCore> TestRandom<T> for u32 {
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
impl TestRandom for u32 {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
rng.next_u32()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RngCore> TestRandom<T> for usize {
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
impl TestRandom for usize {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
rng.next_u32() as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RngCore, U> TestRandom<T> for Vec<U>
|
||||
impl<U> TestRandom for Vec<U>
|
||||
where
|
||||
U: TestRandom<T>,
|
||||
U: TestRandom,
|
||||
{
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
let mut output = vec![];
|
||||
|
||||
for _ in 0..(usize::random_for_test(rng) % 4) {
|
||||
@@ -54,10 +53,25 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, N: Unsigned> TestRandom for FixedLenVec<T, N>
|
||||
where
|
||||
T: TestRandom + Default,
|
||||
{
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
let mut output = vec![];
|
||||
|
||||
for _ in 0..(usize::random_for_test(rng) % std::cmp::min(4, N::to_usize())) {
|
||||
output.push(<T>::random_for_test(rng));
|
||||
}
|
||||
|
||||
output.into()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_test_random_for_u8_array {
|
||||
($len: expr) => {
|
||||
impl<T: RngCore> TestRandom<T> for [u8; $len] {
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
impl TestRandom for [u8; $len] {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
let mut bytes = [0; $len];
|
||||
rng.fill_bytes(&mut bytes);
|
||||
bytes
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use super::TestRandom;
|
||||
use super::*;
|
||||
use crate::Address;
|
||||
use rand::RngCore;
|
||||
|
||||
impl<T: RngCore> TestRandom<T> for Address {
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
impl TestRandom for Address {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
let mut key_bytes = vec![0; 20];
|
||||
rng.fill_bytes(&mut key_bytes);
|
||||
Address::from_slice(&key_bytes[..])
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use super::TestRandom;
|
||||
use super::*;
|
||||
use bls::{AggregateSignature, Signature};
|
||||
use rand::RngCore;
|
||||
|
||||
impl<T: RngCore> TestRandom<T> for AggregateSignature {
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
impl TestRandom for AggregateSignature {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
let signature = Signature::random_for_test(rng);
|
||||
let mut aggregate_signature = AggregateSignature::new();
|
||||
aggregate_signature.add(&signature);
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use super::TestRandom;
|
||||
use super::*;
|
||||
use crate::Bitfield;
|
||||
use rand::RngCore;
|
||||
|
||||
impl<T: RngCore> TestRandom<T> for Bitfield {
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
impl TestRandom for Bitfield {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
let mut raw_bytes = vec![0; 32];
|
||||
rng.fill_bytes(&mut raw_bytes);
|
||||
Bitfield::from_bytes(&raw_bytes)
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use super::TestRandom;
|
||||
use super::*;
|
||||
use crate::Hash256;
|
||||
use rand::RngCore;
|
||||
|
||||
impl<T: RngCore> TestRandom<T> for Hash256 {
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
impl TestRandom for Hash256 {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
let mut key_bytes = vec![0; 32];
|
||||
rng.fill_bytes(&mut key_bytes);
|
||||
Hash256::from_slice(&key_bytes[..])
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use super::TestRandom;
|
||||
use super::*;
|
||||
use bls::{PublicKey, SecretKey};
|
||||
use rand::RngCore;
|
||||
|
||||
impl<T: RngCore> TestRandom<T> for PublicKey {
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
impl TestRandom for PublicKey {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
let secret_key = SecretKey::random_for_test(rng);
|
||||
PublicKey::from_secret_key(&secret_key)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use super::TestRandom;
|
||||
use super::*;
|
||||
use bls::SecretKey;
|
||||
use rand::RngCore;
|
||||
|
||||
impl<T: RngCore> TestRandom<T> for SecretKey {
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
impl TestRandom for SecretKey {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
let mut key_bytes = vec![0; 48];
|
||||
rng.fill_bytes(&mut key_bytes);
|
||||
/*
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use super::TestRandom;
|
||||
use super::*;
|
||||
use bls::{SecretKey, Signature};
|
||||
use rand::RngCore;
|
||||
|
||||
impl<T: RngCore> TestRandom<T> for Signature {
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
impl TestRandom for Signature {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
let secret_key = SecretKey::random_for_test(rng);
|
||||
let mut message = vec![0; 32];
|
||||
rng.fill_bytes(&mut message);
|
||||
|
||||
@@ -12,8 +12,8 @@ pub struct TestingAttestationBuilder {
|
||||
|
||||
impl TestingAttestationBuilder {
|
||||
/// Create a new attestation builder.
|
||||
pub fn new(
|
||||
state: &BeaconState,
|
||||
pub fn new<T: EthSpec>(
|
||||
state: &BeaconState<T>,
|
||||
committee: &[usize],
|
||||
slot: Slot,
|
||||
shard: u64,
|
||||
|
||||
@@ -10,7 +10,12 @@ pub struct TestingAttestationDataBuilder {
|
||||
impl TestingAttestationDataBuilder {
|
||||
/// Configures a new `AttestationData` which attests to all of the same parameters as the
|
||||
/// state.
|
||||
pub fn new(state: &BeaconState, shard: u64, slot: Slot, spec: &ChainSpec) -> Self {
|
||||
pub fn new<T: EthSpec>(
|
||||
state: &BeaconState<T>,
|
||||
shard: u64,
|
||||
slot: Slot,
|
||||
spec: &ChainSpec,
|
||||
) -> Self {
|
||||
let current_epoch = state.current_epoch(spec);
|
||||
let previous_epoch = state.previous_epoch(spec);
|
||||
|
||||
@@ -25,22 +30,22 @@ impl TestingAttestationDataBuilder {
|
||||
|
||||
let target_root = if is_previous_epoch {
|
||||
*state
|
||||
.get_block_root(previous_epoch.start_slot(spec.slots_per_epoch), spec)
|
||||
.get_block_root(previous_epoch.start_slot(spec.slots_per_epoch))
|
||||
.unwrap()
|
||||
} else {
|
||||
*state
|
||||
.get_block_root(current_epoch.start_slot(spec.slots_per_epoch), spec)
|
||||
.get_block_root(current_epoch.start_slot(spec.slots_per_epoch))
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let source_root = *state
|
||||
.get_block_root(source_epoch.start_slot(spec.slots_per_epoch), spec)
|
||||
.get_block_root(source_epoch.start_slot(spec.slots_per_epoch))
|
||||
.unwrap();
|
||||
|
||||
let data = AttestationData {
|
||||
// LMD GHOST vote
|
||||
slot,
|
||||
beacon_block_root: *state.get_block_root(slot, spec).unwrap(),
|
||||
beacon_block_root: *state.get_block_root(slot).unwrap(),
|
||||
|
||||
// FFG Vote
|
||||
source_epoch,
|
||||
|
||||
@@ -82,9 +82,9 @@ impl TestingBeaconBlockBuilder {
|
||||
///
|
||||
/// Note: the signed messages of the split committees will be identical -- it would be possible
|
||||
/// to aggregate these split attestations.
|
||||
pub fn insert_attestations(
|
||||
pub fn insert_attestations<T: EthSpec>(
|
||||
&mut self,
|
||||
state: &BeaconState,
|
||||
state: &BeaconState<T>,
|
||||
secret_keys: &[&SecretKey],
|
||||
num_attestations: usize,
|
||||
spec: &ChainSpec,
|
||||
@@ -171,11 +171,11 @@ impl TestingBeaconBlockBuilder {
|
||||
}
|
||||
|
||||
/// Insert a `Valid` deposit into the state.
|
||||
pub fn insert_deposit(
|
||||
pub fn insert_deposit<T: EthSpec>(
|
||||
&mut self,
|
||||
amount: u64,
|
||||
index: u64,
|
||||
state: &BeaconState,
|
||||
state: &BeaconState<T>,
|
||||
spec: &ChainSpec,
|
||||
) {
|
||||
let keypair = Keypair::random();
|
||||
@@ -193,9 +193,9 @@ impl TestingBeaconBlockBuilder {
|
||||
}
|
||||
|
||||
/// Insert a `Valid` exit into the state.
|
||||
pub fn insert_exit(
|
||||
pub fn insert_exit<T: EthSpec>(
|
||||
&mut self,
|
||||
state: &BeaconState,
|
||||
state: &BeaconState<T>,
|
||||
validator_index: u64,
|
||||
secret_key: &SecretKey,
|
||||
spec: &ChainSpec,
|
||||
@@ -214,9 +214,9 @@ impl TestingBeaconBlockBuilder {
|
||||
///
|
||||
/// Note: this will set the validator to be withdrawable by directly modifying the state
|
||||
/// validator registry. This _may_ cause problems historic hashes, etc.
|
||||
pub fn insert_transfer(
|
||||
pub fn insert_transfer<T: EthSpec>(
|
||||
&mut self,
|
||||
state: &BeaconState,
|
||||
state: &BeaconState<T>,
|
||||
from: u64,
|
||||
to: u64,
|
||||
amount: u64,
|
||||
|
||||
@@ -25,12 +25,12 @@ pub fn keypairs_path() -> PathBuf {
|
||||
///
|
||||
/// This struct should **never be used for production purposes.**
|
||||
#[derive(Clone)]
|
||||
pub struct TestingBeaconStateBuilder {
|
||||
state: BeaconState,
|
||||
pub struct TestingBeaconStateBuilder<T: EthSpec> {
|
||||
state: BeaconState<T>,
|
||||
keypairs: Vec<Keypair>,
|
||||
}
|
||||
|
||||
impl TestingBeaconStateBuilder {
|
||||
impl<T: EthSpec> TestingBeaconStateBuilder<T> {
|
||||
/// Attempts to load validators from a file in `$HOME/.lighthouse/keypairs.raw_keypairs`. If
|
||||
/// the file is unavailable, it generates the keys at runtime.
|
||||
///
|
||||
@@ -154,7 +154,7 @@ impl TestingBeaconStateBuilder {
|
||||
}
|
||||
|
||||
/// Consume the builder and return the `BeaconState` and the keypairs for each validator.
|
||||
pub fn build(self) -> (BeaconState, Vec<Keypair>) {
|
||||
pub fn build(self) -> (BeaconState<T>, Vec<Keypair>) {
|
||||
(self.state, self.keypairs)
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,12 @@ impl TestingPendingAttestationBuilder {
|
||||
///
|
||||
/// * The aggregation and custody bitfields will all be empty, they need to be set with
|
||||
/// `Self::add_committee_participation`.
|
||||
pub fn new(state: &BeaconState, shard: u64, slot: Slot, spec: &ChainSpec) -> Self {
|
||||
pub fn new<T: EthSpec>(
|
||||
state: &BeaconState<T>,
|
||||
shard: u64,
|
||||
slot: Slot,
|
||||
spec: &ChainSpec,
|
||||
) -> Self {
|
||||
let data_builder = TestingAttestationDataBuilder::new(state, shard, slot, spec);
|
||||
|
||||
let pending_attestation = PendingAttestation {
|
||||
|
||||
@@ -2,7 +2,7 @@ use super::Slot;
|
||||
use crate::test_utils::TestRandom;
|
||||
use bls::{PublicKey, Signature};
|
||||
use derivative::Derivative;
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -100,11 +100,11 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RngCore, U> TestRandom<T> for TreeHashVector<U>
|
||||
impl<U> TestRandom for TreeHashVector<U>
|
||||
where
|
||||
U: TestRandom<T>,
|
||||
U: TestRandom,
|
||||
{
|
||||
fn random_for_test(rng: &mut T) -> Self {
|
||||
fn random_for_test(rng: &mut impl RngCore) -> Self {
|
||||
TreeHashVector::from(vec![
|
||||
U::random_for_test(rng),
|
||||
U::random_for_test(rng),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{test_utils::TestRandom, Epoch, Hash256, PublicKey};
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{test_utils::TestRandom, Epoch};
|
||||
use bls::Signature;
|
||||
use rand::RngCore;
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use test_random_derive::TestRandom;
|
||||
|
||||
Reference in New Issue
Block a user