general: code cleanup, refactoring and formatting
This commit is contained in:
parent
c1e9d5a3d9
commit
92bae5f09a
|
@ -9,7 +9,7 @@ function main(parentServicesPath, additionalServices) {
|
|||
moduleName: 'bitcore-node',
|
||||
configName: 'bitcore-node',
|
||||
processTitle: 'bitcore'
|
||||
}).on('require', function (name, module) {
|
||||
}).on('require', function (name) {
|
||||
console.log('Loading:', name);
|
||||
}).on('requireFail', function (name, err) {
|
||||
console.log('Unable to load:', name, err);
|
||||
|
|
|
@ -9,7 +9,7 @@ function main(parentServicesPath, additionalServices) {
|
|||
moduleName: 'bitcore-node',
|
||||
configName: 'bitcore-node',
|
||||
processTitle: 'bitcored'
|
||||
}).on('require', function (name, module) {
|
||||
}).on('require', function (name) {
|
||||
console.log('Loading:', name);
|
||||
}).on('requireFail', function (name, err) {
|
||||
console.log('Unable to load:', name, err);
|
||||
|
|
|
@ -45,7 +45,7 @@ Logger.prototype.warn = function() {
|
|||
* Proxies console.log with color and arg parsing magic
|
||||
* #_log
|
||||
*/
|
||||
Logger.prototype._log = function(color, type) {
|
||||
Logger.prototype._log = function(color) {
|
||||
if (process.env.NODE_ENV === 'test') {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -5,177 +5,11 @@ var BitcoreNode = require('../node');
|
|||
var index = require('../');
|
||||
var bitcore = require('bitcore-lib');
|
||||
var _ = bitcore.deps._;
|
||||
var $ = bitcore.util.preconditions;
|
||||
var log = index.log;
|
||||
var child_process = require('child_process');
|
||||
var fs = require('fs');
|
||||
var shuttingDown = false;
|
||||
|
||||
log.debug = function() {};
|
||||
|
||||
/**
|
||||
* This function will loop over the configuration for services and require the
|
||||
* specified modules, and assemble an array in this format:
|
||||
* [
|
||||
* {
|
||||
* name: 'bitcoind',
|
||||
* config: {},
|
||||
* module: BitcoinService
|
||||
* }
|
||||
* ]
|
||||
* @param {Function} req - The require function to use
|
||||
* @param {Array} servicesPath - The local path (for requiring services)
|
||||
* @param {Object} config
|
||||
* @param {Array} config.services - An array of strings of service names.
|
||||
* @returns {Array}
|
||||
*/
|
||||
function setupServices(req, servicesPath, config) {
|
||||
|
||||
module.paths.push(path.resolve(servicesPath, './node_modules'));
|
||||
|
||||
var services = [];
|
||||
if (config.services) {
|
||||
for (var i = 0; i < config.services.length; i++) {
|
||||
var service = {};
|
||||
service.name = config.services[i];
|
||||
|
||||
var hasConfig = config.servicesConfig && config.servicesConfig[service.name];
|
||||
service.config = hasConfig ? config.servicesConfig[service.name] : {};
|
||||
|
||||
try {
|
||||
// first try in the built-in bitcore-node services directory
|
||||
service.module = req(path.resolve(__dirname, '../services/' + service.name));
|
||||
} catch(e) {
|
||||
|
||||
// check if the package.json specifies a specific file to use
|
||||
var servicePackage = req(service.name + '/package.json');
|
||||
var serviceModule = service.name;
|
||||
if (servicePackage.bitcoreNode) {
|
||||
serviceModule = service.name + '/' + servicePackage.bitcoreNode;
|
||||
}
|
||||
service.module = req(serviceModule);
|
||||
}
|
||||
|
||||
// check that the service supports expected methods
|
||||
if (!service.module.prototype ||
|
||||
!service.module.dependencies ||
|
||||
!service.module.prototype.start ||
|
||||
!service.module.prototype.stop) {
|
||||
throw new Error(
|
||||
'Could not load service "' + service.name + '" as it does not support necessary methods.'
|
||||
);
|
||||
}
|
||||
|
||||
services.push(service);
|
||||
}
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will register event handlers to log the current db sync status.
|
||||
* @param {Node} node
|
||||
*/
|
||||
function registerSyncHandlers(node, delay) {
|
||||
|
||||
delay = delay || 10000;
|
||||
var interval = false;
|
||||
var count = 0;
|
||||
|
||||
function logSyncStatus() {
|
||||
log.info(
|
||||
'Database Sync Status: Tip:', node.services.db.tip.hash,
|
||||
'Height:', node.services.db.tip.__height,
|
||||
'Rate:', count/10, 'blocks per second'
|
||||
);
|
||||
}
|
||||
|
||||
node.on('ready', function() {
|
||||
|
||||
if (node.services.db) {
|
||||
node.on('synced', function() {
|
||||
clearInterval(interval);
|
||||
logSyncStatus();
|
||||
});
|
||||
node.services.db.on('addblock', function(block) {
|
||||
count++;
|
||||
// Initialize logging if not already instantiated
|
||||
if (!interval) {
|
||||
interval = setInterval(function() {
|
||||
logSyncStatus();
|
||||
count = 0;
|
||||
}, delay);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
node.on('stopping', function() {
|
||||
clearInterval(interval);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
log.error('Failed to stop services: ' + err);
|
||||
return _process.exit(1);
|
||||
}
|
||||
log.info('Halted');
|
||||
_process.exit(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
if(err.stack) {
|
||||
log.error(err.stack);
|
||||
}
|
||||
node.stop(function(err) {
|
||||
if(err) {
|
||||
log.error('Failed to stop services: ' + err);
|
||||
}
|
||||
_process.exit(-1);
|
||||
});
|
||||
}
|
||||
if (options.sigint) {
|
||||
if (!shuttingDown) {
|
||||
shuttingDown = true;
|
||||
start.cleanShutdown(_process, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will instantiate and start a Node, requiring the necessary service
|
||||
* modules, and registering event handlers.
|
||||
|
@ -190,6 +24,7 @@ function exitHandler(options, _process, node, err) {
|
|||
* @param {Number} options.config.port - The port to use for the web service
|
||||
*/
|
||||
function start(options) {
|
||||
/* jshint maxstatements: 20 */
|
||||
|
||||
var fullConfig = _.clone(options.config);
|
||||
|
||||
|
@ -242,6 +77,186 @@ function start(options) {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks a service for the expected methods
|
||||
* @param {Object} service
|
||||
*/
|
||||
function checkService(service) {
|
||||
// check that the service supports expected methods
|
||||
if (!service.module.prototype ||
|
||||
!service.module.dependencies ||
|
||||
!service.module.prototype.start ||
|
||||
!service.module.prototype.stop) {
|
||||
throw new Error(
|
||||
'Could not load service "' + service.name + '" as it does not support necessary methods.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Will require a module from local services directory first
|
||||
* and then from available node_modules
|
||||
* @param {Function} req
|
||||
* @param {Object} service
|
||||
*/
|
||||
function loadModule(req, service) {
|
||||
try {
|
||||
// first try in the built-in bitcore-node services directory
|
||||
service.module = req(path.resolve(__dirname, '../services/' + service.name));
|
||||
} catch(e) {
|
||||
|
||||
// check if the package.json specifies a specific file to use
|
||||
var servicePackage = req(service.name + '/package.json');
|
||||
var serviceModule = service.name;
|
||||
if (servicePackage.bitcoreNode) {
|
||||
serviceModule = service.name + '/' + servicePackage.bitcoreNode;
|
||||
}
|
||||
service.module = req(serviceModule);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will loop over the configuration for services and require the
|
||||
* specified modules, and assemble an array in this format:
|
||||
* [
|
||||
* {
|
||||
* name: 'bitcoind',
|
||||
* config: {},
|
||||
* module: BitcoinService
|
||||
* }
|
||||
* ]
|
||||
* @param {Function} req - The require function to use
|
||||
* @param {Array} servicesPath - The local path (for requiring services)
|
||||
* @param {Object} config
|
||||
* @param {Array} config.services - An array of strings of service names.
|
||||
* @returns {Array}
|
||||
*/
|
||||
function setupServices(req, servicesPath, config) {
|
||||
|
||||
module.paths.push(path.resolve(servicesPath, './node_modules'));
|
||||
|
||||
var services = [];
|
||||
if (config.services) {
|
||||
for (var i = 0; i < config.services.length; i++) {
|
||||
var service = {};
|
||||
service.name = config.services[i];
|
||||
|
||||
var hasConfig = config.servicesConfig && config.servicesConfig[service.name];
|
||||
service.config = hasConfig ? config.servicesConfig[service.name] : {};
|
||||
|
||||
loadModule(req, service);
|
||||
checkService(service);
|
||||
|
||||
services.push(service);
|
||||
}
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will register event handlers to log the current db sync status.
|
||||
* @param {Node} node
|
||||
*/
|
||||
function registerSyncHandlers(node, delay) {
|
||||
|
||||
delay = delay || 10000;
|
||||
var interval = false;
|
||||
var count = 0;
|
||||
|
||||
function logSyncStatus() {
|
||||
log.info(
|
||||
'Database Sync Status: Tip:', node.services.db.tip.hash,
|
||||
'Height:', node.services.db.tip.__height,
|
||||
'Rate:', count/10, 'blocks per second'
|
||||
);
|
||||
}
|
||||
|
||||
node.on('ready', function() {
|
||||
|
||||
if (node.services.db) {
|
||||
node.on('synced', function() {
|
||||
clearInterval(interval);
|
||||
logSyncStatus();
|
||||
});
|
||||
node.services.db.on('addblock', function() {
|
||||
count++;
|
||||
// Initialize logging if not already instantiated
|
||||
if (!interval) {
|
||||
interval = setInterval(function() {
|
||||
logSyncStatus();
|
||||
count = 0;
|
||||
}, delay);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
node.on('stopping', function() {
|
||||
clearInterval(interval);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
log.error('Failed to stop services: ' + err);
|
||||
return _process.exit(1);
|
||||
}
|
||||
log.info('Halted');
|
||||
_process.exit(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
if(err.stack) {
|
||||
log.error(err.stack);
|
||||
}
|
||||
node.stop(function(err) {
|
||||
if(err) {
|
||||
log.error('Failed to stop services: ' + err);
|
||||
}
|
||||
_process.exit(-1);
|
||||
});
|
||||
}
|
||||
if (options.sigint) {
|
||||
if (!shuttingDown) {
|
||||
shuttingDown = true;
|
||||
start.cleanShutdown(_process, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
|
||||
module.exports = start;
|
||||
module.exports.registerExitHandlers = registerExitHandlers;
|
||||
module.exports.exitHandler = exitHandler;
|
||||
|
|
|
@ -78,7 +78,7 @@ Service.prototype.stop = function(done) {
|
|||
* Setup express routes
|
||||
* @param {Express} app
|
||||
*/
|
||||
Service.prototype.setupRoutes = function(app) {
|
||||
Service.prototype.setupRoutes = function() {
|
||||
// Setup express routes here
|
||||
};
|
||||
|
||||
|
@ -86,6 +86,4 @@ Service.prototype.getRoutePrefix = function() {
|
|||
return this.name;
|
||||
};
|
||||
|
||||
|
||||
|
||||
module.exports = Service;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var spawn = require('child_process').spawn;
|
||||
var util = require('util');
|
||||
var mkdirp = require('mkdirp');
|
||||
|
@ -16,7 +15,6 @@ var _ = bitcore.deps._;
|
|||
var index = require('../');
|
||||
var errors = index.errors;
|
||||
var log = index.log;
|
||||
var utils = require('../utils');
|
||||
var Service = require('../service');
|
||||
var Transaction = require('../transaction');
|
||||
|
||||
|
@ -30,6 +28,7 @@ var Transaction = require('../transaction');
|
|||
* @param {Node} options.node - A reference to the node
|
||||
*/
|
||||
function Bitcoin(options) {
|
||||
/* jshint maxstatements: 20 */
|
||||
if (!(this instanceof Bitcoin)) {
|
||||
return new Bitcoin(options);
|
||||
}
|
||||
|
@ -1022,6 +1021,7 @@ Bitcoin.prototype._getHeightRangeQuery = function(options, clone) {
|
|||
* @param {Function} callback
|
||||
*/
|
||||
Bitcoin.prototype.getAddressTxids = function(addressArg, options, callback) {
|
||||
/* jshint maxstatements: 16 */
|
||||
var self = this;
|
||||
var queryMempool = _.isUndefined(options.queryMempool) ? true : options.queryMempool;
|
||||
var rangeQuery = false;
|
||||
|
@ -1091,6 +1091,48 @@ Bitcoin.prototype._getConfirmationsDetail = function(transaction) {
|
|||
return Math.max(0, confirmations);
|
||||
};
|
||||
|
||||
Bitcoin.prototype._getAddressDetailsForInput = function(input, inputIndex, result, addressStrings) {
|
||||
if (!input.script) {
|
||||
return;
|
||||
}
|
||||
var inputAddress = input.script.toAddress(this.node.network);
|
||||
if (inputAddress) {
|
||||
var inputAddressString = inputAddress.toString();
|
||||
if (addressStrings.indexOf(inputAddressString) >= 0) {
|
||||
if (!result.addresses[inputAddressString]) {
|
||||
result.addresses[inputAddressString] = {
|
||||
inputIndexes: [inputIndex],
|
||||
outputIndexes: []
|
||||
};
|
||||
} else {
|
||||
result.addresses[inputAddressString].inputIndexes.push(inputIndex);
|
||||
}
|
||||
result.satoshis -= input.output.satoshis;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Bitcoin.prototype._getAddressDetailsForOutput = function(output, outputIndex, result, addressStrings) {
|
||||
if (!output.script) {
|
||||
return;
|
||||
}
|
||||
var outputAddress = output.script.toAddress(this.node.network);
|
||||
if (outputAddress) {
|
||||
var outputAddressString = outputAddress.toString();
|
||||
if (addressStrings.indexOf(outputAddressString) >= 0) {
|
||||
if (!result.addresses[outputAddressString]) {
|
||||
result.addresses[outputAddressString] = {
|
||||
inputIndexes: [],
|
||||
outputIndexes: [outputIndex]
|
||||
};
|
||||
} else {
|
||||
result.addresses[outputAddressString].outputIndexes.push(outputIndex);
|
||||
}
|
||||
result.satoshis += output.satoshis;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Bitcoin.prototype._getAddressDetailsForTransaction = function(transaction, addressStrings) {
|
||||
var result = {
|
||||
addresses: {},
|
||||
|
@ -1099,50 +1141,15 @@ Bitcoin.prototype._getAddressDetailsForTransaction = function(transaction, addre
|
|||
|
||||
for (var inputIndex = 0; inputIndex < transaction.inputs.length; inputIndex++) {
|
||||
var input = transaction.inputs[inputIndex];
|
||||
if (!input.script) {
|
||||
continue;
|
||||
}
|
||||
var inputAddress = input.script.toAddress(this.node.network);
|
||||
if (inputAddress) {
|
||||
var inputAddressString = inputAddress.toString();
|
||||
if (addressStrings.indexOf(inputAddressString) >= 0) {
|
||||
if (!result.addresses[inputAddressString]) {
|
||||
result.addresses[inputAddressString] = {
|
||||
inputIndexes: [inputIndex],
|
||||
outputIndexes: []
|
||||
};
|
||||
} else {
|
||||
result.addresses[inputAddressString].inputIndexes.push(inputIndex);
|
||||
}
|
||||
result.satoshis -= input.output.satoshis;
|
||||
}
|
||||
}
|
||||
this._getAddressDetailsForInput(input, inputIndex, result, addressStrings);
|
||||
}
|
||||
|
||||
for (var outputIndex = 0; outputIndex < transaction.outputs.length; outputIndex++) {
|
||||
var output = transaction.outputs[outputIndex];
|
||||
if (!output.script) {
|
||||
continue;
|
||||
}
|
||||
var outputAddress = output.script.toAddress(this.node.network);
|
||||
if (outputAddress) {
|
||||
var outputAddressString = outputAddress.toString();
|
||||
if (addressStrings.indexOf(outputAddressString) >= 0) {
|
||||
if (!result.addresses[outputAddressString]) {
|
||||
result.addresses[outputAddressString] = {
|
||||
inputIndexes: [],
|
||||
outputIndexes: [outputIndex]
|
||||
};
|
||||
} else {
|
||||
result.addresses[outputAddressString].outputIndexes.push(outputIndex);
|
||||
}
|
||||
result.satoshis += output.satoshis;
|
||||
}
|
||||
}
|
||||
this._getAddressDetailsForOutput(output, outputIndex, result, addressStrings);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
var Service = require('../lib/service');
|
||||
var BitcoreNode = require('../lib/node');
|
||||
var util = require('util');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var should = require('chai').should();
|
||||
|
||||
var TestService = function(options) {
|
||||
this.node = options.node;
|
||||
}
|
||||
};
|
||||
util.inherits(TestService, Service);
|
||||
TestService.dependencies = [];
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ var BitcoinService = proxyquire('../../lib/services/bitcoind', {
|
|||
var defaultBitcoinConf = fs.readFileSync(path.resolve(__dirname, '../data/default.bitcoin.conf'), 'utf8');
|
||||
|
||||
describe('Bitcoin Service', function() {
|
||||
var txhex = '01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000';
|
||||
var txhex = '01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000';
|
||||
|
||||
var baseConfig = {
|
||||
node: {
|
||||
|
|
|
@ -22,15 +22,11 @@ var fakeSocket = new EventEmitter();
|
|||
|
||||
fakeSocket.on('test/event1', function(data) {
|
||||
data.should.equal('testdata');
|
||||
done();
|
||||
});
|
||||
|
||||
fakeSocketListener.emit('connection', fakeSocket);
|
||||
|
||||
fakeSocket.emit('subscribe', 'test/event1');
|
||||
|
||||
|
||||
|
||||
var WebService = proxyquire('../../lib/services/web', {http: httpStub, https: httpsStub, fs: fsStub});
|
||||
|
||||
describe('WebService', function() {
|
||||
|
@ -323,7 +319,7 @@ describe('WebService', function() {
|
|||
var message = {
|
||||
method: 'two',
|
||||
params: [1, 2]
|
||||
}
|
||||
};
|
||||
web.socketMessageHandler(message, function(response) {
|
||||
should.exist(response.error);
|
||||
response.error.message.should.equal('Method Not Found');
|
||||
|
|
Loading…
Reference in New Issue