diff --git a/beacon_node/beacon_chain/test_harness/src/bin.rs b/beacon_node/beacon_chain/test_harness/src/bin.rs index 216e03d9f4..fa5aa45a25 100644 --- a/beacon_node/beacon_chain/test_harness/src/bin.rs +++ b/beacon_node/beacon_chain/test_harness/src/bin.rs @@ -7,6 +7,7 @@ use env_logger::{Builder, Env}; use log::{info, warn}; use ssz::TreeHash; use std::{fs::File, io::prelude::*}; +use types::attester_slashing::AttesterSlashingBuilder; use types::*; use yaml_rust::{Yaml, YamlLoader}; @@ -195,82 +196,17 @@ fn build_double_vote_attester_slashing( harness: &BeaconChainHarness, validator_indices: &[u64], ) -> AttesterSlashing { - let double_voted_slot = Slot::new(0); - let shard = 0; - let justified_epoch = Epoch::new(0); - let epoch = Epoch::new(0); - let hash_1 = Hash256::from("1".as_bytes()); - let hash_2 = Hash256::from("2".as_bytes()); - - let mut slashable_attestation_1 = SlashableAttestation { - validator_indices: validator_indices.to_vec(), - data: AttestationData { - slot: double_voted_slot, - shard, - beacon_block_root: hash_1, - epoch_boundary_root: hash_1, - shard_block_root: hash_1, - latest_crosslink: Crosslink { - epoch, - shard_block_root: hash_1, - }, - justified_epoch, - justified_block_root: hash_1, - }, - custody_bitfield: Bitfield::new(), - aggregate_signature: AggregateSignature::new(), + let signer = |validator_index: u64, message: &[u8], epoch: Epoch, domain: u64| { + harness + .validator_sign(validator_index as usize, message, epoch, domain) + .expect("Unable to sign AttesterSlashing") }; - let mut slashable_attestation_2 = SlashableAttestation { - validator_indices: validator_indices.to_vec(), - data: AttestationData { - slot: double_voted_slot, - shard, - beacon_block_root: hash_2, - epoch_boundary_root: hash_2, - shard_block_root: hash_2, - latest_crosslink: Crosslink { - epoch, - shard_block_root: hash_2, - }, - justified_epoch, - justified_block_root: hash_2, - }, - custody_bitfield: Bitfield::new(), - aggregate_signature: AggregateSignature::new(), - }; - - let add_signatures = |attestation: &mut SlashableAttestation| { - for (i, validator_index) in validator_indices.iter().enumerate() { - let attestation_data_and_custody_bit = AttestationDataAndCustodyBit { - data: attestation.data.clone(), - custody_bit: attestation.custody_bitfield.get(i).unwrap(), - }; - let message = attestation_data_and_custody_bit.hash_tree_root(); - let signature = harness - .validator_sign( - *validator_index as usize, - &message[..], - epoch, - harness.spec.domain_attestation, - ) - .expect("Unable to sign attestation with unknown validator index."); - attestation.aggregate_signature.add(&signature); - } - }; - - add_signatures(&mut slashable_attestation_1); - add_signatures(&mut slashable_attestation_2); - - AttesterSlashing { - slashable_attestation_1, - slashable_attestation_2, - } + AttesterSlashingBuilder::double_vote(validator_indices, signer, &harness.spec) } pub type DepositTuple = (u64, Deposit, Keypair); pub type ProposerSlashingTuple = (u64, ProposerSlashing); -// (slot, validator_indices) pub type AttesterSlashingTuple = (u64, Vec); struct ExecutionResult { diff --git a/eth2/types/src/attester_slashing.rs b/eth2/types/src/attester_slashing.rs index 9cb2123249..ac75a25626 100644 --- a/eth2/types/src/attester_slashing.rs +++ b/eth2/types/src/attester_slashing.rs @@ -1,9 +1,13 @@ -use crate::{test_utils::TestRandom, ChainSpec, SlashableAttestation}; +use crate::{test_utils::TestRandom, SlashableAttestation}; use rand::RngCore; use serde_derive::Serialize; use ssz_derive::{Decode, Encode, TreeHash}; use test_random_derive::TestRandom; +mod builder; + +pub use builder::AttesterSlashingBuilder; + #[derive(Debug, PartialEq, Clone, Serialize, Encode, Decode, TreeHash, TestRandom)] pub struct AttesterSlashing { pub slashable_attestation_1: SlashableAttestation, diff --git a/eth2/types/src/attester_slashing/builder.rs b/eth2/types/src/attester_slashing/builder.rs new file mode 100644 index 0000000000..d382cb64c2 --- /dev/null +++ b/eth2/types/src/attester_slashing/builder.rs @@ -0,0 +1,85 @@ +use crate::*; +use ssz::TreeHash; + +pub struct AttesterSlashingBuilder(); + +impl AttesterSlashingBuilder { + pub fn double_vote( + validator_indices: &[u64], + signer: F, + spec: &ChainSpec, + ) -> AttesterSlashing + where + F: Fn(u64, &[u8], Epoch, u64) -> Signature, + { + let double_voted_slot = Slot::new(0); + let shard = 0; + let justified_epoch = Epoch::new(0); + let epoch = Epoch::new(0); + let hash_1 = Hash256::from("1".as_bytes()); + let hash_2 = Hash256::from("2".as_bytes()); + + let mut slashable_attestation_1 = SlashableAttestation { + validator_indices: validator_indices.to_vec(), + data: AttestationData { + slot: double_voted_slot, + shard, + beacon_block_root: hash_1, + epoch_boundary_root: hash_1, + shard_block_root: hash_1, + latest_crosslink: Crosslink { + epoch, + shard_block_root: hash_1, + }, + justified_epoch, + justified_block_root: hash_1, + }, + custody_bitfield: Bitfield::new(), + aggregate_signature: AggregateSignature::new(), + }; + + let mut slashable_attestation_2 = SlashableAttestation { + validator_indices: validator_indices.to_vec(), + data: AttestationData { + slot: double_voted_slot, + shard, + beacon_block_root: hash_2, + epoch_boundary_root: hash_2, + shard_block_root: hash_2, + latest_crosslink: Crosslink { + epoch, + shard_block_root: hash_2, + }, + justified_epoch, + justified_block_root: hash_2, + }, + custody_bitfield: Bitfield::new(), + aggregate_signature: AggregateSignature::new(), + }; + + let add_signatures = |attestation: &mut SlashableAttestation| { + for (i, validator_index) in validator_indices.iter().enumerate() { + let attestation_data_and_custody_bit = AttestationDataAndCustodyBit { + data: attestation.data.clone(), + custody_bit: attestation.custody_bitfield.get(i).unwrap(), + }; + let message = attestation_data_and_custody_bit.hash_tree_root(); + let signature = signer( + *validator_index, + &message[..], + epoch, + spec.domain_attestation, + ); + attestation.aggregate_signature.add(&signature); + } + }; + + add_signatures(&mut slashable_attestation_1); + add_signatures(&mut slashable_attestation_2); + + AttesterSlashing { + slashable_attestation_1, + slashable_attestation_2, + } + } +}