node/config: refactor config and options.

This commit is contained in:
Christopher Jeffrey 2017-03-08 07:18:53 -08:00
parent 667b0e746d
commit a81733a720
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
23 changed files with 1271 additions and 1089 deletions

188
bin/cli
View File

@ -2,7 +2,7 @@
'use strict';
var config = require('../lib/node/config');
var Config = require('../lib/node/config');
var util = require('../lib/utils/util');
var co = require('../lib/utils/co');
var Client = require('../lib/http/client');
@ -11,10 +11,7 @@ var Amount = require('../lib/btc/amount');
var main;
function CLI() {
this.config = config.parseRaw({
config: true,
arg: true,
env: true,
this.config = new Config({
network: 'main'
});
this.argv = this.config.argv;
@ -39,36 +36,24 @@ CLI.prototype.getWallets = co(function* getWallets() {
});
CLI.prototype.createWallet = co(function* createWallet() {
var options = { id: this.argv[0] };
var options = { id: this.config.str(0) };
var wallet;
if (this.config.type)
options.type = this.config.type;
options.type = this.config.str('type');
options.master = this.config.str('master');
options.mnemonic = this.config.str('mnemonic');
options.m = this.config.num('m');
options.n = this.config.num('n');
options.witness = this.config.bool('witness');
options.passphrase = this.config.str('passphrase');
if (this.config.master)
options.master = this.config.master;
if (this.config.mnemonic)
options.master = this.config.mnemonic;
if (this.config.m)
options.m = this.config.m >>> 0;
if (this.config.n)
options.n = this.config.n >>> 0;
if (this.config.witness != null)
options.witness = !!this.config.witness;
if (this.config.passphrase)
options.passphrase = this.config.passphrase;
if (this.config.watch) {
if (this.config.has('watch')) {
options.watchOnly = true;
options.accountKey = this.config.watch;
options.accountKey = this.config.str('watch');
}
wallet = yield this.client.createWallet(options);
this.log(wallet);
});
@ -78,59 +63,50 @@ CLI.prototype.getMaster = co(function* getMaster() {
});
CLI.prototype.getKey = co(function* getKey() {
var address = this.argv[0];
var address = this.config.str(0);
var key = yield this.wallet.getKey(address);
this.log(key);
});
CLI.prototype.getWIF = co(function* getWIF() {
var address = this.argv[0];
var key = yield this.wallet.getWIF(address, this.config.passphrase);
var address = this.config.str(0);
var key = yield this.wallet.getWIF(address, this.config.str('passphrase'));
this.log(key.privateKey);
});
CLI.prototype.addSharedKey = co(function* addSharedKey() {
var key = this.argv[0];
yield this.wallet.addSharedKey(this.config.account, key);
var key = this.config.str(0);
yield this.wallet.addSharedKey(this.config.str('account'), key);
this.log('Added key.');
});
CLI.prototype.removeSharedKey = co(function* removeSharedKey() {
var key = this.argv[0];
yield this.wallet.removeSharedKey(this.config.account, key);
var key = this.config.str(0);
yield this.wallet.removeSharedKey(this.config.str('account'), key);
this.log('Removed key.');
});
CLI.prototype.getSharedKeys = co(function* getSharedKeys() {
var acct = this.argv[0] || this.config.account;
var acct = this.config.str([0, 'account']);
var account = yield this.wallet.getAccount(acct);
this.log(account.keys);
});
CLI.prototype.getAccount = co(function* getAccount() {
var acct = this.argv[0] || this.config.account;
var acct = this.config.str([0, 'account']);
var account = yield this.wallet.getAccount(acct);
this.log(account);
});
CLI.prototype.createAccount = co(function* createAccount() {
var options = { name: this.argv[0] };
var options = { name: this.config.str(0) };
var account;
if (this.config.type)
options.type = this.config.type;
if (this.config.m)
options.m = this.config.m >>> 0;
if (this.config.n)
options.n = this.config.n >>> 0;
if (this.config.witness != null)
options.witness = !!this.config.witness;
if (this.config.watch)
options.accountKey = this.config.watch;
options.type = this.config.str('type');
options.m = this.config.num('m');
options.n = this.config.num('n');
options.witness = this.config.bool('witness');
options.accountKey = this.config.str('watch');
account = yield this.wallet.createAccount(options);
@ -138,19 +114,19 @@ CLI.prototype.createAccount = co(function* createAccount() {
});
CLI.prototype.createAddress = co(function* createAddress() {
var account = this.argv[0];
var account = this.config.str(0);
var addr = yield this.wallet.createAddress(account);
this.log(addr);
});
CLI.prototype.createChange = co(function* createChange() {
var account = this.argv[0];
var account = this.config.str(0);
var addr = yield this.wallet.createChange(account);
this.log(addr);
});
CLI.prototype.createNested = co(function* createNested() {
var account = this.argv[0];
var account = this.config.str(0);
var addr = yield this.wallet.createNested(account);
this.log(addr);
});
@ -166,7 +142,7 @@ CLI.prototype.getWallet = co(function* getWallet() {
});
CLI.prototype.getTX = co(function* getTX() {
var hash = this.argv[0];
var hash = this.config.str(0);
var txs, tx;
if (util.isBase58(hash)) {
@ -186,7 +162,7 @@ CLI.prototype.getTX = co(function* getTX() {
});
CLI.prototype.getBlock = co(function* getBlock() {
var hash = this.argv[0];
var hash = this.config.str(0);
var block;
if (hash.length !== 64)
@ -203,8 +179,8 @@ CLI.prototype.getBlock = co(function* getBlock() {
});
CLI.prototype.getCoin = co(function* getCoin() {
var hash = this.argv[0];
var index = this.argv[1];
var hash = this.config.str(0);
var index = this.config.num(1);
var coins, coin;
if (util.isBase58(hash)) {
@ -224,17 +200,17 @@ CLI.prototype.getCoin = co(function* getCoin() {
});
CLI.prototype.getWalletHistory = co(function* getWalletHistory() {
var txs = yield this.wallet.getHistory(this.config.account);
var txs = yield this.wallet.getHistory(this.config.str('account'));
this.log(txs);
});
CLI.prototype.getWalletPending = co(function* getWalletPending() {
var txs = yield this.wallet.getPending(this.config.account);
var txs = yield this.wallet.getPending(this.config.str('account'));
this.log(txs);
});
CLI.prototype.getWalletCoins = co(function* getWalletCoins() {
var coins = yield this.wallet.getCoins(this.config.account);
var coins = yield this.wallet.getCoins(this.config.str('account'));
this.log(coins);
});
@ -277,7 +253,7 @@ CLI.prototype.listenWallet = co(function* listenWallet() {
});
CLI.prototype.getBalance = co(function* getBalance() {
var balance = yield this.wallet.getBalance(this.config.account);
var balance = yield this.wallet.getBalance(this.config.str('account'));
this.log(balance);
});
@ -290,19 +266,19 @@ CLI.prototype.sendTX = co(function* sendTX() {
var output = {};
var options, tx;
if (this.config.script) {
output.script = this.config.script;
output.value = Amount.value(this.config.value || this.argv[0]);
if (this.config.has('script')) {
output.script = this.config.str('script');
output.value = Amount.value(this.config.num(['value', 0]));
} else {
output.address = this.config.address || this.argv[0];
output.value = Amount.value(this.config.value || this.argv[1]);
output.address = this.config.str(['address', 0]);
output.value = Amount.value(this.config.num(['value', 1]));
}
options = {
account: this.config.account,
passphrase: this.config.passphrase,
account: this.config.str('account'),
passphrase: this.config.str('passphrase'),
outputs: [output],
rate: this.config.rate
rate: this.config.str('rate')
};
tx = yield this.wallet.send(options);
@ -314,17 +290,17 @@ CLI.prototype.createTX = co(function* createTX() {
var output = {};
var options, tx;
if (this.config.script) {
output.script = this.config.script;
output.value = Amount.value(this.config.value || this.argv[0]);
if (this.config.has('script')) {
output.script = this.config.str('script');
output.value = Amount.value(this.config.str(['value', 0]));
} else {
output.address = this.config.address || this.argv[0];
output.value = Amount.value(this.config.value || this.argv[1]);
output.address = this.config.str(['address', 0]);
output.value = Amount.value(this.config.num(['value', 1]));
}
options = {
account: this.config.account,
passphrase: this.config.passphrase,
account: this.config.str('account'),
passphrase: this.config.str('passphrase'),
outputs: [output]
};
@ -334,33 +310,37 @@ CLI.prototype.createTX = co(function* createTX() {
});
CLI.prototype.signTX = co(function* signTX() {
var options = { passphrase: this.config.passphrase };
var raw = options.tx || this.argv[0];
var tx = yield this.wallet.sign(raw, options);
var options = {};
var raw = this.config.str(['tx', 0]);
options.passphrase = this.config.str('passphrase');
tx = yield this.wallet.sign(raw, options);
this.log(tx);
});
CLI.prototype.zapWallet = co(function* zapWallet() {
var age = (this.config.age >>> 0) || 72 * 60 * 60;
yield this.wallet.zap(this.config.account, age);
var age = this.config.num('age', 72 * 60 * 60);
yield this.wallet.zap(this.config.str('account'), age);
this.log('Zapped!');
});
CLI.prototype.broadcast = co(function* broadcast() {
var raw = this.argv[0] || this.config.tx;
var raw = this.config.str([0, 'tx']);
var tx = yield this.client.broadcast(raw);
this.log('Broadcasted:');
this.log(tx);
});
CLI.prototype.viewTX = co(function* viewTX() {
var raw = this.argv[0] || this.config.tx;
var raw = this.config.str([0, 'tx']);
var tx = yield this.wallet.fill(raw);
this.log(tx);
});
CLI.prototype.getDetails = co(function* getDetails() {
var hash = this.argv[0];
var hash = this.config.str(0);
var details = yield this.wallet.getTX(hash);
this.log(details);
});
@ -371,7 +351,7 @@ CLI.prototype.getWalletBlocks = co(function* getWalletBlocks() {
});
CLI.prototype.getWalletBlock = co(function* getWalletBlock() {
var height = this.argv[0] | 0;
var height = this.config.num(0);
var block = yield this.wallet.getBlock(height);
this.log(block);
});
@ -382,7 +362,7 @@ CLI.prototype.retoken = co(function* retoken() {
});
CLI.prototype.rescan = co(function* rescan() {
var height = this.argv[0];
var height = this.config.num(0);
if (!util.isUInt32(height))
height = null;
@ -393,7 +373,7 @@ CLI.prototype.rescan = co(function* rescan() {
});
CLI.prototype.reset = co(function* reset() {
var hash = this.argv[0];
var hash = this.config.str(0);
if (hash.length !== 64)
hash = +hash;
@ -414,7 +394,7 @@ CLI.prototype.resendWallet = co(function* resendWallet() {
});
CLI.prototype.backup = co(function* backup() {
var path = this.argv[0];
var path = this.config.str(0);
yield this.client.backup(path);
@ -422,8 +402,8 @@ CLI.prototype.backup = co(function* backup() {
});
CLI.prototype.importKey = co(function* importKey() {
var key = this.argv[0];
var account = this.config.account;
var key = this.config.str(0);
var account = this.config.str('account');
if (!key)
throw new Error('No key for import.');
@ -444,8 +424,8 @@ CLI.prototype.importKey = co(function* importKey() {
});
CLI.prototype.importAddress = co(function* importKey() {
var address = this.argv[0];
var account = this.config.account;
var address = this.config.str(0);
var account = this.config.str('account');
yield this.wallet.importAddress(account, address);
this.log('Imported address.');
});
@ -456,8 +436,8 @@ CLI.prototype.lock = co(function* lock() {
});
CLI.prototype.unlock = co(function* unlock() {
var passphrase = this.argv[0];
var timeout = +this.argv[1] || null;
var passphrase = this.config.str(0);
var timeout = this.config.num(1);
yield this.wallet.unlock(passphrase, timeout);
this.log('Unlocked.');
});
@ -492,11 +472,11 @@ CLI.prototype.rpc = co(function* rpc() {
CLI.prototype.handleWallet = co(function* handleWallet() {
this.wallet = new Wallet({
uri: this.config.url || this.config.uri,
apiKey: this.config.apikey,
network: this.config.network,
id: this.config.id || 'primary',
token: this.config.token
uri: this.config.str(['url', 'uri']),
apiKey: this.config.str('api-key'),
network: this.config.str('network'),
id: this.config.str('id', 'primary'),
token: this.config.str('token')
});
switch (this.argv.shift()) {
@ -619,9 +599,9 @@ CLI.prototype.handleWallet = co(function* handleWallet() {
CLI.prototype.handleNode = co(function* handleNode() {
this.client = new Client({
uri: this.config.url || this.config.uri,
apiKey: this.config.apikey,
network: this.config.network
uri: this.config.str(['url', 'uri']),
apiKey: this.config.str('api-key'),
network: this.config.str('network')
});
switch (this.argv.shift()) {

View File

@ -4,35 +4,22 @@
process.title = 'bcoin';
var assert = require('assert');
var bcoin = require('../');
var co = bcoin.co;
var options, node;
var node;
options = bcoin.config({
config: true,
arg: true,
env: true,
logLevel: 'debug',
node = new bcoin.fullnode({
logFile: true,
logLevel: 'debug',
db: 'leveldb',
listen: true
listen: true,
loader: require
});
bcoin.set(options);
node = new bcoin.fullnode(options);
node.on('error', function(err) {
;
});
process.on('uncaughtException', function(err) {
node.logger.debug(err.stack);
node.logger.error(err);
process.exit(1);
});
co.spawn(function *() {
yield node.open();
yield node.connect();

View File

@ -8,36 +8,25 @@ var assert = require('assert');
var bcoin = require('../');
var util = bcoin.util;
var co = bcoin.co;
var options, node;
var node;
options = bcoin.config({
config: true,
arg: true,
env: true,
logLevel: 'debug',
node = bcoin.spvnode({
logFile: true,
db: 'leveldb'
logLevel: 'debug',
db: 'leveldb',
listen: true,
loader: require
});
bcoin.set(options);
node = bcoin.spvnode(options);
node.on('error', function(err) {
;
});
process.on('uncaughtException', function(err) {
node.logger.debug(err.stack);
node.logger.error(err);
process.exit(1);
});
co.spawn(function *() {
yield node.open();
yield node.connect();
if (process.argv.indexOf('--test') !== -1) {
if (node.config.bool('test')) {
node.pool.watchAddress('1VayNert3x1KzbpzMGt2qdqrAThiRovi8');
node.pool.watchOutpoint(new bcoin.outpoint());
node.on('block', function(block) {

View File

@ -102,6 +102,7 @@ reserved-block-sigops: 400
http-host: ::
# http-port: 8332
# ssl: true
# ssl-cert: @/ssl/cert.crt
# ssl-key: @/ssl/priv.key
service-key: bikeshed

View File

@ -2304,6 +2304,7 @@ function ChainOptions(options) {
this.network = Network.primary;
this.logger = Logger.global;
this.prefix = null;
this.location = null;
this.db = 'memory';
this.maxFiles = 64;
@ -2342,6 +2343,19 @@ ChainOptions.prototype.fromOptions = function fromOptions(options) {
this.logger = options.logger;
}
if (options.spv != null) {
assert(typeof options.spv === 'boolean');
this.spv = options.spv;
}
if (options.prefix != null) {
assert(typeof options.prefix === 'string');
this.prefix = options.prefix;
this.location = this.spv
? this.prefix + '/spvchain'
: this.prefix + '/chain';
}
if (options.location != null) {
assert(typeof options.location === 'string');
this.location = options.location;
@ -2367,11 +2381,6 @@ ChainOptions.prototype.fromOptions = function fromOptions(options) {
this.compression = options.compression;
}
if (options.spv != null) {
assert(typeof options.spv === 'boolean');
this.spv = options.spv;
}
if (options.prune != null) {
assert(typeof options.prune === 'boolean');
this.prune = options.prune;

View File

@ -9,7 +9,6 @@
var assert = require('assert');
var LowlevelUp = require('./lowlevelup');
var util = require('../utils/util');
var backends = require('./backends');
/**
@ -33,9 +32,6 @@ function LDB(options) {
var target = LDB.getTarget(options);
var cacheSize = options.cacheSize;
if (target.backend !== 'memory')
util.mkdir(target.location, true);
if (!cacheSize)
cacheSize = 16 << 20;

View File

@ -546,7 +546,6 @@ HTTPBaseOptions.prototype.fromOptions = function fromOptions(options) {
if (options.key != null) {
assert(typeof options.key === 'string' || Buffer.isBuffer(options.key));
this.key = options.key;
this.ssl = true;
}
if (options.cert != null) {
@ -572,6 +571,7 @@ HTTPBaseOptions.prototype.fromOptions = function fromOptions(options) {
if (options.ssl != null) {
assert(typeof options.ssl === 'boolean');
assert(this.key, 'SSL specified with no provided key.');
assert(this.cert, 'SSL specified with no provided cert.');
this.ssl = options.ssl;
}

View File

@ -6,8 +6,8 @@
'use strict';
var fs = require('fs');
var EventEmitter = require('events').EventEmitter;
var fs = require('../utils/fs');
var util = require('../utils/util');
var co = require('../utils/co');
var crypto = require('../crypto/crypto');
@ -2862,7 +2862,7 @@ RPC.prototype.dumpwallet = co(function* dumpwallet(args, help) {
if (fs.unsupported)
return out;
yield writeFile(file, out);
yield fs.writeFile(file, out, 'utf8');
return out;
});
@ -3296,7 +3296,7 @@ RPC.prototype.importwallet = co(function* importwallet(args, help) {
if (rescan && this.chain.options.prune)
throw new RPCError('Cannot rescan when pruned.');
data = yield readFile(file, 'utf8');
data = yield fs.readFile(file, 'utf8');
lines = data.split(/\n+/);
keys = [];
@ -4301,18 +4301,6 @@ function reverseEndian(data) {
}
}
function writeFile(file, data) {
return new Promise(function(resolve, reject) {
fs.writeFile(file, data, co.wrap(resolve, reject));
});
}
function readFile(file, enc) {
return new Promise(function(resolve, reject) {
fs.readFile(file, enc, co.wrap(resolve, reject));
});
}
function sortTX(txs) {
return txs.sort(function(a, b) {
return a.ps - b.ps;

View File

@ -27,6 +27,7 @@ var HD = require('../hd/hd');
var Script = require('../script/script');
var crypto = require('../crypto/crypto');
var Network = require('../protocol/network');
var fs = require('../utils/fs');
var pkg = require('../pkg');
var cob = co.cob;
var RPC;
@ -48,6 +49,7 @@ function HTTPServer(options) {
EventEmitter.call(this);
this.options = new HTTPOptions(options);
this.options.load();
this.network = this.options.network;
this.logger = this.options.logger;
@ -1797,9 +1799,10 @@ function HTTPOptions(options) {
this.sockets = true;
this.host = '127.0.0.1';
this.port = this.network.rpcPort;
this.keyFile = null;
this.certFile = null;
this.key = null;
this.cert = null;
this.ca = null;
this.contentType = 'json';
this.fromOptions(options);
@ -1869,19 +1872,26 @@ HTTPOptions.prototype.fromOptions = function fromOptions(options) {
this.port = options.port;
}
if (options.key != null) {
assert(typeof options.key === 'string' || Buffer.isBuffer(options.key));
this.key = options.key;
if (options.prefix != null) {
assert(typeof options.prefix === 'string');
this.prefix = options.prefix;
this.keyFile = this.prefix + '/key.pem';
this.certFile = this.prefix + '/cert.pem';
}
if (options.cert != null) {
assert(typeof options.cert === 'string' || Buffer.isBuffer(options.cert));
this.cert = options.cert;
if (options.ssl != null) {
assert(typeof options.ssl === 'boolean');
this.ssl = options.ssl;
}
if (options.ca != null) {
assert(Array.isArray(options.ca));
this.ca = options.ca;
if (options.keyFile != null) {
assert(typeof options.keyFile === 'string');
this.keyFile = options.keyFile;
}
if (options.certFile != null) {
assert(typeof options.certFile === 'string');
this.certFile = options.certFile;
}
// Allow no-auth implicitly
@ -1894,6 +1904,22 @@ HTTPOptions.prototype.fromOptions = function fromOptions(options) {
return this;
};
/**
* Load key and cert file.
* @private
*/
HTTPOptions.prototype.load = function load() {
if (!this.ssl)
return;
if (this.keyFile)
this.key = fs.readFileSync(this.keyFile);
if (this.certFile)
this.cert = fs.readFileSync(this.certFile);
};
/**
* Instantiate http options from object.
* @param {Object} options

View File

@ -1984,6 +1984,7 @@ function MempoolOptions(options) {
this.expiryTime = policy.MEMPOOL_EXPIRY_TIME;
this.minRelay = this.network.minRelay;
this.prefix = null;
this.location = null;
this.db = 'memory';
this.maxFiles = 64;
@ -2090,6 +2091,12 @@ MempoolOptions.prototype.fromOptions = function fromOptions(options) {
this.minRelay = options.minRelay;
}
if (options.prefix != null) {
assert(typeof options.prefix === 'string');
this.prefix = options.prefix;
this.location = this.prefix + '/mempool';
}
if (options.location != null) {
assert(typeof options.location === 'string');
this.location = options.location;

View File

@ -20,6 +20,8 @@ var base58 = require('../utils/base58');
var encoding = require('../utils/encoding');
var IP = require('../utils/ip');
var dns = require('./dns');
var fs = require('../utils/fs');
var Logger = require('../node/logger');
/**
* Represents a BIP150 input/output stream.
@ -466,8 +468,9 @@ function AuthDB(options) {
if (!(this instanceof AuthDB))
return new AuthDB(options);
this.logger = null;
this.logger = Logger.global;
this.resolve = dns.lookup;
this.prefix = null;
this.dnsKnown = [];
this.known = {};
@ -476,26 +479,6 @@ function AuthDB(options) {
this._init(options);
}
/**
* Open auth database (lookup known peers).
* @method
* @returns {Promise}
*/
AuthDB.prototype.open = co(function* open() {
yield this.lookup();
});
/**
* Close auth database.
* @method
* @returns {Promise}
*/
AuthDB.prototype.close = co(function* close() {
;
});
/**
* Initialize authdb with options.
* @param {Object} options
@ -524,8 +507,35 @@ AuthDB.prototype._init = function _init(options) {
assert(Array.isArray(options.authPeers));
this.setAuthorized(options.authPeers);
}
if (options.prefix != null) {
assert(typeof options.prefix === 'string');
this.prefix = options.prefix;
}
};
/**
* Open auth database (lookup known peers).
* @method
* @returns {Promise}
*/
AuthDB.prototype.open = co(function* open() {
yield this.readKnown();
yield this.readAuth();
yield this.lookup();
});
/**
* Close auth database.
* @method
* @returns {Promise}
*/
AuthDB.prototype.close = co(function* close() {
;
});
/**
* Add a known peer.
* @param {String} host - Peer Hostname
@ -647,14 +657,12 @@ AuthDB.prototype.populate = co(function* populate(addr, key) {
assert(addr.type === IP.types.DNS, 'Resolved host passed.');
if (this.logger)
this.logger.info('Resolving authorized hosts from: %s.', addr.host);
this.logger.info('Resolving authorized hosts from: %s.', addr.host);
try {
hosts = yield this.resolve(addr.host);
} catch (e) {
if (this.logger)
this.logger.error(e);
this.logger.error(e);
return;
}
@ -668,6 +676,140 @@ AuthDB.prototype.populate = co(function* populate(addr, key) {
}
});
/**
* Parse known peers.
* @param {String} text
* @returns {Object}
*/
AuthDB.prototype.readKnown = co(function* readKnown() {
var file, text;
if (fs.unsupported)
return;
if (!this.prefix)
return;
file = this.prefix + '/known-peers';
try {
text = yield fs.readFile(file, 'utf8');
} catch (e) {
if (e.code === 'ENOENT')
return;
throw e;
}
this.parseKnown(text);
});
/**
* Parse known peers.
* @param {String} text
* @returns {Object}
*/
AuthDB.prototype.parseKnown = function parseKnown(text) {
var lines = text.split(/\n+/);
var i, line, parts, hostname, host, ip, key;
for (i = 0; i < lines.length; i++) {
line = lines[i].trim();
if (line.length === 0)
continue;
if (/^\s*#/.test(line))
continue;
parts = line.split(/\s+/);
if (parts.length < 2)
continue;
hostname = parts[0].trim().split(',');
if (hostname.length >= 2) {
host = hostname[0];
ip = hostname[1];
} else {
host = null;
ip = hostname[0];
}
key = parts[1].trim();
key = new Buffer(key, 'hex');
if (key.length !== 33)
throw new Error('Invalid key: ' + parts[1]);
if (host && host.length > 0)
this.addKnown(host, key);
if (ip.length === 0)
continue;
this.addKnown(ip, key);
}
};
/**
* Parse known peers.
* @param {String} text
* @returns {Object}
*/
AuthDB.prototype.readAuth = co(function* readAuth() {
var file, text;
if (fs.unsupported)
return;
if (!this.prefix)
return;
file = this.prefix + '/authorized-peers';
try {
text = yield fs.readFile(file, 'utf8');
} catch (e) {
if (e.code === 'ENOENT')
return;
throw e;
}
this.parseAuth(text);
});
/**
* Parse authorized peers.
* @param {String} text
* @returns {Buffer[]} keys
*/
AuthDB.prototype.parseAuth = function parseAuth(text) {
var lines = text.split(/\n+/);
var i, line, key;
for (i = 0; i < lines.length; i++) {
line = lines[i].trim();
if (line.length === 0)
continue;
if (/^\s*#/.test(line))
continue;
key = new Buffer(line, 'hex');
if (key.length !== 33)
throw new Error('Invalid key: ' + line);
this.addAuthorized(key);
}
};
/*
* Expose
*/

View File

@ -7,7 +7,6 @@
'use strict';
var assert = require('assert');
var fs = require('fs');
var util = require('../utils/util');
var IP = require('../utils/ip');
var co = require('../utils/co');
@ -20,6 +19,7 @@ var common = require('./common');
var seeds = require('./seeds');
var dns = require('./dns');
var Logger = require('../node/logger');
var fs = require('../utils/fs');
/**
* Host List
@ -195,7 +195,7 @@ HostList.prototype.close = co(function* close() {
*/
HostList.prototype.start = function start() {
if (!this.options.hostLocation)
if (!this.options.location)
return;
assert(this.timer == null);
@ -207,7 +207,7 @@ HostList.prototype.start = function start() {
*/
HostList.prototype.stop = function stop() {
if (!this.options.hostLocation)
if (!this.options.location)
return;
assert(this.timer != null);
@ -249,14 +249,17 @@ HostList.prototype.injectSeeds = function injectSeeds() {
*/
HostList.prototype.loadFile = co(function* loadFile() {
var filename = this.options.hostLocation;
var filename = this.options.location;
var data, json;
if (fs.unsupported)
return;
if (!filename)
return;
try {
data = yield readFile(filename, 'utf8');
data = yield fs.readFile(filename, 'utf8');
} catch (e) {
if (e.code === 'ENOENT')
return;
@ -275,9 +278,12 @@ HostList.prototype.loadFile = co(function* loadFile() {
*/
HostList.prototype.flush = co(function* flush() {
var filename = this.options.hostLocation;
var filename = this.options.location;
var json, data;
if (fs.unsupported)
return;
if (!filename)
return;
@ -287,7 +293,7 @@ HostList.prototype.flush = co(function* flush() {
data = JSON.stringify(json);
try {
yield writeFile(filename, data, 'utf8');
yield fs.writeFile(filename, data, 'utf8');
} catch (e) {
this.logger.warning('Writing hosts failed.');
this.logger.error(e);
@ -1473,7 +1479,8 @@ function HostListOptions(options) {
this.maxBuckets = 20;
this.maxEntries = 50;
this.hostLocation = null;
this.prefix = null;
this.location = null;
this.flushInterval = 120000;
if (options)
@ -1569,9 +1576,15 @@ HostListOptions.prototype.fromOptions = function fromOptions(options) {
this.maxEntries = options.maxEntries;
}
if (options.hostLocation != null) {
assert(typeof options.hostLocation === 'string');
this.hostLocation = options.hostLocation;
if (options.prefix != null) {
assert(typeof options.prefix === 'string');
this.prefix = options.prefix;
this.location = this.prefix + '/hosts.json';
}
if (options.location != null) {
assert(typeof options.location === 'string');
this.location = options.location;
}
if (options.flushInterval != null) {
@ -1585,33 +1598,6 @@ HostListOptions.prototype.fromOptions = function fromOptions(options) {
return this;
};
/*
* Helpers
*/
function readFile(filename, enc) {
return new Promise(function(resolve, reject) {
var err;
if (fs.unsupported) {
err = new Error('File not found.');
err.code = 'ENOENT';
return reject(err);
}
fs.readFile(filename, enc, co.wrap(resolve, reject));
});
}
function writeFile(filename, data, enc) {
return new Promise(function(resolve, reject) {
if (fs.unsupported)
return resolve();
fs.writeFile(filename, data, enc, co.wrap(resolve, reject));
});
}
/*
* Expose
*/

View File

@ -221,8 +221,6 @@ Pool.prototype._open = co(function* _open() {
else
yield this.chain.open();
yield this.hosts.open();
this.logger.info('Pool loaded (maxpeers=%d).', this.options.maxOutbound);
if (this.options.bip150) {
@ -3727,6 +3725,7 @@ function PoolOptions(options) {
this.nonces = new NonceList();
this.prefix = null;
this.checkpoints = true;
this.spv = false;
this.bip37 = false;
@ -3799,6 +3798,11 @@ PoolOptions.prototype.fromOptions = function fromOptions(options) {
this.mempool = options.mempool;
}
if (options.prefix != null) {
assert(typeof options.prefix === 'string');
this.prefix = options.prefix;
}
if (options.checkpoints != null) {
assert(typeof options.checkpoints === 'boolean');
assert(options.checkpoints === this.chain.options.checkpoints);

File diff suppressed because it is too large Load Diff

View File

@ -50,16 +50,16 @@ function FullNode(options) {
this.chain = new Chain({
network: this.network,
logger: this.logger,
db: this.options.db,
location: this.location('chain'),
maxFiles: this.options.maxFiles,
cacheSize: this.options.cacheSize,
forceWitness: this.options.forceWitness,
prune: this.options.prune,
checkpoints: this.options.checkpoints,
coinCache: this.options.coinCache,
indexTX: this.options.indexTX,
indexAddress: this.options.indexAddress
db: this.config.str('db'),
prefix: this.config.prefix,
maxFiles: this.config.num('max-files'),
cacheSize: this.config.mb('cache-size'),
forceWitness: this.config.bool('force-witness'),
prune: this.config.bool('prune'),
checkpoints: this.config.bool('checkpoints'),
coinCache: this.config.mb('coin-cache'),
indexTX: this.config.bool('index-tx'),
indexAddress: this.config.bool('index-address')
});
// Fee estimation.
@ -72,16 +72,16 @@ function FullNode(options) {
logger: this.logger,
chain: this.chain,
fees: this.fees,
db: this.options.db,
location: this.location('mempool'),
persistent: this.options.persistentMempool,
maxSize: this.options.mempoolSize,
limitFree: this.options.limitFree,
limitFreeRelay: this.options.limitFreeRelay,
requireStandard: this.options.requireStandard,
rejectInsaneFees: this.options.rejectInsaneFees,
replaceByFee: this.options.replaceByFee,
indexAddress: this.options.indexAddress
db: this.config.str('db'),
prefix: this.config.prefix,
persistent: this.config.bool('persistent-mempool'),
maxSize: this.config.num('mempool-size'),
limitFree: this.config.bool('limit-free'),
limitFreeRelay: this.config.num('limit-free-relay'),
requireStandard: this.config.bool('require-standard'),
rejectAbsurdFees: this.config.bool('reject-absurd-fees'),
replaceByFee: this.config.bool('replace-by-fee'),
indexAddress: this.config.bool('index-address')
});
// Pool needs access to the chain and mempool.
@ -90,26 +90,25 @@ function FullNode(options) {
logger: this.logger,
chain: this.chain,
mempool: this.mempool,
selfish: this.options.selfish,
compact: this.options.compact,
bip37: this.options.bip37,
bip151: this.options.bip151,
bip150: this.options.bip150,
authPeers: this.options.authPeers,
knownPeers: this.options.knownPeers,
identityKey: this.options.identityKey,
maxOutbound: this.options.maxOutbound,
maxInbound: this.options.maxInbound,
proxy: this.options.proxy,
onion: this.options.onion,
upnp: this.options.upnp,
seeds: this.options.seeds,
nodes: this.options.nodes,
publicHost: this.options.publicHost,
publicPort: this.options.publicPort,
host: this.options.host,
port: this.options.port,
listen: this.options.listen
prefix: this.config.prefix,
selfish: this.config.bool('selfish'),
compact: this.config.bool('compact'),
bip37: this.config.bool('bip37'),
bip151: this.config.bool('bip151'),
bip150: this.config.bool('bip150'),
identityKey: this.config.buf('identity-key'),
maxOutbound: this.config.num('max-outbound'),
maxInbound: this.config.num('max-inbound'),
proxy: this.config.str('proxy'),
onion: this.config.bool('onion'),
upnp: this.config.bool('upnp'),
seeds: this.config.list('seeds'),
nodes: this.config.list('nodes'),
publicHost: this.config.str('public-host'),
publicPort: this.config.num('public-port'),
host: this.config.str('host'),
port: this.config.num('port'),
listen: this.config.bool('listen')
});
// Miner needs access to the chain and mempool.
@ -119,12 +118,12 @@ function FullNode(options) {
chain: this.chain,
mempool: this.mempool,
fees: this.fees,
address: this.options.payoutAddress,
coinbaseFlags: this.options.coinbaseFlags,
preverify: this.options.preverify,
maxWeight: this.options.maxBlockWeight,
reservedWeight: this.options.reservedBlockWeight,
reservedSigops: this.options.reservedBlockSigops
address: this.config.list('payout-address'),
coinbaseFlags: this.config.str('coinbase-flags'),
preverify: this.config.bool('preverify'),
maxWeight: this.config.num('max-weight'),
reservedWeight: this.config.num('reserved-weight'),
reservedSigops: this.config.num('reserved-sigops')
});
// Wallet database needs access to fees.
@ -132,14 +131,14 @@ function FullNode(options) {
network: this.network,
logger: this.logger,
client: this.client,
db: this.options.db,
location: this.location('walletdb'),
maxFiles: this.options.walletMaxFiles,
cacheSize: this.options.walletCacheSize,
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.options.checkpoints,
startHeight: this.options.startHeight,
wipeNoReally: this.options.wipeNoReally,
checkpoints: this.config.bool('checkpoints'),
startHeight: this.config.num('start-height'),
wipeNoReally: this.config.bool('wipe-no-really'),
verify: false
});
@ -149,14 +148,16 @@ function FullNode(options) {
network: this.network,
logger: this.logger,
node: this,
key: this.options.sslKey,
cert: this.options.sslCert,
port: this.options.httpPort,
host: this.options.httpHost,
apiKey: this.options.apiKey,
serviceKey: this.options.serviceKey,
walletAuth: this.options.walletAuth,
noAuth: this.options.noAuth
prefix: this.config.prefix,
ssl: this.config.bool('ssl'),
keyFile: this.config.path('ssl-key'),
certFile: this.config.path('ssl-cert'),
host: this.config.str('http-host'),
port: this.config.num('http-port'),
apiKey: this.config.str('api-key'),
serviceKey: this.config.str('service-key'),
walletAuth: this.config.bool('wallet-auth'),
noAuth: this.config.bool('no-auth')
});
}

View File

@ -4,7 +4,7 @@
* @module node
*/
exports.config = require('./config');
exports.Config = require('./config');
exports.FullNode = require('./fullnode');
exports.Logger = require('./logger');
exports.Node = require('./node');

View File

@ -7,8 +7,9 @@
'use strict';
var assert = require('assert');
var fs = require('fs');
var fs = require('../utils/fs');
var util = require('../utils/util');
var co = require('../utils/co');
/**
* Basic stdout and file logger.
@ -28,8 +29,6 @@ function Logger(options) {
this.console = true;
this.filename = null;
this.stream = null;
this.closed = false;
this.lastFail = 0;
this.init(options);
}
@ -119,39 +118,84 @@ Logger.prototype.init = function init(options) {
assert(typeof options.filename === 'string', 'Bad file.');
this.filename = options.filename;
}
if (options.stream != null) {
assert(typeof options.stream === 'object', 'Bad stream.');
assert(typeof options.stream.write === 'function', 'Bad stream.');
this.stream = options.stream;
}
};
/**
* Open the logger.
*/
Logger.prototype.open = function open() {
this.closed = false;
if (this.stream)
this.stream.open();
};
Logger.prototype.open = co(function* open() {
if (fs.unsupported)
return;
if (!this.filename)
return;
this.stream = yield openStream(this.filename);
this.stream.once('error', this.handleError.bind(this));
});
/**
* Destroy the write stream.
*/
Logger.prototype.close = function close() {
if (!this.stream)
return;
Logger.prototype.close = co(function* close() {
if (this.timer != null) {
co.clearTimeout(this.timer);
this.timer = null;
}
if (this.stream) {
yield closeStream(this.stream);
this.stream = null;
}
});
/**
* Handle write stream error.
* @param {Error} err
*/
Logger.prototype.handleError = function handleError(err) {
try {
this.stream.close();
} catch (e) {
;
}
this.closed = true;
this.stream = null;
this.retry();
};
/**
* Try to reopen the logger.
* @method
* @private
* @returns {Promise}
*/
Logger.prototype.reopen = co(function* reopen() {
try {
this.stream = yield openStream(this.filename);
} catch (e) {
this.retry();
return;
}
this.stream.once('error', this.handleError.bind(this));
});
/**
* Try to reopen the logger after a timeout.
* @method
* @private
* @returns {Promise}
*/
Logger.prototype.retry = function* retry() {
this.timer = co.setTimeout(function() {
this.timer = null;
this.reopen();
}, 10000, this);
};
/**
@ -338,60 +382,6 @@ Logger.prototype.writeConsole = function writeConsole(level, args) {
: process.stdout.write(msg + '\n');
};
/**
* Create or get the current file stream.
* @returns {Object}
*/
Logger.prototype.getStream = function getStream() {
var self = this;
if (this.closed)
return;
if (this.stream)
return this.stream;
if (!this.filename)
return;
if (fs.unsupported)
return;
if (this.lastFail > util.now() - 10)
return;
this.lastFail = 0;
try {
util.mkdir(this.filename, true);
} catch (e) {
this.writeConsole(Logger.levels.WARNING,
['Could not create log directory.']);
this.writeConsole(Logger.levels.ERROR, [e.message]);
this.lastFail = util.now();
return;
}
this.stream = fs.createWriteStream(this.filename, { flags: 'a' });
this.stream.on('error', function(err) {
self.writeConsole(Logger.levels.WARNING,
['Log file stream died!']);
self.writeConsole(Logger.levels.ERROR, [err.message]);
try {
self.stream.close();
} catch (e) {
;
}
// Retry in ten seconds.
self.stream = null;
self.lastFail = util.now();
});
};
/**
* Write a string to the output stream (usually a file).
* @param {String} level
@ -400,7 +390,7 @@ Logger.prototype.getStream = function getStream() {
Logger.prototype.writeStream = function writeStream(level, args) {
var name = Logger.levelsByVal[level];
var stream = this.getStream();
var stream = this.stream;
var prefix, msg;
assert(name, 'Invalid log level.');
@ -469,6 +459,65 @@ Logger.prototype.memory = function memory() {
Logger.global = new Logger();
/*
* Helpers
*/
function openStream(filename) {
return new Promise(function(resolve, reject) {
var stream = fs.createWriteStream(filename, { flags: 'a' });
function onError(err) {
try {
stream.close();
} catch (e) {
;
}
cleanup();
reject(err);
}
function onOpen() {
cleanup();
resolve(stream);
}
function cleanup() {
stream.removeListener('error', onError);
stream.removeListener('open', onOpen);
}
stream.once('error', onError);
stream.once('open', onOpen);
});
}
function closeStream(stream) {
return new Promise(function(resolve, reject) {
function onError(err) {
cleanup();
reject(err);
}
function onClose() {
cleanup();
resolve(stream);
}
function cleanup() {
stream.removeListener('error', onError);
stream.removeListener('close', onClose);
}
stream.removeAllListeners('error');
stream.removeAllListeners('close');
stream.once('error', onError);
stream.once('close', onClose);
stream.close();
});
}
/*
* Expose
*/

View File

@ -17,6 +17,8 @@ var NodeClient = require('./nodeclient');
var workerPool = require('../workers/workerpool').pool;
var ec = require('../crypto/ec');
var native = require('../utils/native');
var fs = require('../utils/fs');
var Config = require('./config');
/**
* Base class from which every other
@ -33,11 +35,12 @@ function Node(options) {
AsyncObject.call(this);
this.options = {};
this.network = Network.primary;
this.prefix = util.HOME + '/.bcoin';
this.config = new Config(options);
this.network = Network.get(this.config.network);
this.startTime = -1;
this.bound = [];
this.plugins = {};
this.stack = [];
this.logger = new Logger();
this.chain = null;
@ -50,7 +53,7 @@ function Node(options) {
this.http = null;
this.client = null;
this.init(options);
this.init();
}
util.inherits(Node, AsyncObject);
@ -61,49 +64,20 @@ util.inherits(Node, AsyncObject);
* @param {Object} options
*/
Node.prototype.initOptions = function initOptions(options) {
if (!options)
return;
Node.prototype.initOptions = function initOptions() {
var config = this.config;
assert(typeof options === 'object');
if (config.has('logger'))
this.logger = config.obj('logger');
this.options = options;
if (config.bool('log-file'))
this.logger.setFile(this.location('debug.log'));
if (options.network != null) {
this.network = Network.get(options.network);
if (this.network !== Network.main)
this.prefix += '/' + this.network.type;
}
if (config.has('log-level'))
this.logger.setLevel(config.str('log-level'));
if (options.prefix != null) {
assert(typeof options.prefix === 'string');
this.prefix = util.normalize(options.prefix);
}
if (options.logger != null) {
assert(typeof options.logger === 'object');
this.logger = options.logger;
}
if (options.logFile != null) {
if (typeof options.logFile === 'string') {
this.logger.setFile(options.logFile);
} else {
assert(typeof options.logFile === 'boolean');
if (options.logFile)
this.logger.setFile(this.location('debug.log'));
}
}
if (options.logLevel != null) {
assert(typeof options.logLevel === 'string');
this.logger.setLevel(options.logLevel);
}
if (options.logConsole != null) {
assert(typeof options.logConsole === 'boolean');
this.logger.console = options.logConsole;
}
if (config.has('log-console'))
this.logger.console = config.bool('log-console');
};
/**
@ -112,24 +86,25 @@ Node.prototype.initOptions = function initOptions(options) {
* @param {Object} options
*/
Node.prototype.init = function init(options) {
Node.prototype.init = function init() {
var self = this;
this.initOptions(options);
this.initOptions();
this.loadPlugins();
// Local client for walletdb
this.client = new NodeClient(this);
this.on('preopen', function() {
self.handlePreopen();
this.hook('preopen', function() {
return self.handlePreopen();
});
this.on('open', function() {
self.handleOpen();
this.hook('open', function() {
return self.handleOpen();
});
this.on('close', function() {
self.handleClose();
this.hook('close', function() {
return self.handleClose();
});
};
@ -138,10 +113,11 @@ Node.prototype.init = function init(options) {
* @private
*/
Node.prototype.handlePreopen = function handlePreopen() {
Node.prototype.handlePreopen = co(function* handlePreopen() {
var self = this;
this.logger.open();
yield fs.mkdirp(this.config.prefix);
yield this.logger.open();
this.bind(this.network.time, 'offset', function(offset) {
self.logger.info('Time offset: %d (%d minutes).', offset, offset / 60 | 0);
@ -173,14 +149,14 @@ Node.prototype.handlePreopen = function handlePreopen() {
}
self.emit('error', err);
});
};
});
/**
* Open node.
* @private
*/
Node.prototype.handleOpen = function handleOpen() {
Node.prototype.handleOpen = co(function* handleOpen() {
this.startTime = util.now();
if (!ec.binding) {
@ -197,19 +173,21 @@ Node.prototype.handleOpen = function handleOpen() {
this.logger.warning('Warning: worker pool is disabled.');
this.logger.warning('Verification will be slow.');
}
};
yield this.openPlugins();
});
/**
* Close node. Unbind all events.
* @private
*/
Node.prototype.handleClose = function handleClose() {
Node.prototype.handleClose = co(function* handleClose() {
var i, bound;
this.startTime = -1;
yield this.closePlugins();
this.logger.close();
this.startTime = -1;
for (i = 0; i < this.bound.length; i++) {
bound = this.bound[i];
@ -217,7 +195,9 @@ Node.prototype.handleClose = function handleClose() {
}
this.bound.length = 0;
};
yield this.logger.close();
});
/**
* Bind to an event on `obj`, save listener for removal.
@ -269,7 +249,7 @@ Node.prototype.error = function error(err) {
*/
Node.prototype.location = function location(name) {
return this.prefix + '/' + name;
return this.config.prefix + '/' + name;
};
/**
@ -296,7 +276,7 @@ Node.prototype.openWallet = co(function* openWallet() {
options = {
id: 'primary',
passphrase: this.options.passphrase
passphrase: this.config.str('passphrase')
};
wallet = yield this.walletdb.ensure(options);
@ -314,6 +294,139 @@ Node.prototype.openWallet = co(function* openWallet() {
this.http.rpc.wallet = wallet;
});
/**
* Attach a plugin.
* @param {Object} plugin
*/
Node.prototype.use = function use(plugin) {
var instance;
assert(plugin, 'Plugin must be an object.');
assert(typeof plugin.init === 'function', '`init` must be a function.');
assert(!this.loaded, 'Cannot add plugin after node is loaded.');
instance = plugin.init(this);
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.');
// Reserved names
switch (plugin.name) {
case 'logger':
case 'chain':
case 'fees':
case 'mempool':
case 'miner':
case 'pool':
case 'walletdb':
assert(false, plugin.name + ' is already added.');
break;
}
assert(!this.plugins[plugin.name], plugin.name + ' is already added.');
this.plugins[plugin.name] = instance;
}
this.stack.push(instance);
};
/**
* Require a plugin.
* @param {String} name
* @returns {Object}
*/
Node.prototype.require = function require(name) {
var plugin;
assert(typeof name === 'string', 'Plugin name must be a string.');
switch (name) {
case 'logger':
assert(this.logger, 'logger is not loaded.');
return this.logger;
case 'chain':
assert(this.chain, 'chain is not loaded.');
return this.chain;
case 'fees':
assert(this.fees, 'fees is not loaded.');
return this.fees;
case 'mempool':
assert(this.mempool, 'mempool is not loaded.');
return this.mempool;
case 'miner':
assert(this.miner, 'miner is not loaded.');
return this.miner;
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];
assert(plugin, name + ' is not loaded.');
return plugin;
};
/**
* Load plugins.
* @private
*/
Node.prototype.loadPlugins = function loadPlugins() {
var plugins = this.config.list('plugins', []);
var loader = this.config.func('loader');
var i, name, plugin;
if (!loader)
return;
for (i = 0; i < plugins.length; i++) {
name = plugins[i];
assert(typeof name === 'string',
'Plugin name must be a string.');
plugin = loader(name);
this.use(plugin);
}
};
/**
* Open plugins.
* @private
*/
Node.prototype.openPlugins = co(function* openPlugins() {
var i, plugin;
for (i = 0; i < this.stack.length; i++) {
plugin = this.stack[i];
yield plugin.open();
}
});
/**
* Close plugins.
* @private
*/
Node.prototype.closePlugins = co(function* closePlugins() {
var i, plugin;
for (i = 0; i < this.stack.length; i++) {
plugin = this.stack[i];
yield plugin.close();
}
});
/*
* Expose
*/

View File

@ -47,12 +47,12 @@ function SPVNode(options) {
this.chain = new Chain({
network: this.network,
logger: this.logger,
db: this.options.db,
location: this.location('spvchain'),
maxFiles: this.options.maxFiles,
cacheSize: this.options.cacheSize,
forceWitness: this.options.forceWitness,
checkpoints: this.options.checkpoints,
db: this.config.str('db'),
prefix: this.config.prefix,
maxFiles: this.config.num('max-files'),
cacheSize: this.config.mb('cache-size'),
forceWitness: this.config.bool('force-witness'),
checkpoints: this.config.bool('checkpoints'),
spv: true
});
@ -60,17 +60,16 @@ function SPVNode(options) {
network: this.network,
logger: this.logger,
chain: this.chain,
proxy: this.options.proxy,
onion: this.options.onion,
upnp: this.options.upnp,
seeds: this.options.seeds,
nodes: this.options.nodes,
bip151: this.options.bip151,
bip150: this.options.bip150,
authPeers: this.options.authPeers,
knownPeers: this.options.knownPeers,
identityKey: this.options.identityKey,
maxOutbound: this.options.maxOutbound,
prefix: this.config.prefix,
proxy: this.config.str('proxy'),
onion: this.config.bool('onion'),
upnp: this.config.bool('upnp'),
seeds: this.config.list('seeds'),
nodes: this.config.list('nodes'),
bip151: this.config.bool('bip151'),
bip150: this.config.bool('bip150'),
identityKey: this.config.buf('identity-key'),
maxOutbound: this.config.num('max-outbound'),
selfish: true,
listen: false
});
@ -79,14 +78,14 @@ function SPVNode(options) {
network: this.network,
logger: this.logger,
client: this.client,
db: this.options.db,
location: this.location('walletdb'),
maxFiles: this.options.walletMaxFiles,
cacheSize: this.options.walletCacheSize,
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.options.checkpoints,
startHeight: this.options.startHeight,
wipeNoReally: this.options.wipeNoReally,
checkpoints: this.config.bool('checkpoints'),
startHeight: this.config.num('start-height'),
wipeNoReally: this.config.bool('wipe-no-really'),
verify: true,
spv: true
});
@ -96,14 +95,16 @@ function SPVNode(options) {
network: this.network,
logger: this.logger,
node: this,
key: this.options.sslKey,
cert: this.options.sslCert,
port: this.options.httpPort,
host: this.options.httpHost,
apiKey: this.options.apiKey,
serviceKey: this.options.serviceKey,
walletAuth: this.options.walletAuth,
noAuth: this.options.noAuth
prefix: this.config.prefix,
ssl: this.config.bool('ssl'),
keyFile: this.config.path('ssl-key'),
certFile: this.config.path('ssl-cert'),
host: this.config.str('host'),
port: this.config.num('port'),
apiKey: this.config.str('api-key'),
serviceKey: this.config.str('service-key'),
walletAuth: this.config.bool('wallet-auth'),
noAuth: this.config.bool('no-auth')
});
}

View File

@ -19,3 +19,12 @@ exports.version = 'v1.0.0-beta.9';
*/
exports.url = 'https://github.com/bcoin-org/bcoin';
/**
* Default prefix.
* @const {String}
*/
exports.prefix = process.platform === 'win32'
? 'C:/Temp/.bcoin'
: '/tmp/.bcoin';

View File

@ -63,7 +63,7 @@ AsyncObject.prototype.__open = co(function* open() {
if (this.loaded)
return;
this.emit('preopen');
yield this.fire('preopen');
this.loading = true;
@ -78,7 +78,7 @@ AsyncObject.prototype.__open = co(function* open() {
this.loading = false;
this.loaded = true;
this.emit('open');
yield this.fire('open');
});
/**
@ -107,7 +107,7 @@ AsyncObject.prototype.__close = co(function* close() {
if (!this.loaded)
return;
this.emit('preclose');
yield this.fire('preclose');
this.closing = true;
@ -122,7 +122,7 @@ AsyncObject.prototype.__close = co(function* close() {
this.closing = false;
this.loaded = false;
this.emit('close');
yield this.fire('close');
});
/**

View File

@ -11,7 +11,6 @@
var assert = require('assert');
var nodeUtil = require('util');
var fs = require('fs');
var os = require('os');
var Number, Math, Date;
@ -983,81 +982,6 @@ util.normalize = function normalize(path, dirname) {
return parts.join('/');
};
/**
* Create a full directory structure.
* @param {String} path
*/
util.mkdirp = function mkdirp(path) {
var i, parts, stat;
if (fs.unsupported)
return;
path = path.replace(/\\/g, '/');
path = path.replace(/(^|\/)\.\//, '$1');
path = path.replace(/\/+\.?$/, '');
parts = path.split(/\/+/);
path = '';
if (process.platform === 'win32') {
if (parts[0].indexOf(':') !== -1)
path = parts.shift() + '/';
}
if (parts.length > 0) {
if (parts[0].length === 0) {
parts.shift();
path = '/';
}
}
for (i = 0; i < parts.length; i++) {
path += parts[i];
try {
stat = fs.statSync(path);
if (!stat.isDirectory())
throw new Error('Could not create directory.');
} catch (e) {
if (e.code === 'ENOENT')
fs.mkdirSync(path, 488 /* 0750 */);
else
throw e;
}
path += '/';
}
};
/**
* Ensure a directory.
* @param {String} path
* @param {Boolean?} dirname
*/
util.mkdir = function mkdir(path, dirname) {
if (util.isBrowser)
return;
path = util.normalize(path, dirname);
if (util._paths[path])
return;
util._paths[path] = true;
return util.mkdirp(path);
};
/**
* Cached mkdirp paths.
* @private
* @type {Object}
*/
util._paths = {};
/**
* Ensure hidden-class mode for object.
* @param {Object} obj

View File

@ -2171,6 +2171,7 @@ function WalletOptions(options) {
this.logger = Logger.global;
this.client = null;
this.prefix = null;
this.location = null;
this.db = 'memory';
this.maxFiles = 64;
@ -2212,6 +2213,12 @@ WalletOptions.prototype.fromOptions = function fromOptions(options) {
this.client = options.client;
}
if (options.prefix != null) {
assert(typeof options.prefix === 'string');
this.prefix = options.prefix;
this.location = this.prefix + '/walletdb';
}
if (options.location != null) {
assert(typeof options.location === 'string');
this.location = options.location;