Demo lean miner, minor PoW improvements (#1630)

This commit is contained in:
Ignotus Peverell 2018-10-03 03:39:16 -07:00 committed by Yeastplume
parent 4d70968e70
commit 2259c18dd6
6 changed files with 239 additions and 91 deletions

View file

@ -19,7 +19,7 @@
use consensus::TargetError; use consensus::TargetError;
use consensus::{ use consensus::{
BLOCK_TIME_SEC, COINBASE_MATURITY, CUT_THROUGH_HORIZON, DEFAULT_MIN_SIZESHIFT, BLOCK_TIME_SEC, COINBASE_MATURITY, CUT_THROUGH_HORIZON, DEFAULT_MIN_SIZESHIFT,
DIFFICULTY_ADJUST_WINDOW, INITIAL_DIFFICULTY, MEDIAN_TIME_WINDOW, PROOFSIZE, DIFFICULTY_ADJUST_WINDOW, EASINESS, INITIAL_DIFFICULTY, MEDIAN_TIME_WINDOW, PROOFSIZE,
REFERENCE_SIZESHIFT, REFERENCE_SIZESHIFT,
}; };
use pow::{self, CuckooContext, Difficulty, EdgeType, PoWContext}; use pow::{self, CuckooContext, Difficulty, EdgeType, PoWContext};
@ -123,7 +123,6 @@ pub fn set_mining_mode(mode: ChainTypes) {
pub fn create_pow_context<T>( pub fn create_pow_context<T>(
edge_bits: u8, edge_bits: u8,
proof_size: usize, proof_size: usize,
easiness_pct: u32,
max_sols: u32, max_sols: u32,
) -> Result<Box<impl PoWContext<T>>, pow::Error> ) -> Result<Box<impl PoWContext<T>>, pow::Error>
where where
@ -132,7 +131,7 @@ where
// Perform whatever tests, configuration etc are needed to determine desired context + edge size // Perform whatever tests, configuration etc are needed to determine desired context + edge size
// + params // + params
// Hardcode to regular cuckoo for now // Hardcode to regular cuckoo for now
CuckooContext::<T>::new(edge_bits, proof_size, easiness_pct, max_sols) CuckooContext::<T>::new(edge_bits, proof_size, EASINESS, max_sols)
// Or switch to cuckatoo as follows: // Or switch to cuckatoo as follows:
// CuckatooContext::<T>::new(edge_bits, proof_size, easiness_pct, max_sols) // CuckatooContext::<T>::new(edge_bits, proof_size, easiness_pct, max_sols)
} }

View file

