Merge branch 'master' into v0.4.0-types

This commit is contained in:
Paul Hauner
2019-03-07 12:03:27 +11:00
35 changed files with 1842 additions and 94 deletions

View File

@@ -27,8 +27,8 @@ impl AttesterSlashingBuilder {
let shard = 0;
let justified_epoch = Epoch::new(0);
let epoch = Epoch::new(0);
let hash_1 = Hash256::from(&[1][..]);
let hash_2 = Hash256::from(&[2][..]);
let hash_1 = Hash256::from_low_u64_le(1);
let hash_2 = Hash256::from_low_u64_le(2);
let mut slashable_attestation_1 = SlashableAttestation {
validator_indices: validator_indices.to_vec(),

View File

@@ -469,18 +469,20 @@ impl BeaconState {
let mut input = self
.get_randao_mix(epoch - spec.min_seed_lookahead, spec)
.ok_or_else(|| Error::InsufficientRandaoMixes)?
.as_bytes()
.to_vec();
input.append(
&mut self
.get_active_index_root(epoch, spec)
.ok_or_else(|| Error::InsufficientIndexRoots)?
.as_bytes()
.to_vec(),
);
input.append(&mut int_to_bytes32(epoch.as_u64()));
Ok(Hash256::from(&hash(&input[..])[..]))
Ok(Hash256::from_slice(&hash(&input[..])[..]))
}
/// Returns the beacon proposer index for the `slot`.
@@ -1155,7 +1157,7 @@ impl BeaconState {
}
fn hash_tree_root<T: TreeHash>(input: Vec<T>) -> Hash256 {
Hash256::from(&input.hash_tree_root()[..])
Hash256::from_slice(&input.hash_tree_root()[..])
}
impl Encodable for BeaconState {

View File

@@ -145,8 +145,8 @@ impl BeaconStateBuilder {
state.previous_shuffling_epoch = epoch - 1;
state.current_shuffling_epoch = epoch;
state.previous_shuffling_seed = Hash256::from(&b"previous_seed"[..]);
state.current_shuffling_seed = Hash256::from(&b"current_seed"[..]);
state.previous_shuffling_seed = Hash256::from_low_u64_le(0);
state.current_shuffling_seed = Hash256::from_low_u64_le(1);
state.previous_justified_epoch = epoch - 2;
state.justified_epoch = epoch - 1;

View File

@@ -0,0 +1,20 @@
use crate::test_utils::TestRandom;
use crate::{Hash256, Slot};
use rand::RngCore;
use serde_derive::Serialize;
use ssz_derive::{Decode, Encode, TreeHash};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Default, Serialize, Encode, Decode, TreeHash, TestRandom)]
pub struct ProposalSignedData {
pub slot: Slot,
pub shard: u64,
pub block_root: Hash256,
}
#[cfg(test)]
mod tests {
use super::*;
ssz_tests!(ProposalSignedData);
}

View File

@@ -25,14 +25,14 @@ impl ProposerSlashingBuilder {
let mut proposal_1 = Proposal {
slot,
shard,
block_root: Hash256::from(&[1][..]),
block_root: Hash256::from_low_u64_le(1),
signature: Signature::empty_signature(),
};
let mut proposal_2 = Proposal {
slot,
shard,
block_root: Hash256::from(&[2][..]),
block_root: Hash256::from_low_u64_le(2),
signature: Signature::empty_signature(),
};

View File

@@ -0,0 +1,132 @@
use super::AttestationData;
use crate::chain_spec::ChainSpec;
use crate::test_utils::TestRandom;
use bls::AggregateSignature;
use rand::RngCore;
use serde_derive::Serialize;
use ssz_derive::{Decode, Encode, TreeHash};
use test_random_derive::TestRandom;
#[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode, TreeHash, TestRandom)]
pub struct SlashableVoteData {
pub custody_bit_0_indices: Vec<u32>,
pub custody_bit_1_indices: Vec<u32>,
pub data: AttestationData,
pub aggregate_signature: AggregateSignature,
}
impl SlashableVoteData {
/// Check if ``attestation_data_1`` and ``attestation_data_2`` have the same target.
///
/// Spec v0.3.0
pub fn is_double_vote(&self, other: &SlashableVoteData, spec: &ChainSpec) -> bool {
self.data.slot.epoch(spec.epoch_length) == other.data.slot.epoch(spec.epoch_length)
}
/// Check if ``attestation_data_1`` surrounds ``attestation_data_2``.
///
/// Spec v0.3.0
pub fn is_surround_vote(&self, other: &SlashableVoteData, spec: &ChainSpec) -> bool {
let source_epoch_1 = self.data.justified_epoch;
let source_epoch_2 = other.data.justified_epoch;
let target_epoch_1 = self.data.slot.epoch(spec.epoch_length);
let target_epoch_2 = other.data.slot.epoch(spec.epoch_length);
(source_epoch_1 < source_epoch_2) && (target_epoch_2 < target_epoch_1)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::chain_spec::ChainSpec;
use crate::slot_epoch::{Epoch, Slot};
use crate::test_utils::{SeedableRng, TestRandom, XorShiftRng};
#[test]
pub fn test_is_double_vote_true() {
let spec = ChainSpec::foundation();
let slashable_vote_first = create_slashable_vote_data(1, 1, &spec);
let slashable_vote_second = create_slashable_vote_data(1, 1, &spec);
assert_eq!(
slashable_vote_first.is_double_vote(&slashable_vote_second, &spec),
true
)
}
#[test]
pub fn test_is_double_vote_false() {
let spec = ChainSpec::foundation();
let slashable_vote_first = create_slashable_vote_data(1, 1, &spec);
let slashable_vote_second = create_slashable_vote_data(2, 1, &spec);
assert_eq!(
slashable_vote_first.is_double_vote(&slashable_vote_second, &spec),
false
);
}
#[test]
pub fn test_is_surround_vote_true() {
let spec = ChainSpec::foundation();
let slashable_vote_first = create_slashable_vote_data(2, 1, &spec);
let slashable_vote_second = create_slashable_vote_data(1, 2, &spec);
assert_eq!(
slashable_vote_first.is_surround_vote(&slashable_vote_second, &spec),
true
);
}
#[test]
pub fn test_is_surround_vote_true_realistic() {
let spec = ChainSpec::foundation();
let slashable_vote_first = create_slashable_vote_data(4, 1, &spec);
let slashable_vote_second = create_slashable_vote_data(3, 2, &spec);
assert_eq!(
slashable_vote_first.is_surround_vote(&slashable_vote_second, &spec),
true
);
}
#[test]
pub fn test_is_surround_vote_false_source_epoch_fails() {
let spec = ChainSpec::foundation();
let slashable_vote_first = create_slashable_vote_data(2, 2, &spec);
let slashable_vote_second = create_slashable_vote_data(1, 1, &spec);
assert_eq!(
slashable_vote_first.is_surround_vote(&slashable_vote_second, &spec),
false
);
}
#[test]
pub fn test_is_surround_vote_false_target_epoch_fails() {
let spec = ChainSpec::foundation();
let slashable_vote_first = create_slashable_vote_data(1, 1, &spec);
let slashable_vote_second = create_slashable_vote_data(2, 2, &spec);
assert_eq!(
slashable_vote_first.is_surround_vote(&slashable_vote_second, &spec),
false
);
}
ssz_tests!(SlashableVoteData);
fn create_slashable_vote_data(
slot_factor: u64,
justified_epoch: u64,
spec: &ChainSpec,
) -> SlashableVoteData {
let mut rng = XorShiftRng::from_seed([42; 16]);
let mut slashable_vote = SlashableVoteData::random_for_test(&mut rng);
slashable_vote.data.slot = Slot::new(slot_factor * spec.epoch_length);
slashable_vote.data.justified_epoch = Epoch::new(justified_epoch);
slashable_vote
}
}

View File

@@ -6,6 +6,6 @@ impl<T: RngCore> TestRandom<T> for Address {
fn random_for_test(rng: &mut T) -> Self {
let mut key_bytes = vec![0; 20];
rng.fill_bytes(&mut key_bytes);
Address::from(&key_bytes[..])
Address::from_slice(&key_bytes[..])
}
}

View File

@@ -6,6 +6,6 @@ impl<T: RngCore> TestRandom<T> for Hash256 {
fn random_for_test(rng: &mut T) -> Self {
let mut key_bytes = vec![0; 32];
rng.fill_bytes(&mut key_bytes);
Hash256::from(&key_bytes[..])
Hash256::from_slice(&key_bytes[..])
}
}

View File

@@ -0,0 +1,34 @@
#[cfg(test)]
#[macro_export]
macro_rules! ssz_tests {
($type: ident) => {
#[test]
pub fn test_ssz_round_trip() {
use crate::test_utils::{SeedableRng, TestRandom, XorShiftRng};
use ssz::{ssz_encode, Decodable};
let mut rng = XorShiftRng::from_seed([42; 16]);
let original = $type::random_for_test(&mut rng);
let bytes = ssz_encode(&original);
let (decoded, _) = $type::ssz_decode(&bytes, 0).unwrap();
assert_eq!(original, decoded);
}
#[test]
pub fn test_hash_tree_root_internal() {
use crate::test_utils::{SeedableRng, TestRandom, XorShiftRng};
use ssz::TreeHash;
let mut rng = XorShiftRng::from_seed([42; 16]);
let original = $type::random_for_test(&mut rng);
let result = original.hash_tree_root_internal();
assert_eq!(result.len(), 32);
// TODO: Add further tests
// https://github.com/sigp/lighthouse/issues/170
}
};
}

View File

@@ -0,0 +1,36 @@
use crate::{test_utils::TestRandom, Hash256, Slot};
use bls::PublicKey;
use rand::RngCore;
use serde_derive::Serialize;
use ssz_derive::{Decode, Encode, TreeHash};
use test_random_derive::TestRandom;
// The information gathered from the PoW chain validator registration function.
#[derive(Debug, Clone, PartialEq, Serialize, Encode, Decode, TreeHash, TestRandom)]
pub struct ValidatorRegistryDeltaBlock {
pub latest_registry_delta_root: Hash256,
pub validator_index: u32,
pub pubkey: PublicKey,
pub slot: Slot,
pub flag: u64,
}
impl Default for ValidatorRegistryDeltaBlock {
/// Yields a "default" `Validator`. Primarily used for testing.
fn default() -> Self {
Self {
latest_registry_delta_root: Hash256::zero(),
validator_index: std::u32::MAX,
pubkey: PublicKey::default(),
slot: Slot::from(std::u64::MAX),
flag: std::u64::MAX,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
ssz_tests!(ValidatorRegistryDeltaBlock);
}