From ad46d3e243e8f19ddaee468e16025c8c533d2b5f Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 24 Aug 2016 07:12:44 -0700 Subject: [PATCH] env: lazily load modules. --- bench/coin.js | 2 + bench/tx.js | 2 + bench/walletdb.js | 2 + lib/env.js | 281 ++++++++++++++++++++++++++++++++++------------ 4 files changed, 214 insertions(+), 73 deletions(-) diff --git a/bench/coin.js b/bench/coin.js index e715a11d..2009eca8 100644 --- a/bench/coin.js +++ b/bench/coin.js @@ -9,6 +9,8 @@ var scriptTypes = constants.scriptTypes; var bench = require('./bench'); var fs = require('fs'); +bcoin.cache(); + var wtx = fs.readFileSync(__dirname + '/../test/data/wtx.hex', 'utf8'); wtx = bcoin.tx.fromRaw(wtx.trim(), 'hex'); diff --git a/bench/tx.js b/bench/tx.js index 6528b3ad..d2333af4 100644 --- a/bench/tx.js +++ b/bench/tx.js @@ -9,6 +9,8 @@ var scriptTypes = constants.scriptTypes; var bench = require('./bench'); var fs = require('fs'); +bcoin.cache(); + var block = bcoin.block.fromJSON(require('../test/data/block300025.json')); var btx = block.txs[397]; diff --git a/bench/walletdb.js b/bench/walletdb.js index 772864d5..e01f0e74 100644 --- a/bench/walletdb.js +++ b/bench/walletdb.js @@ -8,6 +8,8 @@ var assert = require('assert'); var scriptTypes = constants.scriptTypes; var bench = require('./bench'); +bcoin.cache(); + var dummyInput = { prevout: { hash: constants.NULL_HASH, diff --git a/lib/env.js b/lib/env.js index aafa378c..277024ac 100644 --- a/lib/env.js +++ b/lib/env.js @@ -108,111 +108,116 @@ var global = utils.global; function Environment() { this.env = Environment; - this.bn = require('bn.js'); + + // BN + this.require('bn', 'bn.js'); // Protocol - this.constants = require('./protocol/constants'); - this.networks = require('./protocol/networks'); - this.network = require('./protocol/network'); + this.require('constants', './protocol/constants'); + this.require('networks', './protocol/networks'); + this.require('network', './protocol/network'); // Utils - this.utils = require('./utils/utils'); - this.locker = require('./utils/locker'); - this.reader = require('./utils/reader'); - this.writer = require('./utils/writer'); - this.lru = require('./utils/lru'); - this.uri = require('./utils/uri'); - this.errors = require('./utils/errors'); + this.require('utils', './utils/utils'); + this.require('locker', './utils/locker'); + this.require('reader', './utils/reader'); + this.require('writer', './utils/writer'); + this.require('lru', './utils/lru'); + this.require('uri', './utils/uri'); + this.require('errors', './utils/errors'); // Crypto - this.ec = require('./crypto/ec'); - this.crypto = require('./crypto/crypto'); - this.chachapoly = require('./crypto/chachapoly'); - this.scrypt = require('./crypto/scrypt'); - this.siphash = require('./crypto/siphash'); + this.require('ec', './crypto/ec'); + this.require('crypto', './crypto/crypto'); + this.require('chachapoly', './crypto/chachapoly'); + this.require('scrypt', './crypto/scrypt'); + this.require('siphash', './crypto/siphash'); // DB - this.lowlevelup = require('./db/lowlevelup'); - this.ldb = require('./db/ldb'); - this.rbt = require('./db/rbt'); + this.require('lowlevelup', './db/lowlevelup'); + this.require('ldb', './db/ldb'); + this.require('rbt', './db/rbt'); // Script - this.script = require('./script/script'); - this.opcode = require('./script/opcode'); - this.stack = require('./script/stack'); - this.witness = require('./script/witness'); - this.program = require('./script/program'); - this.sc = require('./script/sigcache'); + this.require('script', './script/script'); + this.require('opcode', './script/opcode'); + this.require('stack', './script/stack'); + this.require('witness', './script/witness'); + this.require('program', './script/program'); + this.require('sc', './script/sigcache'); // Primitives - this.bloom = require('./primitives/bloom'); - this.address = require('./primitives/address'); - this.outpoint = require('./primitives/outpoint'); - this.input = require('./primitives/input'); - this.output = require('./primitives/output'); - this.coin = require('./primitives/coin'); - this.invitem = require('./primitives/invitem'); - this.tx = require('./primitives/tx'); - this.mtx = require('./primitives/mtx'); - this.abstractblock = require('./primitives/abstractblock'); - this.memblock = require('./primitives/memblock'); - this.block = require('./primitives/block'); - this.merkleblock = require('./primitives/merkleblock'); - this.headers = require('./primitives/headers'); - this.keyring = require('./primitives/keyring'); + this.require('bloom', './primitives/bloom'); + this.require('address', './primitives/address'); + this.require('outpoint', './primitives/outpoint'); + this.require('input', './primitives/input'); + this.require('output', './primitives/output'); + this.require('coin', './primitives/coin'); + this.require('invitem', './primitives/invitem'); + this.require('tx', './primitives/tx'); + this.require('mtx', './primitives/mtx'); + this.require('abstractblock', './primitives/abstractblock'); + this.require('memblock', './primitives/memblock'); + this.require('block', './primitives/block'); + this.require('merkleblock', './primitives/merkleblock'); + this.require('headers', './primitives/headers'); + this.require('keyring', './primitives/keyring'); // HD - this.hd = require('./hd/hd'); + this.require('hd', './hd/hd'); // Node - this.logger = require('./node/logger'); - this.config = require('./node/config'); - this.node = require('./node/node'); - this.spvnode = require('./node/spvnode'); - this.fullnode = require('./node/fullnode'); + this.require('logger', './node/logger'); + this.require('config', './node/config'); + this.require('node', './node/node'); + this.require('spvnode', './node/spvnode'); + this.require('fullnode', './node/fullnode'); // Net - this.timedata = require('./net/timedata'); - this.packets = require('./net/packets'); - this.bip150 = require('./net/bip150'); - this.bip151 = require('./net/bip151'); - this.bip152 = require('./net/bip152'); - this.peer = require('./net/peer'); - this.pool = require('./net/pool'); + this.require('timedata', './net/timedata'); + this.require('packets', './net/packets'); + this.require('bip150', './net/bip150'); + this.require('bip151', './net/bip151'); + this.require('bip152', './net/bip152'); + this.require('peer', './net/peer'); + this.require('pool', './net/pool'); // Chain - this.coins = require('./chain/coins'); - this.coinview = require('./chain/coinview'); - this.chainentry = require('./chain/chainentry'); - this.chaindb = require('./chain/chaindb'); - this.chain = require('./chain/chain'); + this.require('coins', './chain/coins'); + this.require('coinview', './chain/coinview'); + this.require('chainentry', './chain/chainentry'); + this.require('chaindb', './chain/chaindb'); + this.require('chain', './chain/chain'); // Mempool - this.fees = require('./mempool/fees'); - this.mempool = require('./mempool/mempool'); - this.mempoolentry = this.mempool.MempoolEntry; + this.require('fees', './mempool/fees'); + this.require('mempool', './mempool/mempool'); + this.expose('mempoolentry', 'mempool', 'MempoolEntry'); // Miner - this.miner = require('./miner/miner'); - this.minerblock = require('./miner/minerblock'); + this.require('miner', './miner/miner'); + this.require('minerblock', './miner/minerblock'); // Wallet - this.wallet = require('./wallet/wallet'); - this.account = require('./wallet/account'); - this.walletdb = require('./wallet/walletdb'); - this.path = require('./wallet/path'); + this.require('wallet', './wallet/wallet'); + this.require('account', './wallet/account'); + this.require('walletdb', './wallet/walletdb'); + this.require('path', './wallet/path'); // HTTP - this.http = require('./http'); + this.require('http', './http'); // Workers - this.workers = require('./workers/workers'); + this.require('workers', './workers/workers'); + + // Horrible BIP + this.require('bip70', './bip70/bip70'); // Global Instances - this.sigcache = new this.sc(0); - this.time = new this.timedata(); - this.defaultLogger = new this.logger('none'); - this.workerPool = new this.workers(); + this.instance('sigcache', 'sc', 0); + this.instance('time', 'timedata'); + this.instance('defaultLogger', 'logger', 'none'); + this.instance('workerPool', 'workers'); // Global Worker Properties this.useWorkers = false; @@ -228,6 +233,53 @@ function Environment() { }); } +/** + * Assign a lazily required module. + * @param {String} key + * @param {String} path + */ + +Environment.prototype.require = function _require(key, path) { + var cache; + this.__defineGetter__(key, function() { + if (!cache) + cache = require(path); + return cache; + }); +}; + +/** + * Assign a property for a lazily required module. + * @param {String} key + * @param {String} object + * @param {String} property + */ + +Environment.prototype.expose = function expose(key, object, property) { + var cache; + this.__defineGetter__(key, function() { + if (!cache) + cache = this[object][property]; + return cache; + }); +}; + +/** + * 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 @@ -272,12 +324,95 @@ Environment.prototype.now = function now() { return this.time.now(); }; +/** + * Cache all necessary modules. + * Used for benchmarks and browserify. + */ + +Environment.prototype.cache = function cache() { + require('bn.js'); + require('./protocol/constants'); + require('./protocol/networks'); + require('./protocol/network'); + require('./utils/utils'); + require('./utils/locker'); + require('./utils/reader'); + require('./utils/writer'); + require('./utils/lru'); + require('./utils/uri'); + require('./utils/errors'); + require('./crypto/ec'); + require('./crypto/crypto'); + require('./crypto/chachapoly'); + require('./crypto/scrypt'); + require('./crypto/siphash'); + require('./db/lowlevelup'); + require('./db/ldb'); + require('./db/rbt'); + require('./script/script'); + require('./script/opcode'); + require('./script/stack'); + require('./script/witness'); + require('./script/program'); + require('./script/sigcache'); + require('./primitives/bloom'); + require('./primitives/address'); + require('./primitives/outpoint'); + require('./primitives/input'); + require('./primitives/output'); + require('./primitives/coin'); + require('./primitives/invitem'); + require('./primitives/tx'); + require('./primitives/mtx'); + require('./primitives/abstractblock'); + require('./primitives/memblock'); + require('./primitives/block'); + require('./primitives/merkleblock'); + require('./primitives/headers'); + require('./primitives/keyring'); + require('./hd/hd'); + require('./node/logger'); + require('./node/config'); + require('./node/node'); + require('./node/spvnode'); + require('./node/fullnode'); + require('./net/timedata'); + require('./net/packets'); + require('./net/bip150'); + require('./net/bip151'); + require('./net/bip152'); + require('./net/peer'); + require('./net/pool'); + require('./chain/coins'); + require('./chain/coinview'); + require('./chain/chainentry'); + require('./chain/chaindb'); + require('./chain/chain'); + require('./mempool/fees'); + require('./mempool/mempool'); + require('./miner/miner'); + require('./miner/minerblock'); + require('./wallet/wallet'); + require('./wallet/account'); + require('./wallet/walletdb'); + require('./wallet/path'); + require('./http'); + require('./workers/workers'); + require('./bip70/bip70'); +}; + /* * Expose by converting `exports` to an * Environment. */ +exports.require = Environment.prototype.require; +exports.expose = Environment.prototype.expose; +exports.instance = Environment.prototype.instance; +exports.cache = Environment.prototype.cache; exports.set = Environment.prototype.set; exports.now = Environment.prototype.now; Environment.call(exports); + +utils.fastProp(exports);