parallelize mining. listen for worker pipe errors.

This commit is contained in:
Christopher Jeffrey 2016-05-22 19:24:21 -07:00
parent 53dbac9c87
commit d85956b63f
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
4 changed files with 69 additions and 23 deletions

View File

@ -15,7 +15,8 @@ var node = new bcoin.fullnode({
listen: process.argv.indexOf('--listen') !== -1,
selfish: process.argv.indexOf('--selfish') !== -1,
broadcast: process.argv.indexOf('--broadcast') !== -1,
mine: process.argv.indexOf('--mine') !== -1
mine: process.argv.indexOf('--mine') !== -1,
parallel: process.argv.indexOf('--parallel') !== -1
});
node.on('error', function(err) {
@ -30,15 +31,24 @@ node.open(function(err) {
if (err)
throw err;
if (node.options.mine) {
if (bcoin.network.get().type !== 'regtest')
node.pool.connect();
node.miner.start();
if (node.chain.isFull())
node.startSync();
if (!node.options.mine) {
node.startSync();
return;
}
if (node.network.type === 'regtest') {
node.miner.start();
return;
}
node.pool.connect();
node.startSync();
if (node.chain.isFull()) {
node.miner.start();
return;
}
node.chain.once('full', node.miner.start.bind(node.miner));
});
});

View File

@ -96,7 +96,8 @@ Fullnode.prototype._init = function _init() {
chain: this.chain,
mempool: this.mempool,
address: this.options.payoutAddress,
coinbaseFlags: this.options.coinbaseFlags
coinbaseFlags: this.options.coinbaseFlags,
parallel: this.options.parallel
});
this.walletdb = new bcoin.walletdb({

View File

@ -62,7 +62,7 @@ function Miner(options) {
if (bcoin.useWorkers) {
this.workerPool = new bcoin.workers({
network: this.network,
size: 1,
size: this.options.parallel ? 2 : 1,
timeout: -1
});
}
@ -122,17 +122,14 @@ Miner.prototype._init = function _init() {
});
this.on('block', function(block) {
bcoin.debug(
'Found block: %d (%s)',
block.height,
block.rhash);
// Emit the block hex as a failsafe (in case we can't send it)
bcoin.debug('Raw: %s', block.render().toString('hex'));
bcoin.debug('Found block: %d (%s).', block.height, block.rhash);
bcoin.debug('Raw: %s', block.toRaw('hex'));
});
this.on('status', function(stat) {
bcoin.debug(
'hashrate=%dkhs hashes=%d target=%d height=%d best=%s',
'Miner: hashrate=%dkhs hashes=%d target=%d height=%d best=%s',
stat.hashrate / 1000 | 0,
stat.hashes,
stat.target,
@ -274,6 +271,7 @@ Miner.prototype.createBlock = function createBlock(version, callback) {
address: self.address,
coinbaseFlags: self.coinbaseFlags,
witness: self.chain.segwitActive,
parallel: self.options.parallel,
dsha256: self.dsha256
});
@ -630,9 +628,23 @@ MinerBlock.prototype.mineSync = function mineSync() {
*/
MinerBlock.prototype.mineAsync = function mine(callback) {
var self = this;
if (!this.workerPool)
return this.mine(callback);
function done(err, block) {
self.workerPool.destroy();
callback(err, block);
}
if (this.options.parallel) {
done = utils.once(done);
this.workerPool.mine(this, done);
this.workerPool.mine(this, done);
return;
}
this.workerPool.mine(this, callback);
};

View File

@ -302,8 +302,16 @@ function Worker(pool, id) {
self.emit('exit', -1, null);
});
this.child.stdout.on('data', function(data) {
self.emit('data', data);
this.child.stdin.on('error', function(err) {
self.emit('error', err);
});
this.child.stdout.on('error', function(err) {
self.emit('error', err);
});
this.child.stderr.on('error', function(err) {
self.emit('error', err);
});
this.child.stderr.setEncoding('utf8');
@ -467,6 +475,10 @@ function Master(id, options) {
process.stdin.on('data', function(data) {
self.emit('data', data);
});
// Nowhere to send these errors:
process.stdin.on('error', utils.nop);
process.stdout.on('error', utils.nop);
process.stderr.on('error', utils.nop);
}
this.on('data', function(data) {
@ -533,7 +545,7 @@ Master.prototype.sendEvent = function sendEvent() {
* @param {...String} args
*/
Master.prototype.log = function log() {
Master.prototype.debug = function debug() {
var args, msg;
if (!this.options.debug)
@ -555,6 +567,15 @@ Master.prototype.log = function log() {
process.stderr.write(msg + '\n');
};
/**
* Write an error as a debug message.
* @param {Error} err
*/
Master.prototype.error = function error(err) {
this.debug(err.message);
};
/**
* Destroy the worker.
*/
@ -574,11 +595,13 @@ Master.prototype.destroy = function destroy() {
Master.listen = function listen(id, options) {
var master = new Master(id, options);
var log = master.log.bind(master);
var debug = master.debug.bind(master);
var error = master.error.bind(master);
bcoin.debug = log;
utils.print = log;
utils.error = log;
bcoin.debug = debug;
bcoin.error = error;
utils.print = debug;
utils.error = debug;
master.on('error', function(err) {
bcoin.debug('Master error: %s', err.message);
@ -648,7 +671,7 @@ jobs.mine = function mine(data) {
});
attempt.on('status', function(stat) {
bcoin.debug(
'hashrate=%dkhs hashes=%d target=%d height=%d best=%s',
'Miner: hashrate=%dkhs hashes=%d target=%d height=%d best=%s',
stat.hashrate / 1000 | 0,
stat.hashes,
stat.target,