use croaring::Bitmap;
use crate::pow::common::CuckooParams;
use crate::pow::cuckatoo::CuckatooContext;
use crate::pow::error::Error;
use crate::pow::Proof;
pub struct Lean {
params: CuckooParams,
edges: Bitmap,
}
impl Lean {
pub fn new(edge_bits: u8) -> Lean {
let params = CuckooParams::new(edge_bits, edge_bits, 42).unwrap();
let mut edges = Bitmap::with_container_capacity(params.num_edges as u32);
edges.flip_inplace(0u32..params.num_edges as u32);
Lean { params, edges }
}
pub fn set_header_nonce(&mut self, header: Vec<u8>, nonce: u32) {
self.params.reset_header_nonce(header, Some(nonce)).unwrap();
}
pub fn trim(&mut self) {
while self.edges.cardinality() > (7 * (self.params.num_edges >> 8) / 8) as u64 {
self.count_and_kill();
}
}
pub fn find_cycles(&self, mut ctx: CuckatooContext) -> Result<Vec<Proof>, Error> {
ctx.find_cycles_iter(self.edges.iter().map(|e| e as u64))
}
fn count_and_kill(&mut self) {
for uorv in 0..2 {
let mut nodes = Bitmap::new();
for e in self.edges.iter() {
let node = self.params.sipnode(e.into(), uorv).unwrap();
nodes.add(node as u32);
}
let mut to_kill = Bitmap::new();
for e in self.edges.iter() {
let node = self.params.sipnode(e.into(), uorv).unwrap();
if !nodes.contains((node ^ 1) as u32) {
to_kill.add(e);
}
}
self.edges.andnot_inplace(&to_kill);
}
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::global;
use crate::pow::types::PoWContext;
#[test]
fn lean_miner() {
global::set_local_chain_type(global::ChainTypes::Mainnet);
let nonce = 15465723;
let header = [0u8; 84].to_vec(); let edge_bits = 19;
let mut lean = Lean::new(edge_bits);
lean.set_header_nonce(header.clone(), nonce);
lean.trim();
let mut ctx_u32 = CuckatooContext::new_impl(edge_bits, 42, 10).unwrap();
ctx_u32.set_header_nonce(header, Some(nonce), true).unwrap();
lean.find_cycles(ctx_u32).unwrap();
}
}