Merge branch 'master' into validator-record-update

This commit is contained in:
Grant Wuerker
2018-12-12 18:42:16 -06:00
45 changed files with 1152 additions and 2773 deletions

View File

@@ -1,9 +1,9 @@
use super::Hash256;
use super::{AttestationRecord, SpecialRecord};
use super::{Attestation, SpecialRecord};
#[derive(Debug, PartialEq)]
pub struct ActiveState {
pub pending_attestations: Vec<AttestationRecord>,
pub pending_attestations: Vec<Attestation>,
pub pending_specials: Vec<SpecialRecord>,
pub recent_block_hashes: Vec<Hash256>,
pub randao_mix: Hash256,

View File

@@ -0,0 +1,87 @@
use super::attestation_data::SSZ_ATTESTION_DATA_LENGTH;
use super::bls::{AggregateSignature, BLS_AGG_SIG_BYTE_SIZE};
use super::ssz::{decode_ssz_list, Decodable, DecodeError, Encodable, SszStream, LENGTH_BYTES};
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
};
#[derive(Debug, Clone, PartialEq)]
pub struct Attestation {
pub data: AttestationData,
pub participation_bitfield: Bitfield,
pub custody_bitfield: Bitfield,
pub aggregate_sig: AggregateSignature,
}
impl Encodable for Attestation {
fn ssz_append(&self, s: &mut SszStream) {
s.append(&self.data);
s.append(&self.participation_bitfield);
s.append(&self.custody_bitfield);
s.append_vec(&self.aggregate_sig.as_bytes());
}
}
impl Decodable for Attestation {
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
let (data, i) = AttestationData::ssz_decode(bytes, i)?;
let (participation_bitfield, i) = Bitfield::ssz_decode(bytes, i)?;
let (custody_bitfield, i) = Bitfield::ssz_decode(bytes, i)?;
let (agg_sig_bytes, i) = decode_ssz_list(bytes, i)?;
let aggregate_sig =
AggregateSignature::from_bytes(&agg_sig_bytes).map_err(|_| DecodeError::TooShort)?; // also could be TooLong
let attestation_record = Self {
data,
participation_bitfield,
custody_bitfield,
aggregate_sig,
};
Ok((attestation_record, i))
}
}
impl Attestation {
pub fn zero() -> Self {
Self {
data: AttestationData::zero(),
participation_bitfield: Bitfield::new(),
custody_bitfield: Bitfield::new(),
aggregate_sig: AggregateSignature::new(),
}
}
}
#[cfg(test)]
mod tests {
use super::super::ssz::ssz_encode;
use super::*;
#[test]
pub fn test_attestation_record_min_ssz_length() {
let ar = Attestation::zero();
let ssz = ssz_encode(&ar);
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();
assert_eq!(original, decoded);
}
}

View File

@@ -1,6 +1,18 @@
use super::ssz::{Decodable, DecodeError, Encodable, SszStream};
use super::Hash256;
#[derive(Debug, Clone, PartialEq)]
pub const SSZ_ATTESTION_DATA_LENGTH: usize = {
8 + // slot
8 + // shard
32 + // beacon_block_hash
32 + // epoch_boundary_hash
32 + // shard_block_hash
32 + // latest_crosslink_hash
8 + // justified_slot
32 // justified_block_hash
};
#[derive(Debug, Clone, PartialEq, Default)]
pub struct AttestationData {
pub slot: u64,
pub shard: u64,
@@ -11,3 +23,88 @@ pub struct AttestationData {
pub justified_slot: u64,
pub justified_block_hash: Hash256,
}
impl AttestationData {
pub fn zero() -> Self {
Self {
slot: 0,
shard: 0,
beacon_block_hash: Hash256::zero(),
epoch_boundary_hash: Hash256::zero(),
shard_block_hash: Hash256::zero(),
latest_crosslink_hash: Hash256::zero(),
justified_slot: 0,
justified_block_hash: Hash256::zero(),
}
}
// TODO: Implement this as a merkle root, once tree_ssz is implemented.
// https://github.com/sigp/lighthouse/issues/92
pub fn canonical_root(&self) -> Hash256 {
Hash256::zero()
}
}
impl Encodable for AttestationData {
fn ssz_append(&self, s: &mut SszStream) {
s.append(&self.slot);
s.append(&self.shard);
s.append(&self.beacon_block_hash);
s.append(&self.epoch_boundary_hash);
s.append(&self.shard_block_hash);
s.append(&self.latest_crosslink_hash);
s.append(&self.justified_slot);
s.append(&self.justified_block_hash);
}
}
impl Decodable for AttestationData {
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 (beacon_block_hash, i) = Hash256::ssz_decode(bytes, i)?;
let (epoch_boundary_hash, i) = Hash256::ssz_decode(bytes, i)?;
let (shard_block_hash, i) = Hash256::ssz_decode(bytes, i)?;
let (latest_crosslink_hash, i) = Hash256::ssz_decode(bytes, i)?;
let (justified_slot, i) = u64::ssz_decode(bytes, i)?;
let (justified_block_hash, i) = Hash256::ssz_decode(bytes, i)?;
let attestation_data = AttestationData {
slot,
shard,
beacon_block_hash,
epoch_boundary_hash,
shard_block_hash,
latest_crosslink_hash,
justified_slot,
justified_block_hash,
};
Ok((attestation_data, i))
}
}
#[cfg(test)]
mod tests {
use super::super::ssz::ssz_encode;
use super::*;
#[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()),
};
let ssz = ssz_encode(&original);
let (decoded, _) = AttestationData::ssz_decode(&ssz, 0).unwrap();
assert_eq!(original, decoded);
}
}

