From 6f039e6e6a0a38640b39d7f987c9d4fca499ca4c Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Sun, 23 Dec 2018 23:41:22 +1100 Subject: [PATCH] Add ssz enc/dec for beacon block --- beacon_chain/types/Cargo.toml | 3 +- beacon_chain/types/src/attestation.rs | 49 +++++++++---------- beacon_chain/types/src/attestation_data.rs | 38 ++++++++------ beacon_chain/types/src/beacon_block.rs | 35 +++++++++++++ beacon_chain/types/src/beacon_block_body.rs | 45 ++++++++++++++--- beacon_chain/types/src/casper_slashing.rs | 32 +++++++++++- beacon_chain/types/src/deposit.rs | 43 +++++++--------- beacon_chain/types/src/deposit_data.rs | 32 ++++++------ beacon_chain/types/src/deposit_input.rs | 28 +++++++---- beacon_chain/types/src/exit.rs | 33 +++++++------ beacon_chain/types/src/lib.rs | 48 +++++++++--------- .../types/src/proposal_signed_data.rs | 23 ++++++--- beacon_chain/types/src/proposer_slashing.rs | 39 +++++++-------- .../types/src/random/aggregate_signature.rs | 12 +++++ beacon_chain/types/src/random/bitfield.rs | 11 +++++ beacon_chain/types/src/random/hash256.rs | 11 +++++ beacon_chain/types/src/random/mod.rs | 38 ++++++++++++++ beacon_chain/types/src/random/public_key.rs | 10 ++++ beacon_chain/types/src/random/secret_key.rs | 19 +++++++ beacon_chain/types/src/random/signature.rs | 13 +++++ beacon_chain/types/src/slashable_vote_data.rs | 41 ++++++++-------- 21 files changed, 422 insertions(+), 181 deletions(-) create mode 100644 beacon_chain/types/src/random/aggregate_signature.rs create mode 100644 beacon_chain/types/src/random/bitfield.rs create mode 100644 beacon_chain/types/src/random/hash256.rs create mode 100644 beacon_chain/types/src/random/mod.rs create mode 100644 beacon_chain/types/src/random/public_key.rs create mode 100644 beacon_chain/types/src/random/secret_key.rs create mode 100644 beacon_chain/types/src/random/signature.rs diff --git a/beacon_chain/types/Cargo.toml b/beacon_chain/types/Cargo.toml index cf20f69c0..f49702280 100644 --- a/beacon_chain/types/Cargo.toml +++ b/beacon_chain/types/Cargo.toml @@ -2,10 +2,11 @@ name = "types" version = "0.1.0" authors = ["Paul Hauner "] +edition = "2018" [dependencies] bls = { path = "../utils/bls" } boolean-bitfield = { path = "../utils/boolean-bitfield" } ethereum-types = "0.4.0" -rand = "0.3" +rand = "0.5.5" ssz = { path = "../utils/ssz" } diff --git a/beacon_chain/types/src/attestation.rs b/beacon_chain/types/src/attestation.rs index 40ee2173c..6e7c54d44 100644 --- a/beacon_chain/types/src/attestation.rs +++ b/beacon_chain/types/src/attestation.rs @@ -1,14 +1,8 @@ -use super::attestation_data::SSZ_ATTESTION_DATA_LENGTH; -use super::bls::{AggregateSignature, BLS_AGG_SIG_BYTE_SIZE}; -use super::ssz::{Decodable, DecodeError, Encodable, SszStream, LENGTH_BYTES}; +use super::bls::AggregateSignature; +use super::ssz::{Decodable, DecodeError, Encodable, SszStream}; use super::{AttestationData, Bitfield}; - -pub const MIN_SSZ_ATTESTION_RECORD_LENGTH: usize = { - SSZ_ATTESTION_DATA_LENGTH + // data - 5 + // participation_bitfield (assuming 1 byte of bitfield) - 5 + // custody_bitfield (assuming 1 byte of bitfield) - LENGTH_BYTES + BLS_AGG_SIG_BYTE_SIZE // aggregate sig -}; +use crate::random::TestRandom; +use rand::RngCore; #[derive(Debug, Clone, PartialEq)] pub struct Attestation { @@ -55,30 +49,31 @@ impl Attestation { } } +impl TestRandom for Attestation { + fn random_for_test(rng: &mut T) -> Self { + Self { + data: <_>::random_for_test(rng), + participation_bitfield: <_>::random_for_test(rng), + custody_bitfield: <_>::random_for_test(rng), + aggregate_sig: <_>::random_for_test(rng), + } + } +} + #[cfg(test)] mod tests { use super::super::ssz::ssz_encode; use super::*; + use crate::random::TestRandom; + use rand::{prng::XorShiftRng, SeedableRng}; #[test] - pub fn test_attestation_record_min_ssz_length() { - let ar = Attestation::zero(); - let ssz = ssz_encode(&ar); + pub fn test_ssz_round_trip() { + let mut rng = XorShiftRng::from_seed([42; 16]); + let original = Attestation::random_for_test(&mut rng); - assert_eq!(ssz.len(), MIN_SSZ_ATTESTION_RECORD_LENGTH); - } - - #[test] - pub fn test_attestation_record_ssz_round_trip() { - let original = Attestation { - data: AttestationData::zero(), - participation_bitfield: Bitfield::from_bytes(&vec![17; 42][..]), - custody_bitfield: Bitfield::from_bytes(&vec![18; 12][..]), - aggregate_sig: AggregateSignature::new(), - }; - - let ssz = ssz_encode(&original); - let (decoded, _) = Attestation::ssz_decode(&ssz, 0).unwrap(); + let bytes = ssz_encode(&original); + let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap(); assert_eq!(original, decoded); } diff --git a/beacon_chain/types/src/attestation_data.rs b/beacon_chain/types/src/attestation_data.rs index d75c43b9d..57fcaa430 100644 --- a/beacon_chain/types/src/attestation_data.rs +++ b/beacon_chain/types/src/attestation_data.rs @@ -1,5 +1,7 @@ use super::ssz::{Decodable, DecodeError, Encodable, SszStream}; use super::Hash256; +use crate::random::TestRandom; +use rand::RngCore; pub const SSZ_ATTESTION_DATA_LENGTH: usize = { 8 + // slot @@ -83,27 +85,35 @@ impl Decodable for AttestationData { } } +impl TestRandom for AttestationData { + fn random_for_test(rng: &mut T) -> Self { + Self { + slot: <_>::random_for_test(rng), + shard: <_>::random_for_test(rng), + beacon_block_hash: <_>::random_for_test(rng), + epoch_boundary_hash: <_>::random_for_test(rng), + shard_block_hash: <_>::random_for_test(rng), + latest_crosslink_hash: <_>::random_for_test(rng), + justified_slot: <_>::random_for_test(rng), + justified_block_hash: <_>::random_for_test(rng), + } + } +} + #[cfg(test)] mod tests { use super::super::ssz::ssz_encode; use super::*; + use crate::random::TestRandom; + use rand::{prng::XorShiftRng, SeedableRng}; #[test] - pub fn test_attestation_record_ssz_round_trip() { - let original = AttestationData { - slot: 42, - shard: 16, - beacon_block_hash: Hash256::from("beacon".as_bytes()), - epoch_boundary_hash: Hash256::from("epoch".as_bytes()), - shard_block_hash: Hash256::from("shard".as_bytes()), - latest_crosslink_hash: Hash256::from("xlink".as_bytes()), - justified_slot: 8, - justified_block_hash: Hash256::from("justified".as_bytes()), - }; + pub fn test_ssz_round_trip() { + let mut rng = XorShiftRng::from_seed([42; 16]); + let original = AttestationData::random_for_test(&mut rng); - let ssz = ssz_encode(&original); - - let (decoded, _) = AttestationData::ssz_decode(&ssz, 0).unwrap(); + let bytes = ssz_encode(&original); + let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap(); assert_eq!(original, decoded); } diff --git a/beacon_chain/types/src/beacon_block.rs b/beacon_chain/types/src/beacon_block.rs index b2641cf84..8bbc91592 100644 --- a/beacon_chain/types/src/beacon_block.rs +++ b/beacon_chain/types/src/beacon_block.rs @@ -1,6 +1,8 @@ use super::ssz::{Decodable, DecodeError, Encodable, SszStream}; use super::{BeaconBlockBody, Hash256}; +use crate::random::TestRandom; use bls::AggregateSignature; +use rand::RngCore; #[derive(Debug, PartialEq, Clone, Default)] pub struct BeaconBlock { @@ -49,3 +51,36 @@ impl Decodable for BeaconBlock { )) } } + +impl TestRandom for BeaconBlock { + fn random_for_test(rng: &mut T) -> Self { + Self { + slot: <_>::random_for_test(rng), + parent_root: <_>::random_for_test(rng), + state_root: <_>::random_for_test(rng), + randao_reveal: <_>::random_for_test(rng), + candidate_pow_receipt_root: <_>::random_for_test(rng), + signature: <_>::random_for_test(rng), + body: <_>::random_for_test(rng), + } + } +} + +#[cfg(test)] +mod tests { + use super::super::ssz::ssz_encode; + use super::*; + use crate::random::TestRandom; + use rand::{prng::XorShiftRng, SeedableRng}; + + #[test] + pub fn test_ssz_round_trip() { + let mut rng = XorShiftRng::from_seed([42; 16]); + let original = BeaconBlock::random_for_test(&mut rng); + + let bytes = ssz_encode(&original); + let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap(); + + assert_eq!(original, decoded); + } +} diff --git a/beacon_chain/types/src/beacon_block_body.rs b/beacon_chain/types/src/beacon_block_body.rs index f0c767155..e49ca35bc 100644 --- a/beacon_chain/types/src/beacon_block_body.rs +++ b/beacon_chain/types/src/beacon_block_body.rs @@ -1,5 +1,7 @@ -use super::ssz::{decode_ssz_list, Decodable, DecodeError, Encodable, SszStream}; +use super::ssz::{Decodable, DecodeError, Encodable, SszStream}; use super::{Attestation, CasperSlashing, Deposit, Exit, ProposerSlashing}; +use crate::random::TestRandom; +use rand::RngCore; #[derive(Debug, PartialEq, Clone, Default)] pub struct BeaconBlockBody { @@ -22,11 +24,11 @@ impl Encodable for BeaconBlockBody { impl Decodable for BeaconBlockBody { fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { - let (proposer_slashings, i) = decode_ssz_list(bytes, i)?; - let (casper_slashings, i) = decode_ssz_list(bytes, i)?; - let (attestations, i) = decode_ssz_list(bytes, i)?; - let (deposits, i) = decode_ssz_list(bytes, i)?; - let (exits, i) = decode_ssz_list(bytes, i)?; + let (proposer_slashings, i) = <_>::ssz_decode(bytes, i)?; + let (casper_slashings, i) = <_>::ssz_decode(bytes, i)?; + let (attestations, i) = <_>::ssz_decode(bytes, i)?; + let (deposits, i) = <_>::ssz_decode(bytes, i)?; + let (exits, i) = <_>::ssz_decode(bytes, i)?; Ok(( Self { @@ -40,3 +42,34 @@ impl Decodable for BeaconBlockBody { )) } } + +impl TestRandom for BeaconBlockBody { + fn random_for_test(rng: &mut T) -> Self { + Self { + proposer_slashings: <_>::random_for_test(rng), + casper_slashings: <_>::random_for_test(rng), + attestations: <_>::random_for_test(rng), + deposits: <_>::random_for_test(rng), + exits: <_>::random_for_test(rng), + } + } +} + +#[cfg(test)] +mod tests { + use super::super::ssz::ssz_encode; + use super::*; + use crate::random::TestRandom; + use rand::{prng::XorShiftRng, SeedableRng}; + + #[test] + pub fn test_ssz_round_trip() { + let mut rng = XorShiftRng::from_seed([42; 16]); + let original = BeaconBlockBody::random_for_test(&mut rng); + + let bytes = ssz_encode(&original); + let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap(); + + assert_eq!(original, decoded); + } +} diff --git a/beacon_chain/types/src/casper_slashing.rs b/beacon_chain/types/src/casper_slashing.rs index dfa99cd6b..29fc620fc 100644 --- a/beacon_chain/types/src/casper_slashing.rs +++ b/beacon_chain/types/src/casper_slashing.rs @@ -1,5 +1,7 @@ use super::ssz::{Decodable, DecodeError, Encodable, SszStream}; use super::SlashableVoteData; +use crate::random::TestRandom; +use rand::RngCore; #[derive(Debug, PartialEq, Clone, Default)] pub struct CasperSlashing { @@ -10,7 +12,7 @@ pub struct CasperSlashing { impl Encodable for CasperSlashing { fn ssz_append(&self, s: &mut SszStream) { s.append(&self.slashable_vote_data_1); - s.append(&self.slashable_vote_data_1); + s.append(&self.slashable_vote_data_2); } } @@ -28,3 +30,31 @@ impl Decodable for CasperSlashing { )) } } + +impl TestRandom for CasperSlashing { + fn random_for_test(rng: &mut T) -> Self { + Self { + slashable_vote_data_1: <_>::random_for_test(rng), + slashable_vote_data_2: <_>::random_for_test(rng), + } + } +} + +#[cfg(test)] +mod tests { + use super::super::ssz::ssz_encode; + use super::*; + use crate::random::TestRandom; + use rand::{prng::XorShiftRng, SeedableRng}; + + #[test] + pub fn test_ssz_round_trip() { + let mut rng = XorShiftRng::from_seed([42; 16]); + let original = CasperSlashing::random_for_test(&mut rng); + + let bytes = ssz_encode(&original); + let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap(); + + assert_eq!(original, decoded); + } +} diff --git a/beacon_chain/types/src/deposit.rs b/beacon_chain/types/src/deposit.rs index 7aa375828..2b0025fa4 100644 --- a/beacon_chain/types/src/deposit.rs +++ b/beacon_chain/types/src/deposit.rs @@ -1,5 +1,7 @@ -use super::ssz::{decode_ssz_list, Decodable, DecodeError, Encodable, SszStream}; +use super::ssz::{Decodable, DecodeError, Encodable, SszStream}; use super::{DepositData, Hash256}; +use crate::random::TestRandom; +use rand::RngCore; #[derive(Debug, PartialEq, Clone)] pub struct Deposit { @@ -18,7 +20,7 @@ impl Encodable for Deposit { impl Decodable for Deposit { fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { - let (merkle_branch, i) = decode_ssz_list(bytes, i)?; + let (merkle_branch, i) = <_>::ssz_decode(bytes, i)?; let (merkle_tree_index, i) = <_>::ssz_decode(bytes, i)?; let (deposit_data, i) = <_>::ssz_decode(bytes, i)?; @@ -33,37 +35,30 @@ impl Decodable for Deposit { } } +impl TestRandom for Deposit { + fn random_for_test(rng: &mut T) -> Self { + Self { + merkle_branch: <_>::random_for_test(rng), + merkle_tree_index: <_>::random_for_test(rng), + deposit_data: <_>::random_for_test(rng), + } + } +} + #[cfg(test)] mod tests { use super::super::ssz::ssz_encode; - use super::super::{DepositInput, Hash256}; use super::*; - use bls::{Keypair, Signature}; + use crate::random::TestRandom; + use rand::{prng::XorShiftRng, SeedableRng}; #[test] pub fn test_ssz_round_trip() { - let keypair = Keypair::random(); - - let original = Deposit { - merkle_branch: vec![ - Hash256::from("one".as_bytes()), - Hash256::from("two".as_bytes()), - ], - merkle_tree_index: 19, - deposit_data: DepositData { - deposit_input: DepositInput { - pubkey: keypair.pk, - withdrawal_credentials: Hash256::from("cats".as_bytes()), - randao_commitment: Hash256::from("dogs".as_bytes()), - proof_of_possession: Signature::new(&[42, 42], &keypair.sk), - }, - value: 12, - timestamp: 100, - }, - }; + let mut rng = XorShiftRng::from_seed([42; 16]); + let original = Deposit::random_for_test(&mut rng); let bytes = ssz_encode(&original); - let (decoded, _) = Deposit::ssz_decode(&bytes, 0).unwrap(); + let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap(); assert_eq!(original, decoded); } diff --git a/beacon_chain/types/src/deposit_data.rs b/beacon_chain/types/src/deposit_data.rs index 790beab28..a01a95cba 100644 --- a/beacon_chain/types/src/deposit_data.rs +++ b/beacon_chain/types/src/deposit_data.rs @@ -1,5 +1,7 @@ use super::ssz::{Decodable, DecodeError, Encodable, SszStream}; use super::DepositInput; +use crate::random::TestRandom; +use rand::RngCore; #[derive(Debug, PartialEq, Clone)] pub struct DepositData { @@ -33,30 +35,30 @@ impl Decodable for DepositData { } } +impl TestRandom for DepositData { + fn random_for_test(rng: &mut T) -> Self { + Self { + deposit_input: <_>::random_for_test(rng), + value: <_>::random_for_test(rng), + timestamp: <_>::random_for_test(rng), + } + } +} + #[cfg(test)] mod tests { use super::super::ssz::ssz_encode; - use super::super::Hash256; use super::*; - use bls::{Keypair, Signature}; + use crate::random::TestRandom; + use rand::{prng::XorShiftRng, SeedableRng}; #[test] pub fn test_ssz_round_trip() { - let keypair = Keypair::random(); - - let original = DepositData { - deposit_input: DepositInput { - pubkey: keypair.pk, - withdrawal_credentials: Hash256::from("cats".as_bytes()), - randao_commitment: Hash256::from("dogs".as_bytes()), - proof_of_possession: Signature::new(&[42, 42], &keypair.sk), - }, - value: 12, - timestamp: 100, - }; + let mut rng = XorShiftRng::from_seed([42; 16]); + let original = DepositData::random_for_test(&mut rng); let bytes = ssz_encode(&original); - let (decoded, _) = DepositData::ssz_decode(&bytes, 0).unwrap(); + let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap(); assert_eq!(original, decoded); } diff --git a/beacon_chain/types/src/deposit_input.rs b/beacon_chain/types/src/deposit_input.rs index d9b3e9864..c57437e86 100644 --- a/beacon_chain/types/src/deposit_input.rs +++ b/beacon_chain/types/src/deposit_input.rs @@ -1,6 +1,8 @@ use super::ssz::{decode_ssz_list, Decodable, DecodeError, Encodable, SszStream}; use super::Hash256; +use crate::random::TestRandom; use bls::{PublicKey, Signature}; +use rand::RngCore; #[derive(Debug, PartialEq, Clone)] pub struct DepositInput { @@ -39,25 +41,31 @@ impl Decodable for DepositInput { } } +impl TestRandom for DepositInput { + fn random_for_test(rng: &mut T) -> Self { + Self { + pubkey: <_>::random_for_test(rng), + withdrawal_credentials: <_>::random_for_test(rng), + randao_commitment: <_>::random_for_test(rng), + proof_of_possession: <_>::random_for_test(rng), + } + } +} + #[cfg(test)] mod tests { use super::super::ssz::ssz_encode; use super::*; - use bls::{Keypair, Signature}; + use crate::random::TestRandom; + use rand::{prng::XorShiftRng, SeedableRng}; #[test] pub fn test_ssz_round_trip() { - let keypair = Keypair::random(); - - let original = DepositInput { - pubkey: keypair.pk, - withdrawal_credentials: Hash256::from("cats".as_bytes()), - randao_commitment: Hash256::from("dogs".as_bytes()), - proof_of_possession: Signature::new(&[42, 42], &keypair.sk), - }; + let mut rng = XorShiftRng::from_seed([42; 16]); + let original = DepositInput::random_for_test(&mut rng); let bytes = ssz_encode(&original); - let (decoded, _) = DepositInput::ssz_decode(&bytes, 0).unwrap(); + let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap(); assert_eq!(original, decoded); } diff --git a/beacon_chain/types/src/exit.rs b/beacon_chain/types/src/exit.rs index b32ec3af6..cd0b79b35 100644 --- a/beacon_chain/types/src/exit.rs +++ b/beacon_chain/types/src/exit.rs @@ -1,11 +1,13 @@ use super::ssz::{Decodable, DecodeError, Encodable, SszStream}; -use bls::AggregateSignature; +use crate::random::TestRandom; +use bls::Signature; +use rand::RngCore; #[derive(Debug, PartialEq, Clone)] pub struct Exit { pub slot: u64, pub validator_index: u32, - pub signature: AggregateSignature, + pub signature: Signature, } impl Encodable for Exit { @@ -33,27 +35,30 @@ impl Decodable for Exit { } } +impl TestRandom for Exit { + fn random_for_test(rng: &mut T) -> Self { + Self { + slot: <_>::random_for_test(rng), + validator_index: <_>::random_for_test(rng), + signature: <_>::random_for_test(rng), + } + } +} + #[cfg(test)] mod tests { use super::super::ssz::ssz_encode; use super::*; - use bls::{AggregateSignature, Keypair, Signature}; + use crate::random::TestRandom; + use rand::{prng::XorShiftRng, SeedableRng}; #[test] pub fn test_ssz_round_trip() { - let keypair = Keypair::random(); - let single_signature = Signature::new(&[42, 42], &keypair.sk); - let mut signature = AggregateSignature::new(); - signature.add(&single_signature); - - let original = Exit { - slot: 42, - validator_index: 12, - signature, - }; + let mut rng = XorShiftRng::from_seed([42; 16]); + let original = Exit::random_for_test(&mut rng); let bytes = ssz_encode(&original); - let (decoded, _) = Exit::ssz_decode(&bytes, 0).unwrap(); + let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap(); assert_eq!(original, decoded); } diff --git a/beacon_chain/types/src/lib.rs b/beacon_chain/types/src/lib.rs index e24e77b93..71d6f10e6 100644 --- a/beacon_chain/types/src/lib.rs +++ b/beacon_chain/types/src/lib.rs @@ -3,6 +3,8 @@ extern crate boolean_bitfield; extern crate ethereum_types; extern crate ssz; +mod random; + pub mod active_state; pub mod attestation_data; pub mod attestation; @@ -32,29 +34,29 @@ pub mod validator_registration; use self::ethereum_types::{H160, H256, U256}; use std::collections::HashMap; -pub use active_state::ActiveState; -pub use attestation_data::AttestationData; -pub use attestation::Attestation; -pub use beacon_block::BeaconBlock; -pub use beacon_block_body::BeaconBlockBody; -pub use beacon_state::BeaconState; -pub use casper_slashing::CasperSlashing; -pub use chain_config::ChainConfig; -pub use crosslink_record::CrosslinkRecord; -pub use crystallized_state::CrystallizedState; -pub use deposit::Deposit; -pub use deposit_data::DepositData; -pub use deposit_input::DepositInput; -pub use exit::Exit; -pub use fork_data::ForkData; -pub use pending_attestation_record::PendingAttestationRecord; -pub use proposal_signed_data::ProposalSignedData; -pub use proposer_slashing::ProposerSlashing; -pub use slashable_vote_data::SlashableVoteData; -pub use shard_and_committee::ShardAndCommittee; -pub use special_record::{SpecialRecord, SpecialRecordKind}; -pub use validator_record::{ValidatorRecord, ValidatorStatus}; -pub use validator_registration::ValidatorRegistration; +pub use crate::active_state::ActiveState; +pub use crate::attestation_data::AttestationData; +pub use crate::attestation::Attestation; +pub use crate::beacon_block::BeaconBlock; +pub use crate::beacon_block_body::BeaconBlockBody; +pub use crate::beacon_state::BeaconState; +pub use crate::casper_slashing::CasperSlashing; +pub use crate::chain_config::ChainConfig; +pub use crate::crosslink_record::CrosslinkRecord; +pub use crate::crystallized_state::CrystallizedState; +pub use crate::deposit::Deposit; +pub use crate::deposit_data::DepositData; +pub use crate::deposit_input::DepositInput; +pub use crate::exit::Exit; +pub use crate::fork_data::ForkData; +pub use crate::pending_attestation_record::PendingAttestationRecord; +pub use crate::proposal_signed_data::ProposalSignedData; +pub use crate::proposer_slashing::ProposerSlashing; +pub use crate::slashable_vote_data::SlashableVoteData; +pub use crate::shard_and_committee::ShardAndCommittee; +pub use crate::special_record::{SpecialRecord, SpecialRecordKind}; +pub use crate::validator_record::{ValidatorRecord, ValidatorStatus}; +pub use crate::validator_registration::ValidatorRegistration; pub type Hash256 = H256; pub type Address = H160; diff --git a/beacon_chain/types/src/proposal_signed_data.rs b/beacon_chain/types/src/proposal_signed_data.rs index f44ecdd41..6a038d0eb 100644 --- a/beacon_chain/types/src/proposal_signed_data.rs +++ b/beacon_chain/types/src/proposal_signed_data.rs @@ -1,5 +1,7 @@ use super::ssz::{Decodable, DecodeError, Encodable, SszStream}; use super::Hash256; +use crate::random::TestRandom; +use rand::RngCore; #[derive(Debug, PartialEq, Clone, Default)] pub struct ProposalSignedData { @@ -33,21 +35,30 @@ impl Decodable for ProposalSignedData { } } +impl TestRandom for ProposalSignedData { + fn random_for_test(rng: &mut T) -> Self { + Self { + slot: <_>::random_for_test(rng), + shard: <_>::random_for_test(rng), + block_root: <_>::random_for_test(rng), + } + } +} + #[cfg(test)] mod tests { use super::super::ssz::ssz_encode; use super::*; + use crate::random::TestRandom; + use rand::{prng::XorShiftRng, SeedableRng}; #[test] pub fn test_ssz_round_trip() { - let original = ProposalSignedData { - slot: 42, - shard: 120, - block_root: Hash256::from("cats".as_bytes()), - }; + let mut rng = XorShiftRng::from_seed([42; 16]); + let original = ProposalSignedData::random_for_test(&mut rng); let bytes = ssz_encode(&original); - let (decoded, _) = ProposalSignedData::ssz_decode(&bytes, 0).unwrap(); + let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap(); assert_eq!(original, decoded); } diff --git a/beacon_chain/types/src/proposer_slashing.rs b/beacon_chain/types/src/proposer_slashing.rs index b8d597283..1e2b22b1d 100644 --- a/beacon_chain/types/src/proposer_slashing.rs +++ b/beacon_chain/types/src/proposer_slashing.rs @@ -1,6 +1,8 @@ use super::ssz::{Decodable, DecodeError, Encodable, SszStream}; use super::ProposalSignedData; +use crate::random::TestRandom; use bls::Signature; +use rand::RngCore; #[derive(Debug, PartialEq, Clone, Default)] pub struct ProposerSlashing { @@ -42,35 +44,32 @@ impl Decodable for ProposerSlashing { } } +impl TestRandom for ProposerSlashing { + fn random_for_test(rng: &mut T) -> Self { + Self { + proposer_index: <_>::random_for_test(rng), + proposal_data_1: <_>::random_for_test(rng), + proposal_signature_1: <_>::random_for_test(rng), + proposal_data_2: <_>::random_for_test(rng), + proposal_signature_2: <_>::random_for_test(rng), + } + } +} + #[cfg(test)] mod tests { use super::super::ssz::ssz_encode; - use super::super::Hash256; use super::*; - use bls::{Keypair, Signature}; + use crate::random::TestRandom; + use rand::{prng::XorShiftRng, SeedableRng}; #[test] pub fn test_ssz_round_trip() { - let keypair = Keypair::random(); - - let original = ProposerSlashing { - proposer_index: 42, - proposal_data_1: ProposalSignedData { - slot: 45, - shard: 110, - block_root: Hash256::from("cats".as_bytes()), - }, - proposal_signature_1: Signature::new(&[42, 42], &keypair.sk), - proposal_data_2: ProposalSignedData { - slot: 1, - shard: 260, - block_root: Hash256::from("lol".as_bytes()), - }, - proposal_signature_2: Signature::new(&[7, 8], &keypair.sk), - }; + let mut rng = XorShiftRng::from_seed([42; 16]); + let original = ProposerSlashing::random_for_test(&mut rng); let bytes = ssz_encode(&original); - let (decoded, _) = ProposerSlashing::ssz_decode(&bytes, 0).unwrap(); + let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap(); assert_eq!(original, decoded); } diff --git a/beacon_chain/types/src/random/aggregate_signature.rs b/beacon_chain/types/src/random/aggregate_signature.rs new file mode 100644 index 000000000..6a15f7366 --- /dev/null +++ b/beacon_chain/types/src/random/aggregate_signature.rs @@ -0,0 +1,12 @@ +use super::TestRandom; +use bls::{AggregateSignature, Signature}; +use rand::RngCore; + +impl TestRandom for AggregateSignature { + fn random_for_test(rng: &mut T) -> Self { + let signature = Signature::random_for_test(rng); + let mut aggregate_signature = AggregateSignature::new(); + aggregate_signature.add(&signature); + aggregate_signature + } +} diff --git a/beacon_chain/types/src/random/bitfield.rs b/beacon_chain/types/src/random/bitfield.rs new file mode 100644 index 000000000..15011edd9 --- /dev/null +++ b/beacon_chain/types/src/random/bitfield.rs @@ -0,0 +1,11 @@ +use super::super::Bitfield; +use super::TestRandom; +use rand::RngCore; + +impl TestRandom for Bitfield { + fn random_for_test(rng: &mut T) -> Self { + let mut raw_bytes = vec![0; 32]; + rng.fill_bytes(&mut raw_bytes); + Bitfield::from_bytes(&raw_bytes) + } +} diff --git a/beacon_chain/types/src/random/hash256.rs b/beacon_chain/types/src/random/hash256.rs new file mode 100644 index 000000000..98f5e7899 --- /dev/null +++ b/beacon_chain/types/src/random/hash256.rs @@ -0,0 +1,11 @@ +use super::TestRandom; +use crate::Hash256; +use rand::RngCore; + +impl TestRandom 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[..]) + } +} diff --git a/beacon_chain/types/src/random/mod.rs b/beacon_chain/types/src/random/mod.rs new file mode 100644 index 000000000..0087f8152 --- /dev/null +++ b/beacon_chain/types/src/random/mod.rs @@ -0,0 +1,38 @@ +use rand::RngCore; + +pub mod aggregate_signature; +pub mod bitfield; +pub mod hash256; +pub mod signature; +pub mod secret_key; +pub mod public_key; + +pub trait TestRandom +where T: RngCore +{ + fn random_for_test(rng: &mut T) -> Self; +} + +impl TestRandom for u64 { + fn random_for_test(rng: &mut T) -> Self { + rng.next_u64() + } +} + +impl TestRandom for u32 { + fn random_for_test(rng: &mut T) -> Self { + rng.next_u32() + } +} + +impl TestRandom for Vec +where U: TestRandom +{ + fn random_for_test(rng: &mut T) -> Self { + vec![ + ::random_for_test(rng), + ::random_for_test(rng), + ::random_for_test(rng), + ] + } +} diff --git a/beacon_chain/types/src/random/public_key.rs b/beacon_chain/types/src/random/public_key.rs new file mode 100644 index 000000000..bfccd3e53 --- /dev/null +++ b/beacon_chain/types/src/random/public_key.rs @@ -0,0 +1,10 @@ +use super::TestRandom; +use bls::{PublicKey, SecretKey}; +use rand::RngCore; + +impl TestRandom for PublicKey { + fn random_for_test(rng: &mut T) -> Self { + let secret_key = SecretKey::random_for_test(rng); + PublicKey::from_secret_key(&secret_key) + } +} diff --git a/beacon_chain/types/src/random/secret_key.rs b/beacon_chain/types/src/random/secret_key.rs new file mode 100644 index 000000000..17481c3de --- /dev/null +++ b/beacon_chain/types/src/random/secret_key.rs @@ -0,0 +1,19 @@ +use super::TestRandom; +use bls::SecretKey; +use rand::RngCore; + +impl TestRandom for SecretKey { + fn random_for_test(rng: &mut T) -> Self { + let mut key_bytes = vec![0; 48]; + rng.fill_bytes(&mut key_bytes); + /* + * An `unreachable!` is used here as there's no reason why you cannot constuct a key from a + * fixed-length byte slice. Also, this should only be used during testing so a panic is + * acceptable. + */ + match SecretKey::from_bytes(&key_bytes) { + Ok(key) => key, + Err(_) => unreachable!(), + } + } +} diff --git a/beacon_chain/types/src/random/signature.rs b/beacon_chain/types/src/random/signature.rs new file mode 100644 index 000000000..9ec7aec60 --- /dev/null +++ b/beacon_chain/types/src/random/signature.rs @@ -0,0 +1,13 @@ +use super::TestRandom; +use bls::{SecretKey, Signature}; +use rand::RngCore; + +impl TestRandom for Signature { + fn random_for_test(rng: &mut T) -> Self { + let secret_key = SecretKey::random_for_test(rng); + let mut message = vec![0; 32]; + rng.fill_bytes(&mut message); + + Signature::new(&message, &secret_key) + } +} diff --git a/beacon_chain/types/src/slashable_vote_data.rs b/beacon_chain/types/src/slashable_vote_data.rs index 2bd489978..150b40081 100644 --- a/beacon_chain/types/src/slashable_vote_data.rs +++ b/beacon_chain/types/src/slashable_vote_data.rs @@ -1,6 +1,8 @@ -use super::ssz::{decode_ssz_list, Decodable, DecodeError, Encodable, SszStream}; +use super::ssz::{Decodable, DecodeError, Encodable, SszStream}; use super::AttestationData; +use crate::random::TestRandom; use bls::AggregateSignature; +use rand::RngCore; #[derive(Debug, PartialEq, Clone, Default)] pub struct SlashableVoteData { @@ -21,8 +23,8 @@ impl Encodable for SlashableVoteData { impl Decodable for SlashableVoteData { fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { - let (aggregate_signature_poc_0_indices, i) = decode_ssz_list(bytes, i)?; - let (aggregate_signature_poc_1_indices, i) = decode_ssz_list(bytes, i)?; + let (aggregate_signature_poc_0_indices, i) = <_>::ssz_decode(bytes, i)?; + let (aggregate_signature_poc_1_indices, i) = <_>::ssz_decode(bytes, i)?; let (data, i) = <_>::ssz_decode(bytes, i)?; let (aggregate_signature, i) = <_>::ssz_decode(bytes, i)?; @@ -38,32 +40,31 @@ impl Decodable for SlashableVoteData { } } +impl TestRandom for SlashableVoteData { + fn random_for_test(rng: &mut T) -> Self { + Self { + aggregate_signature_poc_0_indices: <_>::random_for_test(rng), + aggregate_signature_poc_1_indices: <_>::random_for_test(rng), + data: <_>::random_for_test(rng), + aggregate_signature: <_>::random_for_test(rng), + } + } +} + #[cfg(test)] mod tests { use super::super::ssz::ssz_encode; - use super::super::Hash256; use super::*; + use crate::random::TestRandom; + use rand::{prng::XorShiftRng, SeedableRng}; #[test] pub fn test_ssz_round_trip() { - let original = SlashableVoteData { - aggregate_signature_poc_0_indices: vec![0, 1, 2], - aggregate_signature_poc_1_indices: vec![42, 42, 42], - data: AttestationData { - slot: 42, - shard: 16, - beacon_block_hash: Hash256::from("beacon".as_bytes()), - epoch_boundary_hash: Hash256::from("epoch".as_bytes()), - shard_block_hash: Hash256::from("shard".as_bytes()), - latest_crosslink_hash: Hash256::from("xlink".as_bytes()), - justified_slot: 8, - justified_block_hash: Hash256::from("justified".as_bytes()), - }, - aggregate_signature: AggregateSignature::new(), - }; + let mut rng = XorShiftRng::from_seed([42; 16]); + let original = SlashableVoteData::random_for_test(&mut rng); let bytes = ssz_encode(&original); - let (decoded, _) = SlashableVoteData::ssz_decode(&bytes, 0).unwrap(); + let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap(); assert_eq!(original, decoded); }