node/config: refactor config and options.
This commit is contained in:
parent
667b0e746d
commit
a81733a720
188
bin/cli
188
bin/cli
@ -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()) {
|
||||
|
||||
23
bin/node
23
bin/node
@ -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();
|
||||
|
||||
25
bin/spvnode
25
bin/spvnode
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
*/
|
||||
|
||||
@ -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
|
||||
*/
|
||||
|
||||
@ -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);
|
||||
|
||||
1043
lib/node/config.js
1043
lib/node/config.js
File diff suppressed because it is too large
Load Diff
@ -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')
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -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');
|
||||
|
||||
@ -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
|
||||
*/
|
||||
|
||||
237
lib/node/node.js
237
lib/node/node.js
@ -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
|
||||
*/
|
||||
|
||||
@ -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')
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -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';
|
||||
|
||||
@ -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');
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user