View File

@@ -1,127 +0,0 @@
use super::bls::{AggregateSignature, BLS_AGG_SIG_BYTE_SIZE};
use super::ssz::{decode_ssz_list, Decodable, DecodeError, Encodable, SszStream};
use super::{Bitfield, Hash256};
pub const MIN_SSZ_ATTESTION_RECORD_LENGTH: usize = {
8 + // slot
2 + // shard_id
4 + // oblique_parent_hashes (empty list)
32 + // shard_block_hash
5 + // attester_bitfield (assuming 1 byte of bitfield)
8 + // justified_slot
32 + // justified_block_hash
4 + BLS_AGG_SIG_BYTE_SIZE // aggregate sig (two 256 bit points)
};
#[derive(Debug, Clone, PartialEq)]
pub struct AttestationRecord {
pub slot: u64,
pub shard_id: u16,
pub oblique_parent_hashes: Vec<Hash256>,
pub shard_block_hash: Hash256,
pub attester_bitfield: Bitfield,
pub justified_slot: u64,
pub justified_block_hash: Hash256,
pub aggregate_sig: AggregateSignature,
}
impl Encodable for AttestationRecord {
fn ssz_append(&self, s: &mut SszStream) {
s.append(&self.slot);
s.append(&self.shard_id);
s.append_vec(&self.oblique_parent_hashes);
s.append(&self.shard_block_hash);
s.append(&self.attester_bitfield);
s.append(&self.justified_slot);
s.append(&self.justified_block_hash);
s.append_vec(&self.aggregate_sig.as_bytes());
}
}
impl Decodable for AttestationRecord {
fn ssz_decode(bytes: &[u8], i: usize) -> Result<(Self, usize), DecodeError> {
let (slot, i) = u64::ssz_decode(bytes, i)?;
let (shard_id, i) = u16::ssz_decode(bytes, i)?;
let (oblique_parent_hashes, i) = decode_ssz_list(bytes, i)?;
let (shard_block_hash, i) = Hash256::ssz_decode(bytes, i)?;
let (attester_bitfield, i) = Bitfield::ssz_decode(bytes, i)?;
let (justified_slot, i) = u64::ssz_decode(bytes, i)?;
let (justified_block_hash, i) = Hash256::ssz_decode(bytes, i)?;
// Do aggregate sig decoding properly.
let (agg_sig_bytes, i) = decode_ssz_list(bytes, i)?;
let aggregate_sig =
AggregateSignature::from_bytes(&agg_sig_bytes).map_err(|_| DecodeError::TooShort)?; // also could be TooLong
let attestation_record = Self {
slot,
shard_id,
oblique_parent_hashes,
shard_block_hash,
attester_bitfield,
justified_slot,
justified_block_hash,
aggregate_sig,
};
Ok((attestation_record, i))
}
}
impl AttestationRecord {
pub fn zero() -> Self {
Self {
slot: 0,
shard_id: 0,
oblique_parent_hashes: vec![],
shard_block_hash: Hash256::zero(),
attester_bitfield: Bitfield::new(),
justified_slot: 0,
justified_block_hash: Hash256::zero(),
aggregate_sig: AggregateSignature::new(),
}
}
}
#[cfg(test)]
mod tests {
use super::super::ssz::SszStream;
use super::*;
#[test]
pub fn test_attestation_record_min_ssz_length() {
let ar = AttestationRecord::zero();
let mut ssz_stream = SszStream::new();
ssz_stream.append(&ar);
let ssz = ssz_stream.drain();
assert_eq!(ssz.len(), MIN_SSZ_ATTESTION_RECORD_LENGTH);
}
#[test]
pub fn test_attestation_record_min_ssz_encode_decode() {
let original = AttestationRecord {
slot: 7,
shard_id: 9,
oblique_parent_hashes: vec![Hash256::from(&vec![14; 32][..])],
shard_block_hash: Hash256::from(&vec![15; 32][..]),
attester_bitfield: Bitfield::from_bytes(&vec![17; 42][..]),
justified_slot: 19,
justified_block_hash: Hash256::from(&vec![15; 32][..]),
aggregate_sig: AggregateSignature::new(),
};
let mut ssz_stream = SszStream::new();
ssz_stream.append(&original);
let (decoded, _) = AttestationRecord::ssz_decode(&ssz_stream.drain(), 0).unwrap();
assert_eq!(original.slot, decoded.slot);
assert_eq!(original.shard_id, decoded.shard_id);
assert_eq!(
original.oblique_parent_hashes,
decoded.oblique_parent_hashes
);
assert_eq!(original.shard_block_hash, decoded.shard_block_hash);
assert_eq!(original.attester_bitfield, decoded.attester_bitfield);
assert_eq!(original.justified_slot, decoded.justified_slot);
assert_eq!(original.justified_block_hash, decoded.justified_block_hash);
}
}

