Begin implementing new types
This commit is contained in:
parent
be4c6701ac
commit
0260564c15
@ -1,142 +1,28 @@
|
||||
use super::attestation::Attestation;
|
||||
use super::special_record::SpecialRecord;
|
||||
use super::ssz::{Decodable, DecodeError, Encodable, SszStream};
|
||||
use super::Hash256;
|
||||
|
||||
pub const MIN_SSZ_BLOCK_LENGTH: usize = {
|
||||
8 + // slot
|
||||
32 + // randao_reveal
|
||||
32 + // pow_chain_reference
|
||||
4 + // ancestor hashes (assuming empty)
|
||||
32 + // active_state_root
|
||||
32 + // crystallized_state_root
|
||||
4 + // attestations (assuming empty)
|
||||
4 // specials (assuming empty)
|
||||
};
|
||||
pub const MAX_SSZ_BLOCK_LENGTH: usize = MIN_SSZ_BLOCK_LENGTH + (1 << 24);
|
||||
use super::{BeaconBlockBody, Hash256};
|
||||
use bls::AggregateSignature;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Default)]
|
||||
pub struct BeaconBlock {
|
||||
pub slot: u64,
|
||||
pub parent_root: Hash256,
|
||||
pub state_root: Hash256,
|
||||
pub randao_reveal: Hash256,
|
||||
pub pow_chain_reference: Hash256,
|
||||
pub ancestor_hashes: Vec<Hash256>,
|
||||
pub active_state_root: Hash256,
|
||||
pub crystallized_state_root: Hash256,
|
||||
pub attestations: Vec<Attestation>,
|
||||
pub specials: Vec<SpecialRecord>,
|
||||
}
|
||||
|
||||
impl BeaconBlock {
|
||||
pub fn zero() -> Self {
|
||||
Self {
|
||||
slot: 0,
|
||||
randao_reveal: Hash256::zero(),
|
||||
pow_chain_reference: Hash256::zero(),
|
||||
ancestor_hashes: vec![],
|
||||
active_state_root: Hash256::zero(),
|
||||
crystallized_state_root: Hash256::zero(),
|
||||
attestations: vec![],
|
||||
specials: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a reference to `ancestor_hashes[0]`.
|
||||
///
|
||||
/// The first hash in `ancestor_hashes` is the parent of the block.
|
||||
pub fn parent_hash(&self) -> Option<&Hash256> {
|
||||
self.ancestor_hashes.get(0)
|
||||
}
|
||||
pub candidate_pow_receipt_root: Hash256,
|
||||
pub signature: AggregateSignature,
|
||||
pub body: BeaconBlockBody,
|
||||
}
|
||||
|
||||
/*
|
||||
impl Encodable for BeaconBlock {
|
||||
fn ssz_append(&self, s: &mut SszStream) {
|
||||
s.append(&self.slot);
|
||||
s.append(&self.parent_root);
|
||||
s.append(&self.state_root);
|
||||
s.append(&self.randao_reveal);
|
||||
s.append(&self.pow_chain_reference);
|
||||
s.append_vec(&self.ancestor_hashes);
|
||||
s.append(&self.active_state_root);
|
||||
s.append(&self.crystallized_state_root);
|
||||
s.append_vec(&self.attestations);
|
||||
s.append_vec(&self.specials);
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for BeaconBlock {
|
||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||
let (slot, i) = u64::ssz_decode(bytes, i)?;
|
||||
let (randao_reveal, i) = Hash256::ssz_decode(bytes, i)?;
|
||||
let (pow_chain_reference, i) = Hash256::ssz_decode(bytes, i)?;
|
||||
let (ancestor_hashes, i) = Decodable::ssz_decode(bytes, i)?;
|
||||
let (active_state_root, i) = Hash256::ssz_decode(bytes, i)?;
|
||||
let (crystallized_state_root, i) = Hash256::ssz_decode(bytes, i)?;
|
||||
let (attestations, i) = Decodable::ssz_decode(bytes, i)?;
|
||||
let (specials, i) = Decodable::ssz_decode(bytes, i)?;
|
||||
let block = BeaconBlock {
|
||||
slot,
|
||||
randao_reveal,
|
||||
pow_chain_reference,
|
||||
ancestor_hashes,
|
||||
active_state_root,
|
||||
crystallized_state_root,
|
||||
attestations,
|
||||
specials,
|
||||
};
|
||||
Ok((block, i))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_block_zero() {
|
||||
let b = BeaconBlock::zero();
|
||||
assert_eq!(b.slot, 0);
|
||||
assert!(b.randao_reveal.is_zero());
|
||||
assert!(b.pow_chain_reference.is_zero());
|
||||
assert_eq!(b.ancestor_hashes, vec![]);
|
||||
assert!(b.active_state_root.is_zero());
|
||||
assert!(b.crystallized_state_root.is_zero());
|
||||
assert_eq!(b.attestations.len(), 0);
|
||||
assert_eq!(b.specials.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_block_ssz_encode_decode() {
|
||||
let mut b = BeaconBlock::zero();
|
||||
b.ancestor_hashes = vec![Hash256::zero(); 32];
|
||||
|
||||
let mut ssz_stream = SszStream::new();
|
||||
ssz_stream.append(&b);
|
||||
let ssz = ssz_stream.drain();
|
||||
|
||||
let (b_decoded, _) = BeaconBlock::ssz_decode(&ssz, 0).unwrap();
|
||||
|
||||
assert_eq!(b, b_decoded);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_block_min_ssz_length() {
|
||||
let b = BeaconBlock::zero();
|
||||
|
||||
let mut ssz_stream = SszStream::new();
|
||||
ssz_stream.append(&b);
|
||||
let ssz = ssz_stream.drain();
|
||||
|
||||
assert_eq!(ssz.len(), MIN_SSZ_BLOCK_LENGTH);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_block_parent_hash() {
|
||||
let mut b = BeaconBlock::zero();
|
||||
b.ancestor_hashes = vec![
|
||||
Hash256::from("cats".as_bytes()),
|
||||
Hash256::from("dogs".as_bytes()),
|
||||
Hash256::from("birds".as_bytes()),
|
||||
];
|
||||
|
||||
assert_eq!(b.parent_hash().unwrap(), &Hash256::from("cats".as_bytes()));
|
||||
s.append(&self.candidate_pow_receipt_root);
|
||||
s.append_vec(&self.signature.as_bytes());
|
||||
s.append(&self.body);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -0,0 +1,23 @@
|
||||
use super::ssz::{Encodable, SszStream};
|
||||
use super::{Attestation, CasperSlashing, Deposit, Exit, ProposerSlashing};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Default)]
|
||||
pub struct BeaconBlockBody {
|
||||
pub proposer_slashings: Vec<ProposerSlashing>,
|
||||
pub casper_slashings: Vec<CasperSlashing>,
|
||||
pub attestations: Vec<Attestation>,
|
||||
pub deposits: Vec<Deposit>,
|
||||
pub exits: Vec<Exit>,
|
||||
}
|
||||
|
||||
/*
|
||||
impl Encodable for BeaconBlockBody {
|
||||
fn ssz_append(&self, s: &mut SszStream) {
|
||||
s.append(&self.proposer_slashings);
|
||||
s.append(&self.casper_slashings);
|
||||
s.append(&self.attestations);
|
||||
s.append(&self.deposits);
|
||||
s.append(&self.exits);
|
||||
}
|
||||
}
|
||||
*/
|
30
beacon_chain/types/src/casper_slashing.rs
Normal file
30
beacon_chain/types/src/casper_slashing.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use super::ssz::{Decodable, DecodeError, Encodable, SszStream};
|
||||
use super::SlashableVoteData;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Default)]
|
||||
pub struct CasperSlashing {
|
||||
pub slashable_vote_data_1: SlashableVoteData,
|
||||
pub slashable_vote_data_2: SlashableVoteData,
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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)?;
|
||||
|
||||
Ok((
|
||||
CasperSlashing {
|
||||
slashable_vote_data_1,
|
||||
slashable_vote_data_2,
|
||||
},
|
||||
i,
|
||||
))
|
||||
}
|
||||
}
|
24
beacon_chain/types/src/deposit.rs
Normal file
24
beacon_chain/types/src/deposit.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use super::Hash256;
|
||||
use bls::{AggregateSignature, PublicKey};
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Deposit {
|
||||
pub merkle_branch: Vec<Hash256>,
|
||||
pub merkle_tree_index: u64,
|
||||
pub deposit_data: DepositData,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct DepositData {
|
||||
pub deposit_input: DepositInput,
|
||||
pub value: u64,
|
||||
pub timestamp: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct DepositInput {
|
||||
pub pubkey: PublicKey,
|
||||
pub withdrawal_credentials: Hash256,
|
||||
pub randao_commitment: Hash256,
|
||||
pub proof_of_possession: AggregateSignature,
|
||||
}
|
8
beacon_chain/types/src/exit.rs
Normal file
8
beacon_chain/types/src/exit.rs
Normal file
@ -0,0 +1,8 @@
|
||||
use bls::AggregateSignature;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Exit {
|
||||
pub slot: u64,
|
||||
pub validator_index: u32,
|
||||
pub signature: AggregateSignature,
|
||||
}
|
@ -7,16 +7,23 @@ pub mod active_state;
|
||||
pub mod attestation_data;
|
||||
pub mod attestation;
|
||||
pub mod beacon_block;
|
||||
pub mod beacon_block_body;
|
||||
pub mod beacon_state;
|
||||
pub mod candidate_pow_receipt_root_record;
|
||||
pub mod casper_slashing;
|
||||
pub mod chain_config;
|
||||
pub mod crosslink_record;
|
||||
pub mod crystallized_state;
|
||||
pub mod deposit;
|
||||
pub mod exit;
|
||||
pub mod fork_data;
|
||||
pub mod pending_attestation_record;
|
||||
pub mod proposal_signed_data;
|
||||
pub mod proposer_slashing;
|
||||
pub mod shard_and_committee;
|
||||
pub mod shard_reassignment_record;
|
||||
pub mod special_record;
|
||||
pub mod slashable_vote_data;
|
||||
pub mod validator_record;
|
||||
pub mod validator_registration;
|
||||
|
||||
@ -27,12 +34,19 @@ 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, DepositData, 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};
|
||||
|
54
beacon_chain/types/src/proposal_signed_data.rs
Normal file
54
beacon_chain/types/src/proposal_signed_data.rs
Normal file
@ -0,0 +1,54 @@
|
||||
use super::ssz::{Decodable, DecodeError, Encodable, SszStream};
|
||||
use super::Hash256;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Default)]
|
||||
pub struct ProposalSignedData {
|
||||
pub slot: u64,
|
||||
pub shard: u64,
|
||||
pub block_root: Hash256,
|
||||
}
|
||||
|
||||
impl Encodable for ProposalSignedData {
|
||||
fn ssz_append(&self, s: &mut SszStream) {
|
||||
s.append(&self.slot);
|
||||
s.append(&self.shard);
|
||||
s.append(&self.block_root);
|
||||
}
|
||||
}
|
||||
|
||||
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)?;
|
||||
|
||||
Ok((
|
||||
ProposalSignedData {
|
||||
slot,
|
||||
shard,
|
||||
block_root,
|
||||
},
|
||||
i,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::super::ssz::ssz_encode;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
pub fn test_ssz_round_trip() {
|
||||
let original = ProposalSignedData {
|
||||
slot: 42,
|
||||
shard: 120,
|
||||
block_root: Hash256::from("cats".as_bytes()),
|
||||
};
|
||||
|
||||
let bytes = ssz_encode(&original);
|
||||
let (decoded, _) = ProposalSignedData::ssz_decode(&bytes, 0).unwrap();
|
||||
|
||||
assert_eq!(original, decoded);
|
||||
}
|
||||
}
|
77
beacon_chain/types/src/proposer_slashing.rs
Normal file
77
beacon_chain/types/src/proposer_slashing.rs
Normal file
@ -0,0 +1,77 @@
|
||||
use super::ssz::{Decodable, DecodeError, Encodable, SszStream};
|
||||
use super::ProposalSignedData;
|
||||
use bls::Signature;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Default)]
|
||||
pub struct ProposerSlashing {
|
||||
pub proposer_index: u32,
|
||||
pub proposal_data_1: ProposalSignedData,
|
||||
pub proposal_signature_1: Signature,
|
||||
pub proposal_data_2: ProposalSignedData,
|
||||
pub proposal_signature_2: Signature,
|
||||
}
|
||||
|
||||
impl Encodable for ProposerSlashing {
|
||||
fn ssz_append(&self, s: &mut SszStream) {
|
||||
s.append(&self.proposer_index);
|
||||
s.append(&self.proposal_data_1);
|
||||
s.append(&self.proposal_signature_1);
|
||||
s.append(&self.proposal_data_2);
|
||||
s.append(&self.proposal_signature_2);
|
||||
}
|
||||
}
|
||||
|
||||
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)?;
|
||||
|
||||
Ok((
|
||||
ProposerSlashing {
|
||||
proposer_index,
|
||||
proposal_data_1,
|
||||
proposal_signature_1,
|
||||
proposal_data_2,
|
||||
proposal_signature_2,
|
||||
},
|
||||
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 = 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 bytes = ssz_encode(&original);
|
||||
let (decoded, _) = ProposerSlashing::ssz_decode(&bytes, 0).unwrap();
|
||||
|
||||
assert_eq!(original, decoded);
|
||||
}
|
||||
}
|
70
beacon_chain/types/src/slashable_vote_data.rs
Normal file
70
beacon_chain/types/src/slashable_vote_data.rs
Normal file
@ -0,0 +1,70 @@
|
||||
use super::ssz::{decode_ssz_list, Decodable, DecodeError, Encodable, SszStream};
|
||||
use super::AttestationData;
|
||||
use bls::AggregateSignature;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Default)]
|
||||
pub struct SlashableVoteData {
|
||||
pub aggregate_signature_poc_0_indices: Vec<u32>,
|
||||
pub aggregate_signature_poc_1_indices: Vec<u32>,
|
||||
pub data: AttestationData,
|
||||
pub aggregate_signature: AggregateSignature,
|
||||
}
|
||||
|
||||
impl Encodable for SlashableVoteData {
|
||||
fn ssz_append(&self, s: &mut SszStream) {
|
||||
s.append_vec(&self.aggregate_signature_poc_0_indices);
|
||||
s.append_vec(&self.aggregate_signature_poc_1_indices);
|
||||
s.append(&self.data);
|
||||
s.append(&self.aggregate_signature);
|
||||
}
|
||||
}
|
||||
|
||||
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)?;
|
||||
|
||||
Ok((
|
||||
SlashableVoteData {
|
||||
aggregate_signature_poc_0_indices,
|
||||
aggregate_signature_poc_1_indices,
|
||||
data,
|
||||
aggregate_signature,
|
||||
},
|
||||
i,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::super::ssz::ssz_encode;
|
||||
use super::super::Hash256;
|
||||
use super::*;
|
||||
|
||||
#[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 bytes = ssz_encode(&original);
|
||||
let (decoded, _) = SlashableVoteData::ssz_decode(&bytes, 0).unwrap();
|
||||
|
||||
assert_eq!(original, decoded);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user