Merge branch 'v2.1-spec' into validate_block
This commit is contained in:
commit
5c0690d39c
@ -6,11 +6,12 @@ extern crate clap;
|
||||
extern crate network_libp2p;
|
||||
extern crate futures;
|
||||
|
||||
#[macro_use]
|
||||
pub mod utils;
|
||||
pub mod db;
|
||||
pub mod client;
|
||||
pub mod state;
|
||||
pub mod sync;
|
||||
pub mod utils;
|
||||
pub mod config;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
71
lighthouse/state/helpers.rs
Normal file
71
lighthouse/state/helpers.rs
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Collection of helper functions used in the state transition modules
|
||||
*/
|
||||
use super::active_state::ActiveState;
|
||||
use super::block::Block;
|
||||
use super::chain_config::ChainConfig;
|
||||
use super::utils::errors::ParameterError;
|
||||
use super::utils::types::Hash256;
|
||||
|
||||
/*
|
||||
pub fn get_signed_parent_hashes(
|
||||
active_state: &ActiveState,
|
||||
block: &Block,
|
||||
attestation: &AttestationRecord,
|
||||
chain_config: &ChainConfig)
|
||||
-> Vec<Hash256> {
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn get_block_hash(
|
||||
active_state_recent_block_hashes: &Vec<Hash256>,
|
||||
current_block_slot: &u64,
|
||||
slot: &u64,
|
||||
cycle_length: &u64, // convert from standard u8
|
||||
) -> Result<Hash256, ParameterError> {
|
||||
// active_state must have at 2*cycle_length hashes
|
||||
assert_error!(
|
||||
active_state_recent_block_hashes.len() as u64 == cycle_length * 2,
|
||||
ParameterError::InvalidInput(String::from(
|
||||
"active state has incorrect number of block hashes"
|
||||
))
|
||||
);
|
||||
|
||||
let state_start_slot = (*current_block_slot)
|
||||
.checked_sub(cycle_length * 2)
|
||||
.unwrap_or(0);
|
||||
|
||||
assert_error!(
|
||||
(state_start_slot <= *slot) && (*slot < *current_block_slot),
|
||||
ParameterError::InvalidInput(String::from("incorrect slot number"))
|
||||
);
|
||||
|
||||
let index = 2 * cycle_length + (*slot) - *current_block_slot; // should always be positive
|
||||
Ok(active_state_recent_block_hashes[index as usize])
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_get_block_hash() {
|
||||
let block_slot: u64 = 10;
|
||||
let slot: u64 = 3;
|
||||
let cycle_length: u64 = 8;
|
||||
|
||||
let mut block_hashes: Vec<Hash256> = Vec::new();
|
||||
for _i in 0..2 * cycle_length {
|
||||
block_hashes.push(Hash256::random());
|
||||
}
|
||||
|
||||
let result = get_block_hash(&block_hashes, &block_slot, &slot, &cycle_length).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
block_hashes[(2 * cycle_length + slot - block_slot) as usize]
|
||||
);
|
||||
|
||||
println!("{:?}", result);
|
||||
}
|
||||
}
|
@ -17,3 +17,5 @@ pub mod crosslink_record;
|
||||
pub mod shard_and_committee;
|
||||
pub mod transition;
|
||||
pub mod validator_record;
|
||||
pub mod validation;
|
||||
pub mod helpers;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::Hash256;
|
||||
use super::TransitionError;
|
||||
use super::ParameterError;
|
||||
|
||||
/// This function is used to select the hashes used in
|
||||
/// the signing of an AttestationRecord.
|
||||
@ -18,22 +18,22 @@ pub fn attestation_parent_hashes(
|
||||
attestation_slot: u64,
|
||||
current_hashes: &[Hash256],
|
||||
oblique_hashes: &[Hash256])
|
||||
-> Result<Vec<Hash256>, TransitionError>
|
||||
-> Result<Vec<Hash256>, ParameterError>
|
||||
{
|
||||
// This cast places a limit on cycle_length. If you change it, check math
|
||||
// for overflow.
|
||||
let cycle_length: u64 = u64::from(cycle_length);
|
||||
|
||||
if current_hashes.len() as u64 != (cycle_length * 2) {
|
||||
return Err(TransitionError::InvalidInput(String::from(
|
||||
return Err(ParameterError::InvalidInput(String::from(
|
||||
"current_hashes.len() must equal cycle_length * 2")));
|
||||
}
|
||||
if attestation_slot >= block_slot {
|
||||
return Err(TransitionError::InvalidInput(String::from(
|
||||
return Err(ParameterError::InvalidInput(String::from(
|
||||
"attestation_slot must be less than block_slot")));
|
||||
}
|
||||
if oblique_hashes.len() as u64 > cycle_length {
|
||||
return Err(TransitionError::InvalidInput(String::from(
|
||||
return Err(ParameterError::InvalidInput(String::from(
|
||||
"oblique_hashes.len() must be <= cycle_length * 2")));
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ pub fn attestation_parent_hashes(
|
||||
let attestation_distance = block_slot - attestation_slot;
|
||||
|
||||
if attestation_distance > cycle_length {
|
||||
return Err(TransitionError::InvalidInput(String::from(
|
||||
return Err(ParameterError::InvalidInput(String::from(
|
||||
"attestation_slot must be withing one cycle of block_slot")));
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ pub fn attestation_parent_hashes(
|
||||
*/
|
||||
let end = start.checked_add(cycle_length)
|
||||
.and_then(|x| x.checked_sub(oblique_hashes.len() as u64))
|
||||
.ok_or(TransitionError::IntWrapping)?;
|
||||
.ok_or(ParameterError::IntWrapping)?;
|
||||
|
||||
|
||||
let mut hashes = Vec::new();
|
||||
|
@ -1,6 +1,7 @@
|
||||
use super::block;
|
||||
use super::Logger;
|
||||
use super::utils::types::Hash256;
|
||||
use super::utils::errors::ParameterError;
|
||||
use super::db;
|
||||
|
||||
mod attestation_parent_hashes;
|
||||
@ -10,12 +11,6 @@ mod validate_block;
|
||||
pub use self::attestation_parent_hashes::attestation_parent_hashes;
|
||||
pub use self::shuffling::shuffle;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TransitionError {
|
||||
IntWrapping,
|
||||
OutOfBounds,
|
||||
InvalidInput(String),
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
81
lighthouse/state/validation/attestation_validation.rs
Normal file
81
lighthouse/state/validation/attestation_validation.rs
Normal file
@ -0,0 +1,81 @@
|
||||
use super::CrystallizedState;
|
||||
use super::ActiveState;
|
||||
use super::AttestationRecord;
|
||||
use super::Block;
|
||||
use super::ChainConfig;
|
||||
|
||||
use ::utils::errors::AttestationValidationError;
|
||||
|
||||
// implementation of validate_attestation in the v2.1 python reference implementation
|
||||
// see: https://github.com/ethereum/beacon_chain/blob/a79ab2c6f03cbdabf2b6d9d435c26e2b216e09a5/beacon_chain/state/state_transition.py#L61
|
||||
pub fn validate_attestation(
|
||||
crystallized_state: &CrystallizedState,
|
||||
active_state: &ActiveState,
|
||||
attestation: &AttestationRecord,
|
||||
block: &Block,
|
||||
chain_config: &ChainConfig)
|
||||
-> Result<bool, AttestationValidationError> {
|
||||
|
||||
if !(attestation.slot < block.slot_number) {
|
||||
return Err(AttestationValidationError::SlotTooHigh);
|
||||
}
|
||||
|
||||
if !(attestation.slot > (block.slot_number - chain_config.cycle_length as u64)) {
|
||||
return Err(AttestationValidationError::SlotTooLow(format!("Attestation slot number too low\n\tFound: {:?}, Needed greater than: {:?}", attestation.slot, block.slot_number - chain_config.cycle_length as u64)));
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
// test helper functions
|
||||
|
||||
fn generate_standard_state() -> (
|
||||
CrystallizedState,
|
||||
ActiveState,
|
||||
AttestationRecord,
|
||||
Block,
|
||||
ChainConfig) {
|
||||
|
||||
let crystallized_state = CrystallizedState::zero();
|
||||
let active_state = ActiveState::zero();
|
||||
let attestation_record = AttestationRecord::zero();
|
||||
let block = Block::zero();
|
||||
let chain_config = ChainConfig::standard();
|
||||
|
||||
return (crystallized_state, active_state, attestation_record, block, chain_config);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_attestation_validation_slot_high() {
|
||||
// generate standard state
|
||||
let (crystallized_state, active_state, mut attestation_record, mut block, chain_config) = generate_standard_state();
|
||||
// set slot too high
|
||||
attestation_record.slot = 30;
|
||||
block.slot_number = 10;
|
||||
|
||||
let result = validate_attestation(&crystallized_state, &active_state, &attestation_record, &block, &chain_config);
|
||||
assert_eq!(result, Err(AttestationValidationError::SlotTooHigh));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_attestation_validation_slot_low() {
|
||||
// generate standard state
|
||||
let (crystallized_state, active_state, mut attestation_record, mut block, chain_config) = generate_standard_state();
|
||||
// set slot too high
|
||||
attestation_record.slot = 2;
|
||||
block.slot_number = 10;
|
||||
|
||||
let result = validate_attestation(
|
||||
&crystallized_state,
|
||||
&active_state,
|
||||
&attestation_record,
|
||||
&block,
|
||||
&chain_config);
|
||||
//assert_eq!(result, Err(AttestationValidationError::SlotTooLow));
|
||||
}
|
||||
}
|
7
lighthouse/state/validation/mod.rs
Normal file
7
lighthouse/state/validation/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
use super::crystallized_state::CrystallizedState;
|
||||
use super::active_state::ActiveState;
|
||||
use super::attestation_record::AttestationRecord;
|
||||
use super::block::Block;
|
||||
use super::chain_config::ChainConfig;
|
||||
|
||||
mod attestation_validation;
|
17
lighthouse/utils/errors.rs
Normal file
17
lighthouse/utils/errors.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// Collection of custom errors
|
||||
|
||||
#[derive(Debug,PartialEq)]
|
||||
pub enum AttestationValidationError {
|
||||
SlotTooHigh,
|
||||
SlotTooLow(String),
|
||||
IncorrectBitField,
|
||||
NonZeroTrailingBits,
|
||||
AggregateSignatureFail
|
||||
}
|
||||
|
||||
#[derive(Debug,PartialEq)]
|
||||
pub enum ParameterError {
|
||||
IntWrapping,
|
||||
OutOfBounds,
|
||||
InvalidInput(String),
|
||||
}
|
10
lighthouse/utils/macros.rs
Normal file
10
lighthouse/utils/macros.rs
Normal file
@ -0,0 +1,10 @@
|
||||
#[macro_export]
|
||||
macro_rules! assert_error {
|
||||
($exp: expr, $err: expr) => {
|
||||
if ( !$exp ) {
|
||||
return Err($err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,13 @@ extern crate blake2_rfc as blake2;
|
||||
extern crate crypto_mac;
|
||||
extern crate boolean_bitfield;
|
||||
|
||||
#[macro_use]
|
||||
pub mod macros;
|
||||
pub mod hash;
|
||||
pub mod types;
|
||||
pub mod bls;
|
||||
pub mod test_helpers;
|
||||
pub mod logging;
|
||||
pub mod errors;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user