Add attestion ssz splitter, change dir structure
This commit is contained in:
parent
c55b94053b
commit
2141b8c623
@ -22,7 +22,7 @@ pub const MIN_SSZ_ATTESTION_RECORD_LENGTH: usize = {
|
|||||||
4 + BLS_AGG_SIG_BYTE_SIZE // aggregate sig (two 256 bit points)
|
4 + BLS_AGG_SIG_BYTE_SIZE // aggregate sig (two 256 bit points)
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct AttestationRecord {
|
pub struct AttestationRecord {
|
||||||
pub slot: u64,
|
pub slot: u64,
|
||||||
pub shard_id: u16,
|
pub shard_id: u16,
|
17
lighthouse/state/attestation_record/mod.rs
Normal file
17
lighthouse/state/attestation_record/mod.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
use super::bls;
|
||||||
|
use super::ssz;
|
||||||
|
use super::utils;
|
||||||
|
|
||||||
|
|
||||||
|
mod attestation_record;
|
||||||
|
mod ssz_splitter;
|
||||||
|
|
||||||
|
pub use self::attestation_record::{
|
||||||
|
AttestationRecord,
|
||||||
|
MIN_SSZ_ATTESTION_RECORD_LENGTH,
|
||||||
|
};
|
||||||
|
pub use self::ssz_splitter::{
|
||||||
|
split_all,
|
||||||
|
split_one,
|
||||||
|
AttestationSplitError,
|
||||||
|
};
|
139
lighthouse/state/attestation_record/ssz_splitter.rs
Normal file
139
lighthouse/state/attestation_record/ssz_splitter.rs
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
use super::MIN_SSZ_ATTESTION_RECORD_LENGTH as MIN_LENGTH;
|
||||||
|
use super::ssz::LENGTH_BYTES;
|
||||||
|
use super::ssz::decode::decode_length;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum AttestationSplitError {
|
||||||
|
TooShort,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given some ssz slice, find the bounds of each serialized AttestationRecord and return a vec of
|
||||||
|
/// slices point to each.
|
||||||
|
pub fn split_all<'a>(full_ssz: &'a [u8], index: usize)
|
||||||
|
-> Result<Vec<&'a [u8]>, AttestationSplitError>
|
||||||
|
{
|
||||||
|
let mut v = vec![];
|
||||||
|
let mut index = index;
|
||||||
|
while index < full_ssz.len() - 1 {
|
||||||
|
let (slice, i) = split_one(full_ssz, index)?;
|
||||||
|
v.push(slice);
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
|
Ok(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given some ssz slice, find the bounds of one serialized AttestationRecord
|
||||||
|
/// and return a slice pointing to that.
|
||||||
|
pub fn split_one<'a>(full_ssz: &'a [u8], index: usize)
|
||||||
|
-> Result<(&'a [u8], usize), AttestationSplitError>
|
||||||
|
{
|
||||||
|
if full_ssz.len() < MIN_LENGTH {
|
||||||
|
return Err(AttestationSplitError::TooShort);
|
||||||
|
}
|
||||||
|
|
||||||
|
let hashes_len = decode_length(full_ssz, 10, LENGTH_BYTES)
|
||||||
|
.map_err(|_| AttestationSplitError::TooShort)?;
|
||||||
|
|
||||||
|
let bitfield_len = decode_length(
|
||||||
|
full_ssz, hashes_len + 46,
|
||||||
|
LENGTH_BYTES)
|
||||||
|
.map_err(|_| AttestationSplitError::TooShort)?;
|
||||||
|
|
||||||
|
// Subtract one because the min length assume 1 byte of bitfield
|
||||||
|
let len = MIN_LENGTH
|
||||||
|
+ hashes_len
|
||||||
|
+ bitfield_len.saturating_sub(1);
|
||||||
|
|
||||||
|
if full_ssz.len() < len {
|
||||||
|
return Err(AttestationSplitError::TooShort);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((&full_ssz[index..(index + len)], index + len))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use super::super::AttestationRecord;
|
||||||
|
use super::super::utils::types::{
|
||||||
|
Hash256,
|
||||||
|
Bitfield,
|
||||||
|
};
|
||||||
|
use super::super::bls::AggregateSignature;
|
||||||
|
use super::super::ssz::{
|
||||||
|
SszStream,
|
||||||
|
Decodable,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn get_two_records() -> Vec<AttestationRecord> {
|
||||||
|
let a = 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(&vec![17; 42][..]),
|
||||||
|
justified_slot: 19,
|
||||||
|
justified_block_hash: Hash256::from(&vec![15; 32][..]),
|
||||||
|
aggregate_sig: AggregateSignature::new(),
|
||||||
|
};
|
||||||
|
let b = AttestationRecord {
|
||||||
|
slot: 9,
|
||||||
|
shard_id: 7,
|
||||||
|
oblique_parent_hashes: vec![Hash256::from(&vec![15; 32][..])],
|
||||||
|
shard_block_hash: Hash256::from(&vec![14; 32][..]),
|
||||||
|
attester_bitfield: Bitfield::from(&vec![19; 42][..]),
|
||||||
|
justified_slot: 15,
|
||||||
|
justified_block_hash: Hash256::from(&vec![17; 32][..]),
|
||||||
|
aggregate_sig: AggregateSignature::new(),
|
||||||
|
};
|
||||||
|
vec![a, b]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_attestation_ssz_split() {
|
||||||
|
let ars = get_two_records();
|
||||||
|
let a = ars[0].clone();
|
||||||
|
let b = ars[1].clone();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test split one
|
||||||
|
*/
|
||||||
|
let mut ssz_stream = SszStream::new();
|
||||||
|
ssz_stream.append(&a);
|
||||||
|
let ssz = ssz_stream.drain();
|
||||||
|
let (a_ssz, i) = split_one(&ssz, 0).unwrap();
|
||||||
|
assert_eq!(i, ssz.len());
|
||||||
|
let (decoded_a, _) = AttestationRecord::ssz_decode(a_ssz, 0)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(a, decoded_a);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test split two
|
||||||
|
*/
|
||||||
|
let mut ssz_stream = SszStream::new();
|
||||||
|
ssz_stream.append(&a);
|
||||||
|
ssz_stream.append(&b);
|
||||||
|
let ssz = ssz_stream.drain();
|
||||||
|
let ssz_vec = split_all(&ssz, 0).unwrap();
|
||||||
|
let (decoded_a, _) =
|
||||||
|
AttestationRecord::ssz_decode(ssz_vec[0], 0)
|
||||||
|
.unwrap();
|
||||||
|
let (decoded_b, _) =
|
||||||
|
AttestationRecord::ssz_decode(ssz_vec[1], 0)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(a, decoded_a);
|
||||||
|
assert_eq!(b, decoded_b);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test split two with shortened ssz
|
||||||
|
*/
|
||||||
|
let mut ssz_stream = SszStream::new();
|
||||||
|
ssz_stream.append(&a);
|
||||||
|
ssz_stream.append(&b);
|
||||||
|
let ssz = ssz_stream.drain();
|
||||||
|
let ssz = &ssz[0..ssz.len() - 1];
|
||||||
|
assert!(split_all(&ssz, 0).is_err());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,9 +13,6 @@ use super::attestation_record::MIN_SSZ_ATTESTION_RECORD_LENGTH;
|
|||||||
pub enum BlockValidatorError {
|
pub enum BlockValidatorError {
|
||||||
TooShort,
|
TooShort,
|
||||||
TooLong,
|
TooLong,
|
||||||
BadPowHash,
|
|
||||||
SlotTooLow,
|
|
||||||
SlotTooHigh,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const LENGTH_BYTES: usize = 4;
|
const LENGTH_BYTES: usize = 4;
|
||||||
@ -23,7 +20,7 @@ const LENGTH_BYTES: usize = 4;
|
|||||||
/// Allows for reading of block values directly from serialized ssz bytes.
|
/// Allows for reading of block values directly from serialized ssz bytes.
|
||||||
///
|
///
|
||||||
/// The purpose of this struct is to provide the functionality to read block fields directly from
|
/// The purpose of this struct is to provide the functionality to read block fields directly from
|
||||||
/// some serialized SSZ slice, effectively allowing us to read the block without fully
|
/// some serialized SSZ slice allowing us to read the block without fully
|
||||||
/// de-serializing it.
|
/// de-serializing it.
|
||||||
///
|
///
|
||||||
/// This struct should be as "zero-copy" as possible. The `ssz` field is a reference to some slice
|
/// This struct should be as "zero-copy" as possible. The `ssz` field is a reference to some slice
|
||||||
|
@ -52,6 +52,11 @@ fn bytes_for_bits(bits: usize) -> usize {
|
|||||||
(bits.saturating_sub(1) / 8) + 1
|
(bits.saturating_sub(1) / 8) + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn any_of_last_n_bits_are_set(byte: &u8, n: usize) -> bool {
|
||||||
|
let shift = 8_u8.saturating_sub(n as u8);
|
||||||
|
((!0 >> shift) & byte) > 0
|
||||||
|
}
|
||||||
|
|
||||||
pub fn validate_attestation<T>(a: &AttestationRecord,
|
pub fn validate_attestation<T>(a: &AttestationRecord,
|
||||||
block_slot: u64,
|
block_slot: u64,
|
||||||
cycle_length: u8,
|
cycle_length: u8,
|
||||||
@ -162,11 +167,6 @@ pub fn validate_attestation<T>(a: &AttestationRecord,
|
|||||||
Ok((signature_valid, voted_hashmap))
|
Ok((signature_valid, voted_hashmap))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn any_of_last_n_bits_are_set(byte: &u8, n: usize) -> bool {
|
|
||||||
let shift = 8_u8.saturating_sub(n as u8);
|
|
||||||
((!0 >> shift) & byte) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generates the message used to validate the signature provided with an AttestationRecord.
|
/// Generates the message used to validate the signature provided with an AttestationRecord.
|
||||||
///
|
///
|
||||||
/// Ensures that the signer of the message has a view of the chain that is compatible with ours.
|
/// Ensures that the signer of the message has a view of the chain that is compatible with ours.
|
11
lighthouse/state/validation/attestation/mod.rs
Normal file
11
lighthouse/state/validation/attestation/mod.rs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
use super::db;
|
||||||
|
use super::bls;
|
||||||
|
use super::AttestationRecord;
|
||||||
|
use super::ssz;
|
||||||
|
use super::attestation_parent_hashes;
|
||||||
|
use super::utils;
|
||||||
|
|
||||||
|
mod attestation_validation;
|
||||||
|
mod signatures;
|
||||||
|
|
||||||
|
pub use self::attestation_validation::validate_attestation;
|
@ -14,6 +14,5 @@ use super::ssz;
|
|||||||
use super::transition::attestation_parent_hashes;
|
use super::transition::attestation_parent_hashes;
|
||||||
use super::utils;
|
use super::utils;
|
||||||
|
|
||||||
mod attestation_validation;
|
mod attestation;
|
||||||
mod signatures;
|
|
||||||
mod ssz_block;
|
mod ssz_block;
|
||||||
|
@ -3,8 +3,6 @@ extern crate rand;
|
|||||||
use super::utils::types::{ Hash256, Address, U256 };
|
use super::utils::types::{ Hash256, Address, U256 };
|
||||||
use super::bls::{ PublicKey, Keypair };
|
use super::bls::{ PublicKey, Keypair };
|
||||||
|
|
||||||
use self::rand::thread_rng;
|
|
||||||
|
|
||||||
pub struct ValidatorRecord {
|
pub struct ValidatorRecord {
|
||||||
pub pubkey: PublicKey,
|
pub pubkey: PublicKey,
|
||||||
pub withdrawal_shard: u16,
|
pub withdrawal_shard: u16,
|
||||||
|
Loading…
Reference in New Issue
Block a user