spec v0.6.0: update types

This commit is contained in:
Michael Sproul 2019-04-29 14:54:52 +10:00
parent 7dda85e87e
commit 1ad0024045
No known key found for this signature in database
GPG Key ID: 77B1309D2E54E914
22 changed files with 192 additions and 272 deletions

View File

@ -9,7 +9,7 @@ use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
/// Details an attestation that can be slashable.
///
/// Spec v0.5.1
/// Spec v0.6.0
#[derive(
Debug,
Clone,
@ -28,7 +28,7 @@ pub struct Attestation {
pub data: AttestationData,
pub custody_bitfield: Bitfield,
#[signed_root(skip_hashing)]
pub aggregate_signature: AggregateSignature,
pub signature: AggregateSignature,
}
impl Attestation {
@ -49,8 +49,7 @@ impl Attestation {
self.aggregation_bitfield
.union_inplace(&other.aggregation_bitfield);
self.custody_bitfield.union_inplace(&other.custody_bitfield);
self.aggregate_signature
.add_aggregate(&other.aggregate_signature);
self.signature.add_aggregate(&other.signature);
}
}

View File

@ -9,7 +9,7 @@ use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
/// The data upon which an attestation is based.
///
/// Spec v0.5.1
/// Spec v0.6.0
#[derive(
Debug,
Clone,
@ -37,7 +37,7 @@ pub struct AttestationData {
// Crosslink Vote
pub shard: u64,
pub previous_crosslink: Crosslink,
pub previous_crosslink_root: Crosslink,
pub crosslink_data_root: Hash256,
}

View File

@ -1,4 +1,4 @@
use crate::{test_utils::TestRandom, SlashableAttestation};
use crate::{test_utils::TestRandom, IndexedAttestation};
use rand::RngCore;
use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode};
@ -7,7 +7,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
/// Two conflicting attestations.
///
/// Spec v0.5.1
/// Spec v0.6.0
#[derive(
Debug,
PartialEq,
@ -21,8 +21,8 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
TestRandom,
)]
pub struct AttesterSlashing {
pub slashable_attestation_1: SlashableAttestation,
pub slashable_attestation_2: SlashableAttestation,
pub attestation_1: IndexedAttestation,
pub attestation_2: IndexedAttestation,
}
#[cfg(test)]

View File

