This commit is contained in:
Chris Kleeschulte 2017-07-21 11:10:54 -04:00
parent 5043027017
commit 0263aa14ae
10 changed files with 81 additions and 55 deletions

View File

@ -99,6 +99,7 @@ function lookInBuiltInPath(req, service) {
var serviceFile = path.resolve(__dirname, '../services/' + service.name); var serviceFile = path.resolve(__dirname, '../services/' + service.name);
return req(serviceFile); return req(serviceFile);
} catch(e) { } catch(e) {
console.log(e);
log.info('Checked the built-in path: lib/services, for service: ' + service.name); log.info('Checked the built-in path: lib/services, for service: ' + service.name);
} }
} }

View File

@ -187,7 +187,7 @@ BlockService.prototype._primeBlockQueue = function(callback) {
return next(err); return next(err);
} }
if (!block) { if (!data) {
return next(); return next();
} }
@ -220,10 +220,7 @@ BlockService.prototype._detectInitialChainState = function(headers) {
}; };
BlockService.prototype.stop = function(callback) { BlockService.prototype.stop = function(callback) {
if (this._deferTimeout) { setImmediate(callback);
this._deferTimeout.unref();
}
callback();
}; };
BlockService.prototype.subscribe = function(name, emitter) { BlockService.prototype.subscribe = function(name, emitter) {
@ -267,7 +264,7 @@ BlockService.prototype._broadcast = function(subscribers, name, entity) {
BlockService.prototype._cacheBlock = function(block) { BlockService.prototype._cacheBlock = function(block) {
log.debug('Setting block: "' + block.rhash() + '" in the block cache.'); log.debug('Setting block: ' + block.rhash() + ' in the block cache.');
// 1. set the block queue, which holds full blocks in memory // 1. set the block queue, which holds full blocks in memory
this._blockQueue.set(block.rhash(), block); this._blockQueue.set(block.rhash(), block);
@ -318,7 +315,7 @@ BlockService.prototype._findCommonAncestor = function(hash) {
// old tip has to be in database // old tip has to be in database
self._db.get(self._encoding.encodeBlockKey(_oldTip), function(err, data) { self._db.get(self._encoding.encodeBlockKey(_oldTip), function(err, data) {
if (err || !block) { if (err || !data) {
return next(err || new Error('missing block')); return next(err || new Error('missing block'));
} }
@ -359,7 +356,7 @@ BlockService.prototype._getBlock = function(hash, callback) {
return callback(err); return callback(err);
} }
if (!block) { if (!data) {
return callback(); return callback();
} }
@ -594,8 +591,6 @@ BlockService.prototype._selectActiveChain = function() {
var mostChainWork = new BN(0); var mostChainWork = new BN(0);
var headers = this._header.getAllHeaders(); var headers = this._header.getAllHeaders();
var self = this;
if (this._chainTips.length === 1) { if (this._chainTips.length === 1) {
return this._chainTips[0]; return this._chainTips[0];
} }
@ -635,13 +630,13 @@ BlockService.prototype._sendDelta = function() {
this._setTip({ height: newTipHeight, hash: newTipHash }); this._setTip({ height: newTipHeight, hash: newTipHash });
var tipOps = utils.encodeTip(this._tip, this.name); var tipOps = utils.encodeTip(this._tip, this.name);
var tipOps = [{ var ops = [{
type: 'put', type: 'put',
key: tipOps.key, key: tipOps.key,
value: tipOps.value value: tipOps.value
}]; }];
this._db.batch(tipOps); this._db.batch(ops);
if (++this._blockCount >= BlockService.MAX_BLOCKS) { if (++this._blockCount >= BlockService.MAX_BLOCKS) {
this._blockCount = 0; this._blockCount = 0;

View File

@ -39,6 +39,7 @@ function DB(options) {
this._operationsCount = 0; this._operationsCount = 0;
this.GENESIS_HASH = constants.BITCOIN_GENESIS_HASH[this.node.getNetworkName()]; this.GENESIS_HASH = constants.BITCOIN_GENESIS_HASH[this.node.getNetworkName()];
this.node.on('stopping', function() { this.node.on('stopping', function() {
log.warn('Node is stopping, gently closing the database.'); log.warn('Node is stopping, gently closing the database.');
}); });
@ -222,9 +223,21 @@ DB.prototype.stop = function(callback) {
self.close(callback); self.close(callback);
}; };
// for this to work, p2p service has to close out first
// it is feeding more and more ops
DB.prototype.close = function(callback) { DB.prototype.close = function(callback) {
if (this._store && this._store.isOpen()) { var self = this;
this._store.close(callback); if (self._store && self._store.isOpen()) {
// wait for pending write events to complete before issuing the close event
async.until(function() {
return self._operationsCount <= 0;
},
function(next) {
setTimeout(next, 1000);
},
function() {
self._store.close(callback);
});
} }
}; };

View File

@ -85,7 +85,7 @@ HeaderService.prototype.start = function(callback) {
}; };
HeaderService.prototype.stop = function(callback) { HeaderService.prototype.stop = function(callback) {
callback(); setImmediate(callback);
}; };
HeaderService.prototype._startSubscriptions = function() { HeaderService.prototype._startSubscriptions = function() {

View File

@ -16,7 +16,7 @@ MempoolService.dependencies = ['db'];
MempoolService.prototype.getAPIMethods = function() { MempoolService.prototype.getAPIMethods = function() {
var methods = [ var methods = [
['getTransaction', this, this.getTransaction, 1] ['getMempoolTransaction', this, this.getTransaction, 1]
]; ];
return methods; return methods;
}; };
@ -54,21 +54,21 @@ MempoolService.prototype._startSubscriptions = function() {
MempoolService.prototype._onBlock = function(block) { MempoolService.prototype._onBlock = function(block) {
// remove this block's txs from mempool // remove this block's txs from mempool
var ops = block.transactions.map(function(tx) { var ops = block.txs.map(function(tx) {
return { return {
type: 'del', type: 'del',
key: tx.id key: tx.txid()
}; };
}); });
this._db.batch(ops); this._db.batch(ops);
}; };
MempoolService.prototype._onTransaction = function(tx) { MempoolService.prototype._onTransaction = function(tx) {
this._db.put(this._encoding.encodeMempoolTransactionKey(tx.id), this._db.put(this._encoding.encodeMempoolTransactionKey(tx.txid()),
this._encoding.encodeMempoolTransactionValue(tx)); this._encoding.encodeMempoolTransactionValue(tx));
}; };
MempoolService.prototype.getTransaction = function(txid, callback) { MempoolService.prototype.getMempoolTransaction = function(txid, callback) {
this._db.get(this._encoding.encodeMempoolTransactionKey(txid), callback); this._db.get(this._encoding.encodeMempoolTransactionKey(txid), callback);
}; };

View File

@ -117,12 +117,15 @@ P2P.prototype.start = function(callback) {
}; };
P2P.prototype._disconnectPool = function() {
log.info('P2P Service: disconnecting pool and peers. SIGINT issued, system shutdown initiated');
this._pool.disconnect();
};
P2P.prototype.stop = function(callback) { P2P.prototype.stop = function(callback) {
setImmediate(callback);
var self = this;
self._pool.disconnect();
callback();
}; };
P2P.prototype.subscribe = function(name, emitter) { P2P.prototype.subscribe = function(name, emitter) {
@ -300,6 +303,7 @@ P2P.prototype._removePeer = function(peer) {
P2P.prototype._setListeners = function() { P2P.prototype._setListeners = function() {
var self = this; var self = this;
self.node.on('stopping', self._disconnectPool.bind(self));
self._pool.on('peerready', self._onPeerReady.bind(self)); self._pool.on('peerready', self._onPeerReady.bind(self));
self._pool.on('peerdisconnect', self._onPeerDisconnect.bind(self)); self._pool.on('peerdisconnect', self._onPeerDisconnect.bind(self));
self._pool.on('peerinv', self._onPeerInventory.bind(self)); self._pool.on('peerinv', self._onPeerInventory.bind(self));

View File

@ -25,8 +25,7 @@ TimestampService.dependencies = [ 'db', 'block' ];
TimestampService.prototype.getAPIMethods = function() { TimestampService.prototype.getAPIMethods = function() {
return [ return [
['getBlockHashesByTimestamp', this, this.getBlockHashesByTimestamp, 2], ['getBlockHashesByTimestamp', this, this.getBlockHashesByTimestamp, 2]
['syncPercentage', this, this.syncPercentage, 0]
]; ];
}; };
@ -140,9 +139,7 @@ TimestampService.prototype._sync = function() {
TimestampService.prototype._setListeners = function() { TimestampService.prototype._setListeners = function() {
var self = this; var self = this;
self.on('reorg', self._onReorg.bind(self));
self._db.on('error', self._onDbError.bind(self));
self.on('reorg', self._handleReorg.bind(self));
}; };
@ -161,7 +158,7 @@ TimestampService.prototype._onBlock = function(block) {
var operations = []; var operations = [];
var ts = block.header.timestamp; var ts = block.ts;
if (ts <= this._lastBlockTimestamp) { if (ts <= this._lastBlockTimestamp) {
ts = this._lastBlockTimestamp + 1; ts = this._lastBlockTimestamp + 1;
@ -178,13 +175,13 @@ TimestampService.prototype._onBlock = function(block) {
operations = operations.concat([ operations = operations.concat([
{ {
type: 'put', type: 'put',
key: this.encoding.encodeTimestampBlockKey(ts), key: this._encoding.encodeTimestampBlockKey(ts),
value: this.encoding.encodeTimestampBlockValue(block.hash) value: this._encoding.encodeTimestampBlockValue(block.hash)
}, },
{ {
type: 'put', type: 'put',
key: this.encoding.encodeBlockTimestampKey(block.hash), key: this._encoding.encodeBlockTimestampKey(block.hash),
value: this.encoding.encodeBlockTimestampValue(ts) value: this._encoding.encodeBlockTimestampValue(ts)
}, },
{ {
type: 'put', type: 'put',

View File

@ -1,12 +1,12 @@
'use strict'; 'use strict';
var async = require('async');
var BaseService = require('../../service'); var BaseService = require('../../service');
var inherits = require('util').inherits; var inherits = require('util').inherits;
var Encoding = require('./encoding'); var Encoding = require('./encoding');
var utils = require('../../lib/utils'); var utils = require('../../utils');
var _ = require('lodash'); var _ = require('lodash');
var LRU = require('lru-cache'); var LRU = require('lru-cache');
var Unit = require('bitcore-lib').Unit;
function TransactionService(options) { function TransactionService(options) {
BaseService.call(this, options); BaseService.call(this, options);
@ -34,7 +34,6 @@ TransactionService.prototype.getAPIMethods = function() {
['getRawTransaction', this, this.getRawTransaction, 1], ['getRawTransaction', this, this.getRawTransaction, 1],
['getTransaction', this, this.getTransaction, 1], ['getTransaction', this, this.getTransaction, 1],
['getDetailedTransaction', this, this.getDetailedTransaction, 1], ['getDetailedTransaction', this, this.getDetailedTransaction, 1],
['sendTransaction', this, this.sendTransaction, 1],
['syncPercentage', this, this.syncPercentage, 0], ['syncPercentage', this, this.syncPercentage, 0],
['getInputValues', this, this._getInputValues, 1] ['getInputValues', this, this._getInputValues, 1]
]; ];
@ -130,10 +129,10 @@ TransactionService.prototype.syncPercentage = function(callback) {
TransactionService.prototype._cacheOutputValues = function(tx) { TransactionService.prototype._cacheOutputValues = function(tx) {
var values = tx.outputs.map(function(output) { var values = tx.outputs.map(function(output) {
return output.satoshis; return Unit.fromBTC(output.value).toSatoshis();
}); });
this._inputValuesCache.set(tx.id, values); this._inputValuesCache.set(tx.txid(), values);
}; };
@ -143,10 +142,12 @@ TransactionService.prototype._getBlockTimestamp = function(hash) {
TransactionService.prototype._getInputValues = function(tx) { TransactionService.prototype._getInputValues = function(tx) {
var self = this;
return tx.inputs.map(function(input) { return tx.inputs.map(function(input) {
var value = this._inputValuesCache.get(input.prevTxId); var value = self._inputValuesCache.get(input.prevout.txid());
if (value) { if (value) {
return value[input.outputIndex]; return value[input.prevout.index];
} }
return null; return null;
}); });
@ -156,7 +157,7 @@ TransactionService.prototype._onBlock = function(block) {
var self = this; var self = this;
var operations = block.transactions.map(function(tx) { var operations = block.txs.map(function(tx) {
return self._processTransaction(tx, { block: block }); return self._processTransaction(tx, { block: block });
}); });
@ -168,7 +169,7 @@ TransactionService.prototype._onBlock = function(block) {
}; };
TransactionService.prototype._onReorg = function(oldBlockList, newBlockList, commonAncestor) { TransactionService.prototype._onReorg = function(oldBlockList, commonAncestor) {
// if the common ancestor block height is greater than our own, then nothing to do for the reorg // if the common ancestor block height is greater than our own, then nothing to do for the reorg
if (this._tip.height <= commonAncestor.header.height) { if (this._tip.height <= commonAncestor.header.height) {
@ -197,8 +198,6 @@ TransactionService.prototype._onReorg = function(oldBlockList, newBlockList, com
this._db.batch(removalOps); this._db.batch(removalOps);
//call onBlock for each of the new blocks
newBlockList.forEach(this._onBlock.bind(this));
}; };
TransactionService.prototype._processTransaction = function(tx, opts) { TransactionService.prototype._processTransaction = function(tx, opts) {
@ -218,7 +217,7 @@ TransactionService.prototype._processTransaction = function(tx, opts) {
tx.__height = opts.block.height; tx.__height = opts.block.height;
return { return {
key: this._encoding.encodeTransactionKey(tx.id), key: this._encoding.encodeTransactionKey(tx.txid()),
value: this._encoding.encodeTransactionValue(tx) value: this._encoding.encodeTransactionValue(tx)
}; };

31
package-lock.json generated
View File

@ -145,9 +145,12 @@
"dev": true "dev": true
}, },
"async": { "async": {
"version": "1.5.2", "version": "2.5.0",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==",
"requires": {
"lodash": "4.17.4"
}
}, },
"asynckit": { "asynckit": {
"version": "0.4.0", "version": "0.4.0",
@ -379,13 +382,18 @@
} }
}, },
"bitcore-p2p": { "bitcore-p2p": {
"version": "github:bitpay/bitcore-p2p#126566a57bdd4495868571860e9764bdc85d9fef", "version": "github:bitpay/bitcore-p2p#f537eb86b9759985822f0f35887642040b1165cb",
"requires": { "requires": {
"bcoin": "github:bcoin-org/bcoin#ffec8ff2d7e05591d113004ed1aca6e0c4fd1d20", "bcoin": "github:bcoin-org/bcoin#ffec8ff2d7e05591d113004ed1aca6e0c4fd1d20",
"bitcore-lib": "0.14.0", "bitcore-lib": "0.14.0",
"bloom-filter": "0.2.0", "bloom-filter": "0.2.0",
"buffers": "github:bitpay/node-buffers#04f4c4264e0d105db2b99b786843ed64f23230d8", "buffers": "github:bitpay/node-buffers#04f4c4264e0d105db2b99b786843ed64f23230d8",
"socks5-client": "0.3.6" "socks5-client": "0.3.6"
},
"dependencies": {
"buffers": {
"version": "github:bitpay/node-buffers#04f4c4264e0d105db2b99b786843ed64f23230d8"
}
} }
}, },
"bl": { "bl": {
@ -495,9 +503,6 @@
"integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
"optional": true "optional": true
}, },
"buffers": {
"version": "github:bitpay/node-buffers#04f4c4264e0d105db2b99b786843ed64f23230d8"
},
"bufferutil": { "bufferutil": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-1.2.1.tgz", "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-1.2.1.tgz",
@ -1563,6 +1568,12 @@
"uglify-js": "2.8.29" "uglify-js": "2.8.29"
}, },
"dependencies": { "dependencies": {
"async": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
"dev": true
},
"source-map": { "source-map": {
"version": "0.4.4", "version": "0.4.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
@ -1991,6 +2002,12 @@
"wordwrap": "1.0.0" "wordwrap": "1.0.0"
}, },
"dependencies": { "dependencies": {
"async": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
"dev": true
},
"glob": { "glob": {
"version": "5.0.15", "version": "5.0.15",
"resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",

View File

@ -49,7 +49,7 @@
"wallet backend" "wallet backend"
], ],
"dependencies": { "dependencies": {
"async": "^1.3.0", "async": "^2.5.0",
"bcoin": "bcoin-org/bcoin#master", "bcoin": "bcoin-org/bcoin#master",
"bitcoind-rpc": "^0.6.0", "bitcoind-rpc": "^0.6.0",
"bitcore-lib": "^0.14", "bitcore-lib": "^0.14",