Implement ssz Enc/Decode for BeaconState + more
This commit is contained in:
parent
e4e729d309
commit
39f2171053
@ -6,6 +6,9 @@ use super::shard_committee::ShardCommittee;
|
|||||||
use super::shard_reassignment_record::ShardReassignmentRecord;
|
use super::shard_reassignment_record::ShardReassignmentRecord;
|
||||||
use super::validator_record::ValidatorRecord;
|
use super::validator_record::ValidatorRecord;
|
||||||
use super::Hash256;
|
use super::Hash256;
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::RngCore;
|
||||||
|
use ssz::{Decodable, DecodeError, Encodable, SszStream};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct BeaconState {
|
pub struct BeaconState {
|
||||||
@ -51,3 +54,114 @@ impl BeaconState {
|
|||||||
Hash256::zero()
|
Hash256::zero()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Encodable for BeaconState {
|
||||||
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
|
s.append(&self.slot);
|
||||||
|
s.append(&self.genesis_time);
|
||||||
|
s.append(&self.fork_data);
|
||||||
|
s.append(&self.validator_registry);
|
||||||
|
s.append(&self.validator_registry_latest_change_slot);
|
||||||
|
s.append(&self.validator_registry_exit_count);
|
||||||
|
s.append(&self.validator_registry_delta_chain_tip);
|
||||||
|
s.append(&self.randao_mix);
|
||||||
|
s.append(&self.next_seed);
|
||||||
|
s.append(&self.shard_committees_at_slots);
|
||||||
|
s.append(&self.persistent_committees);
|
||||||
|
s.append(&self.persistent_committee_reassignments);
|
||||||
|
s.append(&self.previous_justified_slot);
|
||||||
|
s.append(&self.justified_slot);
|
||||||
|
s.append(&self.justification_bitfield);
|
||||||
|
s.append(&self.finalized_slot);
|
||||||
|
s.append(&self.latest_crosslinks);
|
||||||
|
s.append(&self.latest_block_roots);
|
||||||
|
s.append(&self.latest_penalized_exit_balances);
|
||||||
|
s.append(&self.latest_attestations);
|
||||||
|
s.append(&self.processed_pow_receipt_root);
|
||||||
|
s.append(&self.candidate_pow_receipt_roots);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for BeaconState {
|
||||||
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
|
let (slot, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (genesis_time, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (fork_data, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (validator_registry, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (validator_registry_latest_change_slot, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (validator_registry_exit_count, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (validator_registry_delta_chain_tip, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (randao_mix, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (next_seed, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (shard_committees_at_slots, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (persistent_committees, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (persistent_committee_reassignments, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (previous_justified_slot, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (justified_slot, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (justification_bitfield, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (finalized_slot, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (latest_crosslinks, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (latest_block_roots, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (latest_penalized_exit_balances, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (latest_attestations, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (processed_pow_receipt_root, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (candidate_pow_receipt_roots, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Self {
|
||||||
|
slot,
|
||||||
|
genesis_time,
|
||||||
|
fork_data,
|
||||||
|
validator_registry,
|
||||||
|
validator_registry_latest_change_slot,
|
||||||
|
validator_registry_exit_count,
|
||||||
|
validator_registry_delta_chain_tip,
|
||||||
|
randao_mix,
|
||||||
|
next_seed,
|
||||||
|
shard_committees_at_slots,
|
||||||
|
persistent_committees,
|
||||||
|
persistent_committee_reassignments,
|
||||||
|
previous_justified_slot,
|
||||||
|
justified_slot,
|
||||||
|
justification_bitfield,
|
||||||
|
finalized_slot,
|
||||||
|
latest_crosslinks,
|
||||||
|
latest_block_roots,
|
||||||
|
latest_penalized_exit_balances,
|
||||||
|
latest_attestations,
|
||||||
|
processed_pow_receipt_root,
|
||||||
|
candidate_pow_receipt_roots,
|
||||||
|
},
|
||||||
|
i,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: RngCore> TestRandom<T> for BeaconState {
|
||||||
|
fn random_for_test(rng: &mut T) -> Self {
|
||||||
|
Self {
|
||||||
|
slot: <_>::random_for_test(rng),
|
||||||
|
genesis_time: <_>::random_for_test(rng),
|
||||||
|
fork_data: <_>::random_for_test(rng),
|
||||||
|
validator_registry: <_>::random_for_test(rng),
|
||||||
|
validator_registry_latest_change_slot: <_>::random_for_test(rng),
|
||||||
|
validator_registry_exit_count: <_>::random_for_test(rng),
|
||||||
|
validator_registry_delta_chain_tip: <_>::random_for_test(rng),
|
||||||
|
randao_mix: <_>::random_for_test(rng),
|
||||||
|
next_seed: <_>::random_for_test(rng),
|
||||||
|
shard_committees_at_slots: <_>::random_for_test(rng),
|
||||||
|
persistent_committees: <_>::random_for_test(rng),
|
||||||
|
persistent_committee_reassignments: <_>::random_for_test(rng),
|
||||||
|
previous_justified_slot: <_>::random_for_test(rng),
|
||||||
|
justified_slot: <_>::random_for_test(rng),
|
||||||
|
justification_bitfield: <_>::random_for_test(rng),
|
||||||
|
finalized_slot: <_>::random_for_test(rng),
|
||||||
|
latest_crosslinks: <_>::random_for_test(rng),
|
||||||
|
latest_block_roots: <_>::random_for_test(rng),
|
||||||
|
latest_penalized_exit_balances: <_>::random_for_test(rng),
|
||||||
|
latest_attestations: <_>::random_for_test(rng),
|
||||||
|
processed_pow_receipt_root: <_>::random_for_test(rng),
|
||||||
|
candidate_pow_receipt_roots: <_>::random_for_test(rng),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,60 @@
|
|||||||
|
use super::ssz::{Decodable, DecodeError, Encodable, SszStream};
|
||||||
use super::Hash256;
|
use super::Hash256;
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::RngCore;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct CandidatePoWReceiptRootRecord {
|
pub struct CandidatePoWReceiptRootRecord {
|
||||||
pub candidate_pow_receipt_root: Hash256,
|
pub candidate_pow_receipt_root: Hash256,
|
||||||
pub votes: u64,
|
pub votes: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Encodable for CandidatePoWReceiptRootRecord {
|
||||||
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
|
s.append(&self.candidate_pow_receipt_root);
|
||||||
|
s.append(&self.votes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for CandidatePoWReceiptRootRecord {
|
||||||
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
|
let (candidate_pow_receipt_root, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (votes, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Self {
|
||||||
|
candidate_pow_receipt_root,
|
||||||
|
votes,
|
||||||
|
},
|
||||||
|
i,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: RngCore> TestRandom<T> for CandidatePoWReceiptRootRecord {
|
||||||
|
fn random_for_test(rng: &mut T) -> Self {
|
||||||
|
Self {
|
||||||
|
candidate_pow_receipt_root: <_>::random_for_test(rng),
|
||||||
|
votes: <_>::random_for_test(rng),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::super::ssz::ssz_encode;
|
||||||
|
use super::*;
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::{prng::XorShiftRng, SeedableRng};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_ssz_round_trip() {
|
||||||
|
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||||
|
let original = CandidatePoWReceiptRootRecord::random_for_test(&mut rng);
|
||||||
|
|
||||||
|
let bytes = ssz_encode(&original);
|
||||||
|
let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(original, decoded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
|
use super::ssz::{Decodable, DecodeError, Encodable, SszStream};
|
||||||
use super::Hash256;
|
use super::Hash256;
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::RngCore;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct CrosslinkRecord {
|
pub struct CrosslinkRecord {
|
||||||
@ -15,3 +18,53 @@ impl CrosslinkRecord {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Encodable for CrosslinkRecord {
|
||||||
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
|
s.append(&self.slot);
|
||||||
|
s.append(&self.shard_block_root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for CrosslinkRecord {
|
||||||
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
|
let (slot, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (shard_block_root, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Self {
|
||||||
|
slot,
|
||||||
|
shard_block_root,
|
||||||
|
},
|
||||||
|
i,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: RngCore> TestRandom<T> for CrosslinkRecord {
|
||||||
|
fn random_for_test(rng: &mut T) -> Self {
|
||||||
|
Self {
|
||||||
|
slot: <_>::random_for_test(rng),
|
||||||
|
shard_block_root: <_>::random_for_test(rng),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::super::ssz::ssz_encode;
|
||||||
|
use super::*;
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::{prng::XorShiftRng, SeedableRng};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_ssz_round_trip() {
|
||||||
|
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||||
|
let original = CrosslinkRecord::random_for_test(&mut rng);
|
||||||
|
|
||||||
|
let bytes = ssz_encode(&original);
|
||||||
|
let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(original, decoded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use super::ssz::{decode_ssz_list, Decodable, DecodeError, Encodable, SszStream};
|
use super::ssz::{Decodable, DecodeError, Encodable, SszStream};
|
||||||
use super::Hash256;
|
use super::Hash256;
|
||||||
use crate::test_utils::TestRandom;
|
use crate::test_utils::TestRandom;
|
||||||
use bls::{PublicKey, Signature};
|
use bls::{PublicKey, Signature};
|
||||||
@ -14,7 +14,7 @@ pub struct DepositInput {
|
|||||||
|
|
||||||
impl Encodable for DepositInput {
|
impl Encodable for DepositInput {
|
||||||
fn ssz_append(&self, s: &mut SszStream) {
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
s.append_vec(&self.pubkey.as_bytes());
|
s.append(&self.pubkey);
|
||||||
s.append(&self.withdrawal_credentials);
|
s.append(&self.withdrawal_credentials);
|
||||||
s.append(&self.randao_commitment);
|
s.append(&self.randao_commitment);
|
||||||
s.append(&self.proof_of_possession);
|
s.append(&self.proof_of_possession);
|
||||||
@ -23,8 +23,7 @@ impl Encodable for DepositInput {
|
|||||||
|
|
||||||
impl Decodable for DepositInput {
|
impl Decodable for DepositInput {
|
||||||
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
let (pubkey_bytes, i) = decode_ssz_list(bytes, i)?;
|
let (pubkey, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
let pubkey = PublicKey::from_bytes(&pubkey_bytes).map_err(|_| DecodeError::TooShort)?;
|
|
||||||
let (withdrawal_credentials, i) = <_>::ssz_decode(bytes, i)?;
|
let (withdrawal_credentials, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
let (randao_commitment, i) = <_>::ssz_decode(bytes, i)?;
|
let (randao_commitment, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
let (proof_of_possession, i) = <_>::ssz_decode(bytes, i)?;
|
let (proof_of_possession, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
@ -1,6 +1,64 @@
|
|||||||
|
use super::ssz::{Decodable, DecodeError, Encodable, SszStream};
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::RngCore;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct ForkData {
|
pub struct ForkData {
|
||||||
pub pre_fork_version: u64,
|
pub pre_fork_version: u64,
|
||||||
pub post_fork_version: u64,
|
pub post_fork_version: u64,
|
||||||
pub fork_slot: u64,
|
pub fork_slot: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Encodable for ForkData {
|
||||||
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
|
s.append(&self.pre_fork_version);
|
||||||
|
s.append(&self.post_fork_version);
|
||||||
|
s.append(&self.fork_slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for ForkData {
|
||||||
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
|
let (pre_fork_version, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (post_fork_version, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (fork_slot, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Self {
|
||||||
|
pre_fork_version,
|
||||||
|
post_fork_version,
|
||||||
|
fork_slot,
|
||||||
|
},
|
||||||
|
i,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: RngCore> TestRandom<T> for ForkData {
|
||||||
|
fn random_for_test(rng: &mut T) -> Self {
|
||||||
|
Self {
|
||||||
|
pre_fork_version: <_>::random_for_test(rng),
|
||||||
|
post_fork_version: <_>::random_for_test(rng),
|
||||||
|
fork_slot: <_>::random_for_test(rng),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::super::ssz::ssz_encode;
|
||||||
|
use super::*;
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::{prng::XorShiftRng, SeedableRng};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_ssz_round_trip() {
|
||||||
|
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||||
|
let original = ForkData::random_for_test(&mut rng);
|
||||||
|
|
||||||
|
let bytes = ssz_encode(&original);
|
||||||
|
let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(original, decoded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
|
use super::ssz::{Decodable, DecodeError, Encodable, SszStream};
|
||||||
use super::{AttestationData, Bitfield};
|
use super::{AttestationData, Bitfield};
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::RngCore;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct PendingAttestationRecord {
|
pub struct PendingAttestationRecord {
|
||||||
@ -7,3 +10,61 @@ pub struct PendingAttestationRecord {
|
|||||||
pub custody_bitfield: Bitfield,
|
pub custody_bitfield: Bitfield,
|
||||||
pub slot_included: u64,
|
pub slot_included: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Encodable for PendingAttestationRecord {
|
||||||
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
|
s.append(&self.data);
|
||||||
|
s.append(&self.participation_bitfield);
|
||||||
|
s.append(&self.custody_bitfield);
|
||||||
|
s.append(&self.slot_included);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for PendingAttestationRecord {
|
||||||
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
|
let (data, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (participation_bitfield, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (custody_bitfield, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (slot_included, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Self {
|
||||||
|
data,
|
||||||
|
participation_bitfield,
|
||||||
|
custody_bitfield,
|
||||||
|
slot_included,
|
||||||
|
},
|
||||||
|
i,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: RngCore> TestRandom<T> for PendingAttestationRecord {
|
||||||
|
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),
|
||||||
|
slot_included: <_>::random_for_test(rng),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::super::ssz::ssz_encode;
|
||||||
|
use super::*;
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::{prng::XorShiftRng, SeedableRng};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_ssz_round_trip() {
|
||||||
|
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||||
|
let original = PendingAttestationRecord::random_for_test(&mut rng);
|
||||||
|
|
||||||
|
let bytes = ssz_encode(&original);
|
||||||
|
let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(original, decoded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,28 +1,53 @@
|
|||||||
|
use super::ssz::{Decodable, DecodeError, Encodable, SszStream};
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::RngCore;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct ShardCommittee {
|
pub struct ShardCommittee {
|
||||||
pub shard: u16,
|
pub shard: u64,
|
||||||
pub committee: Vec<usize>,
|
pub committee: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShardCommittee {
|
impl Encodable for ShardCommittee {
|
||||||
/// Returns a new instance where the `shard_id` is zero and the
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
/// committee is an empty vector.
|
s.append(&self.shard);
|
||||||
pub fn zero() -> Self {
|
s.append(&self.committee);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for ShardCommittee {
|
||||||
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
|
let (shard, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (committee, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
|
||||||
|
Ok((Self { shard, committee }, i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: RngCore> TestRandom<T> for ShardCommittee {
|
||||||
|
fn random_for_test(rng: &mut T) -> Self {
|
||||||
Self {
|
Self {
|
||||||
shard: 0,
|
shard: <_>::random_for_test(rng),
|
||||||
committee: vec![],
|
committee: <_>::random_for_test(rng),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use super::super::ssz::ssz_encode;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::{prng::XorShiftRng, SeedableRng};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_shard_and_committee_zero() {
|
pub fn test_ssz_round_trip() {
|
||||||
let s = ShardCommittee::zero();
|
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||||
assert_eq!(s.shard, 0);
|
let original = ShardCommittee::random_for_test(&mut rng);
|
||||||
assert_eq!(s.committee.len(), 0);
|
|
||||||
|
let bytes = ssz_encode(&original);
|
||||||
|
let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(original, decoded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,64 @@
|
|||||||
|
use super::ssz::{Decodable, DecodeError, Encodable, SszStream};
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::RngCore;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct ShardReassignmentRecord {
|
pub struct ShardReassignmentRecord {
|
||||||
pub validator_index: u64,
|
pub validator_index: u64,
|
||||||
pub shard: u64,
|
pub shard: u64,
|
||||||
pub slot: u64,
|
pub slot: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Encodable for ShardReassignmentRecord {
|
||||||
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
|
s.append(&self.validator_index);
|
||||||
|
s.append(&self.shard);
|
||||||
|
s.append(&self.slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for ShardReassignmentRecord {
|
||||||
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
|
let (validator_index, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (shard, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (slot, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Self {
|
||||||
|
validator_index,
|
||||||
|
shard,
|
||||||
|
slot,
|
||||||
|
},
|
||||||
|
i,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: RngCore> TestRandom<T> for ShardReassignmentRecord {
|
||||||
|
fn random_for_test(rng: &mut T) -> Self {
|
||||||
|
Self {
|
||||||
|
validator_index: <_>::random_for_test(rng),
|
||||||
|
shard: <_>::random_for_test(rng),
|
||||||
|
slot: <_>::random_for_test(rng),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::super::ssz::ssz_encode;
|
||||||
|
use super::*;
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::{prng::XorShiftRng, SeedableRng};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_ssz_round_trip() {
|
||||||
|
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||||
|
let original = ShardReassignmentRecord::random_for_test(&mut rng);
|
||||||
|
|
||||||
|
let bytes = ssz_encode(&original);
|
||||||
|
let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(original, decoded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
11
beacon_chain/types/src/test_utils/address.rs
Normal file
11
beacon_chain/types/src/test_utils/address.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
use super::TestRandom;
|
||||||
|
use crate::Address;
|
||||||
|
use rand::RngCore;
|
||||||
|
|
||||||
|
impl<T: RngCore> TestRandom<T> for Address {
|
||||||
|
fn random_for_test(rng: &mut T) -> Self {
|
||||||
|
let mut key_bytes = vec![0; 20];
|
||||||
|
rng.fill_bytes(&mut key_bytes);
|
||||||
|
Address::from(&key_bytes[..])
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ use rand::RngCore;
|
|||||||
|
|
||||||
pub use rand::{prng::XorShiftRng, SeedableRng};
|
pub use rand::{prng::XorShiftRng, SeedableRng};
|
||||||
|
|
||||||
|
pub mod address;
|
||||||
pub mod aggregate_signature;
|
pub mod aggregate_signature;
|
||||||
pub mod bitfield;
|
pub mod bitfield;
|
||||||
pub mod hash256;
|
pub mod hash256;
|
||||||
@ -27,6 +28,12 @@ impl<T: RngCore> TestRandom<T> for u32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: RngCore> TestRandom<T> for usize {
|
||||||
|
fn random_for_test(rng: &mut T) -> Self {
|
||||||
|
rng.next_u32() as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: RngCore, U> TestRandom<T> for Vec<U>
|
impl<T: RngCore, U> TestRandom<T> for Vec<U>
|
||||||
where U: TestRandom<T>
|
where U: TestRandom<T>
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
use super::bls::{Keypair, PublicKey};
|
use super::bls::PublicKey;
|
||||||
use super::{Address, Hash256};
|
use super::{Address, Hash256};
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::RngCore;
|
||||||
|
use ssz::{Decodable, DecodeError, Encodable, SszStream};
|
||||||
use std::convert;
|
use std::convert;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
@ -38,44 +41,131 @@ pub struct ValidatorRecord {
|
|||||||
pub exit_slot: u64,
|
pub exit_slot: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ValidatorRecord {
|
impl Encodable for ValidatorStatus {
|
||||||
/// Generates a new instance where the keypair is generated using
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
/// `rand::thread_rng` entropy and all other fields are set to zero.
|
let byte: u8 = match self {
|
||||||
///
|
ValidatorStatus::PendingActivation => 0,
|
||||||
/// Returns the new instance and new keypair.
|
ValidatorStatus::Active => 1,
|
||||||
pub fn zero_with_thread_rand_keypair() -> (Self, Keypair) {
|
ValidatorStatus::PendingExit => 2,
|
||||||
let keypair = Keypair::random();
|
ValidatorStatus::PendingWithdraw => 3,
|
||||||
let s = Self {
|
ValidatorStatus::Withdrawn => 5,
|
||||||
pubkey: keypair.pk.clone(),
|
ValidatorStatus::Penalized => 127,
|
||||||
withdrawal_shard: 0,
|
|
||||||
withdrawal_address: Address::zero(),
|
|
||||||
randao_commitment: Hash256::zero(),
|
|
||||||
randao_last_change: 0,
|
|
||||||
balance: 0,
|
|
||||||
status: From::from(0),
|
|
||||||
exit_slot: 0,
|
|
||||||
};
|
};
|
||||||
(s, keypair)
|
s.append(&byte);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn status_is(&self, status: ValidatorStatus) -> bool {
|
impl Decodable for ValidatorStatus {
|
||||||
self.status == status
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
|
let (byte, i) = u8::ssz_decode(bytes, i)?;
|
||||||
|
let status = match byte {
|
||||||
|
0 => ValidatorStatus::PendingActivation,
|
||||||
|
1 => ValidatorStatus::Active,
|
||||||
|
2 => ValidatorStatus::PendingExit,
|
||||||
|
3 => ValidatorStatus::PendingWithdraw,
|
||||||
|
5 => ValidatorStatus::Withdrawn,
|
||||||
|
127 => ValidatorStatus::Penalized,
|
||||||
|
_ => return Err(DecodeError::Invalid),
|
||||||
|
};
|
||||||
|
Ok((status, i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: RngCore> TestRandom<T> for ValidatorStatus {
|
||||||
|
fn random_for_test(rng: &mut T) -> Self {
|
||||||
|
let options = vec![
|
||||||
|
ValidatorStatus::PendingActivation,
|
||||||
|
ValidatorStatus::Active,
|
||||||
|
ValidatorStatus::PendingExit,
|
||||||
|
ValidatorStatus::PendingWithdraw,
|
||||||
|
ValidatorStatus::Withdrawn,
|
||||||
|
ValidatorStatus::Penalized,
|
||||||
|
];
|
||||||
|
options[(rng.next_u32() as usize) % options.len()].clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodable for ValidatorRecord {
|
||||||
|
fn ssz_append(&self, s: &mut SszStream) {
|
||||||
|
s.append(&self.pubkey);
|
||||||
|
s.append(&self.withdrawal_shard);
|
||||||
|
s.append(&self.withdrawal_address);
|
||||||
|
s.append(&self.randao_commitment);
|
||||||
|
s.append(&self.randao_last_change);
|
||||||
|
s.append(&self.balance);
|
||||||
|
s.append(&self.status);
|
||||||
|
s.append(&self.exit_slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for ValidatorRecord {
|
||||||
|
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
|
||||||
|
let (pubkey, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (withdrawal_shard, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (withdrawal_address, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (randao_commitment, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (randao_last_change, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (balance, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (status, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
let (exit_slot, i) = <_>::ssz_decode(bytes, i)?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
Self {
|
||||||
|
pubkey,
|
||||||
|
withdrawal_shard,
|
||||||
|
withdrawal_address,
|
||||||
|
randao_commitment,
|
||||||
|
randao_last_change,
|
||||||
|
balance,
|
||||||
|
status,
|
||||||
|
exit_slot,
|
||||||
|
},
|
||||||
|
i,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: RngCore> TestRandom<T> for ValidatorRecord {
|
||||||
|
fn random_for_test(rng: &mut T) -> Self {
|
||||||
|
Self {
|
||||||
|
pubkey: <_>::random_for_test(rng),
|
||||||
|
withdrawal_shard: <_>::random_for_test(rng),
|
||||||
|
withdrawal_address: <_>::random_for_test(rng),
|
||||||
|
randao_commitment: <_>::random_for_test(rng),
|
||||||
|
randao_last_change: <_>::random_for_test(rng),
|
||||||
|
balance: <_>::random_for_test(rng),
|
||||||
|
status: <_>::random_for_test(rng),
|
||||||
|
exit_slot: <_>::random_for_test(rng),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use super::super::ssz::ssz_encode;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::test_utils::TestRandom;
|
||||||
|
use rand::{prng::XorShiftRng, SeedableRng};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_validator_record_zero_rand_keypair() {
|
pub fn test_ssz_round_trip() {
|
||||||
let (v, _kp) = ValidatorRecord::zero_with_thread_rand_keypair();
|
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||||
assert_eq!(v.withdrawal_shard, 0);
|
let original = ValidatorRecord::random_for_test(&mut rng);
|
||||||
assert!(v.withdrawal_address.is_zero());
|
|
||||||
assert!(v.randao_commitment.is_zero());
|
let bytes = ssz_encode(&original);
|
||||||
assert_eq!(v.randao_last_change, 0);
|
let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap();
|
||||||
assert_eq!(v.balance, 0);
|
|
||||||
assert_eq!(v.status, From::from(0));
|
assert_eq!(original, decoded);
|
||||||
assert_eq!(v.exit_slot, 0);
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_validator_status_ssz_round_trip() {
|
||||||
|
let mut rng = XorShiftRng::from_seed([42; 16]);
|
||||||
|
let original = ValidatorStatus::random_for_test(&mut rng);
|
||||||
|
|
||||||
|
let bytes = ssz_encode(&original);
|
||||||
|
let (decoded, _) = <_>::ssz_decode(&bytes, 0).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(original, decoded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use super::{Address, Hash256};
|
use super::{Address, Hash256};
|
||||||
use bls::{create_proof_of_possession, Keypair, PublicKey, Signature};
|
use bls::{PublicKey, Signature};
|
||||||
|
|
||||||
/// The information gathered from the PoW chain validator registration function.
|
/// The information gathered from the PoW chain validator registration function.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
@ -10,17 +10,3 @@ pub struct ValidatorRegistration {
|
|||||||
pub randao_commitment: Hash256,
|
pub randao_commitment: Hash256,
|
||||||
pub proof_of_possession: Signature,
|
pub proof_of_possession: Signature,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ValidatorRegistration {
|
|
||||||
pub fn random() -> Self {
|
|
||||||
let keypair = Keypair::random();
|
|
||||||
|
|
||||||
Self {
|
|
||||||
pubkey: keypair.pk.clone(),
|
|
||||||
withdrawal_shard: 0,
|
|
||||||
withdrawal_address: Address::random(),
|
|
||||||
randao_commitment: Hash256::random(),
|
|
||||||
proof_of_possession: create_proof_of_possession(&keypair),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user