env: refactor how default instances work.

This commit is contained in:
Christopher Jeffrey 2016-10-01 20:52:29 -07:00
parent 960393a53f
commit 376d6303b7
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
17 changed files with 135 additions and 154 deletions

View File

@ -146,7 +146,7 @@ function Environment() {
this.require('stack', './script/stack');
this.require('witness', './script/witness');
this.require('program', './script/program');
this.require('sc', './script/sigcache');
this.require('sigcache', './script/sigcache');
// Primitives
this.require('address', './primitives/address');
@ -176,7 +176,7 @@ function Environment() {
this.require('fullnode', './node/fullnode');
// Net
this.require('timedata', './net/timedata');
this.require('time', './net/timedata');
this.require('packets', './net/packets');
this.require('bip150', './net/bip150');
this.require('bip151', './net/bip151');
@ -217,23 +217,8 @@ function Environment() {
this.require('bip70', './bip70/bip70');
// Global Instances
this.instance('sigcache', 'sc', 0);
this.instance('time', 'timedata');
this.instance('defaultLogger', 'logger', 'none');
this.instance('workerPool', 'workers');
// Global Worker Properties
this.useWorkers = false;
this.master = null;
// Initialize the environment.
this.set({
network: process.env.BCOIN_NETWORK || 'main',
useWorkers: +process.env.BCOIN_USE_WORKERS === 1,
maxWorkers: +process.env.BCOIN_MAX_WORKERS,
workerTimeout: +process.env.BCOIN_WORKER_TIMEOUT,
sigcacheSize: +process.env.BCOIN_SIGCACHE_SIZE
});
this.expose('defaultLogger', 'logger', 'global');
this.expose('workerPool', 'workers', 'global');
}
/**
@ -267,22 +252,6 @@ Environment.prototype.expose = function expose(key, object, property) {
});
};
/**
* Assign an object instance for a lazily assigned property.
* @param {String} key
* @param {String} object
* @param {String} property
*/
Environment.prototype.instance = function instance(key, object, arg) {
var cache;
this.__defineGetter__(key, function() {
if (!cache)
cache = new this[object](arg);
return cache;
});
};
/**
* Set the default network.
* @param {String} options
@ -298,21 +267,9 @@ Environment.prototype.set = function set(options) {
if (options.network)
this.network.set(options.network);
if (typeof options.useWorkers === 'boolean')
this.useWorkers = options.useWorkers;
this.workers.set(options);
if (utils.isNumber(options.maxWorkers))
this.workerPool.size = options.maxWorkers;
if (utils.isNumber(options.workerTimeout))
this.workerPool.timeout = options.workerTimeout;
if (utils.isBrowser && this.useWorkers) {
this.useWorkers = typeof global.Worker === 'function'
|| typeof global.postMessage === 'function';
}
if (utils.isNumber(options.sigcacheSize))
if (options.sigcacheSize != null)
this.sigcache.resize(options.sigcacheSize);
return this;

View File

@ -113,7 +113,7 @@ Miner.prototype._init = function _init() {
stat.best);
});
if (bcoin.useWorkers) {
if (bcoin.workers.enabled) {
this.workerPool = new bcoin.workers({
size: 1,
timeout: -1

View File

@ -112,4 +112,4 @@ function compare(a, b) {
* Expose
*/
module.exports = TimeData;
module.exports = new TimeData();

View File

@ -349,6 +349,12 @@ Logger.prototype.memory = function memory() {
utils.mb(mem.rss - mem.heapTotal));
};
/*
* Default
*/
Logger.global = new Logger('none');
/*
* Expose
*/

View File

@ -7,16 +7,15 @@
'use strict';
var bcoin = require('../env');
var networks = bcoin.networks;
var constants = bcoin.constants;
var Network = require('../protocol/network');
var networks = require('../protocol/networks');
var constants = require('../protocol/constants');
var utils = require('../utils/utils');
var crypto = require('../crypto/crypto');
var assert = utils.assert;
var BufferWriter = require('../utils/writer');
var BufferReader = require('../utils/reader');
var Script = bcoin.script;
var scriptTypes = constants.scriptTypes;
var Script = require('../script/script');
/**
* Represents an address.
@ -39,9 +38,9 @@ function Address(options) {
return new Address(options);
this.hash = constants.ZERO_HASH160;
this.type = scriptTypes.PUBKEYHASH;
this.type = Script.types.PUBKEYHASH;
this.version = -1;
this.network = bcoin.network.get();
this.network = Network.primary;
if (options)
this.fromOptions(options);
@ -113,7 +112,7 @@ Address.prototype.toRaw = function toRaw(network) {
if (!network)
network = this.network;
network = bcoin.network.get(network);
network = Network.get(network);
prefix = Address.getPrefix(this.type, network);
assert(prefix !== -1, 'Not a valid address prefix.');
@ -258,42 +257,42 @@ Address.fromBase58 = function fromBase58(address) {
Address.prototype.fromScript = function fromScript(script) {
if (script.isPubkey()) {
this.hash = crypto.hash160(script.get(0));
this.type = scriptTypes.PUBKEYHASH;
this.type = Script.types.PUBKEYHASH;
this.version = -1;
return this;
}
if (script.isPubkeyhash()) {
this.hash = script.get(2);
this.type = scriptTypes.PUBKEYHASH;
this.type = Script.types.PUBKEYHASH;
this.version = -1;
return this;
}
if (script.isScripthash()) {
this.hash = script.get(1);
this.type = scriptTypes.SCRIPTHASH;
this.type = Script.types.SCRIPTHASH;
this.version = -1;
return this;
}
if (script.isWitnessPubkeyhash()) {
this.hash = script.get(1);
this.type = scriptTypes.WITNESSPUBKEYHASH;
this.type = Script.types.WITNESSPUBKEYHASH;
this.version = 0;
return this;
}
if (script.isWitnessScripthash()) {
this.hash = script.get(1);
this.type = scriptTypes.WITNESSSCRIPTHASH;
this.type = Script.types.WITNESSSCRIPTHASH;
this.version = 0;
return this;
}
if (script.isWitnessMasthash()) {
this.hash = script.get(1);
this.type = scriptTypes.WITNESSSCRIPTHASH;
this.type = Script.types.WITNESSSCRIPTHASH;
this.version = 1;
return this;
}
@ -301,7 +300,7 @@ Address.prototype.fromScript = function fromScript(script) {
// Put this last: it's the slowest to check.
if (script.isMultisig()) {
this.hash = script.hash160();
this.type = scriptTypes.SCRIPTHASH;
this.type = Script.types.SCRIPTHASH;
this.version = -1;
return this;
}
@ -318,14 +317,14 @@ Address.prototype.fromWitness = function fromWitness(witness) {
// since we can't get the version.
if (witness.isPubkeyhashInput()) {
this.hash = crypto.hash160(witness.get(1));
this.type = scriptTypes.WITNESSPUBKEYHASH;
this.type = Script.types.WITNESSPUBKEYHASH;
this.version = 0;
return this;
}
if (witness.isScripthashInput()) {
this.hash = crypto.sha256(witness.get(witness.length - 1));
this.type = scriptTypes.WITNESSSCRIPTHASH;
this.type = Script.types.WITNESSSCRIPTHASH;
this.version = 0;
return this;
}
@ -340,14 +339,14 @@ Address.prototype.fromWitness = function fromWitness(witness) {
Address.prototype.fromInputScript = function fromInputScript(script) {
if (script.isPubkeyhashInput()) {
this.hash = crypto.hash160(script.get(1));
this.type = scriptTypes.PUBKEYHASH;
this.type = Script.types.PUBKEYHASH;
this.version = -1;
return this;
}
if (script.isScripthashInput()) {
this.hash = crypto.hash160(script.get(script.length - 1));
this.type = scriptTypes.SCRIPTHASH;
this.type = Script.types.SCRIPTHASH;
this.version = -1;
return this;
}
@ -405,15 +404,15 @@ Address.prototype.fromHash = function fromHash(hash, type, version, network) {
hash = new Buffer(hash, 'hex');
if (typeof type === 'string')
type = scriptTypes[type.toUpperCase()];
type = Script.types[type.toUpperCase()];
if (type == null)
type = scriptTypes.PUBKEYHASH;
type = Script.types.PUBKEYHASH;
if (version == null)
version = -1;
network = bcoin.network.get(network);
network = Network.get(network);
assert(Buffer.isBuffer(hash));
assert(utils.isNumber(type));
@ -427,11 +426,11 @@ Address.prototype.fromHash = function fromHash(hash, type, version, network) {
} else {
assert(Address.isWitness(type), 'Wrong version (non-witness).');
assert(version >= 0 && version <= 16, 'Bad program version.');
if (version === 0 && type === scriptTypes.WITNESSPUBKEYHASH)
if (version === 0 && type === Script.types.WITNESSPUBKEYHASH)
assert(hash.length === 20, 'Hash is the wrong size.');
else if (version === 0 && type === scriptTypes.WITNESSSCRIPTHASH)
else if (version === 0 && type === Script.types.WITNESSSCRIPTHASH)
assert(hash.length === 32, 'Hash is the wrong size.');
else if (version === 1 && type === scriptTypes.WITNESSSCRIPTHASH)
else if (version === 1 && type === Script.types.WITNESSSCRIPTHASH)
assert(hash.length === 32, 'Hash is the wrong size.');
}
@ -468,9 +467,9 @@ Address.fromHash = function fromHash(hash, type, version, network) {
Address.prototype.fromData = function fromData(data, type, version, network) {
if (typeof type === 'string')
type = scriptTypes[type.toUpperCase()];
type = Script.types[type.toUpperCase()];
if (type === scriptTypes.WITNESSSCRIPTHASH) {
if (type === Script.types.WITNESSSCRIPTHASH) {
if (version === 0) {
assert(Buffer.isBuffer(data));
data = crypto.sha256(data);
@ -480,7 +479,7 @@ Address.prototype.fromData = function fromData(data, type, version, network) {
} else {
throw new Error('Cannot create from version=' + version);
}
} else if (type === scriptTypes.WITNESSPUBKEYHASH) {
} else if (type === Script.types.WITNESSPUBKEYHASH) {
if (version !== 0)
throw new Error('Cannot create from version=' + version);
assert(Buffer.isBuffer(data));
@ -529,7 +528,7 @@ Address.validate = function validate(address, type) {
}
if (typeof type === 'string')
type = scriptTypes[type.toUpperCase()];
type = Script.types[type.toUpperCase()];
if (type && address.type !== type)
return false;
@ -579,13 +578,13 @@ Address.getHash = function getHash(data, enc) {
Address.getPrefix = function getPrefix(type, network) {
var prefixes = network.addressPrefix;
switch (type) {
case scriptTypes.PUBKEYHASH:
case Script.types.PUBKEYHASH:
return prefixes.pubkeyhash;
case scriptTypes.SCRIPTHASH:
case Script.types.SCRIPTHASH:
return prefixes.scripthash;
case scriptTypes.WITNESSPUBKEYHASH:
case Script.types.WITNESSPUBKEYHASH:
return prefixes.witnesspubkeyhash;
case scriptTypes.WITNESSSCRIPTHASH:
case Script.types.WITNESSSCRIPTHASH:
return prefixes.witnessscripthash;
default:
return -1;
@ -603,13 +602,13 @@ Address.getType = function getType(prefix, network) {
var prefixes = network.addressPrefix;
switch (prefix) {
case prefixes.pubkeyhash:
return scriptTypes.PUBKEYHASH;
return Script.types.PUBKEYHASH;
case prefixes.scripthash:
return scriptTypes.SCRIPTHASH;
return Script.types.SCRIPTHASH;
case prefixes.witnesspubkeyhash:
return scriptTypes.WITNESSPUBKEYHASH;
return Script.types.WITNESSPUBKEYHASH;
case prefixes.witnessscripthash:
return scriptTypes.WITNESSSCRIPTHASH;
return Script.types.WITNESSSCRIPTHASH;
default:
return -1;
}
@ -623,9 +622,9 @@ Address.getType = function getType(prefix, network) {
Address.isWitness = function isWitness(type) {
switch (type) {
case scriptTypes.WITNESSPUBKEYHASH:
case Script.types.WITNESSPUBKEYHASH:
return true;
case scriptTypes.WITNESSSCRIPTHASH:
case Script.types.WITNESSSCRIPTHASH:
return true;
default:
return false;

View File

@ -395,17 +395,6 @@ MTX.prototype.scriptVector = function scriptVector(prev, vector, ring) {
*/
MTX.prototype.signInputAsync = function signInputAsync(index, key, type) {
var result;
if (!bcoin.useWorkers) {
try {
result = this.signInput(index, key, type);
} catch (e) {
return Promise.reject(e);
}
return Promise.resolve(result);
}
return bcoin.workerPool.signInput(this, index, key, type);
};
@ -914,17 +903,6 @@ MTX.prototype.sign = function sign(ring, type) {
*/
MTX.prototype.signAsync = function signAsync(ring, type) {
var result;
if (!bcoin.useWorkers) {
try {
result = this.sign(ring, type);
} catch (e) {
return Promise.reject(e);
}
return Promise.resolve(result);
}
return bcoin.workerPool.sign(this, ring, type);
};

View File

@ -714,17 +714,6 @@ TX.prototype.verifyInput = function verifyInput(index, flags) {
*/
TX.prototype.verifyAsync = function verifyAsync(flags) {
var result;
if (!bcoin.useWorkers) {
try {
result = this.verify(flags);
} catch (e) {
return Promise.reject(e);
}
return Promise.resolve(result);
}
if (this.inputs.length === 0)
return Promise.resolve(false);
@ -743,16 +732,7 @@ TX.prototype.verifyAsync = function verifyAsync(flags) {
*/
TX.prototype.verifyInputAsync = function verifyInputAsync(index, flags) {
var input, result;
if (!bcoin.useWorkers) {
try {
result = this.verifyInput(index, flags);
} catch (e) {
return Promise.reject(e);
}
return Promise.resolve(result);
}
var input;
if (typeof index === 'object')
index = this.inputs.indexOf(index);

View File

@ -54,11 +54,18 @@ function Network(options) {
/**
* Default network.
* @type {String}
* @type {Network}
*/
Network.primary = null;
/**
* Default network type.
* @type {String}
*/
Network.type = null;
/*
* Networks (to avoid hash table mode).
*/
@ -137,6 +144,7 @@ Network.create = function create(options) {
Network.set = function set(type) {
assert(typeof type === 'string', 'Bad network.');
Network.primary = Network.get(type);
Network.type = type;
return Network.primary;
};
@ -211,6 +219,12 @@ Network.isNetwork = function isNetwork(obj) {
&& typeof obj.pow === 'object';
};
/*
* Set initial network.
*/
Network.set(process.env.BCOIN_NETWORK || 'main');
/*
* Expose
*/

View File

@ -152,4 +152,4 @@ SigCacheEntry.prototype.equal = function equal(sig, key) {
* Expose
*/
module.exports = SigCache;
module.exports = new SigCache(+process.env.BCOIN_SIGCACHE_SIZE || 0);

View File

@ -6,7 +6,7 @@
'use strict';
var bcoin = require('../env');
var Network = require('../protocol/network');
var utils = require('../utils/utils');
var spawn = require('../utils/spawn');
var co = spawn.co;
@ -818,7 +818,7 @@ Account.prototype.fromRaw = function fromRaw(data) {
var p = new BufferReader(data);
var i, count, key;
this.network = bcoin.network.fromMagic(p.readU32());
this.network = Network.fromMagic(p.readU32());
this.name = p.readVarString('ascii');
this.initialized = p.readU8() === 1;
this.type = p.readU8();

View File

@ -6,7 +6,6 @@
'use strict';
var bcoin = require('../env');
var utils = require('../utils/utils');
var assert = utils.assert;
var constants = require('../protocol/constants');

View File

@ -7,9 +7,9 @@
'use strict';
var bcoin = require('../env');
var EventEmitter = require('events').EventEmitter;
var constants = require('../protocol/constants');
var Network = require('../protocol/network');
var utils = require('../utils/utils');
var Locker = require('../utils/locker');
var spawn = require('../utils/spawn');
@ -2013,7 +2013,7 @@ Wallet.prototype.fromJSON = function fromJSON(json) {
assert(json.token.length === 64);
assert(utils.isNumber(json.tokenDepth));
this.network = bcoin.network.get(json.network);
this.network = Network.get(json.network);
this.wid = json.wid;
this.id = json.id;
this.initialized = json.initialized;
@ -2055,7 +2055,7 @@ Wallet.prototype.toRaw = function toRaw(writer) {
Wallet.prototype.fromRaw = function fromRaw(data) {
var p = new BufferReader(data);
this.network = bcoin.network.fromMagic(p.readU32());
this.network = Network.fromMagic(p.readU32());
this.wid = p.readU32();
this.id = p.readVarString('ascii');
this.initialized = p.readU8() === 1;

View File

@ -7,7 +7,6 @@
'use strict';
var bcoin = require('../env');
var AsyncObject = require('../utils/async');
var utils = require('../utils/utils');
var spawn = require('../utils/spawn');
@ -17,6 +16,7 @@ var co = spawn.co;
var crypto = require('../crypto/crypto');
var assert = utils.assert;
var constants = require('../protocol/constants');
var Network = require('../protocol/network');
var BufferReader = require('../utils/reader');
var BufferWriter = require('../utils/writer');
var Path = require('./path');
@ -25,6 +25,7 @@ var Wallet = require('./wallet');
var Account = require('./account');
var ldb = require('../db/ldb');
var Bloom = require('../utils/bloom');
var Logger = require('../node/logger');
/*
* Database Layout:
@ -140,9 +141,9 @@ function WalletDB(options) {
AsyncObject.call(this);
this.options = options;
this.network = bcoin.network.get(options.network);
this.network = Network.get(options.network);
this.fees = options.fees;
this.logger = options.logger || bcoin.defaultLogger;
this.logger = options.logger || Logger.global;
this.batches = {};
this.wallets = {};

View File

@ -16,6 +16,13 @@ var bcoin = require('../env');
var jobs = exports;
/**
* Master process.
* @type {Master}
*/
jobs.master = null;
/**
* Execute tx.verify() on worker.
* @see TX#verify
@ -113,9 +120,11 @@ jobs.ecSign = function ecSign(msg, key) {
*/
jobs.mine = function mine(attempt) {
attempt.on('status', function(status) {
bcoin.master.sendEvent('status', status);
});
if (jobs.master) {
attempt.on('status', function(status) {
jobs.master.sendEvent('status', status);
});
}
return attempt.mineSync();
};

View File

@ -219,7 +219,16 @@ Workers.prototype.destroy = function destroy() {
*/
Workers.prototype.execute = function execute(method, args, timeout) {
var child;
var result, child;
if (!Workers.enabled) {
try {
result = jobs[method].apply(jobs, args);
} catch (e) {
return Promise.reject(e);
}
return Promise.resolve(result);
}
if (!timeout)
timeout = this.timeout;
@ -384,7 +393,7 @@ Worker.prototype._init = function _init() {
var penv, cp;
penv = {
BCOIN_WORKER_NETWORK: bcoin.network.get().type
BCOIN_WORKER_NETWORK: Network.type
};
if (utils.isBrowser) {
@ -812,7 +821,7 @@ Master.listen = function listen(options) {
return master.send(packet.job, 'response', [null, result]);
});
bcoin.master = master;
jobs.master = master;
return master;
};
@ -1166,6 +1175,35 @@ function fromError(err) {
return [err.message, err.stack + '', err.type];
}
/*
* Default
*/
Workers.global = new Workers();
Workers.enabled = false;
Workers.set = function set(options) {
if (typeof options.useWorkers === 'boolean')
this.enabled = options.useWorkers;
if (utils.isNumber(options.maxWorkers))
this.global.size = options.maxWorkers;
if (utils.isNumber(options.workerTimeout))
this.global.timeout = options.workerTimeout;
if (utils.isBrowser && this.enabled) {
this.enabled = typeof global.Worker === 'function'
|| typeof global.postMessage === 'function';
}
};
Workers.set({
useWorkers: +process.env.BCOIN_USE_WORKERS === 1,
maxWorkers: +process.env.BCOIN_MAX_WORKERS,
workerTimeout: +process.env.BCOIN_WORKER_TIMEOUT
});
/*
* Expose
*/

View File

@ -34,12 +34,12 @@ describe('Chain', function() {
redeemer = bcoin.mtx();
redeemer.addOutput({
address: wallet.receiveAddress.getAddress(),
address: wallet.receive.getAddress(),
value: 25 * 1e8
});
redeemer.addOutput({
address: wallet.changeAddress.getAddress(),
address: wallet.change.getAddress(),
value: 5 * 1e8
});
@ -239,7 +239,7 @@ describe('Chain', function() {
it('should rescan for transactions', cob(function *() {
var total = 0;
var hashes = yield walletdb.getAddressHashes();
var hashes = yield walletdb.getHashes();
yield chain.db.scan(null, hashes, function(block, txs) {
total += txs.length;

View File

@ -114,7 +114,7 @@ describe('HTTP', function() {
assert(receive);
assert.equal(receive.id, 'test');
assert.equal(receive.type, 'pubkeyhash');
assert.equal(receive.change, 0);
assert.equal(receive.branch, 0);
assert(balance);
assert.equal(utils.satoshi(balance.confirmed), 0);
assert.equal(utils.satoshi(balance.unconfirmed), 201840);