This commit is contained in:
Chris Kleeschulte 2017-07-17 10:17:49 -04:00
parent 67e9d63f4b
commit e1b8c583d8
5 changed files with 39 additions and 78 deletions

View File

@ -7,6 +7,7 @@ module.exports = {
regtest: '0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206',
testnet: '000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943', //this is testnet3
testnet5: '000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943' //this is testnet5
}
},
DB_PREFIX: new Buffer('ffff', 'hex')
};

View File

@ -10,28 +10,15 @@ var shuttingDown = false;
var fs = require('fs');
/**
* This function will instantiate and start a Node, requiring the necessary service
* modules, and registering event handlers.
* @param {Object} options
* @param {Object} options.servicesPath - The path to the location of service modules
* @param {String} options.path - The absolute path of the configuration file
* @param {Object} options.config - The parsed bitcore-node.json configuration file
* @param {Array} options.config.services - An array of services names.
* @param {Object} options.config.servicesConfig - Parameters to pass to each service
* @param {String} options.config.network - 'livenet', 'testnet' or 'regtest
* @param {Number} options.config.port - The port to use for the web service
*/
function start(options) {
/* jshint maxstatements: 20 */
var fullConfig = _.clone(options.config);
var servicesPath;
if (options.servicesPath) {
servicesPath = options.servicesPath; // services are in a different directory than the config
servicesPath = options.servicesPath;
} else {
servicesPath = options.path; // defaults to the same directory
servicesPath = options.path;
}
fullConfig.path = path.resolve(options.path, './bitcore-node.json');
@ -201,11 +188,6 @@ function setupServices(req, servicesPath, config) {
return services;
}
/**
* Will shutdown a node and then the process
* @param {Object} _process - The Node.js process object
* @param {Node} node - The Bitcore Node instance
*/
function cleanShutdown(_process, node) {
node.stop(function(err) {
if(err) {
@ -217,15 +199,6 @@ function cleanShutdown(_process, node) {
});
}
/**
* Will handle all the shutdown tasks that need to take place to ensure a safe exit
* @param {Object} options
* @param {String} options.sigint - The signal given was a SIGINT
* @param {Array} options.exit - The signal given was an uncaughtException
* @param {Object} _process - The Node.js process
* @param {Node} node
* @param {Error} error
*/
function exitHandler(options, _process, node, err) {
if (err) {
log.error('uncaught exception:', err);
@ -247,17 +220,8 @@ function exitHandler(options, _process, node, err) {
}
}
/**
* Will register event handlers to stop the node for `process` events
* `uncaughtException` and `SIGINT`.
* @param {Object} _process - The Node.js process
* @param {Node} node
*/
function registerExitHandlers(_process, node) {
//catches uncaught exceptions
_process.on('uncaughtException', exitHandler.bind(null, {exit:true}, _process, node));
//catches ctrl+c event
_process.on('SIGINT', exitHandler.bind(null, {sigint:true}, _process, node));
}

View File

@ -171,7 +171,6 @@ BlockService.prototype.isSynced = function(callback) {
BlockService.prototype.start = function(callback) {
var self = this;
self._setListeners();
async.waterfall([
function(next) {
@ -191,6 +190,7 @@ BlockService.prototype.start = function(callback) {
if(err) {
return callback(err);
}
self._setListeners();
self._startSubscriptions();
callback();
});
@ -406,7 +406,7 @@ BlockService.prototype._getIncompleteChainIndexes = function(block) {
BlockService.prototype._getOldBlocks = function(currentHash, commonAncestorHash) {
// the old blocks should be in the meta colection
if (currentHash === commonAncestorHash || !commonAncestor || !currentHash) {
if (currentHash === commonAncestorHash || !commonAncestorHash || !currentHash) {
return;
}
@ -435,7 +435,7 @@ BlockService.prototype._handleReorg = function(block) {
var commonAncestor = this._findCommonAncestor(block);
var oldBlocks = this._getOldBlocks(this._tip.hash, block.hash, commonAncestor.hash);
if (!commonAncestor || !oldBlocks || oldBlock.length < 1) {
if (!commonAncestor || !oldBlocks || oldBlocks.length < 1) {
log.error('A common ancestor block between hash: ' + this._tip.hash + ' (our current tip) and: ' +
block.hash + ' (the forked block) could not be found. Bitcore-node must exit.');
this.node.stop();
@ -602,7 +602,7 @@ BlockService.prototype._saveMetaData = function(block) {
// tip
this._tip.hash = block.hash;
this._tip.height = block.height;
this._tip.height = this._meta.length;
var tipInfo = utils.encodeTip(this._tip, this.name);
@ -662,18 +662,27 @@ BlockService.prototype._sendDelta = function() {
if (++this._blockCount >= BlockService.MAX_BLOCKS) {
this._latestBlockHash = this._tip.hash;
this._numCompleted = this._tip.height;
this._blockCount = 0;
this._sync();
// this is where we ask the p2p network for more block
var self = this;
// we need a pause here before asking for more blocks so that the db work write queue,
// does not get too large and cause a memory issue
// the larger the difference between network speeds and disk i/o speeds should result in
// larger waits, e.g. gigabit internet speeds and a usb 2.0 5400 rpm hard disk might 10-20
// between each 500 block chunk
setTimeout(function() {
self._sync();
}, 10000);
}
};
BlockService.prototype._setListeners = function() {
var self = this;
self._p2p.once('bestHeight', self._onBestHeight.bind(self));
this._p2p.once('bestHeight', this._onBestHeight.bind(this));
};
@ -681,14 +690,11 @@ BlockService.prototype._setTip = function(tip) {
log.debug('Setting tip to height: ' + tip.height);
log.debug('Setting tip to hash: ' + tip.hash);
this._tip = tip;
this._db.setServiceTip('block', this._tip);
};
BlockService.prototype._startSync = function() {
var currentHeight = this._tip.height;
this._numNeeded = this._bestHeight - currentHeight;
this._numCompleted = currentHeight;
this._numNeeded = this._bestHeight - this._tip.height;
if (this._numNeeded <= 0) {
return;
}
@ -719,8 +725,8 @@ BlockService.prototype._sync = function() {
if (--this._p2pBlockCallsNeeded > 0) {
log.info('Blocks download progress: ' + this._numCompleted + '/' +
this._numNeeded + ' (' + (this._numCompleted/this._numNeeded*100).toFixed(2) + '%)');
log.info('Blocks download progress: ' + this._tip.height + '/' +
this._numNeeded + ' (' + (this._tip.height / this._numNeeded*100).toFixed(2) + '%)');
this._p2p.getBlocks({ startHash: this._latestBlockHash });
return;

View File

@ -22,11 +22,10 @@ function DB(options) {
Service.call(this, options);
this._dbPrefix = constants.DB_PREFIX;
this.version = 1;
this.dbPrefix = new Buffer('00', 'hex');
$.checkState(this.node.network, 'Node is expected to have a "network" property');
this.network = this.node.network;
this._setDataPath();
@ -38,8 +37,10 @@ function DB(options) {
this.subscriptions = {};
this._operationsQueue = 0;
this.GENESIS_HASH = constants.BITCOIN_GENESIS_HASH[this.node.getNetworkName()];
this.node.on('stopping', function() {
log.warn('Node is stopping, gently closing the database.');
});
}
util.inherits(DB, Service);
@ -75,7 +76,7 @@ DB.prototype._checkVersion = function(callback) {
// presupposition is that IF there is a database to open -and- there is a version key
// in the form below, it will be related to us and it must be equal to this service's version.
var versionBuf = Buffer.concat([ self.dbPrefix, new Buffer('version', 'utf8') ]);
var versionBuf = Buffer.concat([ self._dbPrefix, new Buffer('version', 'utf8') ]);
self.get(versionBuf, self.dbOptions, function(err, buffer) {
if (err) {
@ -98,7 +99,7 @@ DB.prototype._checkVersion = function(callback) {
DB.prototype._setVersion = function(callback) {
var versionBuffer = new Buffer(new Array(4));
versionBuffer.writeUInt32BE(this.version);
this.put(this.dbPrefix + 'version', versionBuffer, callback);
this.put(this._dbPrefix + 'version', versionBuffer, callback);
};
DB.prototype.start = function(callback) {
@ -157,11 +158,8 @@ DB.prototype.put = function(key, value, options) {
return;
}
self._operationsQueue++;
self._store.put(key, value, options, function(err) {
self._operationsQueue--;
if (err) {
self.emit('error', err);
return;
@ -178,11 +176,8 @@ DB.prototype.batch = function(ops, options) {
return;
}
self._operationsQueue += ops.length;
self._store.batch(ops, options, function(err) {
self._operationsQueue -= ops.length;
if (err) {
self.emit('error', err);
return;
@ -198,7 +193,7 @@ DB.prototype.createReadStream = function(op) {
stream = this._store.createReadStream(op);
}
if (stream) {
stream.on('error', this.onError.bind(this));
stream.on('error', this._onError.bind(this));
}
return stream;
};
@ -217,13 +212,7 @@ DB.prototype.createKeyStream = function(op) {
DB.prototype.stop = function(callback) {
var self = this;
self._stopping = true;
async.whilst(function() {
return self._operationsQueue > 0;
}, function(next) {
setTimeout(next, 3000);
}, function() {
self.close(callback);
});
self.close(callback);
};
DB.prototype.close = function(callback) {
@ -243,7 +232,7 @@ DB.prototype.getPublishEvents = function() {
DB.prototype.getServiceTip = function(serviceName, callback) {
var keyBuf = Buffer.concat([ this.dbPrefix, new Buffer('tip-' + serviceName, 'utf8') ]);
var keyBuf = Buffer.concat([ this._dbPrefix, new Buffer('tip-' + serviceName, 'utf8') ]);
var self = this;
self.get(keyBuf, function(err, tipBuf) {
@ -278,8 +267,8 @@ DB.prototype.getServiceTip = function(serviceName, callback) {
DB.prototype.getPrefix = function(service, callback) {
var self = this;
var keyBuf = Buffer.concat([ self.dbPrefix, new Buffer('prefix-', 'utf8'), new Buffer(service, 'utf8') ]);
var unusedBuf = Buffer.concat([ self.dbPrefix, new Buffer('nextUnused', 'utf8') ]);
var keyBuf = Buffer.concat([ self._dbPrefix, new Buffer('prefix-', 'utf8'), new Buffer(service, 'utf8') ]);
var unusedBuf = Buffer.concat([ self._dbPrefix, new Buffer('nextUnused', 'utf8') ]);
function getPrefix(next) {

View File

@ -5,6 +5,7 @@ var BufferUtil = bitcore.util.buffer;
var MAX_SAFE_INTEGER = 0x1fffffffffffff; // 2 ^ 53 - 1
var crypto = require('crypto');
var _ = require('lodash');
var constants = require('./constants');
var utils = {};
utils.isHash = function(value) {
@ -218,7 +219,7 @@ utils.removeItemsByIndexList = function(indexList, list) {
};
utils.encodeTip = function(tip, name) {
var key = Buffer.concat([ new Buffer('00', 'hex'),
var key = Buffer.concat([ constants.DB_PREFIX,
new Buffer('tip-' + name, 'utf8') ]);
var heightBuf = new Buffer(4);