refactor: config, plugins, and walletdb.
This commit is contained in:
parent
70a0147080
commit
5cbbdbfb2f
1057
lib/http/base.js
1057
lib/http/base.js
File diff suppressed because it is too large
Load Diff
@ -108,8 +108,8 @@ HTTPClient.prototype._open = co(function* _open() {
|
||||
self.emit('balance', balance);
|
||||
});
|
||||
|
||||
yield this._onConnect();
|
||||
yield this._sendAuth();
|
||||
yield this.onConnect();
|
||||
yield this.sendAuth();
|
||||
});
|
||||
|
||||
/**
|
||||
@ -134,7 +134,7 @@ HTTPClient.prototype._close = function close() {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
HTTPClient.prototype._onConnect = function _onConnect() {
|
||||
HTTPClient.prototype.onConnect = function onConnect() {
|
||||
var self = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
self.socket.once('connect', resolve);
|
||||
@ -147,12 +147,29 @@ HTTPClient.prototype._onConnect = function _onConnect() {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
HTTPClient.prototype._sendAuth = function _sendAuth() {
|
||||
HTTPClient.prototype.sendAuth = function sendAuth() {
|
||||
var self = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
self.socket.emit('auth', self.apiKey, function(err) {
|
||||
if (err)
|
||||
return reject(new Error(err.error));
|
||||
return reject(new Error(err.message));
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Wait for websocket auth.
|
||||
* @private
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
HTTPClient.prototype.sendWalletAuth = function sendWalletAuth() {
|
||||
var self = this;
|
||||
return new Promise(function(resolve, reject) {
|
||||
self.socket.emit('wallet auth', self.apiKey, function(err) {
|
||||
if (err)
|
||||
return reject(new Error(err.message));
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
@ -220,7 +237,7 @@ HTTPClient.prototype._request = co(function* _request(method, endpoint, json) {
|
||||
|
||||
if (res.statusCode !== 200) {
|
||||
if (res.body.error)
|
||||
throw new Error(res.body.error);
|
||||
throw new Error(res.body.error.message);
|
||||
throw new Error('Status code: ' + res.statusCode);
|
||||
}
|
||||
|
||||
@ -369,7 +386,7 @@ HTTPClient.prototype.broadcast = function broadcast(tx) {
|
||||
|
||||
HTTPClient.prototype.rescan = function rescan(height) {
|
||||
var options = { height: height };
|
||||
return this._post('/rescan', options);
|
||||
return this._post('/_admin/rescan', options);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -380,7 +397,7 @@ HTTPClient.prototype.rescan = function rescan(height) {
|
||||
|
||||
HTTPClient.prototype.reset = function reset(block) {
|
||||
var options = { block: block };
|
||||
return this._post('/reset', options);
|
||||
return this._post('/_admin/reset', options);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -389,7 +406,7 @@ HTTPClient.prototype.reset = function reset(block) {
|
||||
*/
|
||||
|
||||
HTTPClient.prototype.resend = function resend() {
|
||||
return this._post('/resend', {});
|
||||
return this._post('/_admin/resend', {});
|
||||
};
|
||||
|
||||
/**
|
||||
@ -400,7 +417,7 @@ HTTPClient.prototype.resend = function resend() {
|
||||
|
||||
HTTPClient.prototype.backup = function backup(path) {
|
||||
var options = { path: path };
|
||||
return this._post('/backup', options);
|
||||
return this._post('/_admin/backup', options);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -417,7 +434,7 @@ HTTPClient.prototype.join = function join(id, token) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
self.socket.emit('wallet join', id, token, function(err) {
|
||||
if (err)
|
||||
return reject(new Error(err.error));
|
||||
return reject(new Error(err.message));
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
@ -437,7 +454,7 @@ HTTPClient.prototype.leave = function leave(id) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
self.socket.emit('wallet leave', id, function(err) {
|
||||
if (err)
|
||||
return reject(new Error(err.error));
|
||||
return reject(new Error(err.message));
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
@ -475,7 +492,7 @@ HTTPClient.prototype.getWallets = function getWallets() {
|
||||
*/
|
||||
|
||||
HTTPClient.prototype.createWallet = function createWallet(options) {
|
||||
return this._post('/wallet', options);
|
||||
return this._put('/wallet/' + options.id, options);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -934,9 +951,9 @@ HTTPClient.prototype.createAccount = function createAccount(id, options) {
|
||||
if (typeof options === 'string')
|
||||
options = { account: options };
|
||||
|
||||
path = '/wallet/' + id + '/account';
|
||||
path = '/wallet/' + id + '/account' + options.account;
|
||||
|
||||
return this._post(path, options);
|
||||
return this._put(path, options);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
1838
lib/http/rpc.js
1838
lib/http/rpc.js
File diff suppressed because it is too large
Load Diff
1800
lib/http/server.js
1800
lib/http/server.js
File diff suppressed because it is too large
Load Diff
@ -115,6 +115,7 @@ HTTPWallet.prototype.open = co(function* open(options) {
|
||||
assert(this.id, 'No ID provided.');
|
||||
|
||||
yield this.client.open();
|
||||
yield this.client.sendWalletAuth();
|
||||
yield this.client.join(this.id, this.token);
|
||||
});
|
||||
|
||||
@ -128,6 +129,7 @@ HTTPWallet.prototype.create = co(function* create(options) {
|
||||
var wallet;
|
||||
|
||||
yield this.client.open();
|
||||
yield this.client.sendWalletAuth();
|
||||
|
||||
wallet = yield this.client.createWallet(options);
|
||||
|
||||
|
||||
@ -107,6 +107,9 @@ Miner.prototype._open = co(function* open() {
|
||||
|
||||
this.logger.info('Miner loaded (flags=%s).',
|
||||
this.options.coinbaseFlags.toString('utf8'));
|
||||
|
||||
if (this.addresses.length === 0)
|
||||
this.logger.warning('No reward address is set for miner!');
|
||||
});
|
||||
|
||||
/**
|
||||
@ -387,7 +390,8 @@ Miner.prototype.addAddress = function addAddress(address) {
|
||||
*/
|
||||
|
||||
Miner.prototype.getAddress = function getAddress() {
|
||||
assert(this.addresses.length !== 0, 'No address passed in for miner.');
|
||||
if (this.addresses.length === 0)
|
||||
return;
|
||||
return this.addresses[Math.random() * this.addresses.length | 0];
|
||||
};
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ var util = require('../utils/util');
|
||||
var co = require('../utils/co');
|
||||
var StaticWriter = require('../utils/staticwriter');
|
||||
var Network = require('../protocol/network');
|
||||
var Address = require('../primitives/address');
|
||||
var TX = require('../primitives/tx');
|
||||
var Block = require('../primitives/block');
|
||||
var Input = require('../primitives/input');
|
||||
@ -232,8 +233,10 @@ MinerBlock.prototype._init = function _init() {
|
||||
input.script.compile();
|
||||
|
||||
// Setup output script (variable size).
|
||||
output.script.clear();
|
||||
output.script.fromAddress(this.address);
|
||||
if (this.address) {
|
||||
output.script.clear();
|
||||
output.script.fromAddress(this.address);
|
||||
}
|
||||
|
||||
// Update commitments.
|
||||
this.refresh();
|
||||
@ -345,6 +348,23 @@ MinerBlock.prototype.extraNonce = function extraNonce() {
|
||||
return bw.render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the reward output address.
|
||||
* @param {Address} address
|
||||
*/
|
||||
|
||||
MinerBlock.prototype.setAddress = function setAddress(address) {
|
||||
var output = this.coinbase.outputs[0];
|
||||
|
||||
this.address = Address(address);
|
||||
|
||||
output.script.clear();
|
||||
output.script.fromAddress(this.address);
|
||||
|
||||
// Update commitments.
|
||||
this.refresh();
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a transaction to the block. Rebuilds the merkle tree,
|
||||
* updates coinbase and commitment.
|
||||
|
||||
@ -268,7 +268,6 @@ Pool.prototype.resetChain = function resetChain() {
|
||||
|
||||
Pool.prototype._close = co(function* close() {
|
||||
yield this.disconnect();
|
||||
yield this.hosts.close();
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@ -243,8 +243,8 @@ Config.prototype.str = function str(key, fallback) {
|
||||
if (value === null)
|
||||
return fallback;
|
||||
|
||||
assert(typeof value === 'string',
|
||||
'Passed in config option is of wrong type.');
|
||||
if (typeof value !== 'string')
|
||||
throw new Error(key + ' must be a string.');
|
||||
|
||||
return value;
|
||||
};
|
||||
@ -266,15 +266,18 @@ Config.prototype.num = function num(key, fallback) {
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
assert(typeof value === 'number',
|
||||
'Passed in config option is of wrong type.');
|
||||
if (typeof value !== 'number')
|
||||
throw new Error(key + ' must be a string.');
|
||||
return value;
|
||||
}
|
||||
|
||||
if (!/^\d+$/.test(value))
|
||||
throw new Error(key + ' must be a number.');
|
||||
|
||||
value = parseInt(value, 10);
|
||||
|
||||
if (!isFinite(value))
|
||||
return fallback;
|
||||
throw new Error(key + ' must be a number.');
|
||||
|
||||
return value;
|
||||
};
|
||||
@ -296,8 +299,8 @@ Config.prototype.bool = function bool(key, fallback) {
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
assert(typeof value === 'boolean',
|
||||
'Passed in config option is of wrong type.');
|
||||
if (typeof value !== 'boolean')
|
||||
throw new Error(key + ' must be a boolean.');
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -307,7 +310,7 @@ Config.prototype.bool = function bool(key, fallback) {
|
||||
if (value === 'false' || value === '0')
|
||||
return false;
|
||||
|
||||
return fallback;
|
||||
throw new Error(key + ' must be a boolean.');
|
||||
};
|
||||
|
||||
/**
|
||||
@ -319,6 +322,7 @@ Config.prototype.bool = function bool(key, fallback) {
|
||||
|
||||
Config.prototype.buf = function buf(key, fallback) {
|
||||
var value = this.get(key);
|
||||
var data;
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
@ -327,12 +331,17 @@ Config.prototype.buf = function buf(key, fallback) {
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
assert(Buffer.isBuffer(value),
|
||||
'Passed in config option is of wrong type.');
|
||||
if (!Buffer.isBuffer(value))
|
||||
throw new Error(key + ' must be a buffer.');
|
||||
return value;
|
||||
}
|
||||
|
||||
return new Buffer(value, 'hex');
|
||||
data = new Buffer(value, 'hex');
|
||||
|
||||
if (data.length !== value.length / 2)
|
||||
throw new Error(key + ' must be a hex string.');
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -352,8 +361,8 @@ Config.prototype.list = function list(key, fallback) {
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
assert(Array.isArray(value),
|
||||
'Passed in config option is of wrong type.');
|
||||
if (!Array.isArray(value))
|
||||
throw new Error(key + ' must be an array.');
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -377,8 +386,8 @@ Config.prototype.obj = function obj(key, fallback) {
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
assert(value && typeof value === 'object',
|
||||
'Passed in config option is of wrong type.');
|
||||
if (!value || typeof value !== 'object')
|
||||
throw new Error(key + ' must be an object.');
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -388,8 +397,8 @@ Config.prototype.obj = function obj(key, fallback) {
|
||||
;
|
||||
}
|
||||
|
||||
assert(value && typeof value === 'object',
|
||||
'Passed in config option is of wrong type.');
|
||||
if (!value || typeof value !== 'object')
|
||||
throw new Error(key + ' must be an object.');
|
||||
|
||||
return value;
|
||||
};
|
||||
@ -411,13 +420,12 @@ Config.prototype.func = function func(key, fallback) {
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
assert(value && typeof value === 'function',
|
||||
'Passed in config option is of wrong type.');
|
||||
if (!value || typeof value !== 'function')
|
||||
throw new Error(key + ' must be a function.');
|
||||
return value;
|
||||
}
|
||||
|
||||
assert(false,
|
||||
'Passed in config option is of wrong type.');
|
||||
throw new Error(key + ' must be a function.');
|
||||
};
|
||||
|
||||
/**
|
||||
@ -486,8 +494,8 @@ Config.prototype.boolpath = function boolpath(key, fallback) {
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
assert(typeof value === 'boolean' || typeof value === 'string',
|
||||
'Passed in config option is of wrong type.');
|
||||
if (typeof value !== 'boolean' && typeof value !== 'string')
|
||||
throw new Error(key + ' must be a boolean or string.');
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@ -15,12 +15,11 @@ var Fees = require('../mempool/fees');
|
||||
var Mempool = require('../mempool/mempool');
|
||||
var Pool = require('../net/pool');
|
||||
var Miner = require('../mining/miner');
|
||||
var WalletDB = require('../wallet/walletdb');
|
||||
var HTTPServer = require('../http/server');
|
||||
|
||||
/**
|
||||
* Respresents a fullnode complete with a
|
||||
* chain, mempool, miner, wallet, etc.
|
||||
* chain, mempool, miner, etc.
|
||||
* @alias module:node.FullNode
|
||||
* @extends Node
|
||||
* @constructor
|
||||
@ -30,7 +29,6 @@ var HTTPServer = require('../http/server');
|
||||
* @property {Mempool} mempool
|
||||
* @property {Pool} pool
|
||||
* @property {Miner} miner
|
||||
* @property {WalletDB} walletdb
|
||||
* @property {HTTPServer} http
|
||||
* @emits FullNode#block
|
||||
* @emits FullNode#tx
|
||||
@ -126,22 +124,6 @@ function FullNode(options) {
|
||||
reservedSigops: this.config.num('reserved-sigops')
|
||||
});
|
||||
|
||||
// Wallet database needs access to fees.
|
||||
this.walletdb = new WalletDB({
|
||||
network: this.network,
|
||||
logger: this.logger,
|
||||
client: this.client,
|
||||
db: this.config.str('db'),
|
||||
prefix: this.config.prefix,
|
||||
maxFiles: this.config.num('walletdb-max-files'),
|
||||
cacheSize: this.config.mb('walletdb-cache-size'),
|
||||
witness: false,
|
||||
checkpoints: this.config.bool('checkpoints'),
|
||||
startHeight: this.config.num('start-height'),
|
||||
wipeNoReally: this.config.bool('wipe-no-really'),
|
||||
verify: false
|
||||
});
|
||||
|
||||
// HTTP needs access to the node.
|
||||
if (!HTTPServer.unsupported) {
|
||||
this.http = new HTTPServer({
|
||||
@ -180,7 +162,6 @@ FullNode.prototype._init = function _init() {
|
||||
this.mempool.on('error', onError);
|
||||
this.pool.on('error', onError);
|
||||
this.miner.on('error', onError);
|
||||
this.walletdb.on('error', onError);
|
||||
|
||||
if (this.http)
|
||||
this.http.on('error', onError);
|
||||
@ -217,6 +198,8 @@ FullNode.prototype._init = function _init() {
|
||||
}
|
||||
self.emit('reset', tip);
|
||||
}));
|
||||
|
||||
this.loadPlugins();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -231,10 +214,8 @@ FullNode.prototype._open = co(function* open() {
|
||||
yield this.mempool.open();
|
||||
yield this.miner.open();
|
||||
yield this.pool.open();
|
||||
yield this.walletdb.open();
|
||||
|
||||
// Ensure primary wallet.
|
||||
yield this.openWallet();
|
||||
yield this.openPlugins();
|
||||
|
||||
if (this.http)
|
||||
yield this.http.open();
|
||||
@ -252,11 +233,8 @@ FullNode.prototype._close = co(function* close() {
|
||||
if (this.http)
|
||||
yield this.http.close();
|
||||
|
||||
yield this.wallet.destroy();
|
||||
yield this.closePlugins();
|
||||
|
||||
this.wallet = null;
|
||||
|
||||
yield this.walletdb.close();
|
||||
yield this.pool.close();
|
||||
yield this.miner.close();
|
||||
yield this.mempool.close();
|
||||
|
||||
@ -13,7 +13,6 @@ var util = require('../utils/util');
|
||||
var co = require('../utils/co');
|
||||
var Network = require('../protocol/network');
|
||||
var Logger = require('./logger');
|
||||
var NodeClient = require('./nodeclient');
|
||||
var workerPool = require('../workers/workerpool').pool;
|
||||
var ec = require('../crypto/ec');
|
||||
var native = require('../utils/native');
|
||||
@ -48,8 +47,6 @@ function Node(options) {
|
||||
this.mempool = null;
|
||||
this.pool = null;
|
||||
this.miner = null;
|
||||
this.walletdb = null;
|
||||
this.wallet = null;
|
||||
this.http = null;
|
||||
this.client = null;
|
||||
|
||||
@ -90,15 +87,15 @@ Node.prototype.init = function init() {
|
||||
var self = this;
|
||||
|
||||
this.initOptions();
|
||||
this.loadPlugins();
|
||||
|
||||
// Local client for walletdb
|
||||
this.client = new NodeClient(this);
|
||||
|
||||
this.hook('preopen', function() {
|
||||
return self.handlePreopen();
|
||||
});
|
||||
|
||||
this.hook('preopen', function() {
|
||||
return self.handlePreclose();
|
||||
});
|
||||
|
||||
this.hook('open', function() {
|
||||
return self.handleOpen();
|
||||
});
|
||||
@ -117,6 +114,7 @@ Node.prototype.handlePreopen = co(function* handlePreopen() {
|
||||
var self = this;
|
||||
|
||||
yield fs.mkdirp(this.config.prefix);
|
||||
|
||||
yield this.logger.open();
|
||||
|
||||
this.bind(this.network.time, 'offset', function(offset) {
|
||||
@ -173,8 +171,14 @@ Node.prototype.handleOpen = co(function* handleOpen() {
|
||||
this.logger.warning('Warning: worker pool is disabled.');
|
||||
this.logger.warning('Verification will be slow.');
|
||||
}
|
||||
});
|
||||
|
||||
yield this.openPlugins();
|
||||
/**
|
||||
* Open node. Bind all events.
|
||||
* @private
|
||||
*/
|
||||
|
||||
Node.prototype.handlePreclose = co(function* handlePreclose() {
|
||||
});
|
||||
|
||||
/**
|
||||
@ -185,8 +189,6 @@ Node.prototype.handleOpen = co(function* handleOpen() {
|
||||
Node.prototype.handleClose = co(function* handleClose() {
|
||||
var i, bound;
|
||||
|
||||
yield this.closePlugins();
|
||||
|
||||
this.startTime = -1;
|
||||
|
||||
for (i = 0; i < this.bound.length; i++) {
|
||||
@ -264,36 +266,6 @@ Node.prototype.uptime = function uptime() {
|
||||
return util.now() - this.startTime;
|
||||
};
|
||||
|
||||
/**
|
||||
* Open and ensure primary wallet.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
Node.prototype.openWallet = co(function* openWallet() {
|
||||
var options, wallet;
|
||||
|
||||
assert(!this.wallet);
|
||||
|
||||
options = {
|
||||
id: 'primary',
|
||||
passphrase: this.config.str('passphrase')
|
||||
};
|
||||
|
||||
wallet = yield this.walletdb.ensure(options);
|
||||
|
||||
this.logger.info(
|
||||
'Loaded wallet with id=%s wid=%d address=%s',
|
||||
wallet.id, wallet.wid, wallet.getAddress());
|
||||
|
||||
if (this.miner && this.miner.addresses.length === 0)
|
||||
this.miner.addAddress(wallet.getAddress());
|
||||
|
||||
this.wallet = wallet;
|
||||
|
||||
if (this.http && this.http.rpc && !this.http.rpc.wallet)
|
||||
this.http.rpc.wallet = wallet;
|
||||
});
|
||||
|
||||
/**
|
||||
* Attach a plugin.
|
||||
* @param {Object} plugin
|
||||
@ -312,25 +284,24 @@ Node.prototype.use = function use(plugin) {
|
||||
assert(typeof instance.open === 'function', '`open` must be a function.');
|
||||
assert(typeof instance.close === 'function', '`close` must be a function.');
|
||||
|
||||
if (plugin.name) {
|
||||
assert(typeof plugin.name === 'string', '`name` must be a string.');
|
||||
if (plugin.id) {
|
||||
assert(typeof plugin.id === 'string', '`name` must be a string.');
|
||||
|
||||
// Reserved names
|
||||
switch (plugin.name) {
|
||||
switch (plugin.id) {
|
||||
case 'logger':
|
||||
case 'chain':
|
||||
case 'fees':
|
||||
case 'mempool':
|
||||
case 'miner':
|
||||
case 'pool':
|
||||
case 'walletdb':
|
||||
assert(false, plugin.name + ' is already added.');
|
||||
assert(false, plugin.id + ' is already added.');
|
||||
break;
|
||||
}
|
||||
|
||||
assert(!this.plugins[plugin.name], plugin.name + ' is already added.');
|
||||
assert(!this.plugins[plugin.id], plugin.id + ' is already added.');
|
||||
|
||||
this.plugins[plugin.name] = instance;
|
||||
this.plugins[plugin.id] = instance;
|
||||
}
|
||||
|
||||
this.stack.push(instance);
|
||||
@ -366,9 +337,6 @@ Node.prototype.require = function require(name) {
|
||||
case 'pool':
|
||||
assert(this.pool, 'pool is not loaded.');
|
||||
return this.pool;
|
||||
case 'walletdb':
|
||||
assert(this.walletdb, 'walletdb is not loaded.');
|
||||
return this.walletdb;
|
||||
}
|
||||
|
||||
plugin = this.plugins[name];
|
||||
@ -392,9 +360,16 @@ Node.prototype.loadPlugins = function loadPlugins() {
|
||||
|
||||
for (i = 0; i < plugins.length; i++) {
|
||||
name = plugins[i];
|
||||
|
||||
assert(typeof name === 'string',
|
||||
'Plugin name must be a string.');
|
||||
|
||||
// Temporary until we separate walletdb out.
|
||||
if (name === 'walletdb')
|
||||
name = __dirname + '/../wallet/walletdb';
|
||||
|
||||
plugin = loader(name);
|
||||
|
||||
this.use(plugin);
|
||||
}
|
||||
};
|
||||
|
||||
@ -13,12 +13,11 @@ var Lock = require('../utils/lock');
|
||||
var Node = require('./node');
|
||||
var Chain = require('../blockchain/chain');
|
||||
var Pool = require('../net/pool');
|
||||
var WalletDB = require('../wallet/walletdb');
|
||||
var HTTPServer = require('../http/server');
|
||||
|
||||
/**
|
||||
* Create an spv node which only maintains
|
||||
* a chain, a pool, and a wallet database.
|
||||
* a chain, a pool, and an http server.
|
||||
* @alias module:node.SPVNode
|
||||
* @extends Node
|
||||
* @constructor
|
||||
@ -27,11 +26,9 @@ var HTTPServer = require('../http/server');
|
||||
* @param {Buffer?} options.sslCert
|
||||
* @param {Number?} options.httpPort
|
||||
* @param {String?} options.httpHost
|
||||
* @param {Object?} options.wallet - Primary {@link Wallet} options.
|
||||
* @property {Boolean} loaded
|
||||
* @property {Chain} chain
|
||||
* @property {Pool} pool
|
||||
* @property {WalletDB} walletdb
|
||||
* @property {HTTPServer} http
|
||||
* @emits SPVNode#block
|
||||
* @emits SPVNode#tx
|
||||
@ -74,22 +71,6 @@ function SPVNode(options) {
|
||||
listen: false
|
||||
});
|
||||
|
||||
this.walletdb = new WalletDB({
|
||||
network: this.network,
|
||||
logger: this.logger,
|
||||
client: this.client,
|
||||
db: this.config.str('db'),
|
||||
prefix: this.config.prefix,
|
||||
maxFiles: this.config.num('max-files'),
|
||||
cacheSize: this.config.mb('cache-size'),
|
||||
witness: false,
|
||||
checkpoints: this.config.bool('checkpoints'),
|
||||
startHeight: this.config.num('start-height'),
|
||||
wipeNoReally: this.config.bool('wipe-no-really'),
|
||||
verify: true,
|
||||
spv: true
|
||||
});
|
||||
|
||||
if (!HTTPServer.unsupported) {
|
||||
this.http = new HTTPServer({
|
||||
network: this.network,
|
||||
@ -129,7 +110,6 @@ SPVNode.prototype._init = function _init() {
|
||||
// Bind to errors
|
||||
this.chain.on('error', onError);
|
||||
this.pool.on('error', onError);
|
||||
this.walletdb.on('error', onError);
|
||||
|
||||
if (this.http)
|
||||
this.http.on('error', onError);
|
||||
@ -165,6 +145,8 @@ SPVNode.prototype._init = function _init() {
|
||||
this.chain.on('reset', function(tip) {
|
||||
self.emit('reset', tip);
|
||||
});
|
||||
|
||||
this.loadPlugins();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -177,10 +159,8 @@ SPVNode.prototype._init = function _init() {
|
||||
SPVNode.prototype._open = co(function* open(callback) {
|
||||
yield this.chain.open();
|
||||
yield this.pool.open();
|
||||
yield this.walletdb.open();
|
||||
|
||||
// Ensure primary wallet.
|
||||
yield this.openWallet();
|
||||
yield this.openPlugins();
|
||||
|
||||
if (this.http)
|
||||
yield this.http.open();
|
||||
@ -198,11 +178,8 @@ SPVNode.prototype._close = co(function* close() {
|
||||
if (this.http)
|
||||
yield this.http.close();
|
||||
|
||||
yield this.wallet.destroy();
|
||||
yield this.closePlugins();
|
||||
|
||||
this.wallet = null;
|
||||
|
||||
yield this.walletdb.close();
|
||||
yield this.pool.close();
|
||||
yield this.chain.close();
|
||||
});
|
||||
|
||||
@ -31,3 +31,4 @@ exports.BufferReader = require('./reader');
|
||||
exports.StaticWriter = require('./staticwriter');
|
||||
exports.util = require('./util');
|
||||
exports.BufferWriter = require('./writer');
|
||||
exports.Validator = require('./validator');
|
||||
|
||||
@ -1037,3 +1037,30 @@ util.promisify = function promisify(func) {
|
||||
return Promise.resolve(result);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get memory usage info.
|
||||
* @returns {Object}
|
||||
*/
|
||||
|
||||
util.memoryUsage = function memoryUsage() {
|
||||
var mem;
|
||||
|
||||
if (!process.memoryUsage) {
|
||||
return {
|
||||
total: 0,
|
||||
jsHeap: 0,
|
||||
jsHeapTotal: 0,
|
||||
nativeHeap: 0
|
||||
};
|
||||
}
|
||||
|
||||
mem = process.memoryUsage();
|
||||
|
||||
return {
|
||||
total: util.mb(mem.rss),
|
||||
jsHeap: util.mb(mem.heapUsed),
|
||||
jsHeapTotal: util.mb(mem.heapTotal),
|
||||
nativeHeap: util.mb(mem.rss - mem.heapTotal)
|
||||
};
|
||||
};
|
||||
|
||||
428
lib/utils/validator.js
Normal file
428
lib/utils/validator.js
Normal file
@ -0,0 +1,428 @@
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
|
||||
/**
|
||||
* Validator
|
||||
* @alias module:utils.Validator
|
||||
* @constructor
|
||||
* @param {Object} options
|
||||
*/
|
||||
|
||||
function Validator(data) {
|
||||
if (!(this instanceof Validator))
|
||||
return new Validator(data);
|
||||
|
||||
this.data = [];
|
||||
|
||||
if (data)
|
||||
this.init(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether a config option is present.
|
||||
* @param {String} key
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Validator.prototype.init = function init(data) {
|
||||
var i, obj;
|
||||
|
||||
assert(data && typeof data === 'object');
|
||||
|
||||
if (!Array.isArray(data))
|
||||
data = [data];
|
||||
|
||||
for (i = 0; i < data.length; i++) {
|
||||
obj = data[i];
|
||||
assert(obj && typeof obj === 'object');
|
||||
this.data.push(obj);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether a config option is present.
|
||||
* @param {String} key
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Validator.prototype.has = function has(key) {
|
||||
var i, map, value;
|
||||
|
||||
assert(typeof key === 'string' || typeof key === 'number',
|
||||
'Key must be a string.');
|
||||
|
||||
for (i = 0; i < this.data.length; i++) {
|
||||
map = this.data[i];
|
||||
value = map[key];
|
||||
if (value != null)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a config option.
|
||||
* @param {String} key
|
||||
* @param {Object?} fallback
|
||||
* @returns {Object|null}
|
||||
*/
|
||||
|
||||
Validator.prototype.get = function get(key, fallback) {
|
||||
var i, keys, value, map;
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
|
||||
if (Array.isArray(key)) {
|
||||
keys = key;
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
value = this.get(key);
|
||||
if (value !== null)
|
||||
return value;
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
assert(typeof key === 'string' || typeof key === 'number',
|
||||
'Key must be a string.');
|
||||
|
||||
for (i = 0; i < this.data.length; i++) {
|
||||
map = this.data[i];
|
||||
value = map[key];
|
||||
if (value != null)
|
||||
return value;
|
||||
}
|
||||
|
||||
return fallback;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a config option (as a string).
|
||||
* @param {String} key
|
||||
* @param {Object?} fallback
|
||||
* @returns {String|null}
|
||||
*/
|
||||
|
||||
Validator.prototype.str = function str(key, fallback) {
|
||||
var value = this.get(key);
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
|
||||
if (value === null)
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string')
|
||||
throw new Error(key + ' must be a string.');
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a config option (as a number).
|
||||
* @param {String} key
|
||||
* @param {Object?} fallback
|
||||
* @returns {Number|null}
|
||||
*/
|
||||
|
||||
Validator.prototype.num = function num(key, fallback) {
|
||||
var value = this.get(key);
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
|
||||
if (value === null)
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
if (typeof value !== 'number')
|
||||
throw new Error(key + ' must be a number.');
|
||||
return value;
|
||||
}
|
||||
|
||||
if (!/^\d+$/.test(value))
|
||||
throw new Error(key + ' must be a number.');
|
||||
|
||||
value = parseInt(value, 10);
|
||||
|
||||
if (!isFinite(value))
|
||||
throw new Error(key + ' must be a number.');
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a config option (as a number).
|
||||
* @param {String} key
|
||||
* @param {Object?} fallback
|
||||
* @returns {Number|null}
|
||||
*/
|
||||
|
||||
Validator.prototype.amt = function amt(key, fallback) {
|
||||
var value = this.get(key);
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
|
||||
if (value === null)
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
if (typeof value !== 'number')
|
||||
throw new Error(key + ' must be a number.');
|
||||
return value;
|
||||
}
|
||||
|
||||
if (!/^\d+(\.\d{0,8})?$/.test(value))
|
||||
throw new Error(key + ' must be a number.');
|
||||
|
||||
value = parseFloat(value);
|
||||
|
||||
if (!isFinite(value))
|
||||
throw new Error(key + ' must be a number.');
|
||||
|
||||
return value * 1e8;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a config option (as a number).
|
||||
* @param {String} key
|
||||
* @param {Object?} fallback
|
||||
* @returns {Number|null}
|
||||
*/
|
||||
|
||||
Validator.prototype.hash = function hash(key, fallback) {
|
||||
var value = this.get(key);
|
||||
var out = '';
|
||||
var i;
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
|
||||
if (value === null)
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
if (!Buffer.isBuffer(value))
|
||||
throw new Error(key + ' must be a buffer.');
|
||||
if (value.length !== 32)
|
||||
throw new Error(key + ' must be a buffer.');
|
||||
return value.toString('hex');
|
||||
}
|
||||
|
||||
if (value.length !== 64)
|
||||
throw new Error(key + ' must be a hex string.');
|
||||
|
||||
if (!/^[0-9a-f]+$/i.test(value))
|
||||
throw new Error(key + ' must be a hex string.');
|
||||
|
||||
for (i = 0; i < value.length; i += 2)
|
||||
out = value.slice(i, i + 2) + out;
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a config option (as a number).
|
||||
* @param {String} key
|
||||
* @param {Object?} fallback
|
||||
* @returns {Number|null}
|
||||
*/
|
||||
|
||||
Validator.prototype.numstr = function numstr(key, fallback) {
|
||||
var value = this.get(key);
|
||||
var num;
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
|
||||
if (value === null)
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
if (typeof value !== 'number')
|
||||
throw new Error(key + ' must be a number or string.');
|
||||
return value;
|
||||
}
|
||||
|
||||
num = parseInt(value, 10);
|
||||
|
||||
if (!isFinite(num))
|
||||
return value;
|
||||
|
||||
return num;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a config option (as a boolean).
|
||||
* @param {String} key
|
||||
* @param {Object?} fallback
|
||||
* @returns {Boolean|null}
|
||||
*/
|
||||
|
||||
Validator.prototype.bool = function bool(key, fallback) {
|
||||
var value = this.get(key);
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
|
||||
if (value === null)
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
assert(typeof value === 'boolean',
|
||||
'Passed in config option is of wrong type.');
|
||||
return value;
|
||||
}
|
||||
|
||||
if (value === 'true' || value === '1')
|
||||
return true;
|
||||
|
||||
if (value === 'false' || value === '0')
|
||||
return false;
|
||||
|
||||
throw new Error(key + ' must be a boolean.');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a config option (as a buffer).
|
||||
* @param {String} key
|
||||
* @param {Object?} fallback
|
||||
* @returns {Buffer|null}
|
||||
*/
|
||||
|
||||
Validator.prototype.buf = function buf(key, fallback) {
|
||||
var value = this.get(key);
|
||||
var data;
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
|
||||
if (value === null)
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
assert(Buffer.isBuffer(value),
|
||||
'Passed in config option is of wrong type.');
|
||||
return value;
|
||||
}
|
||||
|
||||
data = new Buffer(value, 'hex');
|
||||
|
||||
if (data.length !== value.length / 2)
|
||||
throw new Error(key + ' must be a hex string.');
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a config option (as an array of strings).
|
||||
* @param {String} key
|
||||
* @param {Object?} fallback
|
||||
* @returns {String[]|null}
|
||||
*/
|
||||
|
||||
Validator.prototype.array = function array(key, fallback) {
|
||||
var value = this.get(key);
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
|
||||
if (value === null)
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
if (!Array.isArray(value))
|
||||
throw new Error(key + ' must be a list/array.');
|
||||
return value;
|
||||
}
|
||||
|
||||
return value.trim().split(/\s*,\s*/);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a config option (as an object).
|
||||
* @param {String} key
|
||||
* @param {Object?} fallback
|
||||
* @returns {Object|null}
|
||||
*/
|
||||
|
||||
Validator.prototype.obj = function obj(key, fallback) {
|
||||
var value = this.get(key);
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
|
||||
if (value === null)
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
if (!value || typeof value !== 'object')
|
||||
throw new Error(key + ' must be an object.');
|
||||
return value;
|
||||
}
|
||||
|
||||
try {
|
||||
value = JSON.parse(value);
|
||||
} catch (e) {
|
||||
;
|
||||
}
|
||||
|
||||
if (!value || typeof value !== 'object')
|
||||
throw new Error(key + ' must be an object.');
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a config option (as an object).
|
||||
* @param {String} key
|
||||
* @param {Object?} fallback
|
||||
* @returns {Object|null}
|
||||
*/
|
||||
|
||||
Validator.prototype.next = function next(key, fallback) {
|
||||
var value = this.obj(key, fallback);
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
|
||||
if (value === null)
|
||||
return fallback;
|
||||
|
||||
return new Validator(value);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a config option (as a function).
|
||||
* @param {String} key
|
||||
* @param {Object?} fallback
|
||||
* @returns {Function|null}
|
||||
*/
|
||||
|
||||
Validator.prototype.func = function func(key, fallback) {
|
||||
var value = this.get(key);
|
||||
|
||||
if (fallback === undefined)
|
||||
fallback = null;
|
||||
|
||||
if (value === null)
|
||||
return fallback;
|
||||
|
||||
if (typeof value !== 'string') {
|
||||
if (typeof value !== 'function')
|
||||
throw new Error(key + ' must be a function.');
|
||||
return value;
|
||||
}
|
||||
|
||||
throw new Error(key + ' must be a function.');
|
||||
};
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
module.exports = Validator;
|
||||
@ -23,6 +23,9 @@ common.isName = function isName(key) {
|
||||
if (typeof key !== 'string')
|
||||
return false;
|
||||
|
||||
if (key === '_admin')
|
||||
return false;
|
||||
|
||||
if (key === '__proto__')
|
||||
return false;
|
||||
|
||||
|
||||
1087
lib/wallet/http.js
Normal file
1087
lib/wallet/http.js
Normal file
File diff suppressed because it is too large
Load Diff
1847
lib/wallet/rpc.js
Normal file
1847
lib/wallet/rpc.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -1424,7 +1424,7 @@ Wallet.prototype._fund = co(function* fund(mtx, options) {
|
||||
rate = options.rate;
|
||||
|
||||
if (rate == null)
|
||||
rate = yield this.db.estimateFee();
|
||||
rate = yield this.db.estimateFee(options.blocks);
|
||||
|
||||
if (options.smart) {
|
||||
coins = yield this.getSmartCoins(options.account);
|
||||
|
||||
@ -26,6 +26,8 @@ var Logger = require('../node/logger');
|
||||
var Outpoint = require('../primitives/outpoint');
|
||||
var layouts = require('./layout');
|
||||
var records = require('./records');
|
||||
var NodeClient = require('../node/nodeclient');
|
||||
var HTTP = require('./http');
|
||||
var layout = layouts.walletdb;
|
||||
var ChainState = records.ChainState;
|
||||
var BlockMapRecord = records.BlockMapRecord;
|
||||
@ -62,6 +64,20 @@ function WalletDB(options) {
|
||||
this.logger = this.options.logger;
|
||||
this.client = this.options.client;
|
||||
this.db = LDB(this.options);
|
||||
this.primary = null;
|
||||
|
||||
this.http = new HTTP({
|
||||
walletdb: this,
|
||||
network: this.network,
|
||||
logger: this.logger,
|
||||
prefix: this.options.prefix,
|
||||
apiKey: this.options.apiKey,
|
||||
walletAuth: this.options.walletAuth,
|
||||
noAuth: this.options.noAuth,
|
||||
host: this.options.host,
|
||||
port: this.options.port,
|
||||
ssl: this.options.ssl
|
||||
});
|
||||
|
||||
this.state = new ChainState();
|
||||
this.wallets = Object.create(null);
|
||||
@ -83,6 +99,54 @@ function WalletDB(options) {
|
||||
|
||||
util.inherits(WalletDB, AsyncObject);
|
||||
|
||||
/**
|
||||
* Plugin name.
|
||||
* @const {String}
|
||||
*/
|
||||
|
||||
WalletDB.id = 'walletdb';
|
||||
|
||||
/**
|
||||
* Plugin initialization.
|
||||
* @param {Node} node
|
||||
* @returns {WalletDB}
|
||||
*/
|
||||
|
||||
WalletDB.init = function init(node) {
|
||||
var config = node.config;
|
||||
var client = new NodeClient(node);
|
||||
var wdb;
|
||||
|
||||
wdb = new WalletDB({
|
||||
network: node.network,
|
||||
logger: node.logger,
|
||||
client: client,
|
||||
prefix: config.prefix,
|
||||
db: config.str(['wallet-db', 'db']),
|
||||
maxFiles: config.num('wallet-max-files'),
|
||||
cacheSize: config.mb('wallet-cache-size'),
|
||||
witness: config.bool('wallet-witness'),
|
||||
checkpoints: config.bool('wallet-checkpoints'),
|
||||
startHeight: config.num('wallet-start-height'),
|
||||
wipeNoReally: config.bool('wallet-wipe-no-really'),
|
||||
apiKey: config.str(['wallet-api-key', 'api-key']),
|
||||
walletAuth: config.bool('wallet-auth'),
|
||||
noAuth: config.bool('no-auth'),
|
||||
ssl: config.str('wallet-ssl'),
|
||||
host: config.str('wallet-host'),
|
||||
port: config.num('wallet-port'),
|
||||
spv: node.chain.options.spv,
|
||||
verify: node.chain.options.spv
|
||||
});
|
||||
|
||||
if (node.http) {
|
||||
wdb.http.attach(node.http);
|
||||
wdb.http.rpc.attach(node.http.rpc);
|
||||
}
|
||||
|
||||
return wdb;
|
||||
};
|
||||
|
||||
/**
|
||||
* Database layout.
|
||||
* @type {Object}
|
||||
@ -119,6 +183,8 @@ WalletDB.prototype._init = function _init() {
|
||||
*/
|
||||
|
||||
WalletDB.prototype._open = co(function* open() {
|
||||
var wallet;
|
||||
|
||||
yield this.db.open();
|
||||
yield this.db.checkVersion('V', 6);
|
||||
|
||||
@ -134,6 +200,17 @@ WalletDB.prototype._open = co(function* open() {
|
||||
this.depth,
|
||||
this.state.height,
|
||||
this.state.startHeight);
|
||||
|
||||
wallet = yield this.ensure({
|
||||
id: 'primary'
|
||||
});
|
||||
|
||||
this.logger.info(
|
||||
'Loaded wallet with id=%s wid=%d address=%s',
|
||||
wallet.id, wallet.wid, wallet.getAddress());
|
||||
|
||||
this.primary = wallet;
|
||||
this.http.rpc.wallet = wallet;
|
||||
});
|
||||
|
||||
/**
|
||||
@ -2185,6 +2262,12 @@ function WalletOptions(options) {
|
||||
this.startHeight = 0;
|
||||
this.keepBlocks = this.network.block.keepBlocks;
|
||||
this.wipeNoReally = false;
|
||||
this.apiKey = null;
|
||||
this.walletAuth = false;
|
||||
this.noAuth = false;
|
||||
this.ssl = false;
|
||||
this.host = '127.0.0.1';
|
||||
this.port = this.network.rpcPort + 2;
|
||||
|
||||
if (options)
|
||||
this.fromOptions(options);
|
||||
@ -2201,6 +2284,7 @@ WalletOptions.prototype.fromOptions = function fromOptions(options) {
|
||||
if (options.network != null) {
|
||||
this.network = Network.get(options.network);
|
||||
this.keepBlocks = this.network.block.keepBlocks;
|
||||
this.port = this.network.rpcPort + 2;
|
||||
}
|
||||
|
||||
if (options.logger != null) {
|
||||
@ -2270,6 +2354,36 @@ WalletOptions.prototype.fromOptions = function fromOptions(options) {
|
||||
this.wipeNoReally = options.wipeNoReally;
|
||||
}
|
||||
|
||||
if (options.apiKey != null) {
|
||||
assert(typeof options.apiKey === 'string');
|
||||
this.apiKey = options.apiKey;
|
||||
}
|
||||
|
||||
if (options.walletAuth != null) {
|
||||
assert(typeof options.walletAuth === 'boolean');
|
||||
this.walletAuth = options.walletAuth;
|
||||
}
|
||||
|
||||
if (options.noAuth != null) {
|
||||
assert(typeof options.noAuth === 'boolean');
|
||||
this.noAuth = options.noAuth;
|
||||
}
|
||||
|
||||
if (options.ssl != null) {
|
||||
assert(typeof options.ssl === 'boolean');
|
||||
this.ssl = options.ssl;
|
||||
}
|
||||
|
||||
if (options.host != null) {
|
||||
assert(typeof options.host === 'string');
|
||||
this.host = options.host;
|
||||
}
|
||||
|
||||
if (options.port != null) {
|
||||
assert(typeof options.port === 'number');
|
||||
this.port = options.port;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
@ -13,13 +13,15 @@ var FullNode = require('../lib/node/fullnode');
|
||||
var pkg = require('../lib/pkg');
|
||||
|
||||
describe('HTTP', function() {
|
||||
var node, wallet, addr, hash;
|
||||
var node, wallet, walletdb, addr, hash;
|
||||
|
||||
node = new FullNode({
|
||||
network: 'regtest',
|
||||
apiKey: 'foo',
|
||||
walletAuth: true,
|
||||
db: 'memory'
|
||||
db: 'memory',
|
||||
loader: require,
|
||||
plugins: ['walletdb']
|
||||
});
|
||||
|
||||
wallet = new HTTP.Wallet({
|
||||
@ -27,6 +29,8 @@ describe('HTTP', function() {
|
||||
apiKey: 'foo'
|
||||
});
|
||||
|
||||
walletdb = node.require('walletdb');
|
||||
|
||||
node.on('error', function() {});
|
||||
|
||||
this.timeout(15000);
|
||||
@ -82,7 +86,7 @@ describe('HTTP', function() {
|
||||
details = d;
|
||||
});
|
||||
|
||||
yield node.walletdb.addTX(tx);
|
||||
yield walletdb.addTX(tx);
|
||||
yield co.timeout(300);
|
||||
|
||||
assert(receive);
|
||||
|
||||
@ -11,14 +11,19 @@ var MTX = require('../lib/primitives/mtx');
|
||||
// var Client = require('../lib/wallet/client');
|
||||
|
||||
describe('Node', function() {
|
||||
var node = new FullNode({ db: 'memory', apiKey: 'foo', network: 'regtest' });
|
||||
var node = new FullNode({
|
||||
db: 'memory',
|
||||
apiKey: 'foo',
|
||||
network: 'regtest',
|
||||
loader: require,
|
||||
plugins: ['../lib/wallet/walletdb']
|
||||
});
|
||||
var chain = node.chain;
|
||||
var walletdb = node.walletdb;
|
||||
var walletdb = node.require('walletdb');
|
||||
var miner = node.miner;
|
||||
var wallet, tip1, tip2, cb1, cb2, mineBlock;
|
||||
|
||||
// walletdb.client = new Client({ apiKey: 'foo', network: 'regtest' });
|
||||
walletdb.options.resolution = false;
|
||||
|
||||
node.on('error', function() {});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user