mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-07 16:55:46 +00:00
Merge branch 'master' into validator-record-update
This commit is contained in:
@@ -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,
|
||||
|
||||
87
beacon_chain/types/src/attestation.rs
Normal file
87
beacon_chain/types/src/attestation.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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>,
|
||||
}
|
||||
|
||||
|
||||
0
beacon_chain/types/src/beacon_block_body.rs
Normal file
0
beacon_chain/types/src/beacon_block_body.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user