general: code cleanup, refactoring and formatting

This commit is contained in:
Braydon Fuller 2016-04-27 10:57:37 -04:00
parent c1e9d5a3d9
commit 92bae5f09a
9 changed files with 236 additions and 219 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
};
/**

View File

@ -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 = [];

View File

@ -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: {

View File

@ -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');