itns-sidechain/lib/node/node.js

276 lines
5.7 KiB
JavaScript
Raw Normal View History

/*!
2016-03-10 02:40:33 -08:00
* node.js - node object for bcoin
2016-02-14 18:05:21 -08:00
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
2016-04-06 18:20:03 -07:00
* Copyright (c) 2014-2016, Christopher Jeffrey (MIT License).
2016-06-09 16:18:50 -07:00
* https://github.com/bcoin-org/bcoin
2016-02-14 18:05:21 -08:00
*/
2016-06-13 01:06:01 -07:00
'use strict';
2016-08-23 23:26:50 -07:00
var AsyncObject = require('../utils/async');
2016-11-19 10:45:31 -08:00
var util = require('../utils/util');
2016-10-02 02:43:50 -07:00
var co = require('../utils/co');
2016-10-02 01:01:16 -07:00
var assert = require('assert');
var Network = require('../protocol/network');
var Logger = require('./logger');
2016-11-19 21:40:31 -08:00
var NodeClient = require('./nodeclient');
2016-11-19 06:48:55 -08:00
var workerPool = require('../workers/workerpool').pool;
2016-02-14 18:05:21 -08:00
/**
* Base class from which every other
* Node-like object inherits.
* @exports Node
* @constructor
* @abstract
* @param {Object} options
2016-02-14 18:05:21 -08:00
*/
2016-03-10 02:40:33 -08:00
function Node(options) {
if (!(this instanceof Node))
return new Node(options);
2016-02-14 18:05:21 -08:00
AsyncObject.call(this);
2016-02-14 18:05:21 -08:00
2016-08-26 01:14:02 -07:00
if (!options)
options = {};
2016-08-26 05:02:08 -07:00
this.parseOptions(options);
2016-02-14 18:05:21 -08:00
2016-03-10 02:40:33 -08:00
this.options = options;
2016-10-02 01:01:16 -07:00
this.network = Network.get(options.network);
2016-07-04 05:36:06 -07:00
this.prefix = options.prefix;
2016-02-14 18:05:21 -08:00
2016-07-04 05:36:06 -07:00
this.logger = options.logger;
2016-03-10 02:40:33 -08:00
this.chain = null;
2016-07-04 05:36:06 -07:00
this.fees = null;
this.mempool = null;
this.pool = null;
2016-03-10 02:40:33 -08:00
this.miner = null;
this.walletdb = null;
this.wallet = null;
2016-08-26 05:02:08 -07:00
this.http = null;
2016-11-19 21:40:31 -08:00
// Local client for walletdb
this.client = new NodeClient(this);
2016-07-04 05:36:06 -07:00
this._bound = [];
this.__init();
2016-03-10 02:40:33 -08:00
}
2016-02-16 16:13:34 -08:00
2016-11-19 10:45:31 -08:00
util.inherits(Node, AsyncObject);
2016-02-14 18:05:21 -08:00
2016-07-04 05:36:06 -07:00
/**
* Initialize node.
* @private
*/
Node.prototype.__init = function __init() {
var self = this;
if (!this.logger) {
2016-10-02 01:01:16 -07:00
this.logger = new Logger({
level: this.options.logLevel || 'none',
console: this.options.logConsole,
file: this.options.logFile
});
}
2016-07-04 05:36:06 -07:00
this.on('preopen', function() {
self._onOpen();
});
this.on('close', function() {
self._onClose();
});
};
/**
* Open node. Bind all events.
* @private
*/
Node.prototype._onOpen = function _onOpen() {
var self = this;
this.logger.open();
2016-11-28 16:52:30 -08:00
this._bind(this.network.time, 'offset', function(offset) {
2016-07-04 05:36:06 -07:00
self.logger.info('Time offset: %d (%d minutes).', offset, offset / 60 | 0);
});
2016-11-28 16:52:30 -08:00
this._bind(this.network.time, 'sample', function(sample, total) {
2016-07-04 05:36:06 -07:00
self.logger.debug('Added time data: samples=%d, offset=%d (%d minutes).',
total, sample, sample / 60 | 0);
});
2016-11-28 16:52:30 -08:00
this._bind(this.network.time, 'mismatch', function() {
2016-07-04 05:36:06 -07:00
self.logger.warning('Please make sure your system clock is correct!');
});
2016-11-19 06:48:55 -08:00
this._bind(workerPool, 'spawn', function(child) {
2016-07-04 05:36:06 -07:00
self.logger.info('Spawning worker process: %d.', child.id);
});
2016-11-19 06:48:55 -08:00
this._bind(workerPool, 'exit', function(code, child) {
2016-07-04 05:36:06 -07:00
self.logger.warning('Worker %d exited: %s.', child.id, code);
});
2016-11-19 06:48:55 -08:00
this._bind(workerPool, 'error', function(err, child) {
2016-07-04 05:36:06 -07:00
if (child) {
self.logger.error('Worker %d error: %s', child.id, err.message);
return;
}
self.emit('error', err);
});
};
/**
* Close node. Unbind all events.
* @private
*/
Node.prototype._onClose = function _onClose() {
var i, bound;
this.logger.close();
for (i = 0; i < this._bound.length; i++) {
bound = this._bound[i];
bound[0].removeListener(bound[1], bound[2]);
}
this._bound.length = 0;
};
/**
* Bind to an event on `obj`, save listener for removal.
* @private
* @param {EventEmitter} obj
* @param {String} event
* @param {Function} listener
*/
Node.prototype._bind = function _bind(obj, event, listener) {
this._bound.push([obj, event, listener]);
obj.on(event, listener);
};
/**
* Emit and log an error.
* @private
* @param {Error} err
*/
Node.prototype._error = function _error(err) {
2016-08-26 05:02:08 -07:00
if (!err)
return;
2016-11-27 23:54:18 -08:00
if (err.type === 'VerifyError') {
switch (err.reason) {
case 'insufficient priority':
case 'non-final':
this.logger.spam(err.message);
break;
default:
this.logger.error(err.message);
break;
}
} else if (typeof err.code === 'string' && err.code[0] === 'E') {
this.logger.error(err.message);
} else {
this.logger.error(err);
2016-08-26 05:02:08 -07:00
}
2016-07-04 05:36:06 -07:00
this.emit('error', err);
};
/**
* Parse options object.
* @private
* @param {Object} options
* @returns {Object}
*/
2016-08-26 01:14:02 -07:00
Node.prototype.parseOptions = function parseOptions(options) {
2016-10-02 01:01:16 -07:00
options.network = Network.get(options.network);
2016-07-06 11:20:45 -07:00
2016-07-04 05:36:06 -07:00
if (!options.prefix)
2016-11-19 10:45:31 -08:00
options.prefix = util.HOME + '/.bcoin';
2016-07-04 05:36:06 -07:00
if (!options.db)
options.db = 'memory';
2016-11-19 10:45:31 -08:00
options.prefix = util.normalize(options.prefix);
2016-07-04 05:36:06 -07:00
if (options.logFile && typeof options.logFile !== 'string') {
options.logFile = options.prefix;
2016-07-06 11:20:45 -07:00
if (options.network.type !== 'main')
options.logFile += '/' + options.network.type;
2016-07-04 05:36:06 -07:00
options.logFile += '/debug.log';
}
options.logFile = options.logFile
2016-11-19 10:45:31 -08:00
? util.normalize(options.logFile)
2016-07-04 05:36:06 -07:00
: null;
2016-07-29 15:40:39 -07:00
if (options.fast) {
options.headers = true;
options.useCheckpoints = true;
2016-12-04 13:59:08 -08:00
options.cacheSize = 300 << 20;
options.coinCache = 100 << 20;
2016-07-29 15:40:39 -07:00
}
if (options.witness == null)
options.witness = options.network.witness;
2016-07-04 05:36:06 -07:00
return options;
};
/**
* Create a file path from a name
* as well as the node's prefix.
* @param {String} name
* @returns {String}
*/
Node.prototype.location = function location(name) {
var path = this.prefix;
if (this.network.type !== 'main')
path += '/' + this.network.type;
path += '/' + name;
return path;
};
/**
* Open and ensure primary wallet.
2016-09-23 01:05:06 -07:00
* @returns {Promise}
*/
2016-09-21 22:59:48 -07:00
Node.prototype.openWallet = co(function* openWallet() {
2016-09-21 22:58:27 -07:00
var options, wallet;
2016-09-21 22:58:27 -07:00
assert(!this.wallet);
2016-09-21 22:58:27 -07:00
options = {
id: 'primary',
passphrase: this.options.passphrase
};
2016-09-21 22:58:27 -07:00
wallet = yield this.walletdb.ensure(options);
2016-09-21 22:58:27 -07:00
this.logger.info(
'Loaded wallet with id=%s wid=%d address=%s',
wallet.id, wallet.wid, wallet.getAddress());
if (this.miner)
this.miner.addAddress(wallet.getAddress());
2016-09-21 22:58:27 -07:00
this.wallet = wallet;
});
2016-05-15 18:07:06 -07:00
/*
* Expose
*/
2016-05-13 09:23:57 -07:00
module.exports = Node;