@ -15,6 +15,8 @@
//! Common types and traits for cuckoo/cuckatoo family of solvers //! Common types and traits for cuckoo/cuckatoo family of solvers
use blake2::blake2b::blake2b; use blake2::blake2b::blake2b;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use pow::error::{Error, ErrorKind}; use pow::error::{Error, ErrorKind};
use pow::num::{PrimInt, ToPrimitive}; use pow::num::{PrimInt, ToPrimitive};
use pow::siphash::siphash24; use pow::siphash::siphash24;
@ -23,8 +25,6 @@ use std::io::Cursor;
use std::ops::{BitOrAssign, Mul}; use std::ops::{BitOrAssign, Mul};
use std::{fmt, mem}; use std::{fmt, mem};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
/// Operations needed for edge type (going to be u32 or u64) /// Operations needed for edge type (going to be u32 or u64)
pub trait EdgeType: PrimInt + ToPrimitive + Mul + BitOrAssign + Hash {} pub trait EdgeType: PrimInt + ToPrimitive + Mul + BitOrAssign + Hash {}
impl EdgeType for u32 {} impl EdgeType for u32 {}
@ -100,29 +100,6 @@ pub fn create_siphash_keys(header: Vec<u8>) -> Result<[u64; 4], Error> {
]) ])
} }
/// Return siphash masked for type
pub fn sipnode<T>(
keys: &[u64; 4],
edge: T,
edge_mask: &T,
uorv: u64,
shift: bool,
) -> Result<T, Error>
where
T: EdgeType,
{
let hash_u64 = siphash24(
keys,
2 * edge.to_u64().ok_or(ErrorKind::IntegerCast)? + uorv,
);
let mut masked = hash_u64 & edge_mask.to_u64().ok_or(ErrorKind::IntegerCast)?;
if shift {
masked = masked << 1;
masked |= uorv;
}
Ok(T::from(masked).ok_or(ErrorKind::IntegerCast)?)
}
/// Macros to clean up integer unwrapping /// Macros to clean up integer unwrapping
#[macro_export] #[macro_export]
macro_rules! to_u64 { macro_rules! to_u64 {
@ -151,3 +128,80 @@ macro_rules! to_edge {
T::from($n).ok_or(ErrorKind::IntegerCast)? T::from($n).ok_or(ErrorKind::IntegerCast)?
}; };
} }
/// Utility struct to calculate commonly used Cuckoo parameters calculated
/// from header, nonce, sizeshift, etc.
pub struct CuckooParams<T>
where
T: EdgeType,
{
pub edge_bits: u8,
pub proof_size: usize,
pub num_edges: u64,
pub siphash_keys: [u64; 4],
pub easiness: T,
pub edge_mask: T,
}
impl<T> CuckooParams<T>
where
T: EdgeType,
{
/// Instantiates new params and calculate easiness, edge mask, etc
pub fn new(
edge_bits: u8,
proof_size: usize,
easiness_pct: u32,
cuckatoo: bool,
) -> Result<CuckooParams<T>, Error> {
let num_edges = 1 << edge_bits;
let num_nodes = 2 * num_edges as u64;
let easiness = if cuckatoo {
to_u64!(easiness_pct) * num_nodes / 100
} else {
to_u64!(easiness_pct) * num_edges / 100
};
let edge_mask = if cuckatoo {
to_edge!(num_edges - 1)
} else {
to_edge!(num_edges / 2 - 1)
};
Ok(CuckooParams {
siphash_keys: [0; 4],
easiness: to_edge!(easiness),
proof_size,
edge_mask,
num_edges,
edge_bits,
})
}
/// Reset the main keys used for siphash from the header and nonce
pub fn reset_header_nonce(
&mut self,
mut header: Vec<u8>,
nonce: Option<u32>,
) -> Result<(), Error> {
if let Some(n) = nonce {
let len = header.len();
header.truncate(len - mem::size_of::<u32>());
header.write_u32::<LittleEndian>(n)?;
}
self.siphash_keys = set_header_nonce(header, nonce)?;
Ok(())
}
/// Return siphash masked for type
pub fn sipnode(&self, edge: T, uorv: u64, shift: bool) -> Result<T, Error> {
let hash_u64 = siphash24(
&self.siphash_keys,
2 * edge.to_u64().ok_or(ErrorKind::IntegerCast)? + uorv,
);
let mut masked = hash_u64 & self.edge_mask.to_u64().ok_or(ErrorKind::IntegerCast)?;
if shift {
masked = masked << 1;
masked |= uorv;
}
Ok(T::from(masked).ok_or(ErrorKind::IntegerCast)?)
}
}

View file

