mirror of
https://github.com/mimblewimble/grin.git
synced 2025-05-14 13:11:15 +03:00
fmt
This commit is contained in:
parent
9795d9e452
commit
5a82acd199
2 changed files with 84 additions and 69 deletions
|
@ -38,7 +38,7 @@ use store::Store;
|
|||
use core::genesis::genesis;
|
||||
|
||||
fn main() {
|
||||
env_logger::init().unwrap();
|
||||
env_logger::init().unwrap();
|
||||
|
||||
let gen = genesis();
|
||||
let db = Store::open("./store").unwrap();
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Mining service, gathers transactions from the pool, assemble them in a block and mine the block to produce a valid header with its proof-of-work.
|
||||
//! Mining service, gathers transactions from the pool, assemble them in a
|
||||
//! block and mine the block to produce a valid header with its proof-of-work.
|
||||
|
||||
use rand::{self, Rng};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
@ -28,84 +29,98 @@ use chain;
|
|||
use secp;
|
||||
|
||||
pub struct Miner {
|
||||
chain_state: Arc<Mutex<chain::State>>,
|
||||
chain_store: Arc<Mutex<chain::ChainStore>>,
|
||||
chain_state: Arc<Mutex<chain::State>>,
|
||||
chain_store: Arc<Mutex<chain::ChainStore>>,
|
||||
}
|
||||
|
||||
impl Miner {
|
||||
/// Creates a new Miner. Needs references to the chain state and its storage.
|
||||
pub fn new(chain_state: Arc<Mutex<chain::State>>, chain_store: Arc<Mutex<chain::ChainStore>>) -> Miner {
|
||||
Miner{chain_state: chain_state, chain_store: chain_store}
|
||||
}
|
||||
/// Creates a new Miner. Needs references to the chain state and its
|
||||
/// storage.
|
||||
pub fn new(chain_state: Arc<Mutex<chain::State>>,
|
||||
chain_store: Arc<Mutex<chain::ChainStore>>)
|
||||
-> Miner {
|
||||
Miner {
|
||||
chain_state: chain_state,
|
||||
chain_store: chain_store,
|
||||
}
|
||||
}
|
||||
|
||||
/// Starts the mining loop, building a new block on top of the existing chain anytime required and looking for PoW solution.
|
||||
pub fn run_loop(&self) {
|
||||
loop {
|
||||
// get the latest chain state and build a block on top of it
|
||||
let head: core::BlockHeader;
|
||||
let mut latest_hash: Hash;
|
||||
{
|
||||
head = self.chain_store.lock().unwrap().head_header().unwrap();
|
||||
latest_hash = self.chain_state.lock().unwrap().head.last_block_h;
|
||||
}
|
||||
let b = self.build_block(&head);
|
||||
let mut pow_header = pow::PowHeader::from_block(&b);
|
||||
/// Starts the mining loop, building a new block on top of the existing
|
||||
/// chain anytime required and looking for PoW solution.
|
||||
pub fn run_loop(&self) {
|
||||
loop {
|
||||
// get the latest chain state and build a block on top of it
|
||||
let head: core::BlockHeader;
|
||||
let mut latest_hash: Hash;
|
||||
{
|
||||
head = self.chain_store.lock().unwrap().head_header().unwrap();
|
||||
latest_hash = self.chain_state.lock().unwrap().head.last_block_h;
|
||||
}
|
||||
let b = self.build_block(&head);
|
||||
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 transactions) and as long as the head hasn't changed
|
||||
let deadline = time::get_time().sec + 2;
|
||||
let mut sol = None;
|
||||
while head.hash() == latest_hash && time::get_time().sec < deadline {
|
||||
let pow_hash = pow_header.hash();
|
||||
let mut miner = cuckoo::Miner::new(pow_hash.to_slice(), consensus::EASINESS, b.header.cuckoo_len as u32);
|
||||
if let Ok(proof) = miner.mine() {
|
||||
if proof.to_target() <= b.header.target {
|
||||
sol = Some(proof);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pow_header.nonce += 1;
|
||||
{
|
||||
latest_hash = self.chain_state.lock().unwrap().head.last_block_h;
|
||||
}
|
||||
}
|
||||
// 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
|
||||
let deadline = time::get_time().sec + 2;
|
||||
let mut sol = None;
|
||||
while head.hash() == latest_hash && time::get_time().sec < deadline {
|
||||
let pow_hash = pow_header.hash();
|
||||
let mut miner = cuckoo::Miner::new(pow_hash.to_slice(),
|
||||
consensus::EASINESS,
|
||||
b.header.cuckoo_len as u32);
|
||||
if let Ok(proof) = miner.mine() {
|
||||
if proof.to_target() <= b.header.target {
|
||||
sol = Some(proof);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pow_header.nonce += 1;
|
||||
{
|
||||
latest_hash = self.chain_state.lock().unwrap().head.last_block_h;
|
||||
}
|
||||
}
|
||||
|
||||
// if we found a solution, push our block out
|
||||
if let Some(proof) = sol {
|
||||
if let Err(e) = chain::process_block(&b, self.chain_store.lock().unwrap().deref(), chain::NONE) {
|
||||
error!("Error validating mined block: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if we found a solution, push our block out
|
||||
if let Some(proof) = sol {
|
||||
if let Err(e) = chain::process_block(&b,
|
||||
self.chain_store.lock().unwrap().deref(),
|
||||
chain::NONE) {
|
||||
error!("Error validating mined block: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a new block with the chain head as previous and eligible transactions from the pool.
|
||||
fn build_block(&self, head: &core::BlockHeader) -> core::Block {
|
||||
let mut now_sec = time::get_time().sec;
|
||||
let head_sec = head.timestamp.to_timespec().sec;
|
||||
if now_sec == head_sec {
|
||||
now_sec += 1;
|
||||
}
|
||||
let (target, cuckoo_len) = consensus::next_target(now_sec, head_sec, head.target, head.cuckoo_len);
|
||||
/// Builds a new block with the chain head as previous and eligible
|
||||
/// transactions from the pool.
|
||||
fn build_block(&self, head: &core::BlockHeader) -> core::Block {
|
||||
let mut now_sec = time::get_time().sec;
|
||||
let head_sec = head.timestamp.to_timespec().sec;
|
||||
if now_sec == head_sec {
|
||||
now_sec += 1;
|
||||
}
|
||||
let (target, cuckoo_len) =
|
||||
consensus::next_target(now_sec, head_sec, head.target, head.cuckoo_len);
|
||||
|
||||
let mut rng = rand::OsRng::new().unwrap();
|
||||
let secp_inst = secp::Secp256k1::with_caps(secp::ContextFlag::Commit);
|
||||
// TODO get a new key from the user's wallet or something
|
||||
// TODO get a new key from the user's wallet or something
|
||||
let skey = secp::key::SecretKey::new(&secp_inst, &mut rng);
|
||||
|
||||
// TODO populate inputs and outputs from pool transactions
|
||||
core::Block {
|
||||
header: core::BlockHeader {
|
||||
height: head.height+1,
|
||||
previous: head.hash(),
|
||||
timestamp: time::at(time::Timespec::new(now_sec, 0)),
|
||||
cuckoo_len: cuckoo_len,
|
||||
target: target,
|
||||
nonce: rng.gen(),
|
||||
// TODO populate inputs and outputs from pool transactions
|
||||
core::Block {
|
||||
header: core::BlockHeader {
|
||||
height: head.height + 1,
|
||||
previous: head.hash(),
|
||||
timestamp: time::at(time::Timespec::new(now_sec, 0)),
|
||||
cuckoo_len: cuckoo_len,
|
||||
target: target,
|
||||
nonce: rng.gen(),
|
||||
..Default::default()
|
||||
},
|
||||
inputs: vec![],
|
||||
outputs: vec![],
|
||||
proofs: vec![],
|
||||
}
|
||||
}
|
||||
},
|
||||
inputs: vec![],
|
||||
outputs: vec![],
|
||||
proofs: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue