Progress on parent hash selection. Add test.

This commit is contained in:
Paul Hauner 2018-08-24 14:33:05 +10:00
parent 8ba7601ab3
commit 859c48d5e5
2 changed files with 63 additions and 30 deletions

View File

@ -2,38 +2,62 @@ use super::Hash256;
use super::TransitionError; use super::TransitionError;
pub fn get_signed_parent_hashes( pub fn get_signed_parent_hashes(
cycle_length: u64, cycle_length: u8,
block_slot: u64, block_slot: u64,
attestation_slot: u64, attestation_slot: u64,
current_hashes: Vec<Hash256>, current_hashes: Vec<Hash256>,
oblique_hashes: Vec<Hash256>) oblique_hashes: Vec<Hash256>)
-> Result<Vec<Hash256>, TransitionError> -> Result<Vec<Hash256>, TransitionError>
{ {
let start = cycle_length.checked_add(attestation_slot) // This cast places a limit on cycle_length. If you change it, check math
.and_then(|x| x.checked_sub(block_slot)) // for overflow.
.ok_or(TransitionError::IntWrapping)?; let cycle_length: u64 = cycle_length as u64;
let start = start as usize;
let end = cycle_length.checked_mul(2) if current_hashes.len() as u64 != (cycle_length * 2) {
.and_then(|x| x.checked_add(attestation_slot)) return Err(TransitionError::InvalidInput(String::from(
.and_then(|x| x.checked_sub(block_slot)) "current_hashes.len() must equal cycle_length * 2")));
}
if attestation_slot >= block_slot {
return Err(TransitionError::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(
"oblique_hashes.len() must be <= cycle_length * 2")));
}
/*
* Cannot underflow as block_slot cannot be less
* than attestation_slot.
*/
let attestation_distance = block_slot - attestation_slot;
if attestation_distance > cycle_length {
return Err(TransitionError::InvalidInput(String::from(
"attestation_slot must be withing one cycle of block_slot")));
}
/*
* Cannot underflow because attestation_distance cannot
* be larger than cycle_length.
*/
let start = cycle_length - attestation_distance;
/*
* Overflow is potentially impossible, but proof is complicated
* enough to just use checked math.
*
* Math is:
* start + cycle_length - oblique_hashes.len()
*/
let end = start.checked_add(cycle_length)
.and_then(|x| x.checked_sub(oblique_hashes.len() as u64)) .and_then(|x| x.checked_sub(oblique_hashes.len() as u64))
.ok_or(TransitionError::IntWrapping)?; .ok_or(TransitionError::IntWrapping)?;
let end = end as usize;
println!("start: {}, end: {}", start, end);
if end >= current_hashes.len() {
return Err(TransitionError::OutOfBounds);
}
if start > end {
return Err(TransitionError::InvalidInput("cats"));
}
let mut hashes = Vec::new(); let mut hashes = Vec::new();
hashes.extend_from_slice( hashes.extend_from_slice(
&current_hashes[start..end]); &current_hashes[(start as usize)..(end as usize)]);
hashes.append(&mut oblique_hashes.clone()); hashes.append(&mut oblique_hashes.clone());
Ok(hashes) Ok(hashes)
@ -44,25 +68,34 @@ pub fn get_signed_parent_hashes(
mod tests { mod tests {
use super::*; use super::*;
fn get_n_hashes(value: &[u8], n: usize) -> Vec<Hash256> { fn get_range_of_hashes(from: usize, to: usize) -> Vec<Hash256> {
(0..n).map(|_| Hash256::from_slice(value)).collect() (from..to).map(|i| get_hash(&vec![i as u8])).collect()
}
fn get_hash(value: &[u8]) -> Hash256 {
Hash256::from_slice(value)
} }
#[test] #[test]
fn test_get_signed_hashes() { fn test_get_signed_hashes_no_oblique() {
let cycle_length: u64 = 8; /*
let block_slot: u64 = 500; * Google Slides example.
let attestation_slot: u64 = 498; */
let current_hashes = let cycle_length: u8 = 8;
get_n_hashes(b"0", 100); let block_slot: u64 = 19;
let oblique_hashes = get_n_hashes(b"1", 2); let attestation_slot: u64 = 15;
let current_hashes = get_range_of_hashes(3, 19);
let oblique_hashes = vec![];
let result = get_signed_parent_hashes( let result = get_signed_parent_hashes(
cycle_length, cycle_length,
block_slot, block_slot,
attestation_slot, attestation_slot,
current_hashes, current_hashes,
oblique_hashes); oblique_hashes);
// TODO: complete testing
assert!(result.is_ok()); assert!(result.is_ok());
let result = result.unwrap();
assert_eq!(result.len(), cycle_length as usize);
let expected_result = get_range_of_hashes(7, 15);
assert_eq!(result, expected_result);
} }
} }

View File

@ -6,6 +6,6 @@ pub mod helpers;
pub enum TransitionError { pub enum TransitionError {
IntWrapping, IntWrapping,
OutOfBounds, OutOfBounds,
InvalidInput(&str), InvalidInput(String),
} }