@ -18,7 +18,7 @@ use std::mem;
use byteorder::{BigEndian, LittleEndian, WriteBytesExt}; use byteorder::{BigEndian, LittleEndian, WriteBytesExt};
use croaring::Bitmap; use croaring::Bitmap;
use pow::common::{self, EdgeType, Link}; use pow::common::{self, CuckooParams, EdgeType, Link};
use pow::error::{Error, ErrorKind}; use pow::error::{Error, ErrorKind};
use pow::{PoWContext, Proof}; use pow::{PoWContext, Proof};
use util; use util;
@ -158,11 +158,8 @@ pub struct CuckatooContext<T>
where where
T: EdgeType, T: EdgeType,
{ {
siphash_keys: [u64; 4], params: CuckooParams<T>,
easiness: T,
graph: Graph<T>, graph: Graph<T>,
proof_size: usize,
edge_mask: T,
} }
impl<T> PoWContext<T> for CuckatooContext<T> impl<T> PoWContext<T> for CuckatooContext<T>
@ -193,7 +190,8 @@ where
} }
fn find_cycles(&mut self) -> Result<Vec<Proof>, Error> { fn find_cycles(&mut self) -> Result<Vec<Proof>, Error> {
self.find_cycles_impl() let ease = to_u64!(self.params.easiness);
self.find_cycles_iter(0..ease)
} }
fn verify(&self, proof: &Proof) -> Result<(), Error> { fn verify(&self, proof: &Proof) -> Result<(), Error> {
@ -212,22 +210,18 @@ where
easiness_pct: u32, easiness_pct: u32,
max_sols: u32, max_sols: u32,
) -> Result<CuckatooContext<T>, Error> { ) -> Result<CuckatooContext<T>, Error> {
let num_edges = 1 << edge_bits; let params = CuckooParams::new(edge_bits, proof_size, easiness_pct, true)?;
let num_nodes = 2 * num_edges as u64; let num_edges = to_edge!(params.num_edges);
let easiness = to_u64!(easiness_pct) * num_nodes / 100;
Ok(CuckatooContext { Ok(CuckatooContext {
siphash_keys: [0; 4], params,
easiness: to_edge!(easiness), graph: Graph::new(num_edges, max_sols, proof_size)?,
graph: Graph::new(to_edge!(num_edges), max_sols, proof_size)?,
proof_size: proof_size,
edge_mask: to_edge!(num_edges - 1),
}) })
} }
/// Get a siphash key as a hex string (for display convenience) /// Get a siphash key as a hex string (for display convenience)
pub fn sipkey_hex(&self, index: usize) -> Result<String, Error> { pub fn sipkey_hex(&self, index: usize) -> Result<String, Error> {
let mut rdr = vec![]; let mut rdr = vec![];
rdr.write_u64::<BigEndian>(self.siphash_keys[index])?; rdr.write_u64::<BigEndian>(self.params.siphash_keys[index])?;
Ok(util::to_hex(rdr)) Ok(util::to_hex(rdr))
} }
@ -239,16 +233,11 @@ where
/// Set the header and optional nonce in the last part of the header /// Set the header and optional nonce in the last part of the header
pub fn set_header_nonce_impl( pub fn set_header_nonce_impl(
&mut self, &mut self,
mut header: Vec<u8>, header: Vec<u8>,
nonce: Option<u32>, nonce: Option<u32>,
solve: bool, solve: bool,
) -> Result<(), Error> { ) -> Result<(), Error> {
let len = header.len(); self.params.reset_header_nonce(header, nonce)?;
header.truncate(len - mem::size_of::<u32>());
if let Some(n) = nonce {
header.write_u32::<LittleEndian>(n)?;
}
self.siphash_keys = common::set_header_nonce(header, nonce)?;
if solve { if solve {
self.graph.reset()?; self.graph.reset()?;
} }
@ -256,19 +245,26 @@ where
} }
/// Return siphash masked for type /// Return siphash masked for type
fn sipnode(&self, edge: T, uorv: u64) -> Result<T, Error> { pub fn sipnode(&self, edge: T, uorv: u64) -> Result<T, Error> {
common::sipnode::<T>(&self.siphash_keys, edge, &self.edge_mask, uorv, false) self.params.sipnode(edge, uorv, false)
} }
/// Simple implementation of algorithm /// Simple implementation of algorithm
pub fn find_cycles_impl(&mut self) -> Result<Vec<Proof>, Error> {
for n in 0..to_u64!(self.easiness) { pub fn find_cycles_iter<'a, I>(&mut self, iter: I) -> Result<Vec<Proof>, Error>
where
I: Iterator<Item = u64>,
{
let mut val = vec![];
for n in iter {
val.push(n);
let u = self.sipnode(to_edge!(n), 0)?; let u = self.sipnode(to_edge!(n), 0)?;
let v = self.sipnode(to_edge!(n), 1)?; let v = self.sipnode(to_edge!(n), 1)?;
self.graph.add_edge(to_edge!(u), to_edge!(v))?; self.graph.add_edge(to_edge!(u), to_edge!(v))?;
} }
self.graph.solutions.pop(); self.graph.solutions.pop();
for s in &mut self.graph.solutions { for s in &mut self.graph.solutions {
s.nonces = map_vec!(s.nonces, |n| val[*n as usize]);
s.nonces.sort(); s.nonces.sort();
} }
for s in &self.graph.solutions { for s in &self.graph.solutions {
@ -286,11 +282,11 @@ where
pub fn verify_impl(&self, proof: &Proof) -> Result<(), Error> { pub fn verify_impl(&self, proof: &Proof) -> Result<(), Error> {
let nonces = &proof.nonces; let nonces = &proof.nonces;
let mut uvs = vec![0u64; 2 * proof.proof_size()]; let mut uvs = vec![0u64; 2 * proof.proof_size()];
let mut xor0: u64 = (self.proof_size as u64 / 2) & 1; let mut xor0: u64 = (self.params.proof_size as u64 / 2) & 1;
let mut xor1: u64 = xor0; let mut xor1: u64 = xor0;
for n in 0..proof.proof_size() { for n in 0..proof.proof_size() {
if nonces[n] > to_u64!(self.edge_mask) { if nonces[n] > to_u64!(self.params.edge_mask) {
return Err(ErrorKind::Verification("edge too big".to_owned()))?; return Err(ErrorKind::Verification("edge too big".to_owned()))?;
} }
if n > 0 && nonces[n] <= nonces[n - 1] { if n > 0 && nonces[n] <= nonces[n - 1] {
@ -314,7 +310,7 @@ where
j = i; j = i;
let mut k = j; let mut k = j;
loop { loop {
k = (k + 2) % (2 * self.proof_size); k = (k + 2) % (2 * self.params.proof_size);
if k == i { if k == i {
break; break;
} }
@ -335,7 +331,7 @@ where
break; break;
} }
} }
if n == self.proof_size { if n == self.params.proof_size {
Ok(()) Ok(())
} else { } else {
Err(ErrorKind::Verification("cycle too short".to_owned()))? Err(ErrorKind::Verification("cycle too short".to_owned()))?

View file

@ -17,7 +17,7 @@
//! simple miner is included, mostly for testing purposes. John Tromp's Tomato //! simple miner is included, mostly for testing purposes. John Tromp's Tomato
//! miner will be much faster in almost every environment. //! miner will be much faster in almost every environment.
use pow::common::{self, Edge, EdgeType}; use pow::common::{self, CuckooParams, Edge, EdgeType};
use pow::error::{Error, ErrorKind}; use pow::error::{Error, ErrorKind};
use pow::num::ToPrimitive; use pow::num::ToPrimitive;
use pow::{PoWContext, Proof}; use pow::{PoWContext, Proof};
@ -32,11 +32,7 @@ pub struct CuckooContext<T>
where where
T: EdgeType, T: EdgeType,
{ {
edge_bits: u8, params: CuckooParams<T>,
siphash_keys: [u64; 4],
easiness: T,
proof_size: usize,
edge_mask: T,
graph: Vec<T>, graph: Vec<T>,
_max_sols: u32, _max_sols: u32,
} }
@ -88,22 +84,17 @@ where
easiness_pct: u32, easiness_pct: u32,
max_sols: u32, max_sols: u32,
) -> Result<CuckooContext<T>, Error> { ) -> Result<CuckooContext<T>, Error> {
let num_edges = 1 << edge_bits; let params = CuckooParams::new(edge_bits, proof_size, easiness_pct, false)?;
let easiness = to_u64!(easiness_pct) * num_edges / 100; let num_edges = params.num_edges as usize;
Ok(CuckooContext { Ok(CuckooContext {
edge_bits: edge_bits, params: params,
siphash_keys: [0; 4], graph: vec![T::zero(); num_edges + 1],
easiness: to_edge!(easiness),
proof_size: proof_size,
edge_mask: to_edge!(num_edges / 2 - 1),
graph: vec![T::zero(); num_edges as usize + 1],
_max_sols: max_sols, _max_sols: max_sols,
}) })
} }
fn reset(&mut self) -> Result<(), Error> { fn reset(&mut self) -> Result<(), Error> {
let num_edges = 1 << self.edge_bits; self.graph = vec![T::zero(); self.params.num_edges as usize + 1];
self.graph = vec![T::zero(); num_edges + 1];
Ok(()) Ok(())
} }
@ -115,7 +106,7 @@ where
nonce: Option<u32>, nonce: Option<u32>,
solve: bool, solve: bool,
) -> Result<(), Error> { ) -> Result<(), Error> {
self.siphash_keys = common::set_header_nonce(header, nonce)?; self.params.reset_header_nonce(header, nonce)?;
if solve { if solve {
self.reset()?; self.reset()?;
} }
@ -126,7 +117,7 @@ where
/// simply materialized as a u64 from a nonce and an offset (generally 0 or /// simply materialized as a u64 from a nonce and an offset (generally 0 or
/// 1). /// 1).
fn new_node(&self, edge: T, uorv: u64) -> Result<T, Error> { fn new_node(&self, edge: T, uorv: u64) -> Result<T, Error> {
common::sipnode::<T>(&self.siphash_keys, edge, &self.edge_mask, uorv, true) self.params.sipnode(edge, uorv, true)
} }
/// Creates a new edge in the cuckoo graph generated by our seed from a /// Creates a new edge in the cuckoo graph generated by our seed from a
@ -193,7 +184,7 @@ where
nu += 1; nu += 1;
nv += 1; nv += 1;
} }
if nu + nv + 1 == self.proof_size { if nu + nv + 1 == self.params.proof_size {
self.solution(&us, nu as u64, &vs, nv as u64) self.solution(&us, nu as u64, &vs, nv as u64)
} else { } else {
Err(ErrorKind::InvalidCycle(nu + nv + 1))? Err(ErrorKind::InvalidCycle(nu + nv + 1))?
@ -223,8 +214,8 @@ where
}); });
} }
let mut n = 0; let mut n = 0;
let mut sol = vec![T::zero(); self.proof_size]; let mut sol = vec![T::zero(); self.params.proof_size];
for nonce in 0..to_usize!(self.easiness) { for nonce in 0..to_usize!(self.params.easiness) {
let edge = self.new_edge(to_edge!(nonce))?; let edge = self.new_edge(to_edge!(nonce))?;
if cycle.contains(&edge) { if cycle.contains(&edge) {
sol[n] = to_edge!(nonce); sol[n] = to_edge!(nonce);
@ -232,7 +223,7 @@ where
cycle.remove(&edge); cycle.remove(&edge);
} }
} }
return if n == self.proof_size { return if n == self.params.proof_size {
Ok(sol) Ok(sol)
} else { } else {
Err(ErrorKind::NoCycle)? Err(ErrorKind::NoCycle)?
@ -243,7 +234,7 @@ where
pub fn find_cycles_impl(&mut self) -> Result<Vec<Proof>, Error> { pub fn find_cycles_impl(&mut self) -> Result<Vec<Proof>, Error> {
let mut us = [T::zero(); MAXPATHLEN]; let mut us = [T::zero(); MAXPATHLEN];
let mut vs = [T::zero(); MAXPATHLEN]; let mut vs = [T::zero(); MAXPATHLEN];
for nonce in 0..to_usize!(self.easiness) { for nonce in 0..to_usize!(self.params.easiness) {
us[0] = self.new_node(to_edge!(nonce), 0)?; us[0] = self.new_node(to_edge!(nonce), 0)?;
vs[0] = self.new_node(to_edge!(nonce), 1)?; vs[0] = self.new_node(to_edge!(nonce), 1)?;
let u = self.graph[to_usize!(us[0])]; let u = self.graph[to_usize!(us[0])];
@ -258,7 +249,7 @@ where
match sol { match sol {
Ok(s) => { Ok(s) => {
let mut proof = Proof::new(map_vec!(s.to_vec(), |&n| n.to_u64().unwrap_or(0))); let mut proof = Proof::new(map_vec!(s.to_vec(), |&n| n.to_u64().unwrap_or(0)));
proof.cuckoo_sizeshift = self.edge_bits; proof.cuckoo_sizeshift = self.params.edge_bits;
return Ok(vec![proof]); return Ok(vec![proof]);
} }
Err(e) => match e.kind() { Err(e) => match e.kind() {
@ -275,7 +266,7 @@ where
/// nonces form a cycle in a Cuckoo graph. Each nonce generates an edge, we /// nonces form a cycle in a Cuckoo graph. Each nonce generates an edge, we
/// build the nodes on both side of that edge and count the connections. /// build the nodes on both side of that edge and count the connections.
pub fn verify_impl(&self, proof: &Proof) -> Result<(), Error> { pub fn verify_impl(&self, proof: &Proof) -> Result<(), Error> {
let easiness = to_u64!(self.easiness); let easiness = to_u64!(self.params.easiness);
let nonces = &proof.nonces; let nonces = &proof.nonces;
let mut us = vec![T::zero(); proof.proof_size()]; let mut us = vec![T::zero(); proof.proof_size()];
let mut vs = vec![T::zero(); proof.proof_size()]; let mut vs = vec![T::zero(); proof.proof_size()];

111
core/src/pow/lean.rs Normal file
View file

@ -0,0 +1,111 @@
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Lean miner for Cuckatoo Cycle
use std::time::{Duration, Instant};
use croaring::Bitmap;
use pow::common::CuckooParams;
use pow::cuckatoo::CuckatooContext;
use pow::error::{Error, ErrorKind};
use pow::siphash::siphash24;
use pow::{PoWContext, Proof};
/// Lean miner implementation aiming to be as short and simple as possible.
/// As a consequence, it's a little less than 10 times slower than John
/// Tromp's implementation, as it's not optimized for performance and reuses
/// croaring which is likely sub-optimal for this task.
pub struct Lean {
params: CuckooParams<u32>,
edges: Bitmap,
}
impl Lean {
/// Instantiates a new lean miner based on some Cuckatoo parameters
pub fn new(edge_bits: u8, easiness_pct: u32) -> Lean {
// note that proof size doesn't matter to a lean miner
let params = CuckooParams::new(edge_bits, 42, easiness_pct, true).unwrap();
// edge bitmap, before trimming all of them are on
let mut edges = Bitmap::create_with_capacity(params.easiness);
edges.flip_inplace(0..params.easiness.into());
Lean { params, edges }
}
/// Sets the header and nonce to seed the graph
pub fn set_header_nonce(&mut self, header: Vec<u8>, nonce: u32) {
self.params.reset_header_nonce(header, Some(nonce)).unwrap();
}
/// Trim edges in the Cuckatoo graph. This applies multiple trimming rounds
/// and works well for Cuckatoo size above 18.
pub fn trim(&mut self) {
// trimming successively
while self.edges.cardinality() > (7 * (self.params.easiness >> 8) / 8) as u64 {
self.count_and_kill();
}
}
/// Finds the Cuckatoo Cycles on the remaining edges. Delegates the finding
/// to a context, passing the trimmed edges iterator.
pub fn find_cycles(&self, mut ctx: CuckatooContext<u32>) -> Result<Vec<Proof>, Error> {
ctx.find_cycles_iter(self.edges.iter().map(|e| e as u64))
}
fn count_and_kill(&mut self) {
// on each side u or v of the bipartite graph
for uorv in 0..2 {
let mut nodes = Bitmap::create();
// increment count for each node
for e in self.edges.iter() {
let node = self.params.sipnode(e, uorv, false).unwrap();
nodes.add(node);
}
// then kill edges with lone nodes (no neighbour at ^1)
let mut to_kill = Bitmap::create();
for e in self.edges.iter() {
let node = self.params.sipnode(e, uorv, false).unwrap();
if !nodes.contains(node ^ 1) {
to_kill.add(e);
}
}
self.edges.andnot_inplace(&to_kill);
}
}
}
#[cfg(test)]
mod test {
use super::*;
use pow::common;
use pow::cuckatoo::*;
#[test]
fn lean_miner() {
let nonce = 15465723;
let header = [0u8; 84].to_vec(); // with nonce
let edge_bits = 19;
let mut lean = Lean::new(edge_bits, 50);
lean.set_header_nonce(header.clone(), nonce);
lean.trim();
let mut ctx_u32 = CuckatooContext::<u32>::new_impl(edge_bits, 42, 50, 10).unwrap();
ctx_u32.set_header_nonce(header, Some(nonce), true).unwrap();
lean.find_cycles(ctx_u32).unwrap();
}
}

View file

@ -41,6 +41,8 @@ mod common;
pub mod cuckatoo; pub mod cuckatoo;
pub mod cuckoo; pub mod cuckoo;
mod error; mod error;
#[allow(dead_code)]
pub mod lean;
mod siphash; mod siphash;
mod types; mod types;
@ -61,12 +63,8 @@ const MAX_SOLS: u32 = 10;
/// Validates the proof of work of a given header, and that the proof of work /// Validates the proof of work of a given header, and that the proof of work
/// satisfies the requirements of the header. /// satisfies the requirements of the header.
pub fn verify_size(bh: &BlockHeader, cuckoo_sz: u8) -> Result<(), Error> { pub fn verify_size(bh: &BlockHeader, cuckoo_sz: u8) -> Result<(), Error> {
let mut ctx = global::create_pow_context::<u64>( let mut ctx =
cuckoo_sz, global::create_pow_context::<u64>(cuckoo_sz, bh.pow.proof.nonces.len(), MAX_SOLS)?;
bh.pow.proof.nonces.len(),
consensus::EASINESS,
MAX_SOLS,
)?;
ctx.set_header_nonce(bh.pre_pow(), None, false)?; ctx.set_header_nonce(bh.pre_pow(), None, false)?;
ctx.verify(&bh.pow.proof) ctx.verify(&bh.pow.proof)
} }
@ -109,8 +107,7 @@ pub fn pow_size(
loop { loop {
// if we found a cycle (not guaranteed) and the proof hash is higher that the // if we found a cycle (not guaranteed) and the proof hash is higher that the
// diff, we're all good // diff, we're all good
let mut ctx = let mut ctx = global::create_pow_context::<u32>(sz, proof_size, MAX_SOLS)?;
global::create_pow_context::<u32>(sz, proof_size, consensus::EASINESS, MAX_SOLS)?;
ctx.set_header_nonce(bh.pre_pow(), None, true)?; ctx.set_header_nonce(bh.pre_pow(), None, true)?;
if let Ok(proofs) = ctx.find_cycles() { if let Ok(proofs) = ctx.find_cycles() {
bh.pow.proof = proofs[0].clone(); bh.pow.proof = proofs[0].clone();