Refactor: extract common code

This commit is contained in:
Eirik Ogilvie-Wigley
2018-05-23 22:19:10 -06:00
committed by str4d
parent d7a93a03e6
commit 9a5fc3c9f6

View File

@@ -33,6 +33,16 @@ impl Params {
} }
impl Node { impl Node {
fn new(p: &Params, state: &Blake2b, i: u32) -> Self {
let hash = generate_hash(state, i / p.indices_per_hash_output());
let start = ((i % p.indices_per_hash_output()) * p.n / 8) as usize;
let end = start + (p.n as usize) / 8;
Node {
hash: expand_array(&hash.as_bytes()[start..end], p.collision_bit_length(), 0),
indices: vec![i],
}
}
fn from_children(a: Node, b: Node, trim: usize) -> Self { fn from_children(a: Node, b: Node, trim: usize) -> Self {
let hash: Vec<_> = a.hash let hash: Vec<_> = a.hash
.iter() .iter()
@@ -186,6 +196,21 @@ fn distinct_indices(a: &Node, b: &Node) -> bool {
return true; return true;
} }
fn validate_subtrees(p: &Params, a: &Node, b: &Node) -> bool {
if !has_collision(a, b, p.collision_byte_length()) {
// error!("Invalid solution: invalid collision length between StepRows");
false
} else if b.indices_before(a) {
// error!("Invalid solution: Index tree incorrectly ordered");
false
} else if !distinct_indices(a, b) {
// error!("Invalid solution: duplicate indices");
false
} else {
true
}
}
pub fn is_valid_solution_iterative( pub fn is_valid_solution_iterative(
n: u32, n: u32,
k: u32, k: u32,
@@ -201,13 +226,7 @@ pub fn is_valid_solution_iterative(
let mut rows = Vec::new(); let mut rows = Vec::new();
for i in indices { for i in indices {
let hash = generate_hash(&state, i / p.indices_per_hash_output()); rows.push(Node::new(&p, &state, *i));
let start = ((i % p.indices_per_hash_output()) * p.n / 8) as usize;
let end = start + (p.n as usize) / 8;
rows.push(Node {
hash: expand_array(&hash.as_bytes()[start..end], p.collision_bit_length(), 0),
indices: vec![*i],
});
} }
let mut hash_len = p.hash_length(); let mut hash_len = p.hash_length();
@@ -216,16 +235,7 @@ pub fn is_valid_solution_iterative(
for pair in rows.chunks(2) { for pair in rows.chunks(2) {
let a = &pair[0]; let a = &pair[0];
let b = &pair[1]; let b = &pair[1];
if !has_collision(a, b, p.collision_byte_length()) { if !validate_subtrees(&p, a, b) {
// error!("Invalid solution: invalid collision length between StepRows");
return false;
}
if b.indices_before(a) {
// error!("Invalid solution: Index tree incorrectly ordered");
return false;
}
if !distinct_indices(a, b) {
// error!("Invalid solution: duplicate indices");
return false; return false;
} }
cur_rows.push(Node::from_children_ref(a, b, p.collision_byte_length())); cur_rows.push(Node::from_children_ref(a, b, p.collision_byte_length()));
@@ -245,33 +255,18 @@ fn tree_validator(p: &Params, state: &Blake2b, indices: &[u32]) -> Option<Node>
match tree_validator(p, state, &indices[0..mid]) { match tree_validator(p, state, &indices[0..mid]) {
Some(a) => match tree_validator(p, state, &indices[mid..end]) { Some(a) => match tree_validator(p, state, &indices[mid..end]) {
Some(b) => { Some(b) => {
if !has_collision(&a, &b, p.collision_byte_length()) { if validate_subtrees(p, &a, &b) {
// error!("Invalid solution: invalid collision length between StepRows"); Some(Node::from_children(a, b, p.collision_byte_length()))
return None; } else {
None
} }
if b.indices_before(&a) {
// error!("Invalid solution: Index tree incorrectly ordered");
return None;
}
if !distinct_indices(&a, &b) {
// error!("Invalid solution: duplicate indices");
return None;
}
Some(Node::from_children(a, b, p.collision_byte_length()))
} }
None => None, None => None,
}, },
None => None, None => None,
} }
} else { } else {
let i = indices[0]; Some(Node::new(&p, &state, indices[0]))
let hash = generate_hash(&state, i / p.indices_per_hash_output());
let start = ((i % p.indices_per_hash_output()) * p.n / 8) as usize;
let end = start + (p.n as usize) / 8;
Some(Node {
hash: expand_array(&hash.as_bytes()[start..end], p.collision_bit_length(), 0),
indices: vec![i],
})
} }
} }