@ -47,6 +47,7 @@ impl BeaconBlock {
eth1_data: Eth1Data {
deposit_root: spec.zero_hash,
block_hash: spec.zero_hash,
deposit_count: 0,
},
proposer_slashings: vec![],
attester_slashings: vec![],

View File

@ -69,17 +69,11 @@ pub struct BeaconState {
// Validator registry
pub validator_registry: Vec<Validator>,
pub validator_balances: Vec<u64>,
pub validator_registry_update_epoch: Epoch,
pub balances: Vec<u64>,
// Randomness and committees
pub latest_randao_mixes: TreeHashVector<Hash256>,
pub previous_shuffling_start_shard: u64,
pub current_shuffling_start_shard: u64,
pub previous_shuffling_epoch: Epoch,
pub current_shuffling_epoch: Epoch,
pub previous_shuffling_seed: Hash256,
pub current_shuffling_seed: Hash256,
pub latest_start_shard: u64,
// Finality
pub previous_epoch_attestations: Vec<PendingAttestation>,
@ -93,7 +87,8 @@ pub struct BeaconState {
pub finalized_root: Hash256,
// Recent state
pub latest_crosslinks: TreeHashVector<Crosslink>,
pub current_crosslinks: TreeHashVector<Crosslink>,
pub previous_crosslinks: TreeHashVector<Crosslink>,
pub latest_block_roots: TreeHashVector<Hash256>,
latest_state_roots: TreeHashVector<Hash256>,
latest_active_index_roots: TreeHashVector<Hash256>,
@ -103,7 +98,7 @@ pub struct BeaconState {
// Ethereum 1.0 chain data
pub latest_eth1_data: Eth1Data,
pub eth1_data_votes: Vec<Eth1DataVote>,
pub eth1_data_votes: Vec<Eth1Data>,
pub deposit_index: u64,
// Caching (not in the spec)
@ -143,6 +138,7 @@ impl BeaconState {
pub fn genesis(genesis_time: u64, latest_eth1_data: Eth1Data, spec: &ChainSpec) -> BeaconState {
let initial_crosslink = Crosslink {
epoch: spec.genesis_epoch,
previous_crosslink_root: spec.zero_hash,
crosslink_data_root: spec.zero_hash,
};
@ -154,18 +150,12 @@ impl BeaconState {
// Validator registry
validator_registry: vec![], // Set later in the function.
validator_balances: vec![], // Set later in the function.
validator_registry_update_epoch: spec.genesis_epoch,
balances: vec![], // Set later in the function.
// Randomness and committees
latest_randao_mixes: vec![spec.zero_hash; spec.latest_randao_mixes_length as usize]
.into(),
previous_shuffling_start_shard: spec.genesis_start_shard,
current_shuffling_start_shard: spec.genesis_start_shard,
previous_shuffling_epoch: spec.genesis_epoch,
current_shuffling_epoch: spec.genesis_epoch,
previous_shuffling_seed: spec.zero_hash,
current_shuffling_seed: spec.zero_hash,
latest_start_shard: 0, // FIXME(sproul)
// Finality
previous_epoch_attestations: vec![],
@ -179,7 +169,8 @@ impl BeaconState {
finalized_root: spec.zero_hash,
// Recent state
latest_crosslinks: vec![initial_crosslink; spec.shard_count as usize].into(),
current_crosslinks: vec![initial_crosslink.clone(); spec.shard_count as usize].into(),
previous_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]
@ -630,7 +621,7 @@ impl BeaconState {
spec: &ChainSpec,
) -> Result<u64, Error> {
let balance = self
.validator_balances
.balances
.get(validator_index)
.ok_or_else(|| Error::UnknownValidator)?;
Ok(std::cmp::min(*balance, spec.max_deposit_amount))
@ -647,7 +638,8 @@ impl BeaconState {
///
/// Spec v0.5.1
pub fn initiate_validator_exit(&mut self, validator_index: usize) {
self.validator_registry[validator_index].initiated_exit = true;
// FIXME(sproul)
// self.validator_registry[validator_index].initiated_exit = true;
}
/// Returns the `slot`, `shard` and `committee_index` for which a validator must produce an

View File

@ -207,8 +207,9 @@ impl EpochCrosslinkCommitteesBuilder {
) -> Self {
Self {
epoch: state.previous_epoch(spec),
shuffling_start_shard: state.previous_shuffling_start_shard,
shuffling_seed: state.previous_shuffling_seed,
// FIXME(sproul)
shuffling_start_shard: 0,
shuffling_seed: spec.zero_hash,
committees_per_epoch: spec.get_epoch_committee_count(active_validator_indices.len()),
active_validator_indices,
}
@ -222,8 +223,9 @@ impl EpochCrosslinkCommitteesBuilder {
) -> Self {
Self {
epoch: state.current_epoch(spec),
shuffling_start_shard: state.current_shuffling_start_shard,
shuffling_seed: state.current_shuffling_seed,
// FIXME(sproul)
shuffling_start_shard: 0,
shuffling_seed: spec.zero_hash,
committees_per_epoch: spec.get_epoch_committee_count(active_validator_indices.len()),
active_validator_indices,
}
@ -243,8 +245,9 @@ impl EpochCrosslinkCommitteesBuilder {
let next_epoch = state.next_epoch(spec);
let committees_per_epoch = spec.get_epoch_committee_count(active_validator_indices.len());
let epochs_since_last_registry_update =
current_epoch - state.validator_registry_update_epoch;
// FIXME(sproul)
// current_epoch - state.validator_registry_update_epoch;
let epochs_since_last_registry_update = 0u64;
let (seed, shuffling_start_shard) = if registry_change {
let next_seed = state
@ -252,7 +255,9 @@ impl EpochCrosslinkCommitteesBuilder {
.map_err(|_| Error::UnableToGenerateSeed)?;
(
next_seed,
(state.current_shuffling_start_shard + committees_per_epoch) % spec.shard_count,
0,
// FIXME(sproul)
// (state.current_shuffling_start_shard + committees_per_epoch) % spec.shard_count,
)
} else if (epochs_since_last_registry_update > 1)
& epochs_since_last_registry_update.is_power_of_two()
@ -260,11 +265,13 @@ impl EpochCrosslinkCommitteesBuilder {
let next_seed = state
.generate_seed(next_epoch, spec)
.map_err(|_| Error::UnableToGenerateSeed)?;
(next_seed, state.current_shuffling_start_shard)
(
next_seed, 0, /* FIXME(sproul) state.current_shuffling_start_shard*/
)
} else {
(
state.current_shuffling_seed,
state.current_shuffling_start_shard,
spec.zero_hash, // state.current_shuffling_seed,
0 // state.current_shuffling_start_shard,
)
};

View File

@ -8,7 +8,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
/// Specifies the block hash for a shard at an epoch.
///
/// Spec v0.5.1
/// Spec v0.6.0
#[derive(
Debug,
Clone,
@ -25,6 +25,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
)]
pub struct Crosslink {
pub epoch: Epoch,
pub previous_crosslink_root: Hash256,
pub crosslink_data_root: Hash256,
}

View File

@ -8,7 +8,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
/// A deposit to potentially become a beacon chain validator.
///
/// Spec v0.5.1
/// Spec v0.6.0
#[derive(
Debug,
PartialEq,
@ -24,7 +24,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
pub struct Deposit {
pub proof: TreeHashVector<Hash256>,
pub index: u64,
pub deposit_data: DepositData,
pub data: DepositData,
}
#[cfg(test)]

View File

@ -1,14 +1,16 @@
use super::DepositInput;
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;
use tree_hash_derive::{CachedTreeHash, TreeHash};
use tree_hash::{SignedRoot, TreeHash};
use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
/// Data generated by the deposit contract.
/// The data supplied by the user to the deposit contract.
///
/// Spec v0.5.1
/// Spec v0.6.0
#[derive(
Debug,
PartialEq,
@ -17,14 +19,45 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
Deserialize,
Encode,
Decode,
SignedRoot,
TreeHash,
CachedTreeHash,
TestRandom,
)]
pub struct DepositData {
pub pubkey: PublicKey,
pub withdrawal_credentials: Hash256,
pub amount: u64,
pub timestamp: u64,
pub deposit_input: DepositInput,
#[signed_root(skip_hashing)]
pub signature: Signature,
}
impl DepositData {
/// Generate the signature for a given DepositData details.
///
/// Spec v0.5.1
pub fn create_signature(
&self,
secret_key: &SecretKey,
epoch: Epoch,
fork: &Fork,
spec: &ChainSpec,
) -> Signature {
let msg = self.signed_root();
let domain = spec.get_domain(epoch, Domain::Deposit, fork);
Signature::new(msg.as_slice(), domain, secret_key)
}
/// Verify that proof-of-possession is valid.
///
/// Spec v0.5.1
pub fn validate_signature(&self, epoch: Epoch, fork: &Fork, spec: &ChainSpec) -> bool {
let msg = self.signed_root();
let domain = spec.get_domain(epoch, Domain::Deposit, fork);
self.signature.verify(&msg, domain, &self.pubkey)
}
}
#[cfg(test)]
@ -33,4 +66,22 @@ mod tests {
ssz_tests!(DepositData);
cached_tree_hash_tests!(DepositData);
#[test]
fn can_create_and_validate() {
let spec = ChainSpec::foundation();
let fork = Fork::genesis(&spec);
let keypair = Keypair::random();
let epoch = Epoch::new(0);
let mut deposit_input = DepositData {
pubkey: keypair.pk.clone(),
withdrawal_credentials: Hash256::zero(),
signature: Signature::empty_signature(),
};
deposit_input.signature = deposit_input.create_signature(&keypair.sk, epoch, &fork, &spec);
assert!(deposit_input.validate_signature(epoch, &fork, &spec));
}
}

View File

@ -1,92 +0,0 @@
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;
use tree_hash::{SignedRoot, TreeHash};
use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
/// The data supplied by the user to the deposit contract.
///
/// Spec v0.5.1
#[derive(
Debug,
PartialEq,
Clone,
Serialize,
Deserialize,
Encode,
Decode,
SignedRoot,
TreeHash,
CachedTreeHash,
TestRandom,
)]
pub struct DepositInput {
pub pubkey: PublicKey,
pub withdrawal_credentials: Hash256,
#[signed_root(skip_hashing)]
pub proof_of_possession: Signature,
}
impl DepositInput {
/// Generate the 'proof_of_posession' signature for a given DepositInput details.
///
/// Spec v0.5.1
pub fn create_proof_of_possession(
&self,
secret_key: &SecretKey,
epoch: Epoch,
fork: &Fork,
spec: &ChainSpec,
) -> Signature {
let msg = self.signed_root();
let domain = spec.get_domain(epoch, Domain::Deposit, fork);
Signature::new(msg.as_slice(), domain, secret_key)
}
/// Verify that proof-of-possession is valid.
///
/// Spec v0.5.1
pub fn validate_proof_of_possession(
&self,
epoch: Epoch,
fork: &Fork,
spec: &ChainSpec,
) -> bool {
let msg = self.signed_root();
let domain = spec.get_domain(epoch, Domain::Deposit, fork);
self.proof_of_possession.verify(&msg, domain, &self.pubkey)
}
}
#[cfg(test)]
mod tests {
use super::*;
ssz_tests!(DepositInput);
cached_tree_hash_tests!(DepositInput);
#[test]
fn can_create_and_validate() {
let spec = ChainSpec::foundation();
let fork = Fork::genesis(&spec);
let keypair = Keypair::random();
let epoch = Epoch::new(0);
let mut deposit_input = DepositInput {
pubkey: keypair.pk.clone(),
withdrawal_credentials: Hash256::zero(),
proof_of_possession: Signature::empty_signature(),
};
deposit_input.proof_of_possession =
deposit_input.create_proof_of_possession(&keypair.sk, epoch, &fork, &spec);
assert!(deposit_input.validate_proof_of_possession(epoch, &fork, &spec));
}
}

View File

@ -8,7 +8,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
/// Contains data obtained from the Eth1 chain.
///
/// Spec v0.5.1
/// Spec v0.6.0
#[derive(
Debug,
PartialEq,
@ -24,6 +24,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
)]
pub struct Eth1Data {
pub deposit_root: Hash256,
pub deposit_count: u64,
pub block_hash: Hash256,
}

View File

@ -1,36 +0,0 @@
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;
use tree_hash_derive::{CachedTreeHash, TreeHash};
/// A summation of votes for some `Eth1Data`.
///
/// Spec v0.5.1
#[derive(
Debug,
PartialEq,
Clone,
Default,
Serialize,
Deserialize,
Encode,
Decode,
TreeHash,
CachedTreeHash,
TestRandom,
)]
pub struct Eth1DataVote {
pub eth1_data: Eth1Data,
pub vote_count: u64,
}
#[cfg(test)]
mod tests {
use super::*;
ssz_tests!(Eth1DataVote);
cached_tree_hash_tests!(Eth1DataVote);
}

View File

@ -10,7 +10,7 @@ use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
///
/// To be included in an `AttesterSlashing`.
///
/// Spec v0.5.1
/// Spec v0.6.0
#[derive(
Debug,
PartialEq,
@ -24,27 +24,28 @@ use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
TestRandom,
SignedRoot,
)]
pub struct SlashableAttestation {
pub struct IndexedAttestation {
/// Lists validator registry indices, not committee indices.
pub validator_indices: Vec<u64>,
pub custody_bit_0_indices: Vec<u64>,
pub custody_bit_1_indices: Vec<u64>,
pub data: AttestationData,
pub custody_bitfield: Bitfield,
#[signed_root(skip_hashing)]
pub aggregate_signature: AggregateSignature,
pub signature: AggregateSignature,
}
impl SlashableAttestation {
impl IndexedAttestation {
/// Check if ``attestation_data_1`` and ``attestation_data_2`` have the same target.
///
/// Spec v0.5.1
pub fn is_double_vote(&self, other: &SlashableAttestation, spec: &ChainSpec) -> bool {
pub fn is_double_vote(&self, other: &IndexedAttestation, spec: &ChainSpec) -> bool {
self.data.slot.epoch(spec.slots_per_epoch) == other.data.slot.epoch(spec.slots_per_epoch)
}
/// Check if ``attestation_data_1`` surrounds ``attestation_data_2``.
///
/// Spec v0.5.1
pub fn is_surround_vote(&self, other: &SlashableAttestation, spec: &ChainSpec) -> bool {
pub fn is_surround_vote(&self, other: &IndexedAttestation, spec: &ChainSpec) -> bool {
let source_epoch_1 = self.data.source_epoch;
let source_epoch_2 = other.data.source_epoch;
let target_epoch_1 = self.data.slot.epoch(spec.slots_per_epoch);
@ -64,11 +65,11 @@ mod tests {
#[test]
pub fn test_is_double_vote_true() {
let spec = ChainSpec::foundation();
let slashable_vote_first = create_slashable_attestation(1, 1, &spec);
let slashable_vote_second = create_slashable_attestation(1, 1, &spec);
let indexed_vote_first = create_indexed_attestation(1, 1, &spec);
let indexed_vote_second = create_indexed_attestation(1, 1, &spec);
assert_eq!(
slashable_vote_first.is_double_vote(&slashable_vote_second, &spec),
indexed_vote_first.is_double_vote(&indexed_vote_second, &spec),
true
)
}
@ -76,11 +77,11 @@ mod tests {
#[test]
pub fn test_is_double_vote_false() {
let spec = ChainSpec::foundation();
let slashable_vote_first = create_slashable_attestation(1, 1, &spec);
let slashable_vote_second = create_slashable_attestation(2, 1, &spec);
let indexed_vote_first = create_indexed_attestation(1, 1, &spec);
let indexed_vote_second = create_indexed_attestation(2, 1, &spec);
assert_eq!(
slashable_vote_first.is_double_vote(&slashable_vote_second, &spec),
indexed_vote_first.is_double_vote(&indexed_vote_second, &spec),
false
);
}
@ -88,11 +89,11 @@ mod tests {
#[test]
pub fn test_is_surround_vote_true() {
let spec = ChainSpec::foundation();
let slashable_vote_first = create_slashable_attestation(2, 1, &spec);
let slashable_vote_second = create_slashable_attestation(1, 2, &spec);
let indexed_vote_first = create_indexed_attestation(2, 1, &spec);
let indexed_vote_second = create_indexed_attestation(1, 2, &spec);
assert_eq!(
slashable_vote_first.is_surround_vote(&slashable_vote_second, &spec),
indexed_vote_first.is_surround_vote(&indexed_vote_second, &spec),
true
);
}
@ -100,11 +101,11 @@ mod tests {
#[test]
pub fn test_is_surround_vote_true_realistic() {
let spec = ChainSpec::foundation();
let slashable_vote_first = create_slashable_attestation(4, 1, &spec);
let slashable_vote_second = create_slashable_attestation(3, 2, &spec);
let indexed_vote_first = create_indexed_attestation(4, 1, &spec);
let indexed_vote_second = create_indexed_attestation(3, 2, &spec);
assert_eq!(
slashable_vote_first.is_surround_vote(&slashable_vote_second, &spec),
indexed_vote_first.is_surround_vote(&indexed_vote_second, &spec),
true
);
}
@ -112,11 +113,11 @@ mod tests {
#[test]
pub fn test_is_surround_vote_false_source_epoch_fails() {
let spec = ChainSpec::foundation();
let slashable_vote_first = create_slashable_attestation(2, 2, &spec);
let slashable_vote_second = create_slashable_attestation(1, 1, &spec);
let indexed_vote_first = create_indexed_attestation(2, 2, &spec);
let indexed_vote_second = create_indexed_attestation(1, 1, &spec);
assert_eq!(
slashable_vote_first.is_surround_vote(&slashable_vote_second, &spec),
indexed_vote_first.is_surround_vote(&indexed_vote_second, &spec),
false
);
}
@ -124,28 +125,28 @@ mod tests {
#[test]
pub fn test_is_surround_vote_false_target_epoch_fails() {
let spec = ChainSpec::foundation();
let slashable_vote_first = create_slashable_attestation(1, 1, &spec);
let slashable_vote_second = create_slashable_attestation(2, 2, &spec);
let indexed_vote_first = create_indexed_attestation(1, 1, &spec);
let indexed_vote_second = create_indexed_attestation(2, 2, &spec);
assert_eq!(
slashable_vote_first.is_surround_vote(&slashable_vote_second, &spec),
indexed_vote_first.is_surround_vote(&indexed_vote_second, &spec),
false
);
}
ssz_tests!(SlashableAttestation);
cached_tree_hash_tests!(SlashableAttestation);
ssz_tests!(IndexedAttestation);
cached_tree_hash_tests!(IndexedAttestation);
fn create_slashable_attestation(
fn create_indexed_attestation(
slot_factor: u64,
source_epoch: u64,
spec: &ChainSpec,
) -> SlashableAttestation {
) -> IndexedAttestation {
let mut rng = XorShiftRng::from_seed([42; 16]);
let mut slashable_vote = SlashableAttestation::random_for_test(&mut rng);
let mut indexed_vote = IndexedAttestation::random_for_test(&mut rng);
slashable_vote.data.slot = Slot::new(slot_factor * spec.slots_per_epoch);
slashable_vote.data.source_epoch = Epoch::new(source_epoch);
slashable_vote
indexed_vote.data.slot = Slot::new(slot_factor * spec.slots_per_epoch);
indexed_vote.data.source_epoch = Epoch::new(source_epoch);
indexed_vote
}
}

View File

@ -17,15 +17,13 @@ pub mod crosslink;
pub mod crosslink_committee;
pub mod deposit;
pub mod deposit_data;
pub mod deposit_input;
pub mod eth1_data;
pub mod eth1_data_vote;
pub mod fork;
pub mod free_attestation;
pub mod historical_batch;
pub mod indexed_attestation;
pub mod pending_attestation;
pub mod proposer_slashing;
pub mod slashable_attestation;
pub mod transfer;
pub mod tree_hash_vector;
pub mod voluntary_exit;
@ -53,16 +51,14 @@ pub use crate::crosslink::Crosslink;
pub use crate::crosslink_committee::CrosslinkCommittee;
pub use crate::deposit::Deposit;
pub use crate::deposit_data::DepositData;
pub use crate::deposit_input::DepositInput;
pub use crate::eth1_data::Eth1Data;
pub use crate::eth1_data_vote::Eth1DataVote;
pub use crate::fork::Fork;
pub use crate::free_attestation::FreeAttestation;
pub use crate::historical_batch::HistoricalBatch;
pub use crate::indexed_attestation::IndexedAttestation;
pub use crate::pending_attestation::PendingAttestation;
pub use crate::proposer_slashing::ProposerSlashing;
pub use crate::relative_epoch::{Error as RelativeEpochError, RelativeEpoch};
pub use crate::slashable_attestation::SlashableAttestation;
pub use crate::slot_epoch::{Epoch, Slot};
pub use crate::slot_height::SlotHeight;
pub use crate::transfer::Transfer;

View File

@ -8,7 +8,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
/// An attestation that has been included in the state but not yet fully processed.
///
/// Spec v0.5.1
/// Spec v0.6.0
#[derive(
Debug,
Clone,
@ -24,18 +24,22 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
pub struct PendingAttestation {
pub aggregation_bitfield: Bitfield,
pub data: AttestationData,
pub custody_bitfield: Bitfield,
pub inclusion_slot: Slot,
pub proposer_index: u64,
}
impl PendingAttestation {
/// Create a `PendingAttestation` from an `Attestation`, at the given `inclusion_slot`.
pub fn from_attestation(attestation: &Attestation, inclusion_slot: Slot) -> Self {
/// Create a `PendingAttestation` from an `Attestation`.
pub fn from_attestation(
attestation: &Attestation,
inclusion_slot: Slot,
proposer_index: u64,
) -> Self {
PendingAttestation {
data: attestation.data.clone(),
aggregation_bitfield: attestation.aggregation_bitfield.clone(),
custody_bitfield: attestation.custody_bitfield.clone(),
inclusion_slot,
proposer_index,
}
}
}

View File

@ -33,7 +33,7 @@ impl TestingAttestationBuilder {
aggregation_bitfield,
data: data_builder.build(),
custody_bitfield,
aggregate_signature: AggregateSignature::new(),
signature: AggregateSignature::new(),
};
Self {
@ -83,7 +83,7 @@ impl TestingAttestationBuilder {
);
let signature = Signature::new(&message, domain, secret_keys[key_index]);
self.attestation.aggregate_signature.add(&signature)
self.attestation.signature.add(&signature)
}
}

View File

@ -49,8 +49,9 @@ impl TestingAttestationDataBuilder {
// Crosslink vote
shard,
previous_crosslink: Crosslink {
previous_crosslink_root: Crosslink {
epoch: slot.epoch(spec.slots_per_epoch),
previous_crosslink_root: spec.zero_hash,
crosslink_data_root: spec.zero_hash,
},
crosslink_data_root: spec.zero_hash,

View File

@ -34,8 +34,9 @@ impl TestingAttesterSlashingBuilder {
source_root: hash_1,
target_root: hash_1,
shard,
previous_crosslink: Crosslink {
previous_crosslink_root: Crosslink {
epoch,
previous_crosslink_root: hash_1,
crosslink_data_root: hash_1,
},
crosslink_data_root: hash_1,
@ -46,21 +47,23 @@ impl TestingAttesterSlashingBuilder {
..data_1.clone()
};
let mut slashable_attestation_1 = SlashableAttestation {
validator_indices: validator_indices.to_vec(),
let mut attestation_1 = IndexedAttestation {
custody_bit_0_indices: validator_indices.to_vec(),
custody_bit_1_indices: vec![],
data: data_1,
custody_bitfield: Bitfield::new(),
aggregate_signature: AggregateSignature::new(),
signature: AggregateSignature::new(),
};
let mut slashable_attestation_2 = SlashableAttestation {
validator_indices: validator_indices.to_vec(),
let mut attestation_2 = IndexedAttestation {
custody_bit_0_indices: validator_indices.to_vec(),
custody_bit_1_indices: vec![],
data: data_2,
custody_bitfield: Bitfield::new(),
aggregate_signature: AggregateSignature::new(),
signature: AggregateSignature::new(),
};
let add_signatures = |attestation: &mut SlashableAttestation| {
let add_signatures = |attestation: &mut IndexedAttestation| {
// All validators sign with a `false` custody bit.
let attestation_data_and_custody_bit = AttestationDataAndCustodyBit {
data: attestation.data.clone(),
@ -71,16 +74,16 @@ impl TestingAttesterSlashingBuilder {
for (i, validator_index) in validator_indices.iter().enumerate() {
attestation.custody_bitfield.set(i, false);
let signature = signer(*validator_index, &message[..], epoch, Domain::Attestation);
attestation.aggregate_signature.add(&signature);
attestation.signature.add(&signature);
}
};
add_signatures(&mut slashable_attestation_1);
add_signatures(&mut slashable_attestation_2);
add_signatures(&mut attestation_1);
add_signatures(&mut attestation_2);
AttesterSlashing {
slashable_attestation_1,
slashable_attestation_2,
attestation_1,
attestation_2,
}
}
}

View File

@ -95,6 +95,7 @@ impl TestingBeaconStateBuilder {
/// Creates the builder from an existing set of keypairs.
pub fn from_keypairs(keypairs: Vec<Keypair>, spec: &ChainSpec) -> Self {
let validator_count = keypairs.len();
let starting_balance = 32_000_000_000;
debug!(
"Building {} Validator objects from keypairs...",
@ -112,11 +113,12 @@ impl TestingBeaconStateBuilder {
pubkey: keypair.pk.clone(),
withdrawal_credentials,
// All validators start active.
activation_eligibility_epoch: spec.genesis_epoch,
activation_epoch: spec.genesis_epoch,
exit_epoch: spec.far_future_epoch,
withdrawable_epoch: spec.far_future_epoch,
initiated_exit: false,
slashed: false,
effective_balance: starting_balance,
}
})
.collect();
@ -137,16 +139,17 @@ impl TestingBeaconStateBuilder {
genesis_time,
Eth1Data {
deposit_root: Hash256::zero(),
deposit_count: 0,
block_hash: Hash256::zero(),
},
spec,
);
let balances = vec![32_000_000_000; validator_count];
let balances = vec![starting_balance; validator_count];
debug!("Importing {} existing validators...", validator_count);
state.validator_registry = validators;
state.validator_balances = balances;
state.balances = balances;
debug!("BeaconState initialized.");
@ -192,18 +195,13 @@ impl TestingBeaconStateBuilder {
state.slot = slot;
state.previous_shuffling_epoch = epoch - 1;
state.current_shuffling_epoch = epoch;
state.previous_shuffling_seed = Hash256::from_low_u64_le(0);
state.current_shuffling_seed = Hash256::from_low_u64_le(1);
// FIXME(sproul): update latest_start_shard?
state.previous_justified_epoch = epoch - 3;
state.current_justified_epoch = epoch - 2;
state.justification_bitfield = u64::max_value();
state.finalized_epoch = epoch - 3;
state.validator_registry_update_epoch = epoch - 3;
}
/// Creates a full set of attestations for the `BeaconState`. Each attestation has full

View File

@ -14,14 +14,11 @@ impl TestingDepositBuilder {
let deposit = Deposit {
proof: vec![].into(),
index: 0,
deposit_data: DepositData {
amount,
timestamp: 1,
deposit_input: DepositInput {
data: DepositData {
pubkey,
withdrawal_credentials: Hash256::zero(),
proof_of_possession: Signature::empty_signature(),
},
amount,
signature: Signature::empty_signature(),
},
};
@ -43,17 +40,13 @@ impl TestingDepositBuilder {
&get_withdrawal_credentials(&keypair.pk, spec.bls_withdrawal_prefix_byte)[..],
);
self.deposit.deposit_data.deposit_input.pubkey = keypair.pk.clone();
self.deposit
.deposit_data
.deposit_input
.withdrawal_credentials = withdrawal_credentials;
self.deposit.data.pubkey = keypair.pk.clone();
self.deposit.data.withdrawal_credentials = withdrawal_credentials;
self.deposit.deposit_data.deposit_input.proof_of_possession = self
.deposit
.deposit_data
.deposit_input
.create_proof_of_possession(&keypair.sk, epoch, fork, spec);
self.deposit.data.signature =
self.deposit
.data
.create_signature(&keypair.sk, epoch, fork, spec);
}
/// Builds the deposit, consuming the builder.

View File

@ -22,8 +22,9 @@ impl TestingPendingAttestationBuilder {
let pending_attestation = PendingAttestation {
aggregation_bitfield: Bitfield::new(),
data: data_builder.build(),
custody_bitfield: Bitfield::new(),
inclusion_slot: slot + spec.min_attestation_inclusion_delay,
// FIXME(sproul)
proposer_index: 0,
};
Self {
@ -37,15 +38,12 @@ impl TestingPendingAttestationBuilder {
/// `signers` is true.
pub fn add_committee_participation(&mut self, signers: Vec<bool>) {
let mut aggregation_bitfield = Bitfield::new();
let mut custody_bitfield = Bitfield::new();
for (i, signed) in signers.iter().enumerate() {
aggregation_bitfield.set(i, *signed);
custody_bitfield.set(i, false); // Fixed to `false` for phase 0.
}
self.pending_attestation.aggregation_bitfield = aggregation_bitfield;
self.pending_attestation.custody_bitfield = custody_bitfield;
}
/// Returns the `PendingAttestation`, consuming the builder.

View File

@ -7,7 +7,7 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
/// Information about a `BeaconChain` validator.
///
/// Spec v0.5.1
/// Spec v0.6.0
#[derive(
Debug,
Clone,
@ -23,11 +23,12 @@ use tree_hash_derive::{CachedTreeHash, TreeHash};
pub struct Validator {
pub pubkey: PublicKey,
pub withdrawal_credentials: Hash256,
pub activation_eligibility_epoch: Epoch,
pub activation_epoch: Epoch,
pub exit_epoch: Epoch,
pub withdrawable_epoch: Epoch,
pub initiated_exit: bool,
pub slashed: bool,
pub effective_balance: u64,
}
impl Validator {
@ -53,11 +54,12 @@ impl Default for Validator {
Self {
pubkey: PublicKey::default(),
withdrawal_credentials: Hash256::default(),
activation_eligibility_epoch: Epoch::from(std::u64::MAX),
activation_epoch: Epoch::from(std::u64::MAX),
exit_epoch: Epoch::from(std::u64::MAX),
withdrawable_epoch: Epoch::from(std::u64::MAX),
initiated_exit: false,
slashed: false,
effective_balance: std::u64::MAX,
}
}
}