Merge branch 'master' of github.com:sigp/lighthouse into v0.5.0-state-transition-tests

This commit is contained in:
Kirk Baird
2019-03-22 09:23:56 +11:00
66 changed files with 2874 additions and 695 deletions

View File

@@ -25,6 +25,7 @@ ssz = { path = "../utils/ssz" }
ssz_derive = { path = "../utils/ssz_derive" }
swap_or_not_shuffle = { path = "../utils/swap_or_not_shuffle" }
test_random_derive = { path = "../utils/test_random_derive" }
libp2p = { git = "https://github.com/SigP/rust-libp2p", branch = "gossipsub" }
[dev-dependencies]
env_logger = "0.6.0"

View File

@@ -71,7 +71,7 @@ impl BeaconBlock {
/// Note: performs a full tree-hash of `self.body`.
///
/// Spec v0.5.0
pub fn into_header(&self) -> BeaconBlockHeader {
pub fn block_header(&self) -> BeaconBlockHeader {
BeaconBlockHeader {
slot: self.slot,
previous_block_root: self.previous_block_root,
@@ -84,11 +84,11 @@ impl BeaconBlock {
/// Returns a "temporary" header, where the `state_root` is `spec.zero_hash`.
///
/// Spec v0.5.0
pub fn into_temporary_header(&self, spec: &ChainSpec) -> BeaconBlockHeader {
pub fn temporary_block_header(&self, spec: &ChainSpec) -> BeaconBlockHeader {
BeaconBlockHeader {
state_root: spec.zero_hash,
signature: spec.empty_signature.clone(),
..self.into_header()
..self.block_header()
}
}
}

View File

@@ -162,7 +162,7 @@ impl BeaconState {
latest_state_roots: vec![spec.zero_hash; spec.slots_per_historical_root],
latest_active_index_roots: vec![spec.zero_hash; spec.latest_active_index_roots_length],
latest_slashed_balances: vec![0; spec.latest_slashed_exit_length],
latest_block_header: BeaconBlock::empty(spec).into_temporary_header(spec),
latest_block_header: BeaconBlock::empty(spec).temporary_block_header(spec),
historical_roots: vec![],
/*
@@ -193,6 +193,13 @@ impl BeaconState {
Hash256::from_slice(&self.hash_tree_root()[..])
}
pub fn historical_batch(&self) -> HistoricalBatch {
HistoricalBatch {
block_roots: self.latest_block_roots.clone(),
state_roots: self.latest_state_roots.clone(),
}
}
/// If a validator pubkey exists in the validator registry, returns `Some(i)`, otherwise
/// returns `None`.
///
@@ -379,7 +386,28 @@ impl BeaconState {
spec: &ChainSpec,
) -> Result<(), BeaconStateError> {
let i = self.get_latest_block_roots_index(slot, spec)?;
Ok(self.latest_block_roots[i] = block_root)
self.latest_block_roots[i] = block_root;
Ok(())
}
/// Safely obtains the index for `latest_randao_mixes`
///
/// Spec v0.5.0
fn get_randao_mix_index(&self, epoch: Epoch, spec: &ChainSpec) -> Result<usize, Error> {
let current_epoch = self.current_epoch(spec);
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)
}
} else {
Err(Error::EpochOutOfBounds)
}
}
/// XOR-assigns the existing `epoch` randao mix with the hash of the `signature`.
@@ -406,24 +434,24 @@ impl BeaconState {
/// Return the randao mix at a recent ``epoch``.
///
/// # Errors:
/// - `InsufficientRandaoMixes` if `self.latest_randao_mixes` is shorter than
/// `spec.latest_randao_mixes_length`.
/// - `EpochOutOfBounds` if the state no longer stores randao mixes for the given `epoch`.
///
/// Spec v0.5.0
pub fn get_randao_mix(&self, epoch: Epoch, spec: &ChainSpec) -> Result<&Hash256, Error> {
let current_epoch = self.current_epoch(spec);
let i = self.get_randao_mix_index(epoch, spec)?;
Ok(&self.latest_randao_mixes[i])
}
if (current_epoch - (spec.latest_randao_mixes_length as u64) < epoch)
& (epoch <= current_epoch)
{
self.latest_randao_mixes
.get(epoch.as_usize() % spec.latest_randao_mixes_length)
.ok_or_else(|| Error::InsufficientRandaoMixes)
} else {
Err(Error::EpochOutOfBounds)
}
/// Set the randao mix at a recent ``epoch``.
///
/// Spec v0.5.0
pub fn set_randao_mix(
&mut self,
epoch: Epoch,
mix: Hash256,
spec: &ChainSpec,
) -> Result<(), Error> {
let i = self.get_randao_mix_index(epoch, spec)?;
self.latest_randao_mixes[i] = mix;
Ok(())
}
/// Safely obtains the index for `latest_active_index_roots`, given some `epoch`.
@@ -466,7 +494,8 @@ impl BeaconState {
spec: &ChainSpec,
) -> Result<(), Error> {
let i = self.get_active_index_root_index(epoch, spec)?;
Ok(self.latest_active_index_roots[i] = index_root)
self.latest_active_index_roots[i] = index_root;
Ok(())
}
/// Replace `active_index_roots` with clones of `index_root`.
@@ -511,7 +540,8 @@ impl BeaconState {
spec: &ChainSpec,
) -> Result<(), Error> {
let i = self.get_latest_state_roots_index(slot, spec)?;
Ok(self.latest_state_roots[i] = state_root)
self.latest_state_roots[i] = state_root;
Ok(())
}
/// Safely obtains the index for `latest_slashed_balances`, given some `epoch`.
@@ -547,7 +577,8 @@ impl BeaconState {
spec: &ChainSpec,
) -> Result<(), Error> {
let i = self.get_slashed_balance_index(epoch, spec)?;
Ok(self.latest_slashed_balances[i] = balance)
self.latest_slashed_balances[i] = balance;
Ok(())
}
/// Generate a seed for the given `epoch`.
@@ -588,24 +619,6 @@ impl BeaconState {
epoch + 1 + spec.activation_exit_delay
}
/// Activate the validator of the given ``index``.
///
/// Spec v0.5.0
pub fn activate_validator(
&mut self,
validator_index: usize,
is_genesis: bool,
spec: &ChainSpec,
) {
let current_epoch = self.current_epoch(spec);
self.validator_registry[validator_index].activation_epoch = if is_genesis {
spec.genesis_epoch
} else {
self.get_delayed_activation_exit_epoch(current_epoch, spec)
}
}
/// Initiate an exit for the validator of the given `index`.
///
/// Spec v0.5.0

View File

@@ -107,6 +107,7 @@ impl EpochCache {
})
}
/// Return a vec of `CrosslinkCommittee` for a given slot.
pub fn get_crosslink_committees_at_slot(
&self,
slot: Slot,
@@ -116,6 +117,8 @@ impl EpochCache {
.get_crosslink_committees_at_slot(slot, spec)
}
/// Return `Some(CrosslinkCommittee)` if the given shard has a committee during the given
/// `epoch`.
pub fn get_crosslink_committee_for_shard(
&self,
shard: Shard,
@@ -131,6 +134,10 @@ impl EpochCache {
}
}
/// Returns a list of all `validator_registry` indices where the validator is active at the given
/// `epoch`.
///
/// Spec v0.5.0
pub fn get_active_validator_indices(validators: &[Validator], epoch: Epoch) -> Vec<usize> {
let mut active = Vec::with_capacity(validators.len());
@@ -145,13 +152,17 @@ pub fn get_active_validator_indices(validators: &[Validator], epoch: Epoch) -> V
active
}
/// Contains all `CrosslinkCommittees` for an epoch.
#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)]
pub struct EpochCrosslinkCommittees {
/// The epoch the committees are present in.
epoch: Epoch,
/// Each commitee for each slot of the epoch.
pub crosslink_committees: Vec<Vec<CrosslinkCommittee>>,
}
impl EpochCrosslinkCommittees {
/// Return a new instances where all slots have zero committees.
fn new(epoch: Epoch, spec: &ChainSpec) -> Self {
Self {
epoch,
@@ -159,6 +170,7 @@ impl EpochCrosslinkCommittees {
}
}
/// Return a vec of `CrosslinkCommittee` for a given slot.
fn get_crosslink_committees_at_slot(
&self,
slot: Slot,
@@ -176,6 +188,7 @@ impl EpochCrosslinkCommittees {
}
}
/// Builds an `EpochCrosslinkCommittees` object.
pub struct EpochCrosslinkCommitteesBuilder {
epoch: Epoch,
shuffling_start_shard: Shard,
@@ -185,6 +198,7 @@ pub struct EpochCrosslinkCommitteesBuilder {
}
impl EpochCrosslinkCommitteesBuilder {
/// Instantiates a builder that will build for the `state`'s previous epoch.
pub fn for_previous_epoch(
state: &BeaconState,
active_validator_indices: Vec<usize>,
@@ -199,6 +213,7 @@ impl EpochCrosslinkCommitteesBuilder {
}
}
/// Instantiates a builder that will build for the `state`'s next epoch.
pub fn for_current_epoch(
state: &BeaconState,
active_validator_indices: Vec<usize>,
@@ -213,6 +228,10 @@ impl EpochCrosslinkCommitteesBuilder {
}
}
/// Instantiates a builder that will build for the `state`'s next epoch.
///
/// 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,
active_validator_indices: Vec<usize>,
@@ -257,6 +276,7 @@ impl EpochCrosslinkCommitteesBuilder {
})
}
/// Consumes the builder, returning a fully-build `EpochCrosslinkCommittee`.
pub fn build(self, spec: &ChainSpec) -> Result<EpochCrosslinkCommittees, Error> {
// The shuffler fails on a empty list, so if there are no active validator indices, simply
// return an empty list.
@@ -284,7 +304,6 @@ impl EpochCrosslinkCommitteesBuilder {
for (i, slot) in self.epoch.slot_iter(spec.slots_per_epoch).enumerate() {
for j in (0..committees.len())
.into_iter()
.skip(i * committees_per_slot)
.take(committees_per_slot)
{

View File

@@ -114,6 +114,13 @@ pub struct ChainSpec {
domain_deposit: u32,
domain_exit: u32,
domain_transfer: u32,
/*
* Network specific parameters
*
*/
pub boot_nodes: Vec<Multiaddr>,
pub network_id: u8,
}
impl ChainSpec {
@@ -245,6 +252,30 @@ impl ChainSpec {
domain_deposit: 3,
domain_exit: 4,
domain_transfer: 5,
/*
* Boot nodes
*/
boot_nodes: vec![],
network_id: 1, // foundation network id
}
}
/// Returns a `ChainSpec` compatible with the Lighthouse testnet specification.
///
/// Spec v0.4.0
pub fn lighthouse_testnet() -> Self {
/*
* Lighthouse testnet bootnodes
*/
let boot_nodes = vec!["/ip4/127.0.0.1/tcp/9000"
.parse()
.expect("correct multiaddr")];
Self {
boot_nodes,
network_id: 2, // lighthouse testnet network id
..ChainSpec::few_validators()
}
}

View File

@@ -85,3 +85,6 @@ 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 libp2p::floodsub::{Topic, TopicBuilder};
pub use libp2p::multiaddr;
pub use libp2p::Multiaddr;

View File

@@ -33,7 +33,7 @@ impl RelativeEpoch {
/// Returns the `epoch` that `self` refers to, with respect to the `base` epoch.
///
/// Spec v0.5.0
pub fn into_epoch(&self, base: Epoch) -> Epoch {
pub fn into_epoch(self, base: Epoch) -> Epoch {
match self {
RelativeEpoch::Previous => base - 1,
RelativeEpoch::Current => base,

View File

@@ -214,7 +214,7 @@ impl TestingBeaconStateBuilder {
- spec.min_attestation_inclusion_delay;
let last_slot = std::cmp::min(state.slot.as_u64(), last_slot);
for slot in first_slot..last_slot + 1 {
for slot in first_slot..=last_slot {
let slot = Slot::from(slot);
let committees = state

View File

@@ -47,7 +47,7 @@ impl TestingDepositBuilder {
self.deposit
.deposit_data
.deposit_input
.withdrawal_credentials = withdrawal_credentials.clone();
.withdrawal_credentials = withdrawal_credentials;
self.deposit.deposit_data.deposit_input.proof_of_possession = self
.deposit