types: more v0.6.1 updates

This commit is contained in:
Michael Sproul 2019-05-13 17:01:30 +10:00
parent eda8ec8c55
commit 240e269f2f
No known key found for this signature in database
GPG Key ID: 77B1309D2E54E914
13 changed files with 73 additions and 75 deletions

View File

@ -1,5 +1,5 @@
use crate::test_utils::TestRandom; use crate::test_utils::TestRandom;
use crate::{Epoch, Hash256, Slot}; use crate::{Epoch, Hash256};
use rand::RngCore; use rand::RngCore;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode}; use ssz_derive::{Decode, Encode};
@ -9,7 +9,7 @@ use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
/// The data upon which an attestation is based. /// The data upon which an attestation is based.
/// ///
/// Spec v0.6.0 /// Spec v0.6.1
#[derive( #[derive(
Debug, Debug,
Clone, Clone,
@ -27,12 +27,12 @@ use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
)] )]
pub struct AttestationData { pub struct AttestationData {
// LMD GHOST vote // LMD GHOST vote
pub slot: Slot,
pub beacon_block_root: Hash256, pub beacon_block_root: Hash256,
// FFG Vote // FFG Vote
pub source_epoch: Epoch, pub source_epoch: Epoch,
pub source_root: Hash256, pub source_root: Hash256,
pub target_epoch: Epoch,
pub target_root: Hash256, pub target_root: Hash256,
// Crosslink Vote // Crosslink Vote

View File

@ -250,9 +250,14 @@ impl BeaconState {
/// ///
/// If the current epoch is the genesis epoch, the genesis_epoch is returned. /// If the current epoch is the genesis epoch, the genesis_epoch is returned.
/// ///
/// Spec v0.5.1 /// Spec v0.6.1
pub fn previous_epoch(&self, spec: &ChainSpec) -> Epoch { pub fn previous_epoch(&self, spec: &ChainSpec) -> Epoch {
self.current_epoch(&spec) - 1 let current_epoch = self.current_epoch(spec);
if current_epoch > spec.genesis_epoch {
current_epoch - 1
} else {
current_epoch
}
} }
/// The epoch following `self.current_epoch()`. /// The epoch following `self.current_epoch()`.

View File

@ -122,7 +122,7 @@ pub struct ChainSpec {
impl ChainSpec { impl ChainSpec {
/// Return the number of committees in one epoch. /// Return the number of committees in one epoch.
/// ///
/// Spec v0.5.1 /// Spec v0.6.1
pub fn get_epoch_committee_count(&self, active_validator_count: usize) -> u64 { pub fn get_epoch_committee_count(&self, active_validator_count: usize) -> u64 {
std::cmp::max( std::cmp::max(
1, 1,
@ -319,11 +319,11 @@ mod tests {
fn test_get_domain() { fn test_get_domain() {
let spec = ChainSpec::foundation(); let spec = ChainSpec::foundation();
test_domain(Domain::BeaconBlock, spec.domain_beacon_block, &spec); test_domain(Domain::BeaconProposer, spec.domain_beacon_proposer, &spec);
test_domain(Domain::Randao, spec.domain_randao, &spec); test_domain(Domain::Randao, spec.domain_randao, &spec);
test_domain(Domain::Attestation, spec.domain_attestation, &spec); test_domain(Domain::Attestation, spec.domain_attestation, &spec);
test_domain(Domain::Deposit, spec.domain_deposit, &spec); test_domain(Domain::Deposit, spec.domain_deposit, &spec);
test_domain(Domain::Exit, spec.domain_exit, &spec); test_domain(Domain::VoluntaryExit, spec.domain_voluntary_exit, &spec);
test_domain(Domain::Transfer, spec.domain_transfer, &spec); test_domain(Domain::Transfer, spec.domain_transfer, &spec);
} }
} }

View File

@ -13,6 +13,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
Debug, Debug,
Clone, Clone,
PartialEq, PartialEq,
Eq,
Default, Default,
Serialize, Serialize,
Deserialize, Deserialize,

View File

@ -76,6 +76,7 @@ mod tests {
let mut deposit_input = DepositData { let mut deposit_input = DepositData {
pubkey: keypair.pk.clone(), pubkey: keypair.pk.clone(),
amount: 0,
withdrawal_credentials: Hash256::zero(), withdrawal_credentials: Hash256::zero(),
signature: Signature::empty_signature(), signature: Signature::empty_signature(),
}; };

View File

@ -2,7 +2,6 @@ use crate::{
test_utils::{fork_from_hex_str, TestRandom}, test_utils::{fork_from_hex_str, TestRandom},
ChainSpec, Epoch, ChainSpec, Epoch,
}; };
use int_to_bytes::int_to_bytes4;
use rand::RngCore; use rand::RngCore;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode}; use ssz_derive::{Decode, Encode};
@ -11,7 +10,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
/// Specifies a fork of the `BeaconChain`, to prevent replay attacks. /// Specifies a fork of the `BeaconChain`, to prevent replay attacks.
/// ///
/// Spec v0.5.1 /// Spec v0.6.1
#[derive( #[derive(
Debug, Debug,
Clone, Clone,
@ -36,10 +35,11 @@ pub struct Fork {
impl Fork { impl Fork {
/// Initialize the `Fork` from the genesis parameters in the `spec`. /// Initialize the `Fork` from the genesis parameters in the `spec`.
/// ///
/// Spec v0.5.1 /// Spec v0.6.1
pub fn genesis(spec: &ChainSpec) -> Self { pub fn genesis(spec: &ChainSpec) -> Self {
let mut current_version: [u8; 4] = [0; 4]; let current_version: [u8; 4] = [0; 4];
current_version.copy_from_slice(&int_to_bytes4(spec.genesis_fork_version)); // FIXME(sproul): 0 fork?
// current_version.copy_from_slice(&int_to_bytes4(spec.genesis_fork_version));
Self { Self {
previous_version: current_version, previous_version: current_version,
@ -50,7 +50,7 @@ impl Fork {
/// Return the fork version of the given ``epoch``. /// Return the fork version of the given ``epoch``.
/// ///
/// Spec v0.5.1 /// Spec v0.6.1
pub fn get_fork_version(&self, epoch: Epoch) -> [u8; 4] { pub fn get_fork_version(&self, epoch: Epoch) -> [u8; 4] {
if epoch < self.epoch { if epoch < self.epoch {
return self.previous_version; return self.previous_version;
@ -66,10 +66,10 @@ mod tests {
ssz_tests!(Fork); ssz_tests!(Fork);
cached_tree_hash_tests!(Fork); cached_tree_hash_tests!(Fork);
// FIXME(sproul): dunno
fn test_genesis(version: u32, epoch: Epoch) { fn test_genesis(version: u32, epoch: Epoch) {
let mut spec = ChainSpec::foundation(); let mut spec = ChainSpec::foundation();
spec.genesis_fork_version = version;
spec.genesis_epoch = epoch; spec.genesis_epoch = epoch;
let fork = Fork::genesis(&spec); let fork = Fork::genesis(&spec);

View File

@ -1,4 +1,4 @@
use crate::{test_utils::TestRandom, AggregateSignature, AttestationData, Bitfield, ChainSpec}; use crate::{test_utils::TestRandom, AggregateSignature, AttestationData, Bitfield};
use rand::RngCore; use rand::RngCore;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode}; use ssz_derive::{Decode, Encode};
@ -37,99 +37,88 @@ pub struct IndexedAttestation {
impl IndexedAttestation { impl IndexedAttestation {
/// Check if ``attestation_data_1`` and ``attestation_data_2`` have the same target. /// Check if ``attestation_data_1`` and ``attestation_data_2`` have the same target.
/// ///
/// Spec v0.5.1 /// Spec v0.6.1
pub fn is_double_vote(&self, other: &IndexedAttestation, spec: &ChainSpec) -> bool { pub fn is_double_vote(&self, other: &IndexedAttestation) -> bool {
self.data.slot.epoch(spec.slots_per_epoch) == other.data.slot.epoch(spec.slots_per_epoch) self.data.target_epoch == other.data.target_epoch && self.data != other.data
} }
/// Check if ``attestation_data_1`` surrounds ``attestation_data_2``. /// Check if ``attestation_data_1`` surrounds ``attestation_data_2``.
/// ///
/// Spec v0.5.1 /// Spec v0.6.1
pub fn is_surround_vote(&self, other: &IndexedAttestation, spec: &ChainSpec) -> bool { pub fn is_surround_vote(&self, other: &IndexedAttestation) -> bool {
let source_epoch_1 = self.data.source_epoch; self.data.source_epoch < other.data.source_epoch
let source_epoch_2 = other.data.source_epoch; && other.data.target_epoch < self.data.target_epoch
let target_epoch_1 = self.data.slot.epoch(spec.slots_per_epoch);
let target_epoch_2 = other.data.slot.epoch(spec.slots_per_epoch);
(source_epoch_1 < source_epoch_2) & (target_epoch_2 < target_epoch_1)
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::chain_spec::ChainSpec; use crate::slot_epoch::Epoch;
use crate::slot_epoch::{Epoch, Slot};
use crate::test_utils::{SeedableRng, TestRandom, XorShiftRng}; use crate::test_utils::{SeedableRng, TestRandom, XorShiftRng};
#[test] #[test]
pub fn test_is_double_vote_true() { pub fn test_is_double_vote_true() {
let spec = ChainSpec::foundation(); let indexed_vote_first = create_indexed_attestation(1, 1);
let indexed_vote_first = create_indexed_attestation(1, 1, &spec); let indexed_vote_second = create_indexed_attestation(1, 1);
let indexed_vote_second = create_indexed_attestation(1, 1, &spec);
assert_eq!( assert_eq!(
indexed_vote_first.is_double_vote(&indexed_vote_second, &spec), indexed_vote_first.is_double_vote(&indexed_vote_second),
true true
) )
} }
#[test] #[test]
pub fn test_is_double_vote_false() { pub fn test_is_double_vote_false() {
let spec = ChainSpec::foundation(); let indexed_vote_first = create_indexed_attestation(1, 1);
let indexed_vote_first = create_indexed_attestation(1, 1, &spec); let indexed_vote_second = create_indexed_attestation(2, 1);
let indexed_vote_second = create_indexed_attestation(2, 1, &spec);
assert_eq!( assert_eq!(
indexed_vote_first.is_double_vote(&indexed_vote_second, &spec), indexed_vote_first.is_double_vote(&indexed_vote_second),
false false
); );
} }
#[test] #[test]
pub fn test_is_surround_vote_true() { pub fn test_is_surround_vote_true() {
let spec = ChainSpec::foundation(); let indexed_vote_first = create_indexed_attestation(2, 1);
let indexed_vote_first = create_indexed_attestation(2, 1, &spec); let indexed_vote_second = create_indexed_attestation(1, 2);
let indexed_vote_second = create_indexed_attestation(1, 2, &spec);
assert_eq!( assert_eq!(
indexed_vote_first.is_surround_vote(&indexed_vote_second, &spec), indexed_vote_first.is_surround_vote(&indexed_vote_second),
true true
); );
} }
#[test] #[test]
pub fn test_is_surround_vote_true_realistic() { pub fn test_is_surround_vote_true_realistic() {
let spec = ChainSpec::foundation(); let indexed_vote_first = create_indexed_attestation(4, 1);
let indexed_vote_first = create_indexed_attestation(4, 1, &spec); let indexed_vote_second = create_indexed_attestation(3, 2);
let indexed_vote_second = create_indexed_attestation(3, 2, &spec);
assert_eq!( assert_eq!(
indexed_vote_first.is_surround_vote(&indexed_vote_second, &spec), indexed_vote_first.is_surround_vote(&indexed_vote_second),
true true
); );
} }
#[test] #[test]
pub fn test_is_surround_vote_false_source_epoch_fails() { pub fn test_is_surround_vote_false_source_epoch_fails() {
let spec = ChainSpec::foundation(); let indexed_vote_first = create_indexed_attestation(2, 2);
let indexed_vote_first = create_indexed_attestation(2, 2, &spec); let indexed_vote_second = create_indexed_attestation(1, 1);
let indexed_vote_second = create_indexed_attestation(1, 1, &spec);
assert_eq!( assert_eq!(
indexed_vote_first.is_surround_vote(&indexed_vote_second, &spec), indexed_vote_first.is_surround_vote(&indexed_vote_second),
false false
); );
} }
#[test] #[test]
pub fn test_is_surround_vote_false_target_epoch_fails() { pub fn test_is_surround_vote_false_target_epoch_fails() {
let spec = ChainSpec::foundation(); let indexed_vote_first = create_indexed_attestation(1, 1);
let indexed_vote_first = create_indexed_attestation(1, 1, &spec); let indexed_vote_second = create_indexed_attestation(2, 2);
let indexed_vote_second = create_indexed_attestation(2, 2, &spec);
assert_eq!( assert_eq!(
indexed_vote_first.is_surround_vote(&indexed_vote_second, &spec), indexed_vote_first.is_surround_vote(&indexed_vote_second),
false false
); );
} }
@ -137,16 +126,12 @@ mod tests {
ssz_tests!(IndexedAttestation); ssz_tests!(IndexedAttestation);
cached_tree_hash_tests!(IndexedAttestation); cached_tree_hash_tests!(IndexedAttestation);
fn create_indexed_attestation( fn create_indexed_attestation(target_epoch: u64, source_epoch: u64) -> IndexedAttestation {
slot_factor: u64,
source_epoch: u64,
spec: &ChainSpec,
) -> IndexedAttestation {
let mut rng = XorShiftRng::from_seed([42; 16]); let mut rng = XorShiftRng::from_seed([42; 16]);
let mut indexed_vote = IndexedAttestation::random_for_test(&mut rng); let mut indexed_vote = IndexedAttestation::random_for_test(&mut rng);
indexed_vote.data.slot = Slot::new(slot_factor * spec.slots_per_epoch);
indexed_vote.data.source_epoch = Epoch::new(source_epoch); indexed_vote.data.source_epoch = Epoch::new(source_epoch);
indexed_vote.data.target_epoch = Epoch::new(target_epoch);
indexed_vote indexed_vote
} }
} }

View File

@ -1,5 +1,5 @@
use crate::test_utils::TestRandom; use crate::test_utils::TestRandom;
use crate::{Attestation, AttestationData, Bitfield, Slot}; use crate::{Attestation, AttestationData, Bitfield};
use rand::RngCore; use rand::RngCore;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode}; use ssz_derive::{Decode, Encode};
@ -8,7 +8,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
/// An attestation that has been included in the state but not yet fully processed. /// An attestation that has been included in the state but not yet fully processed.
/// ///
/// Spec v0.6.0 /// Spec v0.6.1
#[derive( #[derive(
Debug, Debug,
Clone, Clone,
@ -24,7 +24,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
pub struct PendingAttestation { pub struct PendingAttestation {
pub aggregation_bitfield: Bitfield, pub aggregation_bitfield: Bitfield,
pub data: AttestationData, pub data: AttestationData,
pub inclusion_slot: Slot, pub inclusion_delay: u64,
pub proposer_index: u64, pub proposer_index: u64,
} }
@ -32,13 +32,13 @@ impl PendingAttestation {
/// Create a `PendingAttestation` from an `Attestation`. /// Create a `PendingAttestation` from an `Attestation`.
pub fn from_attestation( pub fn from_attestation(
attestation: &Attestation, attestation: &Attestation,
inclusion_slot: Slot, inclusion_delay: u64,
proposer_index: u64, proposer_index: u64,
) -> Self { ) -> Self {
PendingAttestation { PendingAttestation {
data: attestation.data.clone(), data: attestation.data.clone(),
aggregation_bitfield: attestation.aggregation_bitfield.clone(), aggregation_bitfield: attestation.aggregation_bitfield.clone(),
inclusion_slot, inclusion_delay,
proposer_index, proposer_index,
} }
} }

View File

@ -77,7 +77,7 @@ impl TestingAttestationBuilder {
.tree_hash_root(); .tree_hash_root();
let domain = spec.get_domain( let domain = spec.get_domain(
self.attestation.data.slot.epoch(spec.slots_per_epoch), self.attestation.data.target_epoch,
Domain::Attestation, Domain::Attestation,
fork, fork,
); );

View File

@ -23,6 +23,12 @@ impl TestingAttestationDataBuilder {
state.current_justified_epoch state.current_justified_epoch
}; };
let target_epoch = if is_previous_epoch {
state.previous_epoch(spec)
} else {
state.current_epoch(spec)
};
let target_root = if is_previous_epoch { let target_root = if is_previous_epoch {
*state *state
.get_block_root(previous_epoch.start_slot(spec.slots_per_epoch), spec) .get_block_root(previous_epoch.start_slot(spec.slots_per_epoch), spec)
@ -39,12 +45,12 @@ impl TestingAttestationDataBuilder {
let data = AttestationData { let data = AttestationData {
// LMD GHOST vote // LMD GHOST vote
slot,
beacon_block_root: *state.get_block_root(slot, spec).unwrap(), beacon_block_root: *state.get_block_root(slot, spec).unwrap(),
// FFG Vote // FFG Vote
source_epoch, source_epoch,
source_root, source_root,
target_epoch,
target_root, target_root,
// Crosslink vote // Crosslink vote

View File

@ -21,17 +21,17 @@ impl TestingAttesterSlashingBuilder {
where where
F: Fn(u64, &[u8], Epoch, Domain) -> Signature, F: Fn(u64, &[u8], Epoch, Domain) -> Signature,
{ {
let double_voted_slot = Slot::new(0);
let shard = 0; let shard = 0;
let epoch = Epoch::new(0); let epoch_1 = Epoch::new(1);
let epoch_2 = Epoch::new(2);
let hash_1 = Hash256::from_low_u64_le(1); let hash_1 = Hash256::from_low_u64_le(1);
let hash_2 = Hash256::from_low_u64_le(2); let hash_2 = Hash256::from_low_u64_le(2);
let data_1 = AttestationData { let data_1 = AttestationData {
slot: double_voted_slot,
beacon_block_root: hash_1, beacon_block_root: hash_1,
source_epoch: epoch, source_epoch: epoch_1,
source_root: hash_1, source_root: hash_1,
target_epoch: epoch_2,
target_root: hash_1, target_root: hash_1,
shard, shard,
previous_crosslink_root: hash_1, previous_crosslink_root: hash_1,
@ -69,7 +69,8 @@ impl TestingAttesterSlashingBuilder {
for (i, validator_index) in validator_indices.iter().enumerate() { for (i, validator_index) in validator_indices.iter().enumerate() {
attestation.custody_bitfield.set(i, false); attestation.custody_bitfield.set(i, false);
let signature = signer(*validator_index, &message[..], epoch, Domain::Attestation); let signature =
signer(*validator_index, &message[..], epoch_2, Domain::Attestation);
attestation.signature.add(&signature); attestation.signature.add(&signature);
} }
}; };

View File

@ -246,7 +246,7 @@ impl TestingBeaconStateBuilder {
builder.add_committee_participation(signers); builder.add_committee_participation(signers);
let attestation = builder.build(); let attestation = builder.build();
if attestation.data.slot.epoch(spec.slots_per_epoch) < state.current_epoch(spec) { if attestation.data.target_epoch < state.current_epoch(spec) {
state.previous_epoch_attestations.push(attestation) state.previous_epoch_attestations.push(attestation)
} else { } else {
state.current_epoch_attestations.push(attestation) state.current_epoch_attestations.push(attestation)

View File

@ -11,8 +11,7 @@ pub struct TestingPendingAttestationBuilder {
impl TestingPendingAttestationBuilder { impl TestingPendingAttestationBuilder {
/// Create a new valid* `PendingAttestation` for the given parameters. /// Create a new valid* `PendingAttestation` for the given parameters.
/// ///
/// The `inclusion_slot` will be set to be the earliest possible slot the `Attestation` could /// The `inclusion_delay` will be set to `MIN_ATTESTATION_INCLUSION_DELAY`.
/// have been included (`slot + MIN_ATTESTATION_INCLUSION_DELAY`).
/// ///
/// * The aggregation and custody bitfields will all be empty, they need to be set with /// * The aggregation and custody bitfields will all be empty, they need to be set with
/// `Self::add_committee_participation`. /// `Self::add_committee_participation`.
@ -22,7 +21,7 @@ impl TestingPendingAttestationBuilder {
let pending_attestation = PendingAttestation { let pending_attestation = PendingAttestation {
aggregation_bitfield: Bitfield::new(), aggregation_bitfield: Bitfield::new(),
data: data_builder.build(), data: data_builder.build(),
inclusion_slot: slot + spec.min_attestation_inclusion_delay, inclusion_delay: spec.min_attestation_inclusion_delay,
// FIXME(sproul) // FIXME(sproul)
proposer_index: 0, proposer_index: 0,
}; };