wildtiger 0.0.3

Proof-of-work (PoW) algorithm that is optimized for general-purpose CPUs
Documentation
// Copyright 2019 Stichting Organism
// Copyright 2018 Kodebox, Inc.
// This file is part of CodeChain.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

use mohan::{
    hash::H256,
    U256
};
use std::sync::atomic::{AtomicUsize, Ordering};

pub trait Worker: Send {
    fn init(&mut self, message: &[u8], nonce: u64, target: &U256);
    fn nonce(&mut self, nonce: u64);
    fn proceed(&mut self) -> Option<Vec<Vec<u8>>>;
    fn is_finished(&self) -> bool;
}

static JOB_ID: AtomicUsize = AtomicUsize::new(0);

pub fn work(hash: &H256, target: &U256, mut worker: Box<dyn Worker>, jobs: usize) -> Option<Vec<Vec<u8>>> {
    
    let id = JOB_ID.fetch_add(1, Ordering::SeqCst);
    info!("Starting a new Job {} with hash {}, target: {}", id, hash, target);
    
    worker.init(hash.as_bytes(), 0, target);

    for nonce in 0..=u64::max_value() {
        worker.nonce(nonce);

        while !worker.is_finished() {
            if JOB_ID.load(Ordering::SeqCst) > id + jobs {
                info!("A new job submitted. Stopping the job {}", id);
                return None
            }

            match worker.proceed() {
                Some(solution) => {
                    info!("Nonce: {}", nonce);
                    return Some(solution)
                }
                None => {}
            }
        }
    }
    
    info!("Could not find the solution for hash {}", hash);
    None
}