View File

@@ -1,4 +1,4 @@
use super::attestation_record::AttestationRecord;
use super::attestation::Attestation;
use super::special_record::SpecialRecord;
use super::ssz::{Decodable, DecodeError, Encodable, SszStream};
use super::Hash256;
@@ -15,7 +15,7 @@ pub const MIN_SSZ_BLOCK_LENGTH: usize = {
};
pub const MAX_SSZ_BLOCK_LENGTH: usize = MIN_SSZ_BLOCK_LENGTH + (1 << 24);
#[derive(Debug, PartialEq, Clone)]
#[derive(Debug, PartialEq, Clone, Default)]
pub struct BeaconBlock {
pub slot: u64,
pub randao_reveal: Hash256,
@@ -23,7 +23,7 @@ pub struct BeaconBlock {
pub ancestor_hashes: Vec<Hash256>,
pub active_state_root: Hash256,
pub crystallized_state_root: Hash256,
pub attestations: Vec<AttestationRecord>,
pub attestations: Vec<Attestation>,
pub specials: Vec<SpecialRecord>,
}

View File

@@ -2,6 +2,7 @@ use super::ValidatorRecord;
#[derive(Debug, Clone, PartialEq)]
pub struct ChainConfig {
// Old, potentially outdated constants
pub cycle_length: u8,
pub deposit_size_gwei: u64,
pub shard_count: u16,
@@ -9,8 +10,11 @@ pub struct ChainConfig {
pub max_validator_churn_quotient: u64,
pub genesis_time: u64,
pub slot_duration_millis: u64,
// TODO: revisit this
pub initial_validators: Vec<ValidatorRecord>,
// New constants
pub epoch_length: u64,
pub min_attestation_inclusion_delay: u64,
}
/*
@@ -29,6 +33,10 @@ impl ChainConfig {
genesis_time: TEST_GENESIS_TIME,
slot_duration_millis: 16 * 1000,
initial_validators: vec![],
// New
epoch_length: 64,
min_attestation_inclusion_delay: 4,
}
}
@@ -55,6 +63,10 @@ impl ChainConfig {
genesis_time: TEST_GENESIS_TIME, // arbitrary
slot_duration_millis: 16 * 1000,
initial_validators: vec![],
// New constants
epoch_length: 64,
min_attestation_inclusion_delay: 4,
}
}
}

View File

@@ -2,31 +2,16 @@ use super::Hash256;
#[derive(Clone, Debug, PartialEq)]
pub struct CrosslinkRecord {
pub recently_changed: bool,
pub slot: u64,
pub hash: Hash256,
pub shard_block_hash: Hash256,
}
impl CrosslinkRecord {
/// Generates a new instance where `dynasty` and `hash` are both zero.
pub fn zero() -> Self {
Self {
recently_changed: false,
slot: 0,
hash: Hash256::zero(),
shard_block_hash: Hash256::zero(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_crosslink_record_zero() {
let c = CrosslinkRecord::zero();
assert_eq!(c.recently_changed, false);
assert_eq!(c.slot, 0);
assert!(c.hash.is_zero());
}
}

View File

@@ -5,7 +5,7 @@ extern crate ssz;
pub mod active_state;
pub mod attestation_data;
pub mod attestation_record;
pub mod attestation;
pub mod beacon_block;
pub mod beacon_state;
pub mod candidate_pow_receipt_root_record;
@@ -24,7 +24,7 @@ use std::collections::HashMap;
pub use active_state::ActiveState;
pub use attestation_data::AttestationData;
pub use attestation_record::AttestationRecord;
pub use attestation::Attestation;
pub use beacon_block::BeaconBlock;
pub use beacon_state::BeaconState;
pub use chain_config::ChainConfig;