add a simple miner because we can.
This commit is contained in:
parent
6758d4fe8a
commit
0350b93a0a
@ -498,7 +498,7 @@ Chain.prototype.height = function height() {
|
||||
return this.getTip().height;
|
||||
};
|
||||
|
||||
Chain.prototype.target = function target(last) {
|
||||
Chain.prototype.target = function target(last, block) {
|
||||
var proofOfWorkLimit = utils.toCompact(network.powLimit);
|
||||
var adjustmentInterval = network.powTargetTimespan / network.powTargetSpacing;
|
||||
var newBlockTs, heightFirst, first;
|
||||
@ -512,7 +512,7 @@ Chain.prototype.target = function target(last) {
|
||||
if ((last.height + 1) % adjustmentInterval) {
|
||||
if (network.powAllowMinDifficultyBlocks) {
|
||||
// Special behavior for testnet:
|
||||
newBlockTs = utils.now();
|
||||
newBlockTs = block ? block.ts : utils.now();
|
||||
if (newBlockTs > last.ts + network.powTargetSpacing * 2)
|
||||
return proofOfWorkLimit;
|
||||
|
||||
|
||||
206
lib/bcoin/miner.js
Normal file
206
lib/bcoin/miner.js
Normal file
@ -0,0 +1,206 @@
|
||||
/**
|
||||
* miner.js - simple miner for bcoin
|
||||
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
|
||||
* https://github.com/indutny/bcoin
|
||||
*/
|
||||
|
||||
var bcoin = require('../bcoin');
|
||||
var network = bcoin.protocol.network;
|
||||
var constants = bcoin.protocol.constants;
|
||||
var utils = bcoin.utils;
|
||||
var bn = require('bn.js');
|
||||
var inherits = require('inherits');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var assert = utils.assert;
|
||||
|
||||
/**
|
||||
* Miner
|
||||
*/
|
||||
|
||||
exports.miner = function miner(options, callback) {
|
||||
var chain = bcoin.chain.global;
|
||||
var e = new EventEmitter;
|
||||
var fee = new bn(0);
|
||||
var last = chain.getTip();
|
||||
var nextBlock, timeout, blockChecker;
|
||||
|
||||
function addBlock(b) {
|
||||
var block = b || chain.getTip();
|
||||
if (block.height > last.height) {
|
||||
last = block;
|
||||
// Somebody found the next block before us,
|
||||
// start over with new target.
|
||||
stop();
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
function addTX(tx) {
|
||||
var s;
|
||||
if (tx.height !== -1)
|
||||
return;
|
||||
s = tx.render().length;
|
||||
if (block.size() + s > constants.blocks.maxSize)
|
||||
return;
|
||||
nextBlock.txs.push(tx);
|
||||
fee.iadd(tx.getFee());
|
||||
// Update coinbase value
|
||||
updateCoinbase(nextBlock);
|
||||
// Update merkle root for new coinbase and new tx
|
||||
updateMerkle(nextBlock);
|
||||
}
|
||||
|
||||
function newBlock() {
|
||||
var coinbase, block, target;
|
||||
|
||||
coinbase = bcoin.tx();
|
||||
|
||||
coinbase.input({
|
||||
out: {
|
||||
hash: constants.zeroHash,
|
||||
index: 0xffffffff
|
||||
},
|
||||
script: [
|
||||
new bn(last.height + 1).toArray().reverse(),
|
||||
[],
|
||||
utils.ascii2array(options.msg || 'mined by bcoin')
|
||||
],
|
||||
seq: 0xffffffff
|
||||
});
|
||||
|
||||
coinbase.output({
|
||||
address: options.address,
|
||||
value: new bn(0)
|
||||
});
|
||||
|
||||
target = chain.target(last);
|
||||
|
||||
block = {
|
||||
version: 4,
|
||||
prevBlock: last.verify ? last.hash('hex') : last.hash,
|
||||
merkleRoot: constants.zeroHash.slice(),
|
||||
ts: utils.now(),
|
||||
bits: utils.toCompact(target),
|
||||
nonce: 0
|
||||
};
|
||||
|
||||
block = bcoin.block(block, 'block');
|
||||
delete block.valid;
|
||||
block.verify = block._verify;
|
||||
|
||||
block.target = target;
|
||||
block.extraNonce = new bn(0);
|
||||
|
||||
block.txs.push(coinbase);
|
||||
|
||||
// Update coinbase since our coinbase was added.
|
||||
updateCoinbase(block);
|
||||
// Create our merkle root.
|
||||
updateMerkle(block);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
function updateCoinbase(block) {
|
||||
var coinbase = block.txs[0];
|
||||
coinbase.inputs[0].script[1] = block.extraNonce.toArray();
|
||||
coinbase.outputs[0].value = bcoin.block.reward(last.height + 1).add(fee);
|
||||
}
|
||||
|
||||
function updateMerkle(block) {
|
||||
block.ts = utils.now();
|
||||
block.merkleRoot = block.getMerkleRoot();
|
||||
}
|
||||
|
||||
function iter(block) {
|
||||
timeout = setTimeout(function() {
|
||||
var hash, begin, hps;
|
||||
|
||||
begin = utils.now();
|
||||
|
||||
while (block.nonce <= 0xffffffff) {
|
||||
if (utils.testTarget(block.target, block.hash())) {
|
||||
e.emit('block', block);
|
||||
last = block;
|
||||
nextBlock = newBlock();
|
||||
return iter(nextBlock);
|
||||
}
|
||||
block.nonce++;
|
||||
}
|
||||
|
||||
hps = (0xffffffff / (utils.now() - begin)) * 2;
|
||||
|
||||
block.nonce = 0;
|
||||
block.extraNonce.iaddn(1);
|
||||
|
||||
// We incremented the extraNonce, need to update coinbase.
|
||||
updateCoinbase(block);
|
||||
// We changed the coinbase, need to update merkleRoot.
|
||||
updateMerkle(block);
|
||||
|
||||
e.emit('status', {
|
||||
block: nextBlock,
|
||||
extraNonce: block.extraNonce,
|
||||
hps: hps,
|
||||
target: block.bits
|
||||
});
|
||||
|
||||
return iter(block);
|
||||
}, 10);
|
||||
}
|
||||
|
||||
function start() {
|
||||
blockChecker = setInterval(addBlock, 1000);
|
||||
nextBlock = newBlock();
|
||||
iter(nextBlock);
|
||||
}
|
||||
|
||||
function stop() {
|
||||
if (!timeout)
|
||||
return;
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
clearInterval(blockChecker);
|
||||
blockChecker = null;
|
||||
}
|
||||
|
||||
e.addBlock = addBlock;
|
||||
e.add = e.addTX = addTX;
|
||||
e.start = start;
|
||||
e.stop = stop;
|
||||
|
||||
return e;
|
||||
};
|
||||
|
||||
module.exports = function mine(pool, options) {
|
||||
var options, miner;
|
||||
|
||||
options = {
|
||||
address: options.address,
|
||||
msg: options.msg || 'mined by bcoin',
|
||||
log: options.log
|
||||
};
|
||||
|
||||
miner = exports.miner(options);
|
||||
|
||||
pool.on('tx', function(tx) {
|
||||
miner.addTX(tx);
|
||||
});
|
||||
|
||||
pool.on('block', function(block) {
|
||||
miner.addBlock(block);
|
||||
});
|
||||
|
||||
miner.on('block', function(block) {
|
||||
pool.sendBlock(block);
|
||||
});
|
||||
|
||||
miner.on('status', function(stat) {
|
||||
if (options.log)
|
||||
console.log('Hashes per second: %s', stat.hps);
|
||||
});
|
||||
|
||||
miner.start();
|
||||
|
||||
return miner;
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user