mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-18 13:28:33 +00:00
Merge branch 'docker-env' into v0.6.1
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use self::committee_cache::{get_active_validator_indices, CommitteeCache};
|
||||
use self::committee_cache::get_active_validator_indices;
|
||||
use self::exit_cache::ExitCache;
|
||||
use crate::test_utils::TestRandom;
|
||||
use crate::*;
|
||||
@@ -15,6 +15,7 @@ use test_random_derive::TestRandom;
|
||||
use tree_hash::TreeHash;
|
||||
use tree_hash_derive::{CachedTreeHash, TreeHash};
|
||||
|
||||
pub use self::committee_cache::CommitteeCache;
|
||||
pub use beacon_state_types::*;
|
||||
|
||||
mod beacon_state_types;
|
||||
@@ -111,7 +112,7 @@ where
|
||||
pub previous_crosslinks: FixedLenVec<Crosslink, T::ShardCount>,
|
||||
pub latest_block_roots: FixedLenVec<Hash256, T::SlotsPerHistoricalRoot>,
|
||||
#[compare_fields(as_slice)]
|
||||
latest_state_roots: FixedLenVec<Hash256, T::SlotsPerHistoricalRoot>,
|
||||
pub latest_state_roots: FixedLenVec<Hash256, T::SlotsPerHistoricalRoot>,
|
||||
#[compare_fields(as_slice)]
|
||||
latest_active_index_roots: FixedLenVec<Hash256, T::LatestActiveIndexRootsLength>,
|
||||
latest_slashed_balances: FixedLenVec<u64, T::LatestSlashedExitLength>,
|
||||
@@ -163,7 +164,7 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
spec: &ChainSpec,
|
||||
) -> BeaconState<T> {
|
||||
let initial_crosslink = Crosslink {
|
||||
epoch: spec.genesis_epoch,
|
||||
epoch: T::genesis_epoch(),
|
||||
previous_crosslink_root: spec.zero_hash,
|
||||
crosslink_data_root: spec.zero_hash,
|
||||
};
|
||||
@@ -172,7 +173,7 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
// Misc
|
||||
slot: spec.genesis_slot,
|
||||
genesis_time,
|
||||
fork: Fork::genesis(spec),
|
||||
fork: Fork::genesis(T::genesis_epoch()),
|
||||
|
||||
// Validator registry
|
||||
validator_registry: vec![], // Set later in the function.
|
||||
@@ -188,12 +189,12 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
// Finality
|
||||
previous_epoch_attestations: vec![],
|
||||
current_epoch_attestations: vec![],
|
||||
previous_justified_epoch: spec.genesis_epoch,
|
||||
current_justified_epoch: spec.genesis_epoch,
|
||||
previous_justified_epoch: T::genesis_epoch(),
|
||||
current_justified_epoch: T::genesis_epoch(),
|
||||
previous_justified_root: spec.zero_hash,
|
||||
current_justified_root: spec.zero_hash,
|
||||
justification_bitfield: 0,
|
||||
finalized_epoch: spec.genesis_epoch,
|
||||
finalized_epoch: T::genesis_epoch(),
|
||||
finalized_root: spec.zero_hash,
|
||||
|
||||
// Recent state
|
||||
@@ -300,10 +301,10 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
Ok(cache.epoch_start_shard())
|
||||
}
|
||||
|
||||
pub fn next_epoch_start_shard(&self) -> Result<u64, Error> {
|
||||
pub fn next_epoch_start_shard(&self, spec: &ChainSpec) -> Result<u64, Error> {
|
||||
let cache = self.cache(RelativeEpoch::Current)?;
|
||||
let active_validator_count = cache.active_validator_count();
|
||||
let shard_delta = T::get_shard_delta(active_validator_count);
|
||||
let shard_delta = T::get_shard_delta(active_validator_count, spec.target_committee_size);
|
||||
|
||||
Ok((self.latest_start_shard + shard_delta) % T::ShardCount::to_u64())
|
||||
}
|
||||
@@ -422,7 +423,7 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
};
|
||||
let effective_balance = self.validator_registry[candidate_index].effective_balance;
|
||||
if (effective_balance * MAX_RANDOM_BYTE)
|
||||
>= (spec.max_effective_balance * random_byte as u64)
|
||||
>= (spec.max_effective_balance * u64::from(random_byte))
|
||||
{
|
||||
break candidate_index;
|
||||
}
|
||||
@@ -453,12 +454,8 @@ impl<T: EthSpec> BeaconState<T> {
|
||||
///
|
||||
/// Spec v0.6.0
|
||||
// FIXME(sproul): name swap with get_block_root
|
||||
pub fn get_block_root_at_epoch(
|
||||
&self,
|
||||
epoch: Epoch,
|
||||
spec: &ChainSpec,
|
||||
) -> Result<&Hash256, BeaconStateError> {
|
||||
self.get_block_root(epoch.start_slot(spec.slots_per_epoch))
|
||||
pub fn get_block_root_at_epoch(&self, epoch: Epoch) -> Result<&Hash256, BeaconStateError> {
|
||||
self.get_block_root(epoch.start_slot(T::slots_per_epoch()))
|
||||
}
|
||||
|
||||
/// Sets the block root for some given slot.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::*;
|
||||
use fixed_len_vec::typenum::{Unsigned, U1024, U8, U8192};
|
||||
use fixed_len_vec::typenum::{Unsigned, U0, U1024, U64, U8, U8192};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
|
||||
@@ -9,14 +9,24 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + 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;
|
||||
/// Note: `SlotsPerEpoch` is not necessarily required to be a compile-time constant. We include
|
||||
/// it here just for the convenience of not passing `slots_per_epoch` around all the time.
|
||||
type SlotsPerEpoch: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
type GenesisEpoch: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||
|
||||
fn spec() -> ChainSpec;
|
||||
fn default_spec() -> ChainSpec;
|
||||
|
||||
fn genesis_epoch() -> Epoch {
|
||||
Epoch::new(Self::GenesisEpoch::to_u64())
|
||||
}
|
||||
|
||||
/// Return the number of committees in one epoch.
|
||||
///
|
||||
/// Spec v0.6.1
|
||||
fn get_epoch_committee_count(active_validator_count: usize) -> usize {
|
||||
let target_committee_size = Self::spec().target_committee_size;
|
||||
fn get_epoch_committee_count(
|
||||
active_validator_count: usize,
|
||||
target_committee_size: usize,
|
||||
) -> usize {
|
||||
let shard_count = Self::shard_count();
|
||||
let slots_per_epoch = Self::slots_per_epoch() as usize;
|
||||
|
||||
@@ -32,10 +42,10 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq {
|
||||
/// Return the number of shards to increment `state.latest_start_shard` by in a given epoch.
|
||||
///
|
||||
/// Spec v0.6.3
|
||||
fn get_shard_delta(active_validator_count: usize) -> u64 {
|
||||
fn get_shard_delta(active_validator_count: usize, target_committee_size: usize) -> u64 {
|
||||
std::cmp::min(
|
||||
Self::get_epoch_committee_count(active_validator_count) as u64,
|
||||
Self::ShardCount::to_u64() - Self::ShardCount::to_u64() / Self::spec().slots_per_epoch,
|
||||
Self::get_epoch_committee_count(active_validator_count, target_committee_size) as u64,
|
||||
Self::ShardCount::to_u64() - Self::ShardCount::to_u64() / Self::slots_per_epoch(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -45,21 +55,14 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq {
|
||||
/// basic sense. This count is not required to provide any security guarantees regarding
|
||||
/// decentralization, entropy, etc.
|
||||
fn minimum_validator_count() -> usize {
|
||||
Self::slots_per_epoch() as usize
|
||||
Self::SlotsPerEpoch::to_usize()
|
||||
}
|
||||
|
||||
/// Returns the `SLOTS_PER_EPOCH` constant for this specification.
|
||||
///
|
||||
/// Spec v0.6.1
|
||||
fn slots_per_epoch() -> u64 {
|
||||
Self::spec().slots_per_epoch
|
||||
}
|
||||
|
||||
/// Returns the `SLOTS_PER_EPOCH` constant for this specification.
|
||||
///
|
||||
/// Spec v0.6.1
|
||||
fn genesis_epoch() -> Epoch {
|
||||
Self::spec().genesis_epoch
|
||||
Self::SlotsPerEpoch::to_u64()
|
||||
}
|
||||
|
||||
/// Returns the `SHARD_COUNT` constant for this specification.
|
||||
@@ -102,54 +105,40 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq {
|
||||
///
|
||||
/// Spec v0.6.1
|
||||
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)]
|
||||
pub struct FoundationEthSpec;
|
||||
pub struct MainnetEthSpec;
|
||||
|
||||
impl EthSpec for FoundationEthSpec {
|
||||
impl EthSpec for MainnetEthSpec {
|
||||
type ShardCount = U1024;
|
||||
type SlotsPerHistoricalRoot = U8192;
|
||||
type LatestRandaoMixesLength = U8192;
|
||||
type LatestActiveIndexRootsLength = U8192;
|
||||
type LatestSlashedExitLength = U8192;
|
||||
type SlotsPerEpoch = U64;
|
||||
type GenesisEpoch = U0;
|
||||
|
||||
fn spec() -> ChainSpec {
|
||||
ChainSpec::foundation()
|
||||
fn default_spec() -> ChainSpec {
|
||||
ChainSpec::mainnet()
|
||||
}
|
||||
}
|
||||
|
||||
pub type FoundationBeaconState = BeaconState<FoundationEthSpec>;
|
||||
pub type FoundationBeaconState = BeaconState<MainnetEthSpec>;
|
||||
|
||||
/// Ethereum Foundation specifications, modified to be suitable for < 1000 validators.
|
||||
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)]
|
||||
pub struct FewValidatorsEthSpec;
|
||||
pub struct MinimalEthSpec;
|
||||
|
||||
impl EthSpec for FewValidatorsEthSpec {
|
||||
impl EthSpec for MinimalEthSpec {
|
||||
type ShardCount = U8;
|
||||
type SlotsPerHistoricalRoot = U8192;
|
||||
type LatestRandaoMixesLength = U8192;
|
||||
type LatestActiveIndexRootsLength = U8192;
|
||||
type LatestSlashedExitLength = U8192;
|
||||
type SlotsPerEpoch = U8;
|
||||
type GenesisEpoch = U0;
|
||||
|
||||
fn spec() -> ChainSpec {
|
||||
ChainSpec::few_validators()
|
||||
fn default_spec() -> ChainSpec {
|
||||
ChainSpec::minimal()
|
||||
}
|
||||
}
|
||||
|
||||
pub type FewValidatorsBeaconState = BeaconState<FewValidatorsEthSpec>;
|
||||
|
||||
/// Specifications suitable for a small-scale (< 1000 validators) lighthouse testnet.
|
||||
#[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>;
|
||||
pub type MinimalBeaconState = BeaconState<MinimalEthSpec>;
|
||||
|
||||
@@ -2,6 +2,7 @@ use super::BeaconState;
|
||||
use crate::*;
|
||||
use core::num::NonZeroUsize;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz_derive::{Decode, Encode};
|
||||
use std::ops::Range;
|
||||
use swap_or_not_shuffle::shuffle_list;
|
||||
|
||||
@@ -9,7 +10,7 @@ mod tests;
|
||||
|
||||
/// Computes and stores the shuffling for an epoch. Provides various getters to allow callers to
|
||||
/// read the committees for the given epoch.
|
||||
#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize, Encode, Decode)]
|
||||
pub struct CommitteeCache {
|
||||
initialized_epoch: Option<Epoch>,
|
||||
shuffling: Vec<usize>,
|
||||
@@ -44,12 +45,16 @@ impl CommitteeCache {
|
||||
return Err(Error::InsufficientValidators);
|
||||
}
|
||||
|
||||
let committee_count = T::get_epoch_committee_count(active_validator_indices.len()) as usize;
|
||||
let committee_count = T::get_epoch_committee_count(
|
||||
active_validator_indices.len(),
|
||||
spec.target_committee_size,
|
||||
) as usize;
|
||||
|
||||
let shuffling_start_shard = match relative_epoch {
|
||||
RelativeEpoch::Current => state.latest_start_shard,
|
||||
RelativeEpoch::Previous => {
|
||||
let shard_delta = T::get_shard_delta(active_validator_indices.len());
|
||||
let shard_delta =
|
||||
T::get_shard_delta(active_validator_indices.len(), spec.target_committee_size);
|
||||
|
||||
(state.latest_start_shard + T::ShardCount::to_u64() - shard_delta)
|
||||
% T::ShardCount::to_u64()
|
||||
@@ -57,7 +62,8 @@ impl CommitteeCache {
|
||||
RelativeEpoch::Next => {
|
||||
let current_active_validators =
|
||||
get_active_validator_count(&state.validator_registry, state.current_epoch());
|
||||
let shard_delta = T::get_shard_delta(current_active_validators);
|
||||
let shard_delta =
|
||||
T::get_shard_delta(current_active_validators, spec.target_committee_size);
|
||||
|
||||
(state.latest_start_shard + shard_delta) % T::ShardCount::to_u64()
|
||||
}
|
||||
@@ -152,7 +158,6 @@ impl CommitteeCache {
|
||||
let i = self.shuffled_position(validator_index)?;
|
||||
|
||||
(0..self.committee_count)
|
||||
.into_iter()
|
||||
.map(|nth_committee| (nth_committee, self.compute_committee_range(nth_committee)))
|
||||
.find(|(_, range)| {
|
||||
if let Some(range) = range {
|
||||
|
||||
@@ -20,12 +20,12 @@ fn default_values() {
|
||||
}
|
||||
|
||||
fn new_state<T: EthSpec>(validator_count: usize, slot: Slot) -> BeaconState<T> {
|
||||
let spec = &T::spec();
|
||||
let spec = &T::default_spec();
|
||||
|
||||
let mut builder =
|
||||
TestingBeaconStateBuilder::from_single_keypair(validator_count, &Keypair::random(), spec);
|
||||
|
||||
builder.teleport_to_slot(slot, spec);
|
||||
builder.teleport_to_slot(slot);
|
||||
|
||||
let (state, _keypairs) = builder.build();
|
||||
|
||||
@@ -34,8 +34,8 @@ fn new_state<T: EthSpec>(validator_count: usize, slot: Slot) -> BeaconState<T> {
|
||||
|
||||
#[test]
|
||||
fn fails_without_validators() {
|
||||
let state = new_state::<FewValidatorsEthSpec>(0, Slot::new(0));
|
||||
let spec = &FewValidatorsEthSpec::spec();
|
||||
let state = new_state::<MinimalEthSpec>(0, Slot::new(0));
|
||||
let spec = &MinimalEthSpec::default_spec();
|
||||
|
||||
assert_eq!(
|
||||
CommitteeCache::initialized(&state, state.current_epoch(), &spec),
|
||||
@@ -45,8 +45,8 @@ fn fails_without_validators() {
|
||||
|
||||
#[test]
|
||||
fn initializes_with_the_right_epoch() {
|
||||
let state = new_state::<FewValidatorsEthSpec>(16, Slot::new(0));
|
||||
let spec = &FewValidatorsEthSpec::spec();
|
||||
let state = new_state::<MinimalEthSpec>(16, Slot::new(0));
|
||||
let spec = &MinimalEthSpec::default_spec();
|
||||
|
||||
let cache = CommitteeCache::default();
|
||||
assert_eq!(cache.initialized_epoch, None);
|
||||
@@ -63,14 +63,14 @@ fn initializes_with_the_right_epoch() {
|
||||
|
||||
#[test]
|
||||
fn shuffles_for_the_right_epoch() {
|
||||
let num_validators = FewValidatorsEthSpec::minimum_validator_count() * 2;
|
||||
let num_validators = MinimalEthSpec::minimum_validator_count() * 2;
|
||||
let epoch = Epoch::new(100_000_000);
|
||||
let slot = epoch.start_slot(FewValidatorsEthSpec::slots_per_epoch());
|
||||
let slot = epoch.start_slot(MinimalEthSpec::slots_per_epoch());
|
||||
|
||||
let mut state = new_state::<FewValidatorsEthSpec>(num_validators, slot);
|
||||
let spec = &FewValidatorsEthSpec::spec();
|
||||
let mut state = new_state::<MinimalEthSpec>(num_validators, slot);
|
||||
let spec = &MinimalEthSpec::default_spec();
|
||||
|
||||
let distinct_hashes: Vec<Hash256> = (0..FewValidatorsEthSpec::latest_randao_mixes_length())
|
||||
let distinct_hashes: Vec<Hash256> = (0..MinimalEthSpec::latest_randao_mixes_length())
|
||||
.into_iter()
|
||||
.map(|i| Hash256::from(i as u64))
|
||||
.collect();
|
||||
@@ -118,17 +118,19 @@ fn shuffles_for_the_right_epoch() {
|
||||
|
||||
#[test]
|
||||
fn can_start_on_any_shard() {
|
||||
let num_validators = FewValidatorsEthSpec::minimum_validator_count() * 2;
|
||||
let num_validators = MinimalEthSpec::minimum_validator_count() * 2;
|
||||
let epoch = Epoch::new(100_000_000);
|
||||
let slot = epoch.start_slot(FewValidatorsEthSpec::slots_per_epoch());
|
||||
let slot = epoch.start_slot(MinimalEthSpec::slots_per_epoch());
|
||||
|
||||
let mut state = new_state::<FewValidatorsEthSpec>(num_validators, slot);
|
||||
let spec = &FewValidatorsEthSpec::spec();
|
||||
let mut state = new_state::<MinimalEthSpec>(num_validators, slot);
|
||||
let spec = &MinimalEthSpec::default_spec();
|
||||
|
||||
let shard_delta = FewValidatorsEthSpec::get_shard_delta(num_validators);
|
||||
let shard_count = FewValidatorsEthSpec::shard_count() as u64;
|
||||
let target_committee_size = MinimalEthSpec::default_spec().target_committee_size;
|
||||
|
||||
for i in 0..FewValidatorsEthSpec::shard_count() as u64 {
|
||||
let shard_delta = MinimalEthSpec::get_shard_delta(num_validators, target_committee_size);
|
||||
let shard_count = MinimalEthSpec::shard_count() as u64;
|
||||
|
||||
for i in 0..MinimalEthSpec::shard_count() as u64 {
|
||||
state.latest_start_shard = i;
|
||||
|
||||
let cache = CommitteeCache::initialized(&state, state.current_epoch(), spec).unwrap();
|
||||
@@ -156,15 +158,17 @@ impl EthSpec for ExcessShardsEthSpec {
|
||||
type LatestRandaoMixesLength = U8192;
|
||||
type LatestActiveIndexRootsLength = U8192;
|
||||
type LatestSlashedExitLength = U8192;
|
||||
type SlotsPerEpoch = U8;
|
||||
type GenesisEpoch = U0;
|
||||
|
||||
fn spec() -> ChainSpec {
|
||||
ChainSpec::few_validators()
|
||||
fn default_spec() -> ChainSpec {
|
||||
ChainSpec::minimal()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn starts_on_the_correct_shard() {
|
||||
let spec = &ExcessShardsEthSpec::spec();
|
||||
let spec = &ExcessShardsEthSpec::default_spec();
|
||||
|
||||
let num_validators = ExcessShardsEthSpec::shard_count();
|
||||
|
||||
@@ -206,14 +210,16 @@ fn starts_on_the_correct_shard() {
|
||||
|
||||
let previous_shards = ExcessShardsEthSpec::get_epoch_committee_count(
|
||||
get_active_validator_count(&state.validator_registry, previous_epoch),
|
||||
spec.target_committee_size,
|
||||
);
|
||||
let current_shards = ExcessShardsEthSpec::get_epoch_committee_count(
|
||||
get_active_validator_count(&state.validator_registry, current_epoch),
|
||||
spec.target_committee_size,
|
||||
);
|
||||
let next_shards = ExcessShardsEthSpec::get_epoch_committee_count(
|
||||
get_active_validator_count(&state.validator_registry, next_epoch),
|
||||
spec.target_committee_size,
|
||||
);
|
||||
let next_shards = ExcessShardsEthSpec::get_epoch_committee_count(get_active_validator_count(
|
||||
&state.validator_registry,
|
||||
next_epoch,
|
||||
));
|
||||
|
||||
assert_eq!(
|
||||
previous_shards as usize,
|
||||
|
||||
@@ -7,7 +7,7 @@ ssz_tests!(FoundationBeaconState);
|
||||
cached_tree_hash_tests!(FoundationBeaconState);
|
||||
|
||||
fn test_beacon_proposer_index<T: EthSpec>() {
|
||||
let spec = T::spec();
|
||||
let spec = T::default_spec();
|
||||
let relative_epoch = RelativeEpoch::Current;
|
||||
|
||||
// Build a state for testing.
|
||||
@@ -53,7 +53,7 @@ fn test_beacon_proposer_index<T: EthSpec>() {
|
||||
|
||||
#[test]
|
||||
fn beacon_proposer_index() {
|
||||
test_beacon_proposer_index::<FewValidatorsEthSpec>();
|
||||
test_beacon_proposer_index::<MinimalEthSpec>();
|
||||
}
|
||||
|
||||
/// Should produce (note the set notation brackets):
|
||||
@@ -61,7 +61,7 @@ fn beacon_proposer_index() {
|
||||
/// (current_epoch - LATEST_ACTIVE_INDEX_ROOTS_LENGTH + ACTIVATION_EXIT_DELAY, current_epoch +
|
||||
/// ACTIVATION_EXIT_DELAY]
|
||||
fn active_index_range<T: EthSpec>(current_epoch: Epoch) -> RangeInclusive<Epoch> {
|
||||
let delay = T::spec().activation_exit_delay;
|
||||
let delay = T::default_spec().activation_exit_delay;
|
||||
|
||||
let start: i32 =
|
||||
current_epoch.as_u64() as i32 - T::latest_active_index_roots() as i32 + delay as i32;
|
||||
@@ -79,7 +79,7 @@ fn active_index_range<T: EthSpec>(current_epoch: Epoch) -> RangeInclusive<Epoch>
|
||||
/// Test getting an active index root at the start and end of the valid range, and one either side
|
||||
/// of that range.
|
||||
fn test_active_index<T: EthSpec>(state_slot: Slot) {
|
||||
let spec = T::spec();
|
||||
let spec = T::default_spec();
|
||||
let builder: TestingBeaconStateBuilder<T> =
|
||||
TestingBeaconStateBuilder::from_default_keypairs_file_if_exists(16, &spec);
|
||||
let (mut state, _keypairs) = builder.build();
|
||||
@@ -115,11 +115,11 @@ fn test_active_index<T: EthSpec>(state_slot: Slot) {
|
||||
|
||||
#[test]
|
||||
fn get_active_index_root_index() {
|
||||
test_active_index::<FoundationEthSpec>(Slot::new(0));
|
||||
test_active_index::<MainnetEthSpec>(Slot::new(0));
|
||||
|
||||
let epoch = Epoch::from(FoundationEthSpec::latest_active_index_roots() * 4);
|
||||
let slot = epoch.start_slot(FoundationEthSpec::slots_per_epoch());
|
||||
test_active_index::<FoundationEthSpec>(slot);
|
||||
let epoch = Epoch::from(MainnetEthSpec::latest_active_index_roots() * 4);
|
||||
let slot = epoch.start_slot(MainnetEthSpec::slots_per_epoch());
|
||||
test_active_index::<MainnetEthSpec>(slot);
|
||||
}
|
||||
|
||||
/// Test that
|
||||
@@ -133,8 +133,8 @@ fn test_cache_initialization<'a, T: EthSpec>(
|
||||
spec: &ChainSpec,
|
||||
) {
|
||||
let slot = relative_epoch
|
||||
.into_epoch(state.slot.epoch(spec.slots_per_epoch))
|
||||
.start_slot(spec.slots_per_epoch);
|
||||
.into_epoch(state.slot.epoch(T::slots_per_epoch()))
|
||||
.start_slot(T::slots_per_epoch());
|
||||
|
||||
// Assuming the cache isn't already built, assert that a call to a cache-using function fails.
|
||||
assert_eq!(
|
||||
@@ -166,13 +166,14 @@ fn test_cache_initialization<'a, T: EthSpec>(
|
||||
|
||||
#[test]
|
||||
fn cache_initialization() {
|
||||
let spec = FewValidatorsEthSpec::spec();
|
||||
let spec = MinimalEthSpec::default_spec();
|
||||
|
||||
let builder: TestingBeaconStateBuilder<FewValidatorsEthSpec> =
|
||||
let builder: TestingBeaconStateBuilder<MinimalEthSpec> =
|
||||
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);
|
||||
state.slot =
|
||||
(MinimalEthSpec::genesis_epoch() + 1).start_slot(MinimalEthSpec::slots_per_epoch());
|
||||
|
||||
test_cache_initialization(&mut state, RelativeEpoch::Previous, &spec);
|
||||
test_cache_initialization(&mut state, RelativeEpoch::Current, &spec);
|
||||
@@ -202,7 +203,7 @@ fn tree_hash_cache() {
|
||||
#[cfg(test)]
|
||||
mod committees {
|
||||
use super::*;
|
||||
use crate::beacon_state::FewValidatorsEthSpec;
|
||||
use crate::beacon_state::MinimalEthSpec;
|
||||
use swap_or_not_shuffle::shuffle_list;
|
||||
|
||||
fn execute_committee_consistency_test<T: EthSpec>(
|
||||
@@ -234,7 +235,7 @@ mod committees {
|
||||
(start_shard..start_shard + T::shard_count() as u64).into_iter();
|
||||
|
||||
// Loop through all slots in the epoch being tested.
|
||||
for slot in epoch.slot_iter(spec.slots_per_epoch) {
|
||||
for slot in epoch.slot_iter(T::slots_per_epoch()) {
|
||||
let crosslink_committees = state.get_crosslink_committees_at_slot(slot).unwrap();
|
||||
|
||||
// Assert that the number of committees in this slot is consistent with the reported number
|
||||
@@ -290,7 +291,7 @@ mod committees {
|
||||
state_epoch: Epoch,
|
||||
cache_epoch: RelativeEpoch,
|
||||
) {
|
||||
let spec = &T::spec();
|
||||
let spec = &T::default_spec();
|
||||
|
||||
let mut builder = TestingBeaconStateBuilder::from_single_keypair(
|
||||
validator_count,
|
||||
@@ -298,8 +299,8 @@ mod committees {
|
||||
spec,
|
||||
);
|
||||
|
||||
let slot = state_epoch.start_slot(spec.slots_per_epoch);
|
||||
builder.teleport_to_slot(slot, spec);
|
||||
let slot = state_epoch.start_slot(T::slots_per_epoch());
|
||||
builder.teleport_to_slot(slot);
|
||||
|
||||
let (mut state, _keypairs): (BeaconState<T>, _) = builder.build();
|
||||
|
||||
@@ -325,7 +326,7 @@ mod committees {
|
||||
}
|
||||
|
||||
fn committee_consistency_test_suite<T: EthSpec>(cached_epoch: RelativeEpoch) {
|
||||
let spec = T::spec();
|
||||
let spec = T::default_spec();
|
||||
|
||||
let validator_count = (T::shard_count() * spec.target_committee_size) + 1;
|
||||
|
||||
@@ -333,29 +334,29 @@ mod committees {
|
||||
|
||||
committee_consistency_test::<T>(
|
||||
validator_count as usize,
|
||||
spec.genesis_epoch + 4,
|
||||
T::genesis_epoch() + 4,
|
||||
cached_epoch,
|
||||
);
|
||||
|
||||
committee_consistency_test::<T>(
|
||||
validator_count as usize,
|
||||
spec.genesis_epoch + T::slots_per_historical_root() as u64 * T::slots_per_epoch() * 4,
|
||||
T::genesis_epoch() + T::slots_per_historical_root() as u64 * T::slots_per_epoch() * 4,
|
||||
cached_epoch,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn current_epoch_committee_consistency() {
|
||||
committee_consistency_test_suite::<FewValidatorsEthSpec>(RelativeEpoch::Current);
|
||||
committee_consistency_test_suite::<MinimalEthSpec>(RelativeEpoch::Current);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn previous_epoch_committee_consistency() {
|
||||
committee_consistency_test_suite::<FewValidatorsEthSpec>(RelativeEpoch::Previous);
|
||||
committee_consistency_test_suite::<MinimalEthSpec>(RelativeEpoch::Previous);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn next_epoch_committee_consistency() {
|
||||
committee_consistency_test_suite::<FewValidatorsEthSpec>(RelativeEpoch::Next);
|
||||
committee_consistency_test_suite::<MinimalEthSpec>(RelativeEpoch::Next);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::*;
|
||||
use int_to_bytes::int_to_bytes4;
|
||||
use serde_derive::Deserialize;
|
||||
use test_utils::u8_from_hex_str;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use test_utils::{u8_from_hex_str, u8_to_hex_str};
|
||||
|
||||
/// Each of the BLS signature domains.
|
||||
///
|
||||
@@ -18,7 +18,7 @@ pub enum Domain {
|
||||
/// Holds all the "constants" for a BeaconChain.
|
||||
///
|
||||
/// Spec v0.6.1
|
||||
#[derive(PartialEq, Debug, Clone, Deserialize)]
|
||||
#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct ChainSpec {
|
||||
/*
|
||||
@@ -48,18 +48,19 @@ pub struct ChainSpec {
|
||||
* Initial Values
|
||||
*/
|
||||
pub genesis_slot: Slot,
|
||||
pub genesis_epoch: Epoch,
|
||||
// Skipped because serde TOML can't handle u64::max_value, the typical value for this field.
|
||||
#[serde(skip_serializing)]
|
||||
pub far_future_epoch: Epoch,
|
||||
pub zero_hash: Hash256,
|
||||
#[serde(deserialize_with = "u8_from_hex_str")]
|
||||
#[serde(deserialize_with = "u8_from_hex_str", serialize_with = "u8_to_hex_str")]
|
||||
pub bls_withdrawal_prefix_byte: u8,
|
||||
|
||||
/*
|
||||
* Time parameters
|
||||
*/
|
||||
pub genesis_time: u64,
|
||||
pub seconds_per_slot: u64,
|
||||
pub min_attestation_inclusion_delay: u64,
|
||||
pub slots_per_epoch: u64,
|
||||
pub min_seed_lookahead: Epoch,
|
||||
pub activation_exit_delay: u64,
|
||||
pub slots_per_eth1_voting_period: u64,
|
||||
@@ -137,7 +138,7 @@ impl ChainSpec {
|
||||
/// Returns a `ChainSpec` compatible with the Ethereum Foundation specification.
|
||||
///
|
||||
/// Spec v0.6.1
|
||||
pub(crate) fn foundation() -> Self {
|
||||
pub fn mainnet() -> Self {
|
||||
Self {
|
||||
/*
|
||||
* Misc
|
||||
@@ -166,7 +167,6 @@ impl ChainSpec {
|
||||
* Initial Values
|
||||
*/
|
||||
genesis_slot: Slot::new(0),
|
||||
genesis_epoch: Epoch::new(0),
|
||||
far_future_epoch: Epoch::new(u64::max_value()),
|
||||
zero_hash: Hash256::zero(),
|
||||
bls_withdrawal_prefix_byte: 0,
|
||||
@@ -174,9 +174,9 @@ impl ChainSpec {
|
||||
/*
|
||||
* Time parameters
|
||||
*/
|
||||
genesis_time: u64::from(u32::max_value()),
|
||||
seconds_per_slot: 6,
|
||||
min_attestation_inclusion_delay: 4,
|
||||
slots_per_epoch: 64,
|
||||
min_seed_lookahead: Epoch::new(1),
|
||||
activation_exit_delay: 4,
|
||||
slots_per_eth1_voting_period: 1_024,
|
||||
@@ -219,47 +219,35 @@ impl ChainSpec {
|
||||
* Boot nodes
|
||||
*/
|
||||
boot_nodes: vec![],
|
||||
chain_id: 1, // foundation chain id
|
||||
chain_id: 1, // mainnet chain id
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a `ChainSpec` compatible with the Lighthouse testnet specification.
|
||||
///
|
||||
/// Spec v0.4.0
|
||||
pub(crate) fn lighthouse_testnet() -> Self {
|
||||
/*
|
||||
* Lighthouse testnet bootnodes
|
||||
*/
|
||||
/// Returns a `ChainSpec` compatible with the specification suitable for 8 validators.
|
||||
pub fn minimal() -> Self {
|
||||
let genesis_slot = Slot::new(0);
|
||||
|
||||
// Note: these bootnodes are placeholders.
|
||||
//
|
||||
// Should be updated once static bootnodes exist.
|
||||
let boot_nodes = vec!["/ip4/127.0.0.1/tcp/9000"
|
||||
.parse()
|
||||
.expect("correct multiaddr")];
|
||||
|
||||
Self {
|
||||
boot_nodes,
|
||||
chain_id: 2, // lighthouse testnet chain id
|
||||
..ChainSpec::few_validators()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a `ChainSpec` compatible with the specification suitable for 8 validators.
|
||||
pub(crate) fn few_validators() -> Self {
|
||||
let genesis_slot = Slot::new(0);
|
||||
let slots_per_epoch = 8;
|
||||
let genesis_epoch = genesis_slot.epoch(slots_per_epoch);
|
||||
|
||||
Self {
|
||||
target_committee_size: 1,
|
||||
chain_id: 2, // lighthouse testnet chain id
|
||||
genesis_slot,
|
||||
genesis_epoch,
|
||||
slots_per_epoch,
|
||||
..ChainSpec::foundation()
|
||||
shuffle_round_count: 10,
|
||||
..ChainSpec::mainnet()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ChainSpec {
|
||||
fn default() -> Self {
|
||||
Self::foundation()
|
||||
Self::mainnet()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,12 +257,12 @@ mod tests {
|
||||
use int_to_bytes::int_to_bytes8;
|
||||
|
||||
#[test]
|
||||
fn test_foundation_spec_can_be_constructed() {
|
||||
let _ = ChainSpec::foundation();
|
||||
fn test_mainnet_spec_can_be_constructed() {
|
||||
let _ = ChainSpec::mainnet();
|
||||
}
|
||||
|
||||
fn test_domain(domain_type: Domain, raw_domain: u32, spec: &ChainSpec) {
|
||||
let fork = Fork::genesis(&spec);
|
||||
let fork = Fork::genesis(Epoch::new(0));
|
||||
let epoch = Epoch::new(0);
|
||||
|
||||
let domain = spec.get_domain(epoch, domain_type, &fork);
|
||||
@@ -287,7 +275,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_get_domain() {
|
||||
let spec = ChainSpec::foundation();
|
||||
let spec = ChainSpec::mainnet();
|
||||
|
||||
test_domain(Domain::BeaconProposer, spec.domain_beacon_proposer, &spec);
|
||||
test_domain(Domain::Randao, spec.domain_randao, &spec);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
test_utils::{fork_from_hex_str, TestRandom},
|
||||
ChainSpec, Epoch,
|
||||
Epoch,
|
||||
};
|
||||
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
@@ -36,11 +36,11 @@ impl Fork {
|
||||
/// Initialize the `Fork` from the genesis parameters in the `spec`.
|
||||
///
|
||||
/// Spec v0.6.1
|
||||
pub fn genesis(spec: &ChainSpec) -> Self {
|
||||
pub fn genesis(genesis_epoch: Epoch) -> Self {
|
||||
Self {
|
||||
previous_version: [0; 4],
|
||||
current_version: [0; 4],
|
||||
epoch: spec.genesis_epoch,
|
||||
epoch: genesis_epoch,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,13 +63,9 @@ mod tests {
|
||||
cached_tree_hash_tests!(Fork);
|
||||
|
||||
fn test_genesis(epoch: Epoch) {
|
||||
let mut spec = ChainSpec::foundation();
|
||||
let fork = Fork::genesis(epoch);
|
||||
|
||||
spec.genesis_epoch = epoch;
|
||||
|
||||
let fork = Fork::genesis(&spec);
|
||||
|
||||
assert_eq!(fork.epoch, spec.genesis_epoch, "epoch incorrect");
|
||||
assert_eq!(fork.epoch, epoch, "epoch incorrect");
|
||||
assert_eq!(
|
||||
fork.previous_version, fork.current_version,
|
||||
"previous and current are not identical"
|
||||
|
||||
@@ -31,7 +31,7 @@ pub struct HistoricalBatch<T: EthSpec> {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
pub type FoundationHistoricalBatch = HistoricalBatch<FoundationEthSpec>;
|
||||
pub type FoundationHistoricalBatch = HistoricalBatch<MainnetEthSpec>;
|
||||
|
||||
ssz_tests!(FoundationHistoricalBatch);
|
||||
cached_tree_hash_tests!(FoundationHistoricalBatch);
|
||||
|
||||
@@ -23,6 +23,7 @@ use std::iter::Iterator;
|
||||
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, Sub, SubAssign};
|
||||
|
||||
#[derive(Eq, Debug, Clone, Copy, Default, Serialize, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct Slot(u64);
|
||||
|
||||
#[derive(Eq, Debug, Clone, Copy, Default, Serialize, Deserialize)]
|
||||
@@ -76,7 +77,7 @@ impl Epoch {
|
||||
/// Position of some slot inside an epoch, if any.
|
||||
///
|
||||
/// E.g., the first `slot` in `epoch` is at position `0`.
|
||||
pub fn position(&self, slot: Slot, slots_per_epoch: u64) -> Option<usize> {
|
||||
pub fn position(self, slot: Slot, slots_per_epoch: u64) -> Option<usize> {
|
||||
let start = self.start_slot(slots_per_epoch);
|
||||
let end = self.end_slot(slots_per_epoch);
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ macro_rules! impl_display {
|
||||
key: slog::Key,
|
||||
serializer: &mut slog::Serializer,
|
||||
) -> slog::Result {
|
||||
self.0.serialize(record, key, serializer)
|
||||
slog::Value::serialize(&self.0, record, key, serializer)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ impl TestingAttestationDataBuilder {
|
||||
let previous_epoch = state.previous_epoch();
|
||||
|
||||
let is_previous_epoch =
|
||||
state.slot.epoch(spec.slots_per_epoch) != slot.epoch(spec.slots_per_epoch);
|
||||
state.slot.epoch(T::slots_per_epoch()) != slot.epoch(T::slots_per_epoch());
|
||||
|
||||
let source_epoch = if is_previous_epoch {
|
||||
state.previous_justified_epoch
|
||||
@@ -37,11 +37,11 @@ impl TestingAttestationDataBuilder {
|
||||
|
||||
let target_root = if is_previous_epoch {
|
||||
*state
|
||||
.get_block_root(previous_epoch.start_slot(spec.slots_per_epoch))
|
||||
.get_block_root(previous_epoch.start_slot(T::slots_per_epoch()))
|
||||
.unwrap()
|
||||
} else {
|
||||
*state
|
||||
.get_block_root(current_epoch.start_slot(spec.slots_per_epoch))
|
||||
.get_block_root(current_epoch.start_slot(T::slots_per_epoch()))
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
@@ -57,7 +57,7 @@ impl TestingAttestationDataBuilder {
|
||||
};
|
||||
|
||||
let source_root = *state
|
||||
.get_block_root(source_epoch.start_slot(spec.slots_per_epoch))
|
||||
.get_block_root(source_epoch.start_slot(T::slots_per_epoch()))
|
||||
.unwrap();
|
||||
|
||||
let data = AttestationData {
|
||||
|
||||
@@ -36,9 +36,9 @@ impl TestingBeaconBlockBuilder {
|
||||
/// Signs the block.
|
||||
///
|
||||
/// Modifying the block after signing may invalidate the signature.
|
||||
pub fn sign(&mut self, sk: &SecretKey, fork: &Fork, spec: &ChainSpec) {
|
||||
pub fn sign<T: EthSpec>(&mut self, sk: &SecretKey, fork: &Fork, spec: &ChainSpec) {
|
||||
let message = self.block.signed_root();
|
||||
let epoch = self.block.slot.epoch(spec.slots_per_epoch);
|
||||
let epoch = self.block.slot.epoch(T::slots_per_epoch());
|
||||
let domain = spec.get_domain(epoch, Domain::BeaconProposer, fork);
|
||||
self.block.signature = Signature::new(&message, domain, sk);
|
||||
}
|
||||
@@ -46,8 +46,8 @@ impl TestingBeaconBlockBuilder {
|
||||
/// Sets the randao to be a signature across the blocks epoch.
|
||||
///
|
||||
/// Modifying the block's slot after signing may invalidate the signature.
|
||||
pub fn set_randao_reveal(&mut self, sk: &SecretKey, fork: &Fork, spec: &ChainSpec) {
|
||||
let epoch = self.block.slot.epoch(spec.slots_per_epoch);
|
||||
pub fn set_randao_reveal<T: EthSpec>(&mut self, sk: &SecretKey, fork: &Fork, spec: &ChainSpec) {
|
||||
let epoch = self.block.slot.epoch(T::slots_per_epoch());
|
||||
let message = epoch.tree_hash_root();
|
||||
let domain = spec.get_domain(epoch, Domain::Randao, fork);
|
||||
self.block.body.randao_reveal = Signature::new(&message, domain, sk);
|
||||
@@ -59,14 +59,15 @@ impl TestingBeaconBlockBuilder {
|
||||
}
|
||||
|
||||
/// Inserts a signed, valid `ProposerSlashing` for the validator.
|
||||
pub fn insert_proposer_slashing(
|
||||
pub fn insert_proposer_slashing<T: EthSpec>(
|
||||
&mut self,
|
||||
validator_index: u64,
|
||||
secret_key: &SecretKey,
|
||||
fork: &Fork,
|
||||
spec: &ChainSpec,
|
||||
) {
|
||||
let proposer_slashing = build_proposer_slashing(validator_index, secret_key, fork, spec);
|
||||
let proposer_slashing =
|
||||
build_proposer_slashing::<T>(validator_index, secret_key, fork, spec);
|
||||
self.block.body.proposer_slashings.push(proposer_slashing);
|
||||
}
|
||||
|
||||
@@ -115,7 +116,7 @@ impl TestingBeaconBlockBuilder {
|
||||
// - The slot is too old to be included in a block at this slot.
|
||||
// - The `MAX_ATTESTATIONS`.
|
||||
loop {
|
||||
if state.slot >= slot + spec.slots_per_epoch {
|
||||
if state.slot >= slot + T::slots_per_epoch() {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -194,7 +195,7 @@ impl TestingBeaconBlockBuilder {
|
||||
builder.set_index(index);
|
||||
builder.sign(
|
||||
&keypair,
|
||||
state.slot.epoch(spec.slots_per_epoch),
|
||||
state.slot.epoch(T::slots_per_epoch()),
|
||||
&state.fork,
|
||||
spec,
|
||||
);
|
||||
@@ -211,7 +212,7 @@ impl TestingBeaconBlockBuilder {
|
||||
spec: &ChainSpec,
|
||||
) {
|
||||
let mut builder = TestingVoluntaryExitBuilder::new(
|
||||
state.slot.epoch(spec.slots_per_epoch),
|
||||
state.slot.epoch(T::slots_per_epoch()),
|
||||
validator_index,
|
||||
);
|
||||
|
||||
@@ -234,14 +235,19 @@ impl TestingBeaconBlockBuilder {
|
||||
spec: &ChainSpec,
|
||||
) {
|
||||
let mut builder = TestingTransferBuilder::new(from, to, amount, state.slot);
|
||||
builder.sign(keypair, &state.fork, spec);
|
||||
builder.sign::<T>(keypair, &state.fork, spec);
|
||||
|
||||
self.block.body.transfers.push(builder.build())
|
||||
}
|
||||
|
||||
/// Signs and returns the block, consuming the builder.
|
||||
pub fn build(mut self, sk: &SecretKey, fork: &Fork, spec: &ChainSpec) -> BeaconBlock {
|
||||
self.sign(sk, fork, spec);
|
||||
pub fn build<T: EthSpec>(
|
||||
mut self,
|
||||
sk: &SecretKey,
|
||||
fork: &Fork,
|
||||
spec: &ChainSpec,
|
||||
) -> BeaconBlock {
|
||||
self.sign::<T>(sk, fork, spec);
|
||||
self.block
|
||||
}
|
||||
|
||||
@@ -254,7 +260,7 @@ impl TestingBeaconBlockBuilder {
|
||||
/// Builds an `ProposerSlashing` for some `validator_index`.
|
||||
///
|
||||
/// Signs the message using a `BeaconChainHarness`.
|
||||
fn build_proposer_slashing(
|
||||
fn build_proposer_slashing<T: EthSpec>(
|
||||
validator_index: u64,
|
||||
secret_key: &SecretKey,
|
||||
fork: &Fork,
|
||||
@@ -265,7 +271,7 @@ fn build_proposer_slashing(
|
||||
Signature::new(message, domain, secret_key)
|
||||
};
|
||||
|
||||
TestingProposerSlashingBuilder::double_vote(validator_index, signer, spec)
|
||||
TestingProposerSlashingBuilder::double_vote::<T, _>(validator_index, signer)
|
||||
}
|
||||
|
||||
/// Builds an `AttesterSlashing` for some `validator_indices`.
|
||||
|
||||
@@ -6,7 +6,6 @@ use dirs;
|
||||
use log::debug;
|
||||
use rayon::prelude::*;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::SystemTime;
|
||||
|
||||
pub const KEYPAIRS_FILE: &str = "keypairs.raw_keypairs";
|
||||
|
||||
@@ -113,8 +112,8 @@ impl<T: EthSpec> TestingBeaconStateBuilder<T> {
|
||||
pubkey: keypair.pk.clone(),
|
||||
withdrawal_credentials,
|
||||
// All validators start active.
|
||||
activation_eligibility_epoch: spec.genesis_epoch,
|
||||
activation_epoch: spec.genesis_epoch,
|
||||
activation_eligibility_epoch: T::genesis_epoch(),
|
||||
activation_epoch: T::genesis_epoch(),
|
||||
exit_epoch: spec.far_future_epoch,
|
||||
withdrawable_epoch: spec.far_future_epoch,
|
||||
slashed: false,
|
||||
@@ -123,20 +122,8 @@ impl<T: EthSpec> TestingBeaconStateBuilder<T> {
|
||||
})
|
||||
.collect();
|
||||
|
||||
// TODO: Testing only. Burn with fire later.
|
||||
// set genesis to the last 30 minute block.
|
||||
// this is used for testing only. Allows multiple nodes to connect within a 30min window
|
||||
// and agree on a genesis
|
||||
let now = SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs();
|
||||
let secs_after_last_period = now.checked_rem(30 * 60).unwrap_or(0);
|
||||
// genesis is now the last 30 minute block.
|
||||
let genesis_time = now - secs_after_last_period;
|
||||
|
||||
let mut state = BeaconState::genesis(
|
||||
genesis_time,
|
||||
spec.genesis_time,
|
||||
Eth1Data {
|
||||
deposit_root: Hash256::zero(),
|
||||
deposit_count: 0,
|
||||
@@ -172,8 +159,8 @@ impl<T: EthSpec> TestingBeaconStateBuilder<T> {
|
||||
}
|
||||
|
||||
/// Sets the `BeaconState` to be in a slot, calling `teleport_to_epoch` to update the epoch.
|
||||
pub fn teleport_to_slot(&mut self, slot: Slot, spec: &ChainSpec) {
|
||||
self.teleport_to_epoch(slot.epoch(spec.slots_per_epoch), spec);
|
||||
pub fn teleport_to_slot(&mut self, slot: Slot) {
|
||||
self.teleport_to_epoch(slot.epoch(T::slots_per_epoch()));
|
||||
self.state.slot = slot;
|
||||
}
|
||||
|
||||
@@ -181,10 +168,10 @@ impl<T: EthSpec> TestingBeaconStateBuilder<T> {
|
||||
///
|
||||
/// Sets all justification/finalization parameters to be be as "perfect" as possible (i.e.,
|
||||
/// highest justified and finalized slots, full justification bitfield, etc).
|
||||
fn teleport_to_epoch(&mut self, epoch: Epoch, spec: &ChainSpec) {
|
||||
fn teleport_to_epoch(&mut self, epoch: Epoch) {
|
||||
let state = &mut self.state;
|
||||
|
||||
let slot = epoch.start_slot(spec.slots_per_epoch);
|
||||
let slot = epoch.start_slot(T::slots_per_epoch());
|
||||
|
||||
state.slot = slot;
|
||||
|
||||
@@ -214,8 +201,8 @@ impl<T: EthSpec> TestingBeaconStateBuilder<T> {
|
||||
let current_epoch = state.current_epoch();
|
||||
let previous_epoch = state.previous_epoch();
|
||||
|
||||
let first_slot = previous_epoch.start_slot(spec.slots_per_epoch).as_u64();
|
||||
let last_slot = current_epoch.end_slot(spec.slots_per_epoch).as_u64()
|
||||
let first_slot = previous_epoch.start_slot(T::slots_per_epoch()).as_u64();
|
||||
let last_slot = current_epoch.end_slot(T::slots_per_epoch()).as_u64()
|
||||
- spec.min_attestation_inclusion_delay;
|
||||
let last_slot = std::cmp::min(state.slot.as_u64(), last_slot);
|
||||
|
||||
|
||||
@@ -17,8 +17,9 @@ impl TestingProposerSlashingBuilder {
|
||||
/// - `domain: Domain`
|
||||
///
|
||||
/// Where domain is a domain "constant" (e.g., `spec.domain_attestation`).
|
||||
pub fn double_vote<F>(proposer_index: u64, signer: F, spec: &ChainSpec) -> ProposerSlashing
|
||||
pub fn double_vote<T, F>(proposer_index: u64, signer: F) -> ProposerSlashing
|
||||
where
|
||||
T: EthSpec,
|
||||
F: Fn(u64, &[u8], Epoch, Domain) -> Signature,
|
||||
{
|
||||
let slot = Slot::new(0);
|
||||
@@ -40,13 +41,13 @@ impl TestingProposerSlashingBuilder {
|
||||
|
||||
header_1.signature = {
|
||||
let message = header_1.signed_root();
|
||||
let epoch = slot.epoch(spec.slots_per_epoch);
|
||||
let epoch = slot.epoch(T::slots_per_epoch());
|
||||
signer(proposer_index, &message[..], epoch, Domain::BeaconProposer)
|
||||
};
|
||||
|
||||
header_2.signature = {
|
||||
let message = header_2.signed_root();
|
||||
let epoch = slot.epoch(spec.slots_per_epoch);
|
||||
let epoch = slot.epoch(T::slots_per_epoch());
|
||||
signer(proposer_index, &message[..], epoch, Domain::BeaconProposer)
|
||||
};
|
||||
|
||||
|
||||
@@ -29,10 +29,10 @@ impl TestingTransferBuilder {
|
||||
/// Signs the transfer.
|
||||
///
|
||||
/// The keypair must match that of the `from` validator index.
|
||||
pub fn sign(&mut self, keypair: Keypair, fork: &Fork, spec: &ChainSpec) {
|
||||
pub fn sign<T: EthSpec>(&mut self, keypair: Keypair, fork: &Fork, spec: &ChainSpec) {
|
||||
self.transfer.pubkey = keypair.pk;
|
||||
let message = self.transfer.signed_root();
|
||||
let epoch = self.transfer.slot.epoch(spec.slots_per_epoch);
|
||||
let epoch = self.transfer.slot.epoch(T::slots_per_epoch());
|
||||
let domain = spec.get_domain(epoch, Domain::Transfer, fork);
|
||||
|
||||
self.transfer.signature = Signature::new(&message, domain, &keypair.sk);
|
||||
|
||||
@@ -14,5 +14,5 @@ pub use rand::{
|
||||
RngCore,
|
||||
{prng::XorShiftRng, SeedableRng},
|
||||
};
|
||||
pub use serde_utils::{fork_from_hex_str, graffiti_from_hex_str, u8_from_hex_str};
|
||||
pub use serde_utils::{fork_from_hex_str, graffiti_from_hex_str, u8_from_hex_str, u8_to_hex_str};
|
||||
pub use test_random::TestRandom;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use serde::de::Error;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use serde::{Deserialize, Deserializer, Serializer};
|
||||
|
||||
pub const FORK_BYTES_LEN: usize = 4;
|
||||
pub const GRAFFITI_BYTES_LEN: usize = 32;
|
||||
@@ -13,6 +13,17 @@ where
|
||||
u8::from_str_radix(&s.as_str()[2..], 16).map_err(D::Error::custom)
|
||||
}
|
||||
|
||||
#[allow(clippy::trivially_copy_pass_by_ref)] // Serde requires the `byte` to be a ref.
|
||||
pub fn u8_to_hex_str<S>(byte: &u8, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut hex: String = "0x".to_string();
|
||||
hex.push_str(&hex::encode(&[*byte]));
|
||||
|
||||
serializer.serialize_str(&hex)
|
||||
}
|
||||
|
||||
pub fn fork_from_hex_str<'de, D>(deserializer: D) -> Result<[u8; FORK_BYTES_LEN], D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
|
||||
Reference in New Issue
Block a user