cpuminer: improve start/stop handling.

This commit is contained in:
Christopher Jeffrey 2017-03-12 09:59:39 -07:00
parent aa7e550f91
commit b104e664a7
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 79 additions and 54 deletions

View File

@ -13,6 +13,7 @@ var co = require('../utils/co');
var AsyncObject = require('../utils/asyncobject');
var workerPool = require('../workers/workerpool').pool;
var mine = require('./mine');
var Lock = require('../utils/lock');
/**
* CPU miner.
@ -33,11 +34,13 @@ function CPUMiner(miner) {
this.network = this.miner.network;
this.logger = this.miner.logger;
this.chain = this.miner.chain;
this.locker = new Lock();
this.running = false;
this.stopping = false;
this.job = null;
this.since = 0;
this.stopJob = null;
this._init();
}
@ -67,25 +70,6 @@ CPUMiner.prototype._init = function _init() {
if (self.job.attempt.prevBlock === tip.prevBlock)
self.job.destroy();
});
this.on('block', function(block, entry) {
// Emit the block hex as a failsafe (in case we can't send it)
self.logger.info('Found block: %d (%s).', entry.height, entry.rhash());
self.logger.debug('Raw: %s', block.toRaw().toString('hex'));
});
this.on('status', function(job, hashes, hashrate) {
var attempt = job.attempt;
var tip = util.revHex(attempt.prevBlock);
self.logger.info(
'Miner: hashrate=%dkhs hashes=%d target=%d height=%d best=%s',
Math.floor(hashrate / 1000),
hashes,
attempt.bits,
attempt.height,
tip);
});
};
/**
@ -106,14 +90,6 @@ CPUMiner.prototype._open = co(function* open() {
*/
CPUMiner.prototype._close = co(function* close() {
if (!this.running)
return;
if (this.stopping) {
yield this._onStop();
return;
}
yield this.stop();
});
@ -124,7 +100,7 @@ CPUMiner.prototype._close = co(function* close() {
*/
CPUMiner.prototype.start = co(function* start() {
var block, entry;
var block, entry, job;
assert(!this.running, 'Miner is already running.');
@ -140,7 +116,7 @@ CPUMiner.prototype.start = co(function* start() {
if (this.stopping)
break;
this.emit('error', e);
continue;
break;
}
if (this.stopping)
@ -152,7 +128,7 @@ CPUMiner.prototype.start = co(function* start() {
if (this.stopping)
break;
this.emit('error', e);
continue;
break;
}
if (this.stopping)
@ -166,22 +142,38 @@ CPUMiner.prototype.start = co(function* start() {
} catch (e) {
if (this.stopping)
break;
if (e.type === 'VerifyError') {
this.logger.warning('Mined an invalid block!');
this.logger.error(e);
continue;
}
this.emit('error', e);
continue;
break;
}
if (!entry) {
this.logger.warning('Mined a bad-prevblk (race condition?)');
continue;
break;
}
if (this.stopping)
break;
// Log the block hex as a failsafe (in case we can't send it).
this.logger.info('Found block: %d (%s).', entry.height, entry.rhash());
this.logger.debug('Raw: %s', block.toRaw().toString('hex'));
this.emit('block', block, entry);
}
this.emit('done');
job = this.stopJob;
if (job) {
this.stopJob = null;
job.resolve();
}
});
/**
@ -191,18 +183,34 @@ CPUMiner.prototype.start = co(function* start() {
*/
CPUMiner.prototype.stop = co(function* stop() {
var unlock = yield this.locker.lock();
try {
return yield this._stop();
} finally {
unlock();
}
});
/**
* Stop mining (without a lock).
* @method
* @returns {Promise}
*/
CPUMiner.prototype.stop = co(function* stop() {
if (!this.running)
return;
assert(this.running, 'Miner is not running.');
assert(!this.stopping, 'Miner is already stopping.');
this.stopping = true;
yield this._onDone();
yield this.wait();
this.running = false;
this.stopping = false;
this.job = null;
this.emit('stop');
});
/**
@ -211,23 +219,11 @@ CPUMiner.prototype.stop = co(function* stop() {
* @returns {Promise}
*/
CPUMiner.prototype._onDone = function _onDone() {
CPUMiner.prototype.wait = function wait() {
var self = this;
return new Promise(function(resolve, reject) {
self.once('done', resolve);
});
};
/**
* Wait for `stop` event.
* @private
* @returns {Promise}
*/
CPUMiner.prototype._onStop = function _onStop() {
var self = this;
return new Promise(function(resolve, reject) {
self.once('stop', resolve);
assert(!self.stopJob);
self.stopJob = co.job(resolve, reject);
});
};
@ -407,7 +403,20 @@ CPUMiner.prototype.iterate = function iterate(job) {
*/
CPUMiner.prototype.sendStatus = function sendStatus(job, nonce) {
this.emit('status', job, job.getHashes(nonce), job.getRate(nonce));
var attempt = job.attempt;
var tip = util.revHex(attempt.prevBlock);
var hashes = job.getHashes(nonce);
var hashrate = job.getRate(nonce);
this.logger.info(
'Status: hashrate=%dkhs hashes=%d target=%d height=%d best=%s',
Math.floor(hashrate / 1000),
hashes,
attempt.bits,
attempt.height,
tip);
this.emit('status', job, hash, hashrate);
};
/**
@ -498,8 +507,7 @@ CPUJob.prototype.refresh = function refresh() {
*/
CPUJob.prototype.updateNonce = function updateNonce() {
this.nonce2++;
if (this.nonce2 === 0x100000000) {
if (++this.nonce2 === 0x100000000) {
this.nonce2 = 0;
this.nonce1++;
}

View File

@ -42,10 +42,27 @@ function Miner(options) {
this.addresses = this.options.addresses;
this.locker = this.chain.locker;
this.cpu = new CPUMiner(this);
this.init();
}
util.inherits(Miner, AsyncObject);
/**
* Open the miner, wait for the chain and mempool to load.
* @method
* @alias module:mining.Miner#open
* @returns {Promise}
*/
Miner.prototype.init = function init() {
var self = this;
this.cpu.on('error', function(err) {
self.emit('error', err);
});
};
/**
* Open the miner, wait for the chain and mempool to load.
* @method