From 368a218af4081711f659990821b5c2ffc6d49cb0 Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Fri, 21 Dec 2018 15:44:11 +1100 Subject: [PATCH] Add types, more ssz testing for existing types --- beacon_chain/types/src/beacon_block.rs | 29 ++++- beacon_chain/types/src/casper_slashing.rs | 4 +- beacon_chain/types/src/deposit.rs | 100 ++++++------------ beacon_chain/types/src/deposit_data.rs | 63 +++++++++++ beacon_chain/types/src/deposit_input.rs | 64 +++++++++++ beacon_chain/types/src/exit.rs | 32 +++++- beacon_chain/types/src/lib.rs | 6 +- .../types/src/proposal_signed_data.rs | 6 +- beacon_chain/types/src/proposer_slashing.rs | 12 +-- beacon_chain/types/src/slashable_vote_data.rs | 4 +- 10 files changed, 233 insertions(+), 87 deletions(-) create mode 100644 beacon_chain/types/src/deposit_data.rs create mode 100644 beacon_chain/types/src/deposit_input.rs diff --git a/beacon_chain/types/src/beacon_block.rs b/beacon_chain/types/src/beacon_block.rs index ad87ec84a3..b2641cf84c 100644 --- a/beacon_chain/types/src/beacon_block.rs +++ b/beacon_chain/types/src/beacon_block.rs @@ -13,7 +13,6 @@ pub struct BeaconBlock { pub body: BeaconBlockBody, } -/* impl Encodable for BeaconBlock { fn ssz_append(&self, s: &mut SszStream) { s.append(&self.slot); @@ -21,8 +20,32 @@ impl Encodable for BeaconBlock { s.append(&self.state_root); s.append(&self.randao_reveal); s.append(&self.candidate_pow_receipt_root); - s.append_vec(&self.signature.as_bytes()); + s.append(&self.signature); s.append(&self.body); } } -*/ + +impl Decodable for BeaconBlock { + fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { + let (slot, i) = <_>::ssz_decode(bytes, i)?; + let (parent_root, i) = <_>::ssz_decode(bytes, i)?; + let (state_root, i) = <_>::ssz_decode(bytes, i)?; + let (randao_reveal, i) = <_>::ssz_decode(bytes, i)?; + let (candidate_pow_receipt_root, i) = <_>::ssz_decode(bytes, i)?; + let (signature, i) = <_>::ssz_decode(bytes, i)?; + let (body, i) = <_>::ssz_decode(bytes, i)?; + + Ok(( + Self { + slot, + parent_root, + state_root, + randao_reveal, + candidate_pow_receipt_root, + signature, + body, + }, + i, + )) + } +} diff --git a/beacon_chain/types/src/casper_slashing.rs b/beacon_chain/types/src/casper_slashing.rs index a8f722652b..dfa99cd6b0 100644 --- a/beacon_chain/types/src/casper_slashing.rs +++ b/beacon_chain/types/src/casper_slashing.rs @@ -16,8 +16,8 @@ impl Encodable for CasperSlashing { impl Decodable for CasperSlashing { fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { - let (slashable_vote_data_1, i) = SlashableVoteData::ssz_decode(bytes, i)?; - let (slashable_vote_data_2, i) = SlashableVoteData::ssz_decode(bytes, i)?; + let (slashable_vote_data_1, i) = <_>::ssz_decode(bytes, i)?; + let (slashable_vote_data_2, i) = <_>::ssz_decode(bytes, i)?; Ok(( CasperSlashing { diff --git a/beacon_chain/types/src/deposit.rs b/beacon_chain/types/src/deposit.rs index 3b2ad87a62..7aa3758285 100644 --- a/beacon_chain/types/src/deposit.rs +++ b/beacon_chain/types/src/deposit.rs @@ -1,6 +1,5 @@ use super::ssz::{decode_ssz_list, Decodable, DecodeError, Encodable, SszStream}; -use super::Hash256; -use bls::{AggregateSignature, PublicKey}; +use super::{DepositData, Hash256}; #[derive(Debug, PartialEq, Clone)] pub struct Deposit { @@ -20,8 +19,8 @@ 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_tree_index, i) = u64::ssz_decode(bytes, i)?; - let (deposit_data, i) = DepositData::ssz_decode(bytes, i)?; + let (merkle_tree_index, i) = <_>::ssz_decode(bytes, i)?; + let (deposit_data, i) = <_>::ssz_decode(bytes, i)?; Ok(( Self { @@ -34,71 +33,38 @@ impl Decodable for Deposit { } } -#[derive(Debug, PartialEq, Clone)] -pub struct DepositData { - pub deposit_input: DepositInput, - pub value: u64, - pub timestamp: u64, -} +#[cfg(test)] +mod tests { + use super::super::ssz::ssz_encode; + use super::super::{DepositInput, Hash256}; + use super::*; + use bls::{Keypair, Signature}; -impl Encodable for DepositData { - fn ssz_append(&self, s: &mut SszStream) { - s.append(&self.deposit_input); - s.append(&self.value); - s.append(&self.timestamp); - } -} + #[test] + pub fn test_ssz_round_trip() { + let keypair = Keypair::random(); -impl Decodable for DepositData { - fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { - let (deposit_input, i) = DepositInput::ssz_decode(bytes, i)?; - let (value, i) = u64::ssz_decode(bytes, i)?; - let (timestamp, i) = u64::ssz_decode(bytes, i)?; - - Ok(( - Self { - deposit_input, - value, - timestamp, + 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, }, - i, - )) - } -} - -#[derive(Debug, PartialEq, Clone)] -pub struct DepositInput { - pub pubkey: PublicKey, - pub withdrawal_credentials: Hash256, - pub randao_commitment: Hash256, - pub proof_of_possession: AggregateSignature, -} - -impl Encodable for DepositInput { - fn ssz_append(&self, s: &mut SszStream) { - s.append_vec(&self.pubkey.as_bytes()); - s.append(&self.withdrawal_credentials); - s.append(&self.randao_commitment); - s.append(&self.proof_of_possession); - } -} - -impl Decodable for DepositInput { - fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { - let (pubkey_bytes, i) = decode_ssz_list(bytes, i)?; - let pubkey = PublicKey::from_bytes(&pubkey_bytes).map_err(|_| DecodeError::TooShort)?; - let (withdrawal_credentials, i) = Hash256::ssz_decode(bytes, i)?; - let (randao_commitment, i) = Hash256::ssz_decode(bytes, i)?; - let (proof_of_possession, i) = AggregateSignature::ssz_decode(bytes, i)?; - - Ok(( - Self { - pubkey, - withdrawal_credentials, - randao_commitment, - proof_of_possession, - }, - i, - )) + }; + + let bytes = ssz_encode(&original); + let (decoded, _) = Deposit::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 new file mode 100644 index 0000000000..790beab287 --- /dev/null +++ b/beacon_chain/types/src/deposit_data.rs @@ -0,0 +1,63 @@ +use super::ssz::{Decodable, DecodeError, Encodable, SszStream}; +use super::DepositInput; + +#[derive(Debug, PartialEq, Clone)] +pub struct DepositData { + pub deposit_input: DepositInput, + pub value: u64, + pub timestamp: u64, +} + +impl Encodable for DepositData { + fn ssz_append(&self, s: &mut SszStream) { + s.append(&self.deposit_input); + s.append(&self.value); + s.append(&self.timestamp); + } +} + +impl Decodable for DepositData { + fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { + let (deposit_input, i) = <_>::ssz_decode(bytes, i)?; + let (value, i) = <_>::ssz_decode(bytes, i)?; + let (timestamp, i) = <_>::ssz_decode(bytes, i)?; + + Ok(( + Self { + deposit_input, + value, + timestamp, + }, + i, + )) + } +} + +#[cfg(test)] +mod tests { + use super::super::ssz::ssz_encode; + use super::super::Hash256; + use super::*; + use bls::{Keypair, Signature}; + + #[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 bytes = ssz_encode(&original); + let (decoded, _) = DepositData::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 new file mode 100644 index 0000000000..d9b3e98643 --- /dev/null +++ b/beacon_chain/types/src/deposit_input.rs @@ -0,0 +1,64 @@ +use super::ssz::{decode_ssz_list, Decodable, DecodeError, Encodable, SszStream}; +use super::Hash256; +use bls::{PublicKey, Signature}; + +#[derive(Debug, PartialEq, Clone)] +pub struct DepositInput { + pub pubkey: PublicKey, + pub withdrawal_credentials: Hash256, + pub randao_commitment: Hash256, + pub proof_of_possession: Signature, +} + +impl Encodable for DepositInput { + fn ssz_append(&self, s: &mut SszStream) { + s.append_vec(&self.pubkey.as_bytes()); + s.append(&self.withdrawal_credentials); + s.append(&self.randao_commitment); + s.append(&self.proof_of_possession); + } +} + +impl Decodable for DepositInput { + fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { + let (pubkey_bytes, i) = decode_ssz_list(bytes, i)?; + let pubkey = PublicKey::from_bytes(&pubkey_bytes).map_err(|_| DecodeError::TooShort)?; + let (withdrawal_credentials, i) = <_>::ssz_decode(bytes, i)?; + let (randao_commitment, i) = <_>::ssz_decode(bytes, i)?; + let (proof_of_possession, i) = <_>::ssz_decode(bytes, i)?; + + Ok(( + Self { + pubkey, + withdrawal_credentials, + randao_commitment, + proof_of_possession, + }, + i, + )) + } +} + +#[cfg(test)] +mod tests { + use super::super::ssz::ssz_encode; + use super::*; + use bls::{Keypair, Signature}; + + #[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 bytes = ssz_encode(&original); + let (decoded, _) = DepositInput::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 c4753354da..b32ec3af69 100644 --- a/beacon_chain/types/src/exit.rs +++ b/beacon_chain/types/src/exit.rs @@ -18,9 +18,9 @@ impl Encodable for Exit { impl Decodable for Exit { fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { - let (slot, i) = u64::ssz_decode(bytes, i)?; - let (validator_index, i) = u32::ssz_decode(bytes, i)?; - let (signature, i) = AggregateSignature::ssz_decode(bytes, i)?; + let (slot, i) = <_>::ssz_decode(bytes, i)?; + let (validator_index, i) = <_>::ssz_decode(bytes, i)?; + let (signature, i) = <_>::ssz_decode(bytes, i)?; Ok(( Self { @@ -32,3 +32,29 @@ impl Decodable for Exit { )) } } + +#[cfg(test)] +mod tests { + use super::super::ssz::ssz_encode; + use super::*; + use bls::{AggregateSignature, Keypair, Signature}; + + #[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 bytes = ssz_encode(&original); + let (decoded, _) = Exit::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 c71a205b74..e24e77b934 100644 --- a/beacon_chain/types/src/lib.rs +++ b/beacon_chain/types/src/lib.rs @@ -15,6 +15,8 @@ pub mod chain_config; pub mod crosslink_record; pub mod crystallized_state; pub mod deposit; +pub mod deposit_data; +pub mod deposit_input; pub mod exit; pub mod fork_data; pub mod pending_attestation_record; @@ -40,7 +42,9 @@ pub use casper_slashing::CasperSlashing; pub use chain_config::ChainConfig; pub use crosslink_record::CrosslinkRecord; pub use crystallized_state::CrystallizedState; -pub use deposit::{Deposit, DepositData, DepositInput}; +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; diff --git a/beacon_chain/types/src/proposal_signed_data.rs b/beacon_chain/types/src/proposal_signed_data.rs index 25a6f0e042..f44ecdd417 100644 --- a/beacon_chain/types/src/proposal_signed_data.rs +++ b/beacon_chain/types/src/proposal_signed_data.rs @@ -18,9 +18,9 @@ impl Encodable for ProposalSignedData { impl Decodable for ProposalSignedData { fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { - let (slot, i) = u64::ssz_decode(bytes, i)?; - let (shard, i) = u64::ssz_decode(bytes, i)?; - let (block_root, i) = Hash256::ssz_decode(bytes, i)?; + let (slot, i) = <_>::ssz_decode(bytes, i)?; + let (shard, i) = <_>::ssz_decode(bytes, i)?; + let (block_root, i) = <_>::ssz_decode(bytes, i)?; Ok(( ProposalSignedData { diff --git a/beacon_chain/types/src/proposer_slashing.rs b/beacon_chain/types/src/proposer_slashing.rs index 0daab8ea8f..b8d597283d 100644 --- a/beacon_chain/types/src/proposer_slashing.rs +++ b/beacon_chain/types/src/proposer_slashing.rs @@ -1,4 +1,4 @@ -use super::ssz::{decode_ssz_list, Decodable, DecodeError, Encodable, SszStream}; +use super::ssz::{Decodable, DecodeError, Encodable, SszStream}; use super::ProposalSignedData; use bls::Signature; @@ -23,11 +23,11 @@ impl Encodable for ProposerSlashing { impl Decodable for ProposerSlashing { fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> { - let (proposer_index, i) = u32::ssz_decode(bytes, i)?; - let (proposal_data_1, i) = ProposalSignedData::ssz_decode(bytes, i)?; - let (proposal_signature_1, i) = Signature::ssz_decode(bytes, i)?; - let (proposal_data_2, i) = ProposalSignedData::ssz_decode(bytes, i)?; - let (proposal_signature_2, i) = Signature::ssz_decode(bytes, i)?; + let (proposer_index, i) = <_>::ssz_decode(bytes, i)?; + let (proposal_data_1, i) = <_>::ssz_decode(bytes, i)?; + let (proposal_signature_1, i) = <_>::ssz_decode(bytes, i)?; + let (proposal_data_2, i) = <_>::ssz_decode(bytes, i)?; + let (proposal_signature_2, i) = <_>::ssz_decode(bytes, i)?; Ok(( ProposerSlashing { diff --git a/beacon_chain/types/src/slashable_vote_data.rs b/beacon_chain/types/src/slashable_vote_data.rs index 7a8f3d4da2..2bd4899781 100644 --- a/beacon_chain/types/src/slashable_vote_data.rs +++ b/beacon_chain/types/src/slashable_vote_data.rs @@ -23,8 +23,8 @@ 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 (data, i) = AttestationData::ssz_decode(bytes, i)?; - let (aggregate_signature, i) = AggregateSignature::ssz_decode(bytes, i)?; + let (data, i) = <_>::ssz_decode(bytes, i)?; + let (aggregate_signature, i) = <_>::ssz_decode(bytes, i)?; Ok(( SlashableVoteData {