mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-01 17:01:09 +03:00
Several bug fixes to the miner loop. Now builds the block properly and updates the shared head state.
This commit is contained in:
parent
57eb7ad0a9
commit
17104977de
1 changed files with 33 additions and 20 deletions
|
@ -20,6 +20,7 @@ use std::sync::{Arc, Mutex};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use time;
|
use time;
|
||||||
|
|
||||||
|
use adapters::ChainToNetAdapter;
|
||||||
use core::consensus;
|
use core::consensus;
|
||||||
use core::core;
|
use core::core;
|
||||||
use core::core::hash::{Hash, Hashed};
|
use core::core::hash::{Hash, Hashed};
|
||||||
|
@ -31,15 +32,21 @@ use secp;
|
||||||
pub struct Miner {
|
pub struct Miner {
|
||||||
chain_head: Arc<Mutex<chain::Tip>>,
|
chain_head: Arc<Mutex<chain::Tip>>,
|
||||||
chain_store: Arc<chain::ChainStore>,
|
chain_store: Arc<chain::ChainStore>,
|
||||||
|
/// chain adapter to net
|
||||||
|
chain_adapter: Arc<ChainToNetAdapter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Miner {
|
impl Miner {
|
||||||
/// Creates a new Miner. Needs references to the chain state and its
|
/// Creates a new Miner. Needs references to the chain state and its
|
||||||
/// storage.
|
/// storage.
|
||||||
pub fn new(chain_head: Arc<Mutex<chain::Tip>>, chain_store: Arc<chain::ChainStore>) -> Miner {
|
pub fn new(chain_head: Arc<Mutex<chain::Tip>>,
|
||||||
|
chain_store: Arc<chain::ChainStore>,
|
||||||
|
chain_adapter: Arc<ChainToNetAdapter>)
|
||||||
|
-> Miner {
|
||||||
Miner {
|
Miner {
|
||||||
chain_head: chain_head,
|
chain_head: chain_head,
|
||||||
chain_store: chain_store,
|
chain_store: chain_store,
|
||||||
|
chain_adapter: chain_adapter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,15 +62,17 @@ impl Miner {
|
||||||
head = self.chain_store.head_header().unwrap();
|
head = self.chain_store.head_header().unwrap();
|
||||||
latest_hash = self.chain_head.lock().unwrap().last_block_h;
|
latest_hash = self.chain_head.lock().unwrap().last_block_h;
|
||||||
}
|
}
|
||||||
let b = self.build_block(&head);
|
let mut b = self.build_block(&head);
|
||||||
let mut pow_header = pow::PowHeader::from_block(&b);
|
let mut pow_header = pow::PowHeader::from_block(&b);
|
||||||
|
|
||||||
// look for a pow for at most 2 sec on the same block (to give a chance to new
|
// look for a pow for at most 2 sec on the same block (to give a chance to new
|
||||||
// transactions) and as long as the head hasn't changed
|
// transactions) and as long as the head hasn't changed
|
||||||
let deadline = time::get_time().sec + 2;
|
let deadline = time::get_time().sec + 2;
|
||||||
let mut sol = None;
|
let mut sol = None;
|
||||||
debug!("Mining at Cuckoo{} for at most 2 secs.",
|
debug!("Mining at Cuckoo{} for at most 2 secs on block {}.",
|
||||||
b.header.cuckoo_len);
|
b.header.cuckoo_len,
|
||||||
|
latest_hash);
|
||||||
|
let mut iter_count = 0;
|
||||||
while head.hash() == latest_hash && time::get_time().sec < deadline {
|
while head.hash() == latest_hash && time::get_time().sec < deadline {
|
||||||
let pow_hash = pow_header.hash();
|
let pow_hash = pow_header.hash();
|
||||||
let mut miner = cuckoo::Miner::new(pow_hash.to_slice(),
|
let mut miner = cuckoo::Miner::new(pow_hash.to_slice(),
|
||||||
|
@ -79,16 +88,28 @@ impl Miner {
|
||||||
{
|
{
|
||||||
latest_hash = self.chain_head.lock().unwrap().last_block_h;
|
latest_hash = self.chain_head.lock().unwrap().last_block_h;
|
||||||
}
|
}
|
||||||
|
iter_count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we found a solution, push our block out
|
// if we found a solution, push our block out
|
||||||
if let Some(proof) = sol {
|
if let Some(proof) = sol {
|
||||||
info!("Found valid proof of work, adding block {}.", b.hash());
|
info!("Found valid proof of work, adding block {}.", b.hash());
|
||||||
if let Err(e) = chain::process_block(&b, self.chain_store.clone(), chain::NONE) {
|
b.header.pow = proof;
|
||||||
|
b.header.nonce = pow_header.nonce;
|
||||||
|
let res = chain::process_block(&b,
|
||||||
|
self.chain_store.clone(),
|
||||||
|
self.chain_adapter.clone(),
|
||||||
|
chain::NONE);
|
||||||
|
if let Err(e) = res {
|
||||||
error!("Error validating mined block: {:?}", e);
|
error!("Error validating mined block: {:?}", e);
|
||||||
|
} else if let Ok(Some(tip)) = res {
|
||||||
|
let chain_head = self.chain_head.clone();
|
||||||
|
let mut head = chain_head.lock().unwrap();
|
||||||
|
*head = tip;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug!("No solution found, continuing...")
|
debug!("No solution found after {} iterations, continuing...",
|
||||||
|
iter_count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,19 +131,11 @@ impl Miner {
|
||||||
let skey = secp::key::SecretKey::new(&secp_inst, &mut rng);
|
let skey = secp::key::SecretKey::new(&secp_inst, &mut rng);
|
||||||
|
|
||||||
// TODO populate inputs and outputs from pool transactions
|
// TODO populate inputs and outputs from pool transactions
|
||||||
core::Block {
|
let mut b = core::Block::new(head, vec![], skey).unwrap();
|
||||||
header: core::BlockHeader {
|
b.header.nonce = rng.gen();
|
||||||
height: head.height + 1,
|
b.header.target = target;
|
||||||
previous: head.hash(),
|
b.header.cuckoo_len = cuckoo_len;
|
||||||
timestamp: time::at(time::Timespec::new(now_sec, 0)),
|
b.header.timestamp = time::at(time::Timespec::new(now_sec, 0));
|
||||||
cuckoo_len: cuckoo_len,
|
b
|
||||||
target: target,
|
|
||||||
nonce: rng.gen(),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
inputs: vec![],
|
|
||||||
outputs: vec![],
|
|
||||||
proofs: vec![],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue