mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21:08 +03:00
Changes to allow for testing and playing with cuckoo-miner integration (#76)
* Refactoring to allow for different miner implementations. Added conditional support for compiling and loading the cuckoo-miner plugin project. * Small changes to experimentally integrate with cuckoo-miner and compatibility with latest version of cuckoo-miner. * Turning off inclusion of cuckoo_miner by default * Disabling simulate_parallel_mining test for now
This commit is contained in:
parent
60705eff76
commit
12480e7310
13 changed files with 226 additions and 38 deletions
12
Cargo.toml
12
Cargo.toml
|
@ -8,7 +8,6 @@ members = ["api", "chain", "core", "grin", "p2p", "store", "util", "pool", "wall
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
grin_api = { path = "./api" }
|
grin_api = { path = "./api" }
|
||||||
grin_grin = { path = "./grin" }
|
|
||||||
grin_wallet = { path = "./wallet" }
|
grin_wallet = { path = "./wallet" }
|
||||||
secp256k1zkp = { path = "./secp256k1zkp" }
|
secp256k1zkp = { path = "./secp256k1zkp" }
|
||||||
|
|
||||||
|
@ -20,3 +19,14 @@ serde = "~1.0.8"
|
||||||
serde_derive = "~1.0.8"
|
serde_derive = "~1.0.8"
|
||||||
serde_json = "~1.0.2"
|
serde_json = "~1.0.2"
|
||||||
tiny-keccak = "1.1"
|
tiny-keccak = "1.1"
|
||||||
|
|
||||||
|
[dependencies.grin_grin]
|
||||||
|
path = "./grin"
|
||||||
|
version = "*"
|
||||||
|
default-features = false
|
||||||
|
#Comment this in to use the cuckoo-miner package
|
||||||
|
#ensure cuckoo-miner is cloned next to the
|
||||||
|
#grin directory
|
||||||
|
#features = ["cuckoo_miner", "use-cuckoo-miner"]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,10 +38,13 @@ pub const BLOCK_TIME_SEC: i64 = 60;
|
||||||
/// Cuckoo-cycle proof size (cycle length)
|
/// Cuckoo-cycle proof size (cycle length)
|
||||||
pub const PROOFSIZE: usize = 42;
|
pub const PROOFSIZE: usize = 42;
|
||||||
|
|
||||||
|
|
||||||
/// Default Cuckoo Cycle size shift used for mining and validating.
|
/// Default Cuckoo Cycle size shift used for mining and validating.
|
||||||
pub const DEFAULT_SIZESHIFT: u8 = 30;
|
pub const DEFAULT_SIZESHIFT: u8 = 30;
|
||||||
|
|
||||||
/// Lower Cuckoo size shift for tests and testnet
|
/// Lower Cuckoo size shift for tests and testnet
|
||||||
|
/// This should be changed to correspond with the
|
||||||
|
/// loaded plugin if using cuckoo-miner
|
||||||
pub const TEST_SIZESHIFT: u8 = 12;
|
pub const TEST_SIZESHIFT: u8 = 12;
|
||||||
|
|
||||||
/// Default Cuckoo Cycle easiness, high enough to have good likeliness to find
|
/// Default Cuckoo Cycle easiness, high enough to have good likeliness to find
|
||||||
|
|
|
@ -77,7 +77,6 @@ pub trait Committed {
|
||||||
fn overage(&self) -> i64;
|
fn overage(&self) -> i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Proof of work
|
/// Proof of work
|
||||||
#[derive(Copy)]
|
#[derive(Copy)]
|
||||||
pub struct Proof(pub [u32; PROOFSIZE]);
|
pub struct Proof(pub [u32; PROOFSIZE]);
|
||||||
|
|
|
@ -26,6 +26,7 @@ use crypto::sha2::Sha256;
|
||||||
use consensus::PROOFSIZE;
|
use consensus::PROOFSIZE;
|
||||||
use core::Proof;
|
use core::Proof;
|
||||||
use pow::siphash::siphash24;
|
use pow::siphash::siphash24;
|
||||||
|
use pow::MiningWorker;
|
||||||
|
|
||||||
const MAXPATHLEN: usize = 8192;
|
const MAXPATHLEN: usize = 8192;
|
||||||
|
|
||||||
|
@ -153,8 +154,32 @@ impl Cuckoo {
|
||||||
/// tests, being impractical with sizes greater than 2^22.
|
/// tests, being impractical with sizes greater than 2^22.
|
||||||
pub struct Miner {
|
pub struct Miner {
|
||||||
easiness: u64,
|
easiness: u64,
|
||||||
cuckoo: Cuckoo,
|
cuckoo: Option<Cuckoo>,
|
||||||
graph: Vec<u32>,
|
graph: Vec<u32>,
|
||||||
|
sizeshift: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MiningWorker for Miner {
|
||||||
|
|
||||||
|
/// Creates a new miner
|
||||||
|
fn new(ease: u32, sizeshift: u32) -> Miner {
|
||||||
|
let size = 1 << sizeshift;
|
||||||
|
let graph = vec![0; size + 1];
|
||||||
|
let easiness = (ease as u64) * (size as u64) / 100;
|
||||||
|
Miner {
|
||||||
|
easiness: easiness,
|
||||||
|
cuckoo: None,
|
||||||
|
graph: graph,
|
||||||
|
sizeshift: sizeshift,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mine(&mut self, header: &[u8]) -> Result<Proof, Error> {
|
||||||
|
let size = 1 << self.sizeshift;
|
||||||
|
self.graph = vec![0; size + 1];
|
||||||
|
self.cuckoo=Some(Cuckoo::new(header, self.sizeshift));
|
||||||
|
self.mine_impl()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// What type of cycle we have found?
|
/// What type of cycle we have found?
|
||||||
|
@ -168,26 +193,15 @@ enum CycleSol {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Miner {
|
impl Miner {
|
||||||
/// Creates a new miner
|
|
||||||
pub fn new(header: &[u8], ease: u32, sizeshift: u32) -> Miner {
|
|
||||||
let cuckoo = Cuckoo::new(header, sizeshift);
|
|
||||||
let size = 1 << sizeshift;
|
|
||||||
let graph = vec![0; size + 1];
|
|
||||||
let easiness = (ease as u64) * (size as u64) / 100;
|
|
||||||
Miner {
|
|
||||||
easiness: easiness,
|
|
||||||
cuckoo: cuckoo,
|
|
||||||
graph: graph,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Searches for a solution
|
/// Searches for a solution
|
||||||
pub fn mine(&mut self) -> Result<Proof, Error> {
|
pub fn mine_impl(&mut self) -> Result<Proof, Error> {
|
||||||
let mut us = [0; MAXPATHLEN];
|
let mut us = [0; MAXPATHLEN];
|
||||||
let mut vs = [0; MAXPATHLEN];
|
let mut vs = [0; MAXPATHLEN];
|
||||||
for nonce in 0..self.easiness {
|
for nonce in 0..self.easiness {
|
||||||
us[0] = self.cuckoo.new_node(nonce, 0) as u32;
|
us[0] = self.cuckoo.as_mut().unwrap().new_node(nonce, 0) as u32;
|
||||||
vs[0] = self.cuckoo.new_node(nonce, 1) as u32;
|
vs[0] = self.cuckoo.as_mut().unwrap().new_node(nonce, 1) as u32;
|
||||||
let u = self.graph[us[0] as usize];
|
let u = self.graph[us[0] as usize];
|
||||||
let v = self.graph[vs[0] as usize];
|
let v = self.graph[vs[0] as usize];
|
||||||
if us[0] == 0 {
|
if us[0] == 0 {
|
||||||
|
@ -198,7 +212,9 @@ impl Miner {
|
||||||
|
|
||||||
let sol = self.find_sol(nu, &us, nv, &vs);
|
let sol = self.find_sol(nu, &us, nv, &vs);
|
||||||
match sol {
|
match sol {
|
||||||
CycleSol::ValidProof(res) => return Ok(Proof(res)),
|
CycleSol::ValidProof(res) => {
|
||||||
|
return Ok(Proof(res))
|
||||||
|
},
|
||||||
CycleSol::InvalidCycle(_) => continue,
|
CycleSol::InvalidCycle(_) => continue,
|
||||||
CycleSol::NoCycle => {
|
CycleSol::NoCycle => {
|
||||||
self.update_graph(nu, &us, nv, &vs);
|
self.update_graph(nu, &us, nv, &vs);
|
||||||
|
@ -240,7 +256,7 @@ impl Miner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_sol(&self, mut nu: usize, us: &[u32], mut nv: usize, vs: &[u32]) -> CycleSol {
|
fn find_sol(&mut self, mut nu: usize, us: &[u32], mut nv: usize, vs: &[u32]) -> CycleSol {
|
||||||
if us[nu] == vs[nv] {
|
if us[nu] == vs[nv] {
|
||||||
let min = cmp::min(nu, nv);
|
let min = cmp::min(nu, nv);
|
||||||
nu -= min;
|
nu -= min;
|
||||||
|
@ -259,7 +275,7 @@ impl Miner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn solution(&self, us: &[u32], mut nu: u32, vs: &[u32], mut nv: u32) -> CycleSol {
|
fn solution(&mut self, us: &[u32], mut nu: u32, vs: &[u32], mut nv: u32) -> CycleSol {
|
||||||
let mut cycle = HashSet::new();
|
let mut cycle = HashSet::new();
|
||||||
cycle.insert(Edge {
|
cycle.insert(Edge {
|
||||||
u: us[0] as u64,
|
u: us[0] as u64,
|
||||||
|
@ -284,7 +300,7 @@ impl Miner {
|
||||||
let mut n = 0;
|
let mut n = 0;
|
||||||
let mut sol = [0; PROOFSIZE];
|
let mut sol = [0; PROOFSIZE];
|
||||||
for nonce in 0..self.easiness {
|
for nonce in 0..self.easiness {
|
||||||
let edge = self.cuckoo.new_edge(nonce);
|
let edge = self.cuckoo.as_mut().unwrap().new_edge(nonce);
|
||||||
if cycle.contains(&edge) {
|
if cycle.contains(&edge) {
|
||||||
sol[n] = nonce as u32;
|
sol[n] = nonce as u32;
|
||||||
n += 1;
|
n += 1;
|
||||||
|
@ -344,13 +360,13 @@ mod test {
|
||||||
/// generated by other implementations.
|
/// generated by other implementations.
|
||||||
#[test]
|
#[test]
|
||||||
fn mine20_vectors() {
|
fn mine20_vectors() {
|
||||||
let nonces1 = Miner::new(&[49], 75, 20).mine().unwrap();
|
let nonces1 = Miner::new(75, 20).mine(&[49]).unwrap();
|
||||||
assert_eq!(V1, nonces1);
|
assert_eq!(V1, nonces1);
|
||||||
|
|
||||||
let nonces2 = Miner::new(&[50], 70, 20).mine().unwrap();
|
let nonces2 = Miner::new(70, 20).mine(&[50]).unwrap();
|
||||||
assert_eq!(V2, nonces2);
|
assert_eq!(V2, nonces2);
|
||||||
|
|
||||||
let nonces3 = Miner::new(&[51], 70, 20).mine().unwrap();
|
let nonces3 = Miner::new(70, 20).mine(&[51]).unwrap();
|
||||||
assert_eq!(V3, nonces3);
|
assert_eq!(V3, nonces3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,13 +397,13 @@ mod test {
|
||||||
// cuckoo20
|
// cuckoo20
|
||||||
for n in 1..5 {
|
for n in 1..5 {
|
||||||
let h = [n; 32];
|
let h = [n; 32];
|
||||||
let nonces = Miner::new(&h, 75, 20).mine().unwrap();
|
let nonces = Miner::new(75, 20).mine(&h).unwrap();
|
||||||
assert!(Cuckoo::new(&h, 20).verify(nonces, 75));
|
assert!(Cuckoo::new(&h, 20).verify(nonces, 75));
|
||||||
}
|
}
|
||||||
// cuckoo18
|
// cuckoo18
|
||||||
for n in 1..5 {
|
for n in 1..5 {
|
||||||
let h = [n; 32];
|
let h = [n; 32];
|
||||||
let nonces = Miner::new(&h, 75, 18).mine().unwrap();
|
let nonces = Miner::new(75, 18).mine(&h).unwrap();
|
||||||
assert!(Cuckoo::new(&h, 18).verify(nonces, 75));
|
assert!(Cuckoo::new(&h, 18).verify(nonces, 75));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,25 @@ use consensus::EASINESS;
|
||||||
use consensus::MINIMUM_DIFFICULTY;
|
use consensus::MINIMUM_DIFFICULTY;
|
||||||
use core::BlockHeader;
|
use core::BlockHeader;
|
||||||
use core::hash::Hashed;
|
use core::hash::Hashed;
|
||||||
|
use core::Proof;
|
||||||
use core::target::Difficulty;
|
use core::target::Difficulty;
|
||||||
use pow::cuckoo::{Cuckoo, Miner, Error};
|
use pow::cuckoo::{Cuckoo, Miner, Error};
|
||||||
|
|
||||||
|
|
||||||
|
/// Should be implemented by anything providing mining services
|
||||||
|
///
|
||||||
|
|
||||||
|
pub trait MiningWorker {
|
||||||
|
|
||||||
|
//This only sets parameters and does initialisation work now
|
||||||
|
fn new(ease: u32, sizeshift: u32) -> Self;
|
||||||
|
|
||||||
|
//Actually perform a mining attempt on the given input and
|
||||||
|
//return a proof if found
|
||||||
|
fn mine(&mut self, header: &[u8]) -> Result<Proof, Error>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// 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: u32) -> bool {
|
pub fn verify_size(bh: &BlockHeader, cuckoo_sz: u32) -> bool {
|
||||||
|
@ -65,7 +81,7 @@ pub fn pow_size(bh: &mut BlockHeader, diff: Difficulty, sizeshift: u32) -> Resul
|
||||||
|
|
||||||
// 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
|
||||||
if let Ok(proof) = Miner::new(&pow_hash[..], EASINESS, sizeshift).mine() {
|
if let Ok(proof) = Miner::new(EASINESS, sizeshift).mine(&pow_hash[..]) {
|
||||||
if proof.to_difficulty() >= diff {
|
if proof.to_difficulty() >= diff {
|
||||||
bh.pow = proof;
|
bh.pow = proof;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
|
@ -4,6 +4,10 @@ version = "0.1.0"
|
||||||
authors = ["Ignotus Peverell <igno.peverell@protonmail.com>"]
|
authors = ["Ignotus Peverell <igno.peverell@protonmail.com>"]
|
||||||
workspace = ".."
|
workspace = ".."
|
||||||
|
|
||||||
|
[features]
|
||||||
|
# Compliation flag whether to include the experimental cuckoo-miner crate
|
||||||
|
use-cuckoo-miner = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
grin_api = { path = "../api" }
|
grin_api = { path = "../api" }
|
||||||
grin_chain = { path = "../chain" }
|
grin_chain = { path = "../chain" }
|
||||||
|
@ -15,6 +19,8 @@ grin_util = { path = "../util" }
|
||||||
grin_wallet = { path = "../wallet" }
|
grin_wallet = { path = "../wallet" }
|
||||||
secp256k1zkp = { path = "../secp256k1zkp" }
|
secp256k1zkp = { path = "../secp256k1zkp" }
|
||||||
|
|
||||||
|
#cuckoo_miner = { version = "*", optional=true, path = "../../cuckoo-miner"}
|
||||||
|
|
||||||
env_logger="^0.3.5"
|
env_logger="^0.3.5"
|
||||||
futures = "^0.1.9"
|
futures = "^0.1.9"
|
||||||
futures-cpupool = "^0.1.3"
|
futures-cpupool = "^0.1.3"
|
||||||
|
|
|
@ -46,12 +46,18 @@ extern crate grin_util as util;
|
||||||
extern crate grin_wallet as wallet;
|
extern crate grin_wallet as wallet;
|
||||||
extern crate secp256k1zkp as secp;
|
extern crate secp256k1zkp as secp;
|
||||||
|
|
||||||
|
#[cfg(feature = "use-cuckoo-miner")]
|
||||||
|
extern crate cuckoo_miner;
|
||||||
|
|
||||||
mod adapters;
|
mod adapters;
|
||||||
mod miner;
|
mod miner;
|
||||||
|
#[cfg(feature = "use-cuckoo-miner")]
|
||||||
|
mod plugin;
|
||||||
mod server;
|
mod server;
|
||||||
mod seed;
|
mod seed;
|
||||||
mod sync;
|
mod sync;
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
|
|
||||||
pub use server::{Server};
|
pub use server::{Server};
|
||||||
pub use types::{ServerConfig, MinerConfig, Seeding, ServerStats};
|
pub use types::{ServerConfig, MinerConfig, Seeding, ServerStats};
|
||||||
|
|
|
@ -19,6 +19,7 @@ use rand::{self, Rng};
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std;
|
use std;
|
||||||
|
use std::env;
|
||||||
use time;
|
use time;
|
||||||
|
|
||||||
use adapters::{ChainToPoolAndNetAdapter, PoolToChainAdapter};
|
use adapters::{ChainToPoolAndNetAdapter, PoolToChainAdapter};
|
||||||
|
@ -26,9 +27,11 @@ use api;
|
||||||
use core::consensus;
|
use core::consensus;
|
||||||
use core::consensus::*;
|
use core::consensus::*;
|
||||||
use core::core;
|
use core::core;
|
||||||
|
use core::core::Proof;
|
||||||
|
use core::pow::cuckoo;
|
||||||
use core::core::target::Difficulty;
|
use core::core::target::Difficulty;
|
||||||
use core::core::hash::{Hash, Hashed};
|
use core::core::hash::{Hash, Hashed};
|
||||||
use core::pow::cuckoo;
|
use core::pow::MiningWorker;
|
||||||
use core::ser;
|
use core::ser;
|
||||||
use chain;
|
use chain;
|
||||||
use secp;
|
use secp;
|
||||||
|
@ -75,10 +78,11 @@ impl Miner {
|
||||||
|
|
||||||
/// Starts the mining loop, building a new block on top of the existing
|
/// Starts the mining loop, building a new block on top of the existing
|
||||||
/// chain anytime required and looking for PoW solution.
|
/// chain anytime required and looking for PoW solution.
|
||||||
pub fn run_loop(&self) {
|
pub fn run_loop<T: MiningWorker>(&self, mut miner:T) {
|
||||||
|
|
||||||
info!("(Server ID: {}) Starting miner loop.", self.debug_output_id);
|
info!("(Server ID: {}) Starting miner loop.", self.debug_output_id);
|
||||||
let mut coinbase = self.get_coinbase();
|
let mut coinbase = self.get_coinbase();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// get the latest chain state and build a block on top of it
|
// get the latest chain state and build a block on top of it
|
||||||
let head = self.chain.head_header().unwrap();
|
let head = self.chain.head_header().unwrap();
|
||||||
|
@ -102,14 +106,12 @@ impl Miner {
|
||||||
}
|
}
|
||||||
while head.hash() == latest_hash && time::get_time().sec < deadline {
|
while head.hash() == latest_hash && time::get_time().sec < deadline {
|
||||||
let pow_hash = b.hash();
|
let pow_hash = b.hash();
|
||||||
let mut miner =
|
if let Ok(proof) = miner.mine(&pow_hash[..]) {
|
||||||
cuckoo::Miner::new(&pow_hash[..], consensus::EASINESS, self.config.cuckoo_size);
|
|
||||||
if let Ok(proof) = miner.mine() {
|
|
||||||
let proof_diff=proof.to_difficulty();
|
let proof_diff=proof.to_difficulty();
|
||||||
debug!("(Server ID: {}) Header difficulty is: {}, Proof difficulty is: {}",
|
/*debug!("(Server ID: {}) Header difficulty is: {}, Proof difficulty is: {}",
|
||||||
self.debug_output_id,
|
self.debug_output_id,
|
||||||
b.header.difficulty,
|
b.header.difficulty,
|
||||||
proof_diff);
|
proof_diff);*/
|
||||||
|
|
||||||
if proof_diff >= b.header.difficulty {
|
if proof_diff >= b.header.difficulty {
|
||||||
sol = Some(proof);
|
sol = Some(proof);
|
||||||
|
|
104
grin/src/plugin.rs
Normal file
104
grin/src/plugin.rs
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
// Copyright 2017 The Grin Developers
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
//! Plugin wrapper for cuckoo miner, implementing common traits
|
||||||
|
//! with the existing embedded miner. This is all included conditionally
|
||||||
|
//! for compatibility reasons with those who aren't interested in playing
|
||||||
|
//! with cuckoo-miner at present
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
use core::pow::cuckoo;
|
||||||
|
use core::pow::cuckoo::Error;
|
||||||
|
use core::pow::MiningWorker;
|
||||||
|
use core::consensus::TEST_SIZESHIFT;
|
||||||
|
|
||||||
|
use core::core::Proof;
|
||||||
|
|
||||||
|
use cuckoo_miner::{
|
||||||
|
CuckooMiner,
|
||||||
|
CuckooPluginManager,
|
||||||
|
CuckooMinerConfig,
|
||||||
|
CuckooMinerError,
|
||||||
|
CuckooMinerSolution,
|
||||||
|
CuckooPluginCapabilities};
|
||||||
|
|
||||||
|
pub struct PluginMiner {
|
||||||
|
miner:CuckooMiner,
|
||||||
|
last_solution: CuckooMinerSolution,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MiningWorker for PluginMiner {
|
||||||
|
|
||||||
|
/// This will initialise a plugin according to what's currently
|
||||||
|
/// included in CONSENSUS::TEST_SIZESHIFT, just using the edgetrim
|
||||||
|
/// version of the miner for now, though this should become
|
||||||
|
/// configurable somehow
|
||||||
|
|
||||||
|
fn new(ease: u32, sizeshift: u32) -> Self {
|
||||||
|
|
||||||
|
//Get directory of executable
|
||||||
|
let mut exe_path=env::current_exe().unwrap();
|
||||||
|
exe_path.pop();
|
||||||
|
let exe_path=exe_path.to_str().unwrap();
|
||||||
|
|
||||||
|
//First, load and query the plugins in the given directory
|
||||||
|
//These should all be stored in 'deps' at the moment relative, though
|
||||||
|
//to the executable path, though they should appear somewhere else
|
||||||
|
//when packaging is more//thought out
|
||||||
|
|
||||||
|
let mut plugin_manager = CuckooPluginManager::new().unwrap();
|
||||||
|
let result=plugin_manager.load_plugin_dir(String::from(format!("{}/deps", exe_path))).expect("");
|
||||||
|
|
||||||
|
//Get a list of installed plugins and capabilities.. filtering for the one we want
|
||||||
|
//Just use the baseline edgetrim (i.e. cuckoo_miner.cpp) for now
|
||||||
|
//You need to change the value TEST_SIZESHIFT in consensus.rs for now to modify this,
|
||||||
|
//so that blocks mined in this version will validate
|
||||||
|
|
||||||
|
let filter = format!("simple_{}", TEST_SIZESHIFT);
|
||||||
|
|
||||||
|
let caps = plugin_manager.get_available_plugins(&filter).unwrap();
|
||||||
|
//insert it into the miner configuration being created below
|
||||||
|
|
||||||
|
let mut config = CuckooMinerConfig::new();
|
||||||
|
|
||||||
|
info!("Mining using plugin: {}", caps[0].full_path.clone());
|
||||||
|
config.plugin_full_path = caps[0].full_path.clone();
|
||||||
|
//Set threads, should read this from a configuration file
|
||||||
|
//somewhere or query the system to determine a default
|
||||||
|
config.num_threads=4;
|
||||||
|
//let plugin decide number of trims
|
||||||
|
config.num_trims=0;
|
||||||
|
|
||||||
|
//this will load the associated plugin
|
||||||
|
let miner = CuckooMiner::new(config).expect("");
|
||||||
|
|
||||||
|
PluginMiner {
|
||||||
|
miner: miner,
|
||||||
|
last_solution: CuckooMinerSolution::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// And simply calls the mine function of the loaded plugin
|
||||||
|
/// returning whether a solution was found and the solution itself
|
||||||
|
|
||||||
|
fn mine(&mut self, header: &[u8]) -> Result<Proof, cuckoo::Error> {
|
||||||
|
let result = self.miner.mine(&header, &mut self.last_solution).unwrap();
|
||||||
|
if result == true {
|
||||||
|
return Ok(Proof(self.last_solution.solution_nonces));
|
||||||
|
}
|
||||||
|
Err(Error::NoSolution)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
//! Mining plugin manager, using the cuckoo-miner crate to provide
|
||||||
|
//! a mining worker implementation
|
||||||
|
//!
|
||||||
|
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
|
@ -31,6 +31,8 @@ use chain;
|
||||||
use chain::ChainStore;
|
use chain::ChainStore;
|
||||||
use core::{self, consensus};
|
use core::{self, consensus};
|
||||||
use core::core::hash::Hashed;
|
use core::core::hash::Hashed;
|
||||||
|
use core::pow::cuckoo;
|
||||||
|
use core::pow::MiningWorker;
|
||||||
use miner;
|
use miner;
|
||||||
use p2p;
|
use p2p;
|
||||||
use pool;
|
use pool;
|
||||||
|
@ -39,6 +41,9 @@ use store;
|
||||||
use sync;
|
use sync;
|
||||||
use types::*;
|
use types::*;
|
||||||
|
|
||||||
|
#[cfg(feature = "use-cuckoo-miner")]
|
||||||
|
use plugin::PluginMiner;
|
||||||
|
|
||||||
/// Grin server holding internal structures.
|
/// Grin server holding internal structures.
|
||||||
pub struct Server {
|
pub struct Server {
|
||||||
pub config: ServerConfig,
|
pub config: ServerConfig,
|
||||||
|
@ -142,11 +147,24 @@ impl Server {
|
||||||
|
|
||||||
/// Start mining for blocks on a separate thread. Relies on a toy miner,
|
/// Start mining for blocks on a separate thread. Relies on a toy miner,
|
||||||
/// mostly for testing.
|
/// mostly for testing.
|
||||||
|
#[cfg(not(feature = "use-cuckoo-miner"))]
|
||||||
pub fn start_miner(&self, config: MinerConfig) {
|
pub fn start_miner(&self, config: MinerConfig) {
|
||||||
let mut miner = miner::Miner::new(config, self.chain.clone(), self.tx_pool.clone());
|
let mut miner = miner::Miner::new(config.clone(), self.chain.clone(), self.tx_pool.clone());
|
||||||
miner.set_debug_output_id(format!("Port {}",self.config.p2p_config.port));
|
miner.set_debug_output_id(format!("Port {}",self.config.p2p_config.port));
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
miner.run_loop();
|
let test_cuckoo_miner = cuckoo::Miner::new(consensus::EASINESS, config.cuckoo_size.clone());
|
||||||
|
miner.run_loop(test_cuckoo_miner);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// And a version we only get if we're using the cuckoo miner crate
|
||||||
|
#[cfg(feature = "use-cuckoo-miner")]
|
||||||
|
pub fn start_miner(&self, config: MinerConfig) {
|
||||||
|
let mut miner = miner::Miner::new(config.clone(), self.chain.clone(), self.tx_pool.clone());
|
||||||
|
miner.set_debug_output_id(format!("Port {}",self.config.p2p_config.port));
|
||||||
|
thread::spawn(move || {
|
||||||
|
let test_cuckoo_miner = PluginMiner::new(consensus::EASINESS, config.cuckoo_size.clone());
|
||||||
|
miner.run_loop(test_cuckoo_miner);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,7 @@ pub struct MinerConfig {
|
||||||
/// Size of Cuckoo Cycle to mine on
|
/// Size of Cuckoo Cycle to mine on
|
||||||
pub cuckoo_size: u32,
|
pub cuckoo_size: u32,
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ServerConfig {
|
impl Default for ServerConfig {
|
||||||
|
|
|
@ -125,7 +125,10 @@ fn simulate_seeding () {
|
||||||
/// as a seed. Meant to test the evolution of mining difficulty with miners running at
|
/// as a seed. Meant to test the evolution of mining difficulty with miners running at
|
||||||
/// different rates
|
/// different rates
|
||||||
|
|
||||||
#[test]
|
|
||||||
|
//Just going to comment this out as an automatically run test for the time being,
|
||||||
|
//As it's more for actively testing and hurts CI a lot
|
||||||
|
//#[test]
|
||||||
fn simulate_parallel_mining(){
|
fn simulate_parallel_mining(){
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue