Add attestion ssz splitter, change dir structure

This commit is contained in:
Paul Hauner 2018-09-24 21:53:42 +10:00
parent c55b94053b
commit 2141b8c623
No known key found for this signature in database
GPG Key ID: 303E4494BB28068C
9 changed files with 175 additions and 14 deletions

View File

@ -22,7 +22,7 @@ pub const MIN_SSZ_ATTESTION_RECORD_LENGTH: usize = {
4 + BLS_AGG_SIG_BYTE_SIZE // aggregate sig (two 256 bit points)
};
#[derive(Debug)]
#[derive(Debug, Clone, PartialEq)]
pub struct AttestationRecord {
pub slot: u64,
pub shard_id: u16,

View 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,
};

View 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());
}
}

View File

@ -13,9 +13,6 @@ use super::attestation_record::MIN_SSZ_ATTESTION_RECORD_LENGTH;
pub enum BlockValidatorError {
TooShort,
TooLong,
BadPowHash,
SlotTooLow,
SlotTooHigh,
}
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.
///
/// 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.
///
/// This struct should be as "zero-copy" as possible. The `ssz` field is a reference to some slice

View File

@ -52,6 +52,11 @@ fn bytes_for_bits(bits: usize) -> usize {
(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,
block_slot: u64,
cycle_length: u8,
@ -162,11 +167,6 @@ pub fn validate_attestation<T>(a: &AttestationRecord,
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.
///
/// Ensures that the signer of the message has a view of the chain that is compatible with ours.

View 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;

View File

@ -14,6 +14,5 @@ use super::ssz;
use super::transition::attestation_parent_hashes;
use super::utils;
mod attestation_validation;
mod signatures;
mod attestation;
mod ssz_block;

View File

@ -3,8 +3,6 @@ extern crate rand;
use super::utils::types::{ Hash256, Address, U256 };
use super::bls::{ PublicKey, Keypair };
use self::rand::thread_rng;
pub struct ValidatorRecord {
pub pubkey: PublicKey,
pub withdrawal_shard: u16,