From 5eb3946e3803c9ceccb391b54d9fc2b22866a580 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 13 May 2016 09:23:57 -0700 Subject: [PATCH] major refactor. --- bin/node | 6 +- lib/bcoin.js | 29 +---- lib/bcoin/abstractblock.js | 16 +-- lib/bcoin/address.js | 37 +++--- lib/bcoin/block.js | 18 +-- lib/bcoin/chain.js | 103 +++++++++-------- lib/bcoin/chainblock.js | 28 +++-- lib/bcoin/chaindb.js | 47 ++++---- lib/bcoin/coin.js | 9 +- lib/bcoin/coins.js | 6 +- lib/bcoin/coinview.js | 6 +- lib/bcoin/compactblock.js | 6 +- lib/bcoin/env.js | 209 +++++++++++++++++++--------------- lib/bcoin/errors.js | 10 +- lib/bcoin/fullnode.js | 17 +-- lib/bcoin/hd.js | 24 ++-- lib/bcoin/headers.js | 6 +- lib/bcoin/http/client.js | 22 ++-- lib/bcoin/http/index.js | 20 ++-- lib/bcoin/http/provider.js | 16 +-- lib/bcoin/http/server.js | 17 ++- lib/bcoin/input.js | 28 ++--- lib/bcoin/keypair.js | 26 +++-- lib/bcoin/ldb.js | 9 +- lib/bcoin/mempool.js | 27 +++-- lib/bcoin/merkleblock.js | 6 +- lib/bcoin/miner.js | 15 ++- lib/bcoin/mtx.js | 19 ++-- lib/bcoin/network.js | 111 ++++++++++++++++++ lib/bcoin/node.js | 7 +- lib/bcoin/output.js | 22 +--- lib/bcoin/peer.js | 21 ++-- lib/bcoin/pool.js | 15 ++- lib/bcoin/profiler.js | 29 +++-- lib/bcoin/protocol/framer.js | 26 +++-- lib/bcoin/protocol/index.js | 14 +-- lib/bcoin/protocol/network.js | 12 -- lib/bcoin/protocol/parser.js | 17 +-- lib/bcoin/script.js | 43 +++---- lib/bcoin/spvnode.js | 15 +-- lib/bcoin/timedata.js | 6 +- lib/bcoin/tx.js | 29 +++-- lib/bcoin/txdb.js | 21 ++-- lib/bcoin/wallet.js | 32 ++---- lib/bcoin/walletdb.js | 11 +- lib/bcoin/worker.js | 20 ++-- lib/bcoin/workers.js | 26 ++--- 47 files changed, 653 insertions(+), 606 deletions(-) create mode 100644 lib/bcoin/network.js diff --git a/bin/node b/bin/node index 98f02a08..49fa2450 100755 --- a/bin/node +++ b/bin/node @@ -1,9 +1,11 @@ #!/usr/bin/env node -var bcoin = require('../')({ debug: true, debugFile: true }); +var bcoin = require('../'); var utils = bcoin.utils; var assert = utils.assert; +bcoin.setDefaults({ debug: true, debugFile: true }); + process.on('uncaughtException', function(err) { bcoin.debug(err ? err.stack + '' : err + ''); process.exit(1); @@ -27,7 +29,7 @@ node.open(function(err) { throw err; if (node.options.mine) { - if (bcoin.protocol.network.type !== 'regtest') + if (bcoin.network.get().type !== 'regtest') node.pool.connect(); node.miner.start(); return; diff --git a/lib/bcoin.js b/lib/bcoin.js index d4e2b4be..be417fb5 100644 --- a/lib/bcoin.js +++ b/lib/bcoin.js @@ -10,7 +10,9 @@ var Environment = require('./bcoin/env'); var utils = require('./bcoin/utils'); var global = utils.global; -var env = {}; + +if (utils.isBrowser) + global.bcoin = exports; /** * Create a new Environment. Note that this will @@ -20,26 +22,5 @@ var env = {}; * @returns {Environment} */ -function BCoin(options) { - var network = 'main'; - - if (options) { - if (options.network) - network = options.network; - else if (typeof options === 'string') - network = options; - } - - if (!env[network]) - env[network] = new Environment(options); - - return env[network]; -} - -BCoin.env = Environment; -BCoin.utils = utils; - -if (utils.isBrowser) - global.bcoin = BCoin; - -module.exports = BCoin; +utils.merge(exports, Environment.prototype); +Environment.call(exports); diff --git a/lib/bcoin/abstractblock.js b/lib/bcoin/abstractblock.js index 310579b9..99dafcf5 100644 --- a/lib/bcoin/abstractblock.js +++ b/lib/bcoin/abstractblock.js @@ -5,11 +5,9 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var utils = bcoin.utils; var assert = utils.assert; -var network = bcoin.protocol.network; /** * The class which all block-like objects inherit from. @@ -133,15 +131,6 @@ AbstractBlock.prototype.verifyHeaders = function verifyHeaders(ret) { return true; }; -/** - * Test against the genesis block. - * @returns {Boolean} - */ - -AbstractBlock.prototype.isGenesis = function isGenesis() { - return this.hash('hex') === network.genesis.hash; -}; - /** * Set the `height` property and the `height` * property of all transactions within the block. @@ -164,5 +153,4 @@ AbstractBlock.prototype.__defineGetter__('rhash', function() { return utils.revHex(this.hash('hex')); }); -return AbstractBlock; -}; +module.exports = AbstractBlock; diff --git a/lib/bcoin/address.js b/lib/bcoin/address.js index 834b968d..8b7808ea 100644 --- a/lib/bcoin/address.js +++ b/lib/bcoin/address.js @@ -5,8 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var utils = bcoin.utils; var assert = utils.assert; var network = bcoin.protocol.network; @@ -230,7 +229,7 @@ Address.prototype.getProgramAddress = function getProgramAddress() { if (!this._programAddress) { hash = this.getProgramHash(); - address = Address.compileHash(hash, 'scripthash'); + address = this.compileHash(hash, 'scripthash'); this._programAddress = address; } @@ -299,10 +298,10 @@ Address.prototype.getScriptAddress = function getScriptAddress() { if (!this._scriptAddress) { if (this.witness) { hash = this.getScriptHash256(); - address = Address.compileHash(hash, 'witnessscripthash', 0); + address = this.compileHash(hash, 'witnessscripthash', 0); } else { hash = this.getScriptHash160(); - address = Address.compileHash(hash, 'scripthash'); + address = this.compileHash(hash, 'scripthash'); } this._scriptAddress = address; } @@ -336,9 +335,9 @@ Address.prototype.getKeyAddress = function getKeyAddress() { if (!this._address) { hash = this.getKeyHash(); if (this.witness) - address = Address.compileHash(hash, 'witnesspubkeyhash', 0); + address = this.compileHash(hash, 'witnesspubkeyhash', 0); else - address = Address.compileHash(hash, 'pubkeyhash'); + address = this.compileHash(hash, 'pubkeyhash'); this._address = address; } @@ -614,7 +613,7 @@ Address.sha256 = function sha256(key) { * @throws Error on bad hash/prefix. */ -Address.compileHash = function compileHash(hash, type, version) { +Address.compileHash = function compileHash(hash, type, version, network) { var p, prefix; if (!Buffer.isBuffer(hash)) @@ -623,6 +622,8 @@ Address.compileHash = function compileHash(hash, type, version) { if (!type) type = 'pubkeyhash'; + network = bcoin.network.get(network); + prefix = network.address.prefixes[type]; if (version == null) @@ -658,13 +659,13 @@ Address.compileHash = function compileHash(hash, type, version) { * @returns {Base58Address} */ -Address.compileData = function compileData(data, type, version) { +Address.compileData = function compileData(data, type, version, network) { if (type === 'witnessscripthash') data = Address.sha256(data); else data = Address.hash160(data); - return Address.compileHash(data, type, version); + return Address.compileHash(data, type, version, network); }; /** @@ -674,7 +675,7 @@ Address.compileData = function compileData(data, type, version) { * @throws Parse error */ -Address.parse = function parse(address) { +Address.parse = function parse(address, network) { var prefix, type, version, hash; if (!Buffer.isBuffer(address)) @@ -683,6 +684,8 @@ Address.parse = function parse(address) { p = new BufferReader(address, true); prefix = p.readU8(); + network = bcoin.network.get(network); + type = network.address.prefixesByVal[prefix]; version = network.address.versions[type]; @@ -734,6 +737,10 @@ Address.validate = function validate(address, type) { return true; }; +Address.prototype.compileHash = function compileHash(hash, type, version) { + return Address.compileHash(hash, type, version, this.network); +}; + /** * Convert an Address to a more json-friendly object. * @param {String?} passphrase - Address passphrase @@ -749,7 +756,7 @@ Address.prototype.toJSON = function toJSON(passphrase) { return { v: 1, name: 'address', - network: network.type, + network: this.network.type, label: this.label, change: this.change, derived: this.derived, @@ -778,9 +785,6 @@ Address.fromJSON = function fromJSON(json, passphrase) { assert.equal(json.v, 1); assert.equal(json.name, 'address'); - if (json.network) - assert.equal(json.network, network.type); - w = new Address({ label: json.label, change: json.change, @@ -798,5 +802,4 @@ Address.fromJSON = function fromJSON(json, passphrase) { return w; }; -return Address; -}; +module.exports = Address; diff --git a/lib/bcoin/block.js b/lib/bcoin/block.js index 26b50562..97e667d9 100644 --- a/lib/bcoin/block.js +++ b/lib/bcoin/block.js @@ -5,8 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var bn = require('bn.js'); var utils = require('./utils'); var assert = utils.assert; @@ -430,8 +429,8 @@ Block.prototype.getCoinbaseHeight = function getCoinbaseHeight() { * @returns {BN} reward */ -Block.prototype.getReward = function getReward() { - var reward = Block.reward(this.height); +Block.prototype.getReward = function getReward(network) { + var reward = Block.reward(this.height, network); var i; for (i = 1; i < this.txs.length; i++) @@ -457,9 +456,11 @@ Block.prototype.getClaimed = function getClaimed() { * @returns {BN} */ -Block.reward = function reward(height) { - var halvings = height / network.halvingInterval | 0; - var reward; +Block.reward = function reward(height, network) { + var halvings, reward; + + network = bcoin.network.get(network); + halvings = height / network.halvingInterval | 0; if (height < 0) return new bn(0); @@ -644,5 +645,4 @@ Block.isBlock = function isBlock(obj) { && typeof obj.toCompact === 'function'; }; -return Block; -}; +module.exports = Block; diff --git a/lib/bcoin/chain.js b/lib/bcoin/chain.js index 4a57ffe6..d92d3bfe 100644 --- a/lib/bcoin/chain.js +++ b/lib/bcoin/chain.js @@ -5,12 +5,10 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var EventEmitter = require('events').EventEmitter; var bn = require('bn.js'); var constants = bcoin.protocol.constants; -var network = bcoin.protocol.network; var utils = require('./utils'); var assert = utils.assert; var VerifyError = bcoin.errors.VerifyError; @@ -67,6 +65,7 @@ function Chain(options) { this.options = options; this.loaded = false; + this.network = bcoin.network.get(options.network); this.db = new bcoin.chaindb(this, options); this.total = 0; this.adding = false; @@ -103,7 +102,7 @@ Chain.prototype._init = function _init() { // Hook into events for debugging this.on('block', function(block, entry) { - if (self.height < network.block.slowHeight) + if (self.height < self.network.block.slowHeight) return; bcoin.debug('Block %s (%d) added to chain.', @@ -212,7 +211,7 @@ Chain.prototype._init = function _init() { if (tip.height > self.bestHeight) { self.bestHeight = tip.height; - network.height = tip.height; + self.network.updateHeight(tip.height); } bcoin.profiler.snapshot(); @@ -293,7 +292,7 @@ Chain.prototype._preload = function _preload(callback) { if (!this.options.spv) return callback(); - if (network.type !== 'main') + if (this.network.type !== 'main') return callback(); bcoin.debug('Loading %s', url); @@ -382,7 +381,7 @@ Chain.prototype._preload = function _preload(callback) { data.height = height; // Make sure the genesis block is correct. - if (data.height === 0 && data.hash !== network.genesis.hash) { + if (data.height === 0 && data.hash !== self.network.genesis.hash) { stream.destroy(); return callback(new Error('Bad genesis block.')); } @@ -456,6 +455,10 @@ Chain.prototype._verifyContext = function _verifyContext(block, prev, callback) }); }; +Chain.prototype.isGenesis = function isGenesis(block) { + return block.hash('hex') === this.network.genesis.hash; +}; + /** * Contextual verification for a block, including * version deployments (IsSuperMajority), versionbits, @@ -476,7 +479,7 @@ Chain.prototype._verify = function _verify(block, prev, callback) { return callback(new VerifyError(block, 'invalid', ret.reason, ret.score)); // Skip the genesis block. Skip all blocks in spv mode. - if (this.options.spv || block.isGenesis()) { + if (this.options.spv || this.isGenesis(block)) { return callback(null, { flags: constants.flags.MANDATORY_VERIFY_FLAGS, lockFlags: constants.flags.MANDATORY_LOCKTIME_FLAGS, @@ -649,7 +652,7 @@ Chain.prototype._checkDeployments = function _checkDeployments(block, prev, ance // Only allow version 5 blocks (bip141 - segnet3) // once the majority of blocks are using it. - if (network.segwitHeight !== -1 && height >= network.segwitHeight) { + if (this.network.segwitHeight !== -1 && height >= this.network.segwitHeight) { if (block.version < 5 && prev.isOutdated(5, ancestors)) return callback(new VerifyError(block, 'obsolete', 'bad-version', 0)); } @@ -667,7 +670,7 @@ Chain.prototype._checkDeployments = function _checkDeployments(block, prev, ance state.flags |= constants.flags.VERIFY_CHECKLOCKTIMEVERIFY; // Segregrated witness is now usable (bip141 - segnet3) - if (network.segwitHeight !== -1 && height >= network.segwitHeight) { + if (this.network.segwitHeight !== -1 && height >= this.network.segwitHeight) { if (block.version >= 5 && prev.isUpgraded(5, ancestors)) { state.flags |= constants.flags.VERIFY_WITNESS; state.segwit = true; @@ -732,20 +735,20 @@ Chain.prototype._checkDuplicates = function _checkDuplicates(block, prev, callba if (this.options.spv) return callback(); - if (block.isGenesis()) + if (this.isGenesis(block)) return callback(); - if (network.block.bip34height === -1 || height <= network.block.bip34height) + if (this.network.block.bip34height === -1 || height <= this.network.block.bip34height) return this._findDuplicates(block, prev, callback); - this.db.get(network.block.bip34height, function(err, entry) { + this.db.get(this.network.block.bip34height, function(err, entry) { if (err) return callback(err); // It was no longer possible to create duplicate // TXs once bip34 went into effect. We can check // for this to avoid a DB lookup. - if (entry && entry.hash === network.block.bip34hash) + if (entry && entry.hash === self.network.block.bip34hash) return callback(); return self._findDuplicates(block, prev, callback); @@ -818,12 +821,12 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, state, callbac if (this.options.spv) return callback(); - if (block.isGenesis()) + if (this.isGenesis(block)) return callback(); // If we are an ancestor of a checkpoint, we can // skip the input verification. - if (height <= network.checkpoints.lastHeight) { + if (height <= this.network.checkpoints.lastHeight) { if (this.options.useCheckpoints) scriptCheck = false; historical = true; @@ -906,7 +909,7 @@ Chain.prototype._checkInputs = function _checkInputs(block, prev, state, callbac } // Make sure the miner isn't trying to conjure more coins. - if (block.getClaimed().cmp(block.getReward()) > 0) { + if (block.getClaimed().cmp(block.getReward(self.network)) > 0) { return callback(new VerifyError(block, 'invalid', 'bad-cb-amount', @@ -1096,7 +1099,7 @@ Chain.prototype.disconnect = function disconnect(entry, callback) { self.height = entry.height; self.bestHeight = entry.height; - network.height = entry.height; + self.network.updateHeight(entry.height); self.emit('tip', entry); @@ -1151,7 +1154,7 @@ Chain.prototype.connect = function connect(entry, callback) { self.height = entry.height; self.bestHeight = entry.height; - network.height = entry.height; + self.network.updateHeight(entry.height); self.emit('tip', entry); @@ -1220,7 +1223,7 @@ Chain.prototype._setBestChain = function _setBestChain(entry, block, prev, callb // We don't have a genesis block yet. if (!this.tip) { - if (entry.hash !== network.genesis.hash) { + if (entry.hash !== this.network.genesis.hash) { return utils.asyncify(callback)(new VerifyError(block, 'invalid', 'bad-genblk', @@ -1405,7 +1408,7 @@ Chain.prototype.add = function add(block, callback, force) { } // Special case for genesis block. - if (block.isGenesis()) + if (self.isGenesis(block)) return done(); // Validate the block we want to add. @@ -1445,7 +1448,7 @@ Chain.prototype.add = function add(block, callback, force) { if (height > self.bestHeight) { self.bestHeight = height; - network.height = height; + self.network.height = height; } // If previous block wasn't ever seen, @@ -1462,7 +1465,7 @@ Chain.prototype.add = function add(block, callback, force) { // getblocks sync, making it an orphan). if (block.getCoinbaseHeight() > self.bestHeight) { self.bestHeight = block.getCoinbaseHeight(); - network.height = self.bestHeight; + self.network.height = self.bestHeight; } self.emit('orphan', block, { @@ -1475,7 +1478,7 @@ Chain.prototype.add = function add(block, callback, force) { } // Verify the checkpoint. - checkpoint = network.checkpoints[height]; + checkpoint = self.network.checkpoints[height]; if (checkpoint) { self.emit('checkpoint', block, { height: height, @@ -1520,6 +1523,7 @@ Chain.prototype.add = function add(block, callback, force) { try { block = block.toBlock(); } catch (e) { + utils.print(e.stack + ''); return done(new VerifyError(block, 'malformed', 'error parsing message', @@ -1837,11 +1841,11 @@ Chain.prototype.isInitial = function isInitial() { if (this.synced) return false; - if (this.height < network.checkpoints.lastHeight) + if (this.height < this.network.checkpoints.lastHeight) return true; return this.height < this.bestHeight - 24 * 6 - || this.tip.ts < utils.now() - network.block.maxTipAge; + || this.tip.ts < utils.now() - this.network.block.maxTipAge; }; /** @@ -1855,7 +1859,7 @@ Chain.prototype.getProgress = function getProgress() { if (!this.tip) return 0; - start = network.genesis.ts; + start = this.network.genesis.ts; current = this.tip.ts - start; end = utils.now() - start - 40 * 60; @@ -1922,7 +1926,7 @@ Chain.prototype.getLocator = function getLocator(start, callback, force) { step *= 2; if (height === 0) - return next(null, { hash: network.genesis.hash, height: 0 }); + return next(null, { hash: self.network.genesis.hash, height: 0 }); if (!main) return entry.getAncestorByHeight(height, next); @@ -1976,7 +1980,7 @@ Chain.prototype.getOrphanRoot = function getOrphanRoot(hash) { Chain.prototype.getCurrentTarget = function getCurrentTarget(callback) { if (!this.tip) - return callback(null, utils.toCompact(network.pow.limit)); + return callback(null, utils.toCompact(this.network.pow.limit)); return this.getTargetAsync(null, this.tip, callback); }; @@ -1991,12 +1995,12 @@ Chain.prototype.getCurrentTarget = function getCurrentTarget(callback) { Chain.prototype.getTargetAsync = function getTargetAsync(block, prev, callback) { var self = this; - if ((prev.height + 1) % network.pow.retargetInterval !== 0) { - if (!network.pow.allowMinDifficultyBlocks) + if ((prev.height + 1) % this.network.pow.retargetInterval !== 0) { + if (!this.network.pow.allowMinDifficultyBlocks) return utils.asyncify(callback)(null, this.getTarget(block, prev)); } - return prev.getAncestors(network.pow.retargetInterval, function(err, ancestors) { + return prev.getAncestors(this.network.pow.retargetInterval, function(err, ancestors) { if (err) return callback(err); @@ -2014,7 +2018,7 @@ Chain.prototype.getTargetAsync = function getTargetAsync(block, prev, callback) */ Chain.prototype.getTarget = function getTarget(block, prev, ancestors) { - var powLimit = utils.toCompact(network.pow.limit); + var powLimit = utils.toCompact(this.network.pow.limit); var ts, first, i; // Genesis @@ -2022,16 +2026,16 @@ Chain.prototype.getTarget = function getTarget(block, prev, ancestors) { return powLimit; // Do not retarget - if ((prev.height + 1) % network.pow.retargetInterval !== 0) { - if (network.pow.allowMinDifficultyBlocks) { + if ((prev.height + 1) % this.network.pow.retargetInterval !== 0) { + if (this.network.pow.allowMinDifficultyBlocks) { // Special behavior for testnet: ts = block ? (block.ts || block) : bcoin.now(); - if (ts > prev.ts + network.pow.targetSpacing * 2) + if (ts > prev.ts + this.network.pow.targetSpacing * 2) return powLimit; i = 1; while (ancestors[i] - && prev.height % network.pow.retargetInterval !== 0 + && prev.height % this.network.pow.retargetInterval !== 0 && prev.bits === powLimit) { prev = ancestors[i++]; } @@ -2040,7 +2044,7 @@ Chain.prototype.getTarget = function getTarget(block, prev, ancestors) { } // Back 2 weeks - first = ancestors[network.pow.retargetInterval - 1]; + first = ancestors[this.network.pow.retargetInterval - 1]; assert(first); @@ -2056,10 +2060,10 @@ Chain.prototype.getTarget = function getTarget(block, prev, ancestors) { */ Chain.prototype.retarget = function retarget(prev, first) { - var powTargetTimespan = new bn(network.pow.targetTimespan); + var powTargetTimespan = new bn(this.network.pow.targetTimespan); var actualTimespan, target; - if (network.pow.noRetargeting) + if (this.network.pow.noRetargeting) return prev.bits; actualTimespan = new bn(prev.ts - first.ts); @@ -2074,8 +2078,8 @@ Chain.prototype.retarget = function retarget(prev, first) { target.imul(actualTimespan); target = target.div(powTargetTimespan); - if (target.cmp(network.pow.limit) > 0) - target = network.pow.limit.clone(); + if (target.cmp(this.network.pow.limit) > 0) + target = this.network.pow.limit.clone(); return utils.toCompact(target); }; @@ -2118,7 +2122,7 @@ Chain.prototype.findLocator = function findLocator(locator, callback) { Chain.prototype.isActive = function isActive(prev, id, callback) { // Optimization for main - if (network.type === 'main' && prev.height < 400000) + if (this.network.type === 'main' && prev.height < 400000) return callback(null, false); this.getState(prev, id, function(err, state) { @@ -2141,9 +2145,9 @@ Chain.prototype.isActive = function isActive(prev, id, callback) { Chain.prototype.getState = function getState(prev, id, callback) { var self = this; - var period = network.minerConfirmationWindow; - var threshold = network.ruleChangeActivationThreshold; - var deployment = network.deployments[id]; + var period = this.network.minerConfirmationWindow; + var threshold = this.network.ruleChangeActivationThreshold; + var deployment = this.network.deployments[id]; var timeStart, timeTimeout, compute, height; if (!deployment) @@ -2294,8 +2298,8 @@ Chain.prototype.computeBlockVersion = function computeBlockVersion(prev, callbac var self = this; var version = 0; - utils.forEachSerial(Object.keys(network.deployments), function(id, next) { - var deployment = network.deployments[id]; + utils.forEachSerial(Object.keys(this.network.deployments), function(id, next) { + var deployment = self.network.deployments[id]; self.getState(prev, id, function(err, state) { if (err) return next(err); @@ -2499,5 +2503,4 @@ Chain.prototype.checkLocks = function checkLocks(prev, tx, flags, callback) { }); }; -return Chain; -}; +module.exports = Chain; diff --git a/lib/bcoin/chainblock.js b/lib/bcoin/chainblock.js index 10f6b859..465e7b3f 100644 --- a/lib/bcoin/chainblock.js +++ b/lib/bcoin/chainblock.js @@ -5,11 +5,9 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var bn = require('bn.js'); var constants = bcoin.protocol.constants; -var network = bcoin.protocol.network; var utils = require('./utils'); var assert = utils.assert; var BufferWriter = require('./writer'); @@ -45,6 +43,7 @@ function ChainBlock(chain, data, prev) { return new ChainBlock(chain, data); this.chain = chain; + this.network = this.chain.network; this.hash = data.hash; this.version = data.version; @@ -85,7 +84,7 @@ ChainBlock.prototype.getChainwork = function getChainwork(prev) { */ ChainBlock.prototype.isGenesis = function isGenesis() { - return this.hash === network.genesis.hash; + return this.hash === this.network.genesis.hash; }; /** @@ -97,10 +96,10 @@ ChainBlock.prototype.isGenesis = function isGenesis() { */ ChainBlock.prototype.getRetargetAncestors = function getRetargetAncestors(callback) { - var majorityWindow = network.block.majorityWindow; + var majorityWindow = this.network.block.majorityWindow; var medianTimespan = constants.block.MEDIAN_TIMESPAN; - var powDiffInterval = network.pow.retargetInterval; - var allowMinDiff = network.pow.allowMinDifficultyBlocks; + var powDiffInterval = this.network.pow.retargetInterval; + var allowMinDiff = this.network.pow.allowMinDifficultyBlocks; var max = Math.max(majorityWindow, medianTimespan); if ((this.height + 1) % powDiffInterval === 0 || allowMinDiff) max = Math.max(max, powDiffInterval); @@ -292,7 +291,7 @@ ChainBlock.prototype.getMedianTimeAsync = function getMedianTimeAsync(callback) */ ChainBlock.prototype.isOutdated = function isOutdated(version, ancestors) { - return this.isSuperMajority(version, network.block.majorityRejectOutdated, ancestors); + return this.isSuperMajority(version, this.network.block.majorityRejectOutdated, ancestors); }; /** @@ -305,7 +304,7 @@ ChainBlock.prototype.isOutdated = function isOutdated(version, ancestors) { ChainBlock.prototype.isOutdatedAsync = function isOutdatedAsync(version, callback) { return this.isSuperMajorityAsync( version, - network.block.majorityRejectOutdated, + this.network.block.majorityRejectOutdated, callback); }; @@ -317,7 +316,7 @@ ChainBlock.prototype.isOutdatedAsync = function isOutdatedAsync(version, callbac */ ChainBlock.prototype.isUpgraded = function isUpgraded(version, ancestors) { - return this.isSuperMajority(version, network.block.majorityEnforceUpgrade, ancestors); + return this.isSuperMajority(version, this.network.block.majorityEnforceUpgrade, ancestors); }; /** @@ -330,7 +329,7 @@ ChainBlock.prototype.isUpgraded = function isUpgraded(version, ancestors) { ChainBlock.prototype.isUpgradedAsync = function isUpgradedAsync(version, callback) { return this.isSuperMajorityAsync( version, - network.block.majorityEnforceUpgrade, + this.network.block.majorityEnforceUpgrade, callback); }; @@ -345,7 +344,7 @@ ChainBlock.prototype.isUpgradedAsync = function isUpgradedAsync(version, callbac ChainBlock.prototype.isSuperMajority = function isSuperMajority(version, required, ancestors) { var entry = this; var found = 0; - var majorityWindow = network.block.majorityWindow; + var majorityWindow = this.network.block.majorityWindow; var i; for (i = 0; i < majorityWindow && found < required && entry; i++) { @@ -368,7 +367,7 @@ ChainBlock.prototype.isSuperMajority = function isSuperMajority(version, require ChainBlock.prototype.isSuperMajorityAsync = function isSuperMajorityAsync(version, required, callback) { var self = this; - return this.getAncestors(network.block.majorityWindow, function(err, ancestors) { + return this.getAncestors(this.network.block.majorityWindow, function(err, ancestors) { if (err) return callback(err); @@ -485,5 +484,4 @@ ChainBlock.isChainBlock = function isChainBlock(obj) { && typeof obj.getMedianTime === 'function'; }; -return ChainBlock; -}; +module.exports = ChainBlock; diff --git a/lib/bcoin/chaindb.js b/lib/bcoin/chaindb.js index df173e91..ade60692 100644 --- a/lib/bcoin/chaindb.js +++ b/lib/bcoin/chaindb.js @@ -5,8 +5,6 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - /* * Database Layout: * R -> tip hash @@ -22,8 +20,8 @@ module.exports = function(bcoin) { * C/[address]/[hash] -> dummy (coin by address) */ +var bcoin = require('../bcoin'); var EventEmitter = require('events').EventEmitter; -var network = bcoin.protocol.network; var constants = bcoin.protocol.constants; var utils = require('./utils'); var assert = utils.assert; @@ -71,6 +69,7 @@ function ChainDB(chain, options) { this.options = options; this.chain = chain; + this.network = this.chain.network; this.keepBlocks = options.keepBlocks || 288; this.prune = !!options.prune; @@ -83,7 +82,7 @@ function ChainDB(chain, options) { // We add a padding of 100 for forked chains, // reorgs, chain locator creation and the bip34 // check. - this.cacheWindow = (network.pow.retargetInterval + 1) * 2 + 100; + this.cacheWindow = (this.network.pow.retargetInterval + 1) * 2 + 100; this.coinCache = new NullCache(100000); this.cacheHash = new bcoin.lru(this.cacheWindow); @@ -102,6 +101,7 @@ ChainDB.prototype._init = function _init() { return; this.db = bcoin.ldb({ + network: this.network, name: this.options.name || (this.options.spv ? 'spvchain' : 'chain'), location: this.options.location, db: this.options.db, @@ -126,7 +126,7 @@ ChainDB.prototype._init = function _init() { self.emit('open'); } - self.db.has('h/' + network.genesis.hash, function(err, exists) { + self.db.has('h/' + self.network.genesis.hash, function(err, exists) { if (err) return self.emit('error', err); @@ -134,18 +134,18 @@ ChainDB.prototype._init = function _init() { return finish(); genesis = new bcoin.chainblock(self.chain, { - hash: network.genesis.hash, - version: network.genesis.version, - prevBlock: network.genesis.prevBlock, - merkleRoot: network.genesis.merkleRoot, - ts: network.genesis.ts, - bits: network.genesis.bits, - nonce: network.genesis.nonce, + hash: self.network.genesis.hash, + version: self.network.genesis.version, + prevBlock: self.network.genesis.prevBlock, + merkleRoot: self.network.genesis.merkleRoot, + ts: self.network.genesis.ts, + bits: self.network.genesis.bits, + nonce: self.network.genesis.nonce, height: 0, chainwork: null }, null); - block = bcoin.block.fromRaw(network.genesisBlock, 'hex'); + block = bcoin.block.fromRaw(self.network.genesisBlock, 'hex'); block.setHeight(0); self.save(genesis, block, true, finish); @@ -616,7 +616,7 @@ ChainDB.prototype.isMainChain = function isMainChain(hash, callback) { query = hash; } - if (hash === this.chain.tip.hash || hash === network.genesis.hash) + if (hash === this.chain.tip.hash || hash === this.network.genesis.hash) return utils.asyncify(callback)(null, true); return this.getHeight(query, function(err, height) { @@ -784,7 +784,7 @@ ChainDB.prototype.connectBlock = function connectBlock(block, batch, callback) { } // Genesis block's coinbase is unspendable. - if (block.hash('hex') === network.genesis.hash) + if (this.chain.isGenesis(block)) return utils.nextTick(callback); this._ensureBlock(block, function(err, block) { @@ -801,7 +801,7 @@ ChainDB.prototype.connectBlock = function connectBlock(block, batch, callback) { if (self.options.indexTX) { batch.put('t/' + hash, tx.toExtended()); if (self.options.indexAddress) { - addresses = tx.getAddresses(); + addresses = tx.getAddresses(self.network); for (j = 0; j < addresses.length; j++) { address = addresses[j]; batch.put('T/' + address + '/' + hash, DUMMY); @@ -819,7 +819,7 @@ ChainDB.prototype.connectBlock = function connectBlock(block, batch, callback) { assert(input.coin); if (self.options.indexAddress) { - address = input.getAddress(); + address = input.getAddress(self.network); if (address) batch.del('C/' + address + '/' + key); } @@ -841,7 +841,7 @@ ChainDB.prototype.connectBlock = function connectBlock(block, batch, callback) { coin = bcoin.coin(tx, j); if (self.options.indexAddress) { - address = output.getAddress(); + address = output.getAddress(self.network); if (address) batch.put('C/' + address + '/' + key, DUMMY); } @@ -893,7 +893,7 @@ ChainDB.prototype.disconnectBlock = function disconnectBlock(block, batch, callb if (self.options.indexTX) { batch.del('t/' + hash); if (self.options.indexAddress) { - addresses = tx.getAddresses(); + addresses = tx.getAddresses(self.network); for (j = 0; j < addresses.length; j++) { address = addresses[j]; batch.del('T/' + address + '/' + hash); @@ -911,7 +911,7 @@ ChainDB.prototype.disconnectBlock = function disconnectBlock(block, batch, callb assert(input.coin); if (self.options.indexAddress) { - address = input.getAddress(); + address = input.getAddress(self.network); if (address) batch.put('C/' + address + '/' + key, DUMMY); } @@ -929,7 +929,7 @@ ChainDB.prototype.disconnectBlock = function disconnectBlock(block, batch, callb continue; if (self.options.indexAddress) { - address = output.getAddress(); + address = output.getAddress(self.network); if (address) batch.del('C/' + address + '/' + key); } @@ -1431,7 +1431,7 @@ ChainDB.prototype._pruneBlock = function _pruneBlock(block, batch, callback) { if (!this.prune) return callback(); - if (block.height <= network.block.pruneAfterHeight) + if (block.height <= this.network.block.pruneAfterHeight) return callback(); futureHeight = pad32(block.height + this.keepBlocks); @@ -1466,5 +1466,4 @@ NullCache.prototype.get = function get(key) {}; NullCache.prototype.has = function has(key) {}; NullCache.prototype.reset = function reset() {}; -return ChainDB; -}; +module.exports = ChainDB; diff --git a/lib/bcoin/coin.js b/lib/bcoin/coin.js index 063586ec..b8c4c143 100644 --- a/lib/bcoin/coin.js +++ b/lib/bcoin/coin.js @@ -5,12 +5,10 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var bn = require('bn.js'); var utils = require('./utils'); var assert = utils.assert; -var network = bcoin.protocol.network; /** * Represents an unspent output. @@ -84,7 +82,7 @@ utils.inherits(Coin, bcoin.output); Coin.prototype.getConfirmations = function getConfirmations(height) { if (height == null) - height = network.height; + height = bcoin.network.get().height; if (this.height === -1) return 0; @@ -284,5 +282,4 @@ Coin.isCoin = function isCoin(obj) { && typeof obj.getConfirmations === 'function'; }; -return Coin; -}; +module.exports = Coin; diff --git a/lib/bcoin/coins.js b/lib/bcoin/coins.js index 4d1d954d..319cca70 100644 --- a/lib/bcoin/coins.js +++ b/lib/bcoin/coins.js @@ -5,8 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var utils = bcoin.utils; var assert = utils.assert; var constants = bcoin.protocol.constants; @@ -274,5 +273,4 @@ Coins.fromRaw = function fromRaw(buf, hash) { return new Coins(Coins.parseRaw(buf), hash); }; -return Coins; -}; +module.exports = Coins; diff --git a/lib/bcoin/coinview.js b/lib/bcoin/coinview.js index ec759081..78477adb 100644 --- a/lib/bcoin/coinview.js +++ b/lib/bcoin/coinview.js @@ -5,8 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var utils = bcoin.utils; var assert = utils.assert; var constants = bcoin.protocol.constants; @@ -162,5 +161,4 @@ CoinView.prototype.toArray = function toArray() { return out; }; -return CoinView; -}; +module.exports = CoinView; diff --git a/lib/bcoin/compactblock.js b/lib/bcoin/compactblock.js index 68115426..0d2edb49 100644 --- a/lib/bcoin/compactblock.js +++ b/lib/bcoin/compactblock.js @@ -5,8 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var bn = require('bn.js'); var utils = require('./utils'); var assert = utils.assert; @@ -117,5 +116,4 @@ CompactBlock.isCompactBlock = function isCompactBlock(obj) { return obj && typeof obj.toBlock === 'function'; }; -return CompactBlock; -}; +module.exports = CompactBlock; diff --git a/lib/bcoin/env.js b/lib/bcoin/env.js index 99092ff7..8f9ca054 100644 --- a/lib/bcoin/env.js +++ b/lib/bcoin/env.js @@ -109,8 +109,8 @@ try { */ function Environment(options) { - if (!(this instanceof Environment)) - return new Environment(options); + // if (!(this instanceof Environment)) + // return new Environment(options); if (!options) options = {}; @@ -125,49 +125,6 @@ function Environment(options) { this.isBrowser = utils.isBrowser; - this.prefix = options.prefix - || process.env.BCOIN_PREFIX - || process.env.HOME + '/.bcoin'; - - this.networkType = options.network - || process.env.BCOIN_NETWORK - || 'main'; - - this.db = options.db || process.env.BCOIN_DB; - this.debugLogs = options.debug; - this.debugFile = options.debugFile; - this.profile = options.profile; - this.useWorkers = options.useWorkers; - this.maxWorkers = options.maxWorkers; - this.workerTimeout = options.workerTimeout; - - if (this.debugLogs == null && process.env.BCOIN_DEBUG != null) - this.debugLogs = +process.env.BCOIN_DEBUG === 1; - - if (this.debugFile == null && process.env.BCOIN_DEBUGFILE != null) { - if (process.env.BCOIN_DEBUGFILE === '0' - || process.env.BCOIN_DEBUGFILE === '1') { - this.debugFile = +process.env.BCOIN_DEBUGFILE !== 0; - } else { - this.debugFile = process.env.BCOIN_DEBUGFILE; - } - } - - if (this.debugFile && typeof this.debugFile !== 'string') - this.debugFile = this.prefix + '/debug.log' - - if (this.profile == null && process.env.BCOIN_PROFILE != null) - this.profile = +process.env.BCOIN_PROFILE === 1; - - if (this.useWorkers == null && process.env.BCOIN_USE_WORKERS != null) - this.useWorkers = +process.env.BCOIN_USE_WORKERS === 1; - - if (this.maxWorkers == null && process.env.BCOIN_MAX_WORKERS != null) - this.maxWorkers = +process.env.BCOIN_MAX_WORKERS; - - if (this.workerTime == null && process.env.BCOIN_WORKER_TIMEOUT != null) - this.workerTimeout = +process.env.BCOIN_WORKER_TIMEOUT; - this.bn = require('bn.js'); this.utils = require('./utils'); this.locker = require('./locker'); @@ -180,60 +137,128 @@ function Environment(options) { this.lowlevelup = require('./lowlevelup'); this.uri = require('./uri'); - this.protocol = require('./protocol')(this); - this.errors = require('./errors')(this); - this.profiler = require('./profiler')(this); - this.ldb = require('./ldb')(this); - this.timedata = require('./timedata')(this); - this.script = require('./script')(this); - this.stack = this.script.stack; - this.witness = this.script.witness; - this.input = require('./input')(this); - this.output = require('./output')(this); - this.coin = require('./coin')(this); - this.coins = require('./coins')(this); - this.coinview = require('./coinview')(this); - this.tx = require('./tx')(this); - this.mtx = require('./mtx')(this); - this.txdb = require('./txdb')(this); - this.abstractblock = require('./abstractblock')(this); - this.compactblock = require('./compactblock')(this); - this.block = require('./block')(this); - this.merkleblock = require('./merkleblock')(this); - this.headers = require('./headers')(this); - this.node = require('./node')(this); - this.spvnode = require('./spvnode')(this); - this.fullnode = require('./fullnode')(this); - this.chainblock = require('./chainblock')(this); - this.chaindb = require('./chaindb')(this); - this.chain = require('./chain')(this); - this.mempool = require('./mempool')(this); - this.mempoolentry = this.mempool.mempoolentry; - this.keypair = require('./keypair')(this); - this.hd = require('./hd')(this); - this.address = require('./address')(this); - this.wallet = require('./wallet')(this); - this.walletdb = require('./walletdb')(this); - this.provider = this.walletdb.provider; - this.peer = require('./peer')(this); - this.pool = require('./pool')(this); - this.miner = require('./miner')(this); - this.minerblock = this.miner.minerblock; - this.http = require('./http')(this); - this.workers = this.useWorkers && !this.isBrowser - ? require('./work' + 'ers')(this) - : null; + this.network = require('./network'); + this.protocol = require('./protocol'); + this.errors = require('./errors'); + this.ldb = require('./ldb'); + this.profiler = require('./profiler'); + this.timedata = require('./timedata'); + this.script = require('./script'); + this.stack = this.script.Stack; + this.witness = this.script.Witness; + this.input = require('./input'); + this.output = require('./output'); + this.coin = require('./coin'); + this.coins = require('./coins'); + this.coinview = require('./coinview'); + this.tx = require('./tx'); + this.mtx = require('./mtx'); + this.txdb = require('./txdb'); + this.abstractblock = require('./abstractblock'); + this.compactblock = require('./compactblock'); + this.block = require('./block'); + this.merkleblock = require('./merkleblock'); + this.headers = require('./headers'); + this.node = require('./node'); + this.spvnode = require('./spvnode'); + this.fullnode = require('./fullnode'); + this.chainblock = require('./chainblock'); + this.chaindb = require('./chaindb'); + this.chain = require('./chain'); + this.mempool = require('./mempool'); + this.mempoolentry = this.mempool.MempoolEntry; + this.keypair = require('./keypair'); + this.hd = require('./hd'); + this.address = require('./address'); + this.wallet = require('./wallet'); + this.walletdb = require('./walletdb'); + this.provider = this.walletdb.Provider; + this.peer = require('./peer'); + this.pool = require('./pool'); + this.miner = require('./miner'); + this.minerblock = this.miner.MinerBlock; + this.http = require('./http'); - this.time = new this.timedata(); + this.workers = null; this.workerPool = null; - if (this.workers) { + this.prefix = null; + this.networkType = null; + this.db = null; + this.debugLogs = null; + this.debugFile = null; + this.profile = null; + this.useWorkers = null; + this.maxWorkers = null; + this.workerTimeout = null; + + this.time = new this.timedata(); + + this.setDefaults(options); +} + +Environment.prototype.setDefaults = function setDefaults(options) { + options = utils.merge({}, options); + + options.prefix = options.prefix + || process.env.BCOIN_PREFIX + || process.env.HOME + '/.bcoin'; + + options.network = options.network + || process.env.BCOIN_NETWORK + || 'main'; + + if (!options.db) + options.db = process.env.BCOIN_DB; + + if (options.debug == null && process.env.BCOIN_DEBUG != null) + options.debug = +process.env.BCOIN_DEBUG === 1; + + if (options.debugFile == null && process.env.BCOIN_DEBUGFILE != null) { + if (process.env.BCOIN_DEBUGFILE === '0' + || process.env.BCOIN_DEBUGFILE === '1') { + options.debugFile = +process.env.BCOIN_DEBUGFILE !== 0; + } else { + options.debugFile = process.env.BCOIN_DEBUGFILE; + } + } + + if (options.profile == null && process.env.BCOIN_PROFILE != null) + options.profile = +process.env.BCOIN_PROFILE === 1; + + if (options.useWorkers == null && process.env.BCOIN_USE_WORKERS != null) + options.useWorkers = +process.env.BCOIN_USE_WORKERS === 1; + + if (options.maxWorkers == null && process.env.BCOIN_MAX_WORKERS != null) + options.maxWorkers = +process.env.BCOIN_MAX_WORKERS; + + if (options.workerTime == null && process.env.BCOIN_WORKER_TIMEOUT != null) + options.workerTimeout = +process.env.BCOIN_WORKER_TIMEOUT; + + if (options.debugFile && typeof options.debugFile !== 'string') + options.debugFile = options.prefix + '/debug.log' + + this.prefix = options.prefix; + this.networkType = options.network; + this.db = options.db; + this.debugLogs = !!options.debug; + this.debugFile = options.debugFile; + this.profile = options.profile; + this.useWorkers = !!options.useWorkers; + this.maxWorkers = options.maxWorkers; + this.workerTimeout = options.workerTimeout; + + this.network.set(this.networkType); + + if (this.useWorkers) { + this.workers = require('./workers'); this.workerPool = new this.workers({ size: this.maxWorkers, - timeout: this.workerTimeout + timeout: this.workerTimeout, + network: this.network.get(this.network.primary) }); } -} +}; /** * Ensure the `prefix`. diff --git a/lib/bcoin/errors.js b/lib/bcoin/errors.js index 2180058d..bf939afb 100644 --- a/lib/bcoin/errors.js +++ b/lib/bcoin/errors.js @@ -5,8 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var utils = bcoin.utils; var constants = bcoin.protocol.constants; @@ -110,8 +109,5 @@ function ScriptError(code, op, ip) { utils.inherits(ScriptError, Error); -return { - VerifyError: VerifyError, - ScriptError: ScriptError -}; -}; +exports.VerifyError = VerifyError; +exports.ScriptError = ScriptError; diff --git a/lib/bcoin/fullnode.js b/lib/bcoin/fullnode.js index dfcaf525..b539552f 100644 --- a/lib/bcoin/fullnode.js +++ b/lib/bcoin/fullnode.js @@ -5,11 +5,9 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var utils = require('./utils'); var assert = utils.assert; -var network = bcoin.protocol.network; /** * Create a fullnode complete with a chain, @@ -64,6 +62,7 @@ Fullnode.prototype._init = function _init() { this.wallet = null; this.chain = new bcoin.chain({ + network: this.network, preload: false, spv: false, prune: this.options.prune, @@ -72,6 +71,7 @@ Fullnode.prototype._init = function _init() { // Mempool needs access to the chain. this.mempool = new bcoin.mempool({ + network: this.network, chain: this.chain, limitFree: this.options.limitFree, limitFreeRelay: this.options.limitFreeRelay, @@ -82,9 +82,10 @@ Fullnode.prototype._init = function _init() { // Pool needs access to the chain and mempool. this.pool = new bcoin.pool({ + network: this.network, chain: this.chain, mempool: this.mempool, - witness: network.witness, + witness: this.network.witness, listen: this.options.listen, selfish: this.options.selfish, broadcast: this.options.broadcast, @@ -93,6 +94,7 @@ Fullnode.prototype._init = function _init() { // Miner needs access to the chain and mempool. this.miner = new bcoin.miner({ + network: this.network, chain: this.chain, mempool: this.mempool, address: this.options.payoutAddress, @@ -100,15 +102,17 @@ Fullnode.prototype._init = function _init() { }); this.walletdb = new bcoin.walletdb({ + network: this.network, verify: false }); // HTTP needs access to the node. this.http = new bcoin.http.server({ + network: this.network, node: this, key: this.options.sslKey, cert: this.options.sslCert, - port: this.options.httpPort || network.rpcPort, + port: this.options.httpPort || this.network.rpcPort, host: this.options.httpHost || '0.0.0.0' }); @@ -597,5 +601,4 @@ Fullnode.prototype.getConfidence = function getConfidence(tx, callback) { return this.mempool.getConfidence(tx, callback); }; -return Fullnode; -}; +module.exports = Fullnode; diff --git a/lib/bcoin/hd.js b/lib/bcoin/hd.js index 07be97fa..ffc4b853 100644 --- a/lib/bcoin/hd.js +++ b/lib/bcoin/hd.js @@ -76,8 +76,7 @@ * SOFTWARE. */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var bn = require('bn.js'); var utils = require('./utils'); var ec = require('./ec'); @@ -378,7 +377,7 @@ function HDPrivateKey(options) { assert(options, 'No options for HD private key.'); assert(options.depth <= 0xff, 'Depth is too high.'); - this.network = options.network || network.type; + this.network = bcoin.network.get(options.network); this.xprivkey = options.xprivkey; this.mnemonic = options.mnemonic; @@ -405,7 +404,7 @@ HDPrivateKey.prototype.__defineGetter__('hdPublicKey', function() { if (!this._hdPublicKey) { this._hdPublicKey = new HDPublicKey({ network: this.network, - version: network[this.network].prefixes.xpubkey, + version: this.network.prefixes.xpubkey, depth: this.depth, parentFingerPrint: this.parentFingerPrint, childIndex: this.childIndex, @@ -506,7 +505,7 @@ HDPrivateKey.prototype.deriveAccount44 = function deriveAccount44(options) { } if (coinType == null) - coinType = this.network === 'main' ? 0 : 1; + coinType = this.network.type === 'main' ? 0 : 1; assert(utils.isNumber(coinType)); assert(utils.isNumber(accountIndex)); @@ -702,9 +701,7 @@ HDPrivateKey.parseSeed = function parseSeed(seed, networkType) { hash = utils.hmac('sha512', data, 'Bitcoin seed'); return { - version: networkType - ? network[networkType].prefixes.xprivkey - : network.prefixes.xprivkey, + version: bcoin.network.get(networkType).prefixes.xprivkey, depth: 0, parentFingerPrint: new Buffer([0, 0, 0, 0]), childIndex: 0, @@ -756,9 +753,7 @@ HDPrivateKey._generate = function _generate(options, networkType) { entropy = ec.random(32); return { - version: networkType - ? network[networkType].prefixes.xprivkey - : network.prefixes.xprivkey, + version: bcoin.network.get(networkType).prefixes.xprivkey, depth: 0, parentFingerPrint: new Buffer([0, 0, 0, 0]), childIndex: 0, @@ -990,7 +985,7 @@ function HDPublicKey(options) { assert(options, 'No options for HDPublicKey'); assert(options.depth <= 0xff, 'Depth is too high.'); - this.network = options.network || network.type; + this.network = bcoin.network.get(options.network); this.xpubkey = options.xpubkey; this.xprivkey = null; @@ -1335,7 +1330,7 @@ HDPublicKey.isHDPublicKey = function isHDPublicKey(obj) { */ HDPrivateKey.prototype.toSecret = function toSecret() { - return KeyPair.toSecret.call(this); + return KeyPair.prototype.toSecret.call(this); }; HD.mnemonic = Mnemonic; @@ -1345,5 +1340,4 @@ HD.privateKey = HDPrivateKey; HD.publicKey = HDPublicKey; HD.fromJSON = HDPrivateKey.fromJSON; -return HD; -}; +module.exports = HD; diff --git a/lib/bcoin/headers.js b/lib/bcoin/headers.js index 994da3ae..9a05120b 100644 --- a/lib/bcoin/headers.js +++ b/lib/bcoin/headers.js @@ -5,8 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var utils = require('./utils'); /** @@ -155,5 +154,4 @@ Headers.isHeaders = function isHeaders(obj) { && typeof obj.toBlock !== 'function'; }; -return Headers; -}; +module.exports = Headers; diff --git a/lib/bcoin/http/client.js b/lib/bcoin/http/client.js index a8b23ba0..069d7905 100644 --- a/lib/bcoin/http/client.js +++ b/lib/bcoin/http/client.js @@ -5,10 +5,8 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../../bcoin'); var EventEmitter = require('events').EventEmitter; -var network = bcoin.protocol.network; var utils = require('../utils'); var assert = utils.assert; var request = require('./request'); @@ -21,19 +19,20 @@ var request = require('./request'); * @param {Object?} options */ -function HTTPClient(uri, options) { +function HTTPClient(options) { if (!(this instanceof HTTPClient)) - return new HTTPClient(uri, options); + return new HTTPClient(options); if (!options) options = {}; EventEmitter.call(this); - this.uri = uri; + this.uri = options.uri; this.loaded = false; this.id = null; this.options = options; + this.network = bcoin.network.get(options.network); this._init(); } @@ -63,7 +62,7 @@ HTTPClient.prototype._init = function _init() { self.socket.on('version', function(info) { bcoin.debug('Connected to bcoin server: %s (%s)', info.version, info.network); - assert(info.network === network.type, 'Wrong network.'); + assert(info.network === self.network.type, 'Wrong network.'); }); self.socket.on('tx', function(tx, map) { @@ -224,7 +223,7 @@ HTTPClient.prototype._request = function _request(method, endpoint, json, callba return callback(err); networkType = res.headers['x-bcoin-network']; - assert(networkType === network.type, 'Wrong network.'); + assert(networkType === self.network.type, 'Wrong network.'); if (res.statusCode === 404) return callback(); @@ -335,7 +334,7 @@ HTTPClient.prototype.getWallet = function getWallet(id, passphrase, callback) { return callback(e); } - json.provider = new bcoin.http.provider(self.uri); + json.provider = new bcoin.http.provider(self.options); return callback(null, new bcoin.wallet(json)); }); @@ -361,7 +360,7 @@ HTTPClient.prototype.createWallet = function createWallet(options, callback) { return callback(e); } - json.provider = new bcoin.http.provider(self.uri); + json.provider = new bcoin.http.provider(self.options); return callback(null, new bcoin.wallet(json)); }); @@ -914,5 +913,4 @@ HTTPClient.prototype.getInfo = function getInfo(callback) { }); }; -return HTTPClient; -}; +module.exports = HTTPClient; diff --git a/lib/bcoin/http/index.js b/lib/bcoin/http/index.js index d033a65c..15defd2f 100644 --- a/lib/bcoin/http/index.js +++ b/lib/bcoin/http/index.js @@ -5,17 +5,13 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - bcoin.http = {}; +var utils = require('../utils'); - bcoin.http.request = require('./request'); - bcoin.http.client = require('./client')(bcoin); - bcoin.http.provider = require('./provider')(bcoin); +exports.request = require('./request'); +exports.provider = require('./provider'); +exports.client = require('./client'); - if (!bcoin.isBrowser) { - bcoin.http.base = require('./ba' + 'se'); - bcoin.http.server = require('./ser' + 'ver')(bcoin); - } - - return bcoin.http; -}; +if (!utils.isBrowser) { + exports.base = require('./ba' + 'se'); + exports.server = require('./ser' + 'ver'); +} diff --git a/lib/bcoin/http/provider.js b/lib/bcoin/http/provider.js index 3fbc4093..c1979fdc 100644 --- a/lib/bcoin/http/provider.js +++ b/lib/bcoin/http/provider.js @@ -5,13 +5,13 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../../bcoin'); var EventEmitter = require('events').EventEmitter; var utils = require('../utils'); var assert = utils.assert; -var HTTPClient = bcoin.http.client; +var http = require('./'); +var HTTPClient = http.client; /** * HTTPProvider @@ -20,13 +20,14 @@ var HTTPClient = bcoin.http.client; * @param {String} uri */ -function HTTPProvider(uri) { +function HTTPProvider(options) { if (!(this instanceof HTTPProvider)) - return new HTTPProvider(uri); + return new HTTPProvider(options); EventEmitter.call(this); - this.client = new HTTPClient(uri); + this.client = new HTTPClient(options); + this.network = bcoin.network.get(options.network); this.uri = uri; this.id = null; this._init(); @@ -201,5 +202,4 @@ HTTPProvider.prototype.zap = function zap(now, age, callback) { return this.client.zapWallet(this.id, now, age, callback); }; -return HTTPProvider; -}; +module.exports = HTTPProvider; diff --git a/lib/bcoin/http/server.js b/lib/bcoin/http/server.js index f1070cfe..23bfa409 100644 --- a/lib/bcoin/http/server.js +++ b/lib/bcoin/http/server.js @@ -5,12 +5,11 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../../bcoin'); var EventEmitter = require('events').EventEmitter; var constants = bcoin.protocol.constants; -var network = bcoin.protocol.network; -var HTTPBase = bcoin.http.base; +var http = require('./'); +var HTTPBase = http.base; var utils = require('../utils'); var assert = utils.assert; @@ -33,6 +32,7 @@ function HTTPServer(options) { assert(this.node, 'HTTP requires a Node.'); + this.network = this.node.network; this.walletdb = this.node.walletdb; this.mempool = this.node.mempool; this.pool = this.node.pool; @@ -68,7 +68,7 @@ HTTPServer.prototype._init = function _init() { res.setHeader('X-Bcoin-Version', constants.USER_VERSION); res.setHeader('X-Bcoin-Agent', constants.USER_AGENT); - res.setHeader('X-Bcoin-Network', network.type); + res.setHeader('X-Bcoin-Network', self.network.type); res.setHeader('X-Bcoin-Height', self.node.chain.height + ''); res.setHeader('X-Bcoin-Tip', utils.revHex(self.node.chain.tip.hash)); @@ -187,7 +187,7 @@ HTTPServer.prototype._init = function _init() { send(200, { version: constants.USER_VERSION, agent: constants.USER_AGENT, - network: network.type, + network: self.network.type, height: self.node.chain.height, tip: utils.revHex(self.node.chain.tip.hash), peers: self.node.pool.peers.all.length, @@ -670,7 +670,7 @@ HTTPServer.prototype._initIO = function _initIO() { socket.emit('version', { version: constants.USER_AGENT, - network: network.type + network: self.network.type }); }); @@ -785,5 +785,4 @@ HTTPServer.prototype.listen = function listen(port, host, callback) { }); }; -return HTTPServer; -}; +module.exports = HTTPServer; diff --git a/lib/bcoin/input.js b/lib/bcoin/input.js index 27e73a6f..72f690d7 100644 --- a/lib/bcoin/input.js +++ b/lib/bcoin/input.js @@ -5,8 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var utils = require('./utils'); var assert = utils.assert; var constants = bcoin.protocol.constants; @@ -41,7 +40,7 @@ function Input(options, mutable) { this.prevout = options.prevout; this.script = bcoin.script(options.script, this.mutable); this.sequence = options.sequence == null ? 0xffffffff : options.sequence; - this.witness = bcoin.script.witness(options.witness, this.mutable); + this.witness = bcoin.witness(options.witness, this.mutable); if (options.coin) this.coin = bcoin.coin(options.coin); @@ -52,14 +51,6 @@ function Input(options, mutable) { assert(typeof this.sequence === 'number'); } -Input.prototype.__defineGetter__('type', function() { - return this.getType(); -}); - -Input.prototype.__defineGetter__('address', function() { - return this.getAddress(); -}); - /** * Get the previous output script type. Will "guess" * based on the input script and/or witness if coin @@ -160,23 +151,23 @@ Input.prototype.getSubtype = function getSubtype() { * @returns {String?} address */ -Input.prototype.getAddress = function getAddress() { +Input.prototype.getAddress = function getAddress(network) { var address; if (this.isCoinbase()) return; if (this.coin) - return this.coin.getAddress(); + return this.coin.getAddress(network); if (this._address) return this._address; if (this.witness.items.length > 0) - address = this.witness.getInputAddress(); + address = this.witness.getInputAddress(network); if (!address) - address = this.script.getInputAddress(); + address = this.script.getInputAddress(network); if (!this.mutable) this._address = address; @@ -209,8 +200,8 @@ Input.prototype.isCoinbase = function isCoinbase() { * @returns {Boolean} Whether the input matched. */ -Input.prototype.test = function test(addressMap) { - var address = this.getAddress(); +Input.prototype.test = function test(addressMap, network) { + var address = this.getAddress(network); if (!address) return false; @@ -426,5 +417,4 @@ Input.isInput = function isInput(obj) { && typeof obj.getAddress === 'function'; }; -return Input; -}; +module.exports = Input; diff --git a/lib/bcoin/keypair.js b/lib/bcoin/keypair.js index 51bec7e6..39159375 100644 --- a/lib/bcoin/keypair.js +++ b/lib/bcoin/keypair.js @@ -5,8 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var utils = require('./utils'); var assert = utils.assert; var network = bcoin.protocol.network; @@ -34,6 +33,7 @@ function KeyPair(options) { this.options = options; this.key = null; this.compressed = options.compressed !== false; + this.network = bcoin.network.get(options.network); if (!options.privateKey && !options.publicKey) throw new Error('No options for keypair'); @@ -129,7 +129,7 @@ KeyPair.prototype.getPublicKey = function getPublicKey(enc) { */ KeyPair.prototype.toSecret = function toSecret() { - return KeyPair.toSecret(this.getPrivateKey(), this.compressed); + return KeyPair.toSecret(this.getPrivateKey(), this.compressed, this.network); }; /** @@ -139,9 +139,10 @@ KeyPair.prototype.toSecret = function toSecret() { * @returns {Base58String} */ -KeyPair.toSecret = function toSecret(privateKey, compressed) { +KeyPair.toSecret = function toSecret(privateKey, compressed, network) { var p = new BufferWriter(); + network = bcoin.network.get(network); p.writeU8(network.prefixes.privkey); p.writeBytes(privateKey); @@ -163,9 +164,18 @@ KeyPair.parseSecret = function parseSecret(secret) { var data = utils.fromBase58(secret); var p = new BufferReader(data, true); var compressed = false; - var privateKey; + var prefix, type, privateKey; - assert(p.readU8() === network.prefixes.privkey, 'Bad network.'); + prefix = p.readU8(); + + for (i = 0; i < network.types.length; i++) { + type = network.types[i]; + prefix = network[type].prefixes.privkey; + if (data.version === prefix) + break; + } + + assert(i < network.types.length, 'Network not found.'); privateKey = p.readBytes(32); @@ -177,6 +187,7 @@ KeyPair.parseSecret = function parseSecret(secret) { p.verifyChecksum(); return { + network: type, privateKey: privateKey, compressed: compressed }; @@ -262,5 +273,4 @@ KeyPair.fromJSON = function fromJSON(json, passphrase) { return new KeyPair(KeyPair.parseJSON(json, passphrase)); }; -return KeyPair; -}; +module.exports = KeyPair; diff --git a/lib/bcoin/ldb.js b/lib/bcoin/ldb.js index 6bc0c352..233c1493 100644 --- a/lib/bcoin/ldb.js +++ b/lib/bcoin/ldb.js @@ -7,11 +7,9 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var LowlevelUp = require('./lowlevelup'); var utils = bcoin.utils; -var network = bcoin.protocol.network; var db = {}; /** @@ -69,7 +67,7 @@ function getLocation(options) { + '/' + options.name + '-' - + network.type + + bcoin.network.get(options.network).type + '.db'; } @@ -132,5 +130,4 @@ function repair(options, callback) { ldb.destroy = destroy; ldb.repair = repair; -return ldb; -}; +module.exports = ldb; diff --git a/lib/bcoin/mempool.js b/lib/bcoin/mempool.js index b10c0683..c89ea234 100644 --- a/lib/bcoin/mempool.js +++ b/lib/bcoin/mempool.js @@ -5,17 +5,15 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - /* * Database Layout: * (inherits all from txdb) */ +var bcoin = require('../bcoin'); var EventEmitter = require('events').EventEmitter; var bn = require('bn.js'); var constants = bcoin.protocol.constants; -var network = bcoin.protocol.network; var utils = require('./utils'); var assert = utils.assert; var BufferWriter = require('./writer'); @@ -66,6 +64,7 @@ function Mempool(options) { assert(this.chain, 'Mempool requires a blockchain.'); + this.network = this.chain.network; this.loaded = false; this.locker = new bcoin.locker(this, this.addTX, 100 << 20); @@ -87,7 +86,7 @@ function Mempool(options) { this.relayPriority = this.options.relayPriority !== false; this.requireStandard = this.options.requireStandard != null ? this.options.requireStandard - : network.requireStandard; + : this.network.requireStandard; this.rejectAbsurdFees = this.options.rejectAbsurdFees !== false; this.prematureWitness = !!this.options.prematureWitness; this.accurateMemory = !!this.options.accurateMemory; @@ -120,6 +119,7 @@ Mempool.prototype._init = function _init() { var self = this; var unlock = this._lock(utils.nop, []); var options = { + network: this.network, name: this.options.name || 'mempool', location: this.options.location, db: this.options.db || 'memory' @@ -1543,7 +1543,7 @@ Mempool.prototype._addUnchecked = function _addUnchecked(entry, callback) { batch.put('m/' + pad32(entry.ts) + '/' + hash, DUMMY); if (this.options.indexAddress) { - addresses = tx.getAddresses(); + addresses = tx.getAddresses(this.network); for (i = 0; i < addresses.length; i++) batch.put('T/' + addresses[i] + '/' + hash, DUMMY); } @@ -1561,7 +1561,7 @@ Mempool.prototype._addUnchecked = function _addUnchecked(entry, callback) { batch.put('s/' + key, tx.hash()); if (this.options.indexAddress) { - address = input.getAddress(); + address = input.getAddress(this.network); if (address) batch.del('C/' + address + '/' + key); } @@ -1579,7 +1579,7 @@ Mempool.prototype._addUnchecked = function _addUnchecked(entry, callback) { batch.put('c/' + key, coin); if (this.options.indexAddress) { - address = output.getAddress(); + address = output.getAddress(this.network); if (address) batch.put('C/' + address + '/' + key, DUMMY); } @@ -1617,7 +1617,7 @@ Mempool.prototype._removeUnchecked = function _removeUnchecked(hash, limit, call batch.del('m/' + pad32(entry.ts) + '/' + hash); if (self.options.indexAddress) { - addresses = tx.getAddresses(); + addresses = tx.getAddresses(self.network); for (i = 0; i < addresses.length; i++) batch.del('T/' + addresses[i] + '/' + hash); } @@ -1641,14 +1641,14 @@ Mempool.prototype._removeUnchecked = function _removeUnchecked(hash, limit, call if (result) { batch.put('c/' + key, input.coin.toRaw()); if (self.options.indexAddress) { - address = input.getAddress(); + address = input.getAddress(self.network); if (address) batch.put('C/' + address + '/' + key, DUMMY); } } else { batch.del('c/' + key); if (self.options.indexAddress) { - address = input.getAddress(); + address = input.getAddress(self.network); if (address) batch.del('C/' + address + '/' + key); } @@ -1669,7 +1669,7 @@ Mempool.prototype._removeUnchecked = function _removeUnchecked(hash, limit, call batch.del('c/' + key); if (self.options.indexAddress) { - address = output.getAddress(); + address = output.getAddress(self.network); if (address) batch.del('C/' + address + '/' + key); } @@ -1943,7 +1943,6 @@ function mallocUsage(alloc) { return ((alloc + 15) >>> 3) << 3; } -Mempool.mempoolentry = MempoolEntry; +Mempool.MempoolEntry = MempoolEntry; -return Mempool; -}; +module.exports = Mempool; diff --git a/lib/bcoin/merkleblock.js b/lib/bcoin/merkleblock.js index 94cf21cb..4efdd7ad 100644 --- a/lib/bcoin/merkleblock.js +++ b/lib/bcoin/merkleblock.js @@ -5,8 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var utils = require('./utils'); /** @@ -403,5 +402,4 @@ MerkleBlock.isMerkleBlock = function isMerkleBlock(obj) { && typeof obj.verifyPartial === 'function'; }; -return MerkleBlock; -}; +module.exports = MerkleBlock; diff --git a/lib/bcoin/miner.js b/lib/bcoin/miner.js index 77402b75..9ad52979 100644 --- a/lib/bcoin/miner.js +++ b/lib/bcoin/miner.js @@ -5,12 +5,10 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var utils = require('./utils'); var assert = utils.assert; var constants = bcoin.protocol.constants; -var network = bcoin.protocol.network; var bn = require('bn.js'); var EventEmitter = require('events').EventEmitter; @@ -52,6 +50,7 @@ function Miner(options) { assert(this.chain, 'Miner requires a blockchain.'); + this.network = this.chain.network; this.running = false; this.timeout = null; this.loaded = false; @@ -62,6 +61,7 @@ function Miner(options) { if (bcoin.useWorkers) { this.workerPool = new bcoin.workers({ + network: this.network, size: 1, timeout: -1 }); @@ -118,7 +118,7 @@ Miner.prototype._init = function _init() { self.stop(); setTimeout(function() { self.start(); - }, network.type === 'regtest' ? 100 : 5000); + }, self.network.type === 'regtest' ? 100 : 5000); }); this.on('block', function(block) { @@ -386,7 +386,7 @@ function MinerBlock(options) { // miner succeeded. new Buffer(options.coinbaseFlags, 'ascii') ]), - witness: new bcoin.script.witness(), + witness: new bcoin.witness(), sequence: 0xffffffff }); @@ -672,7 +672,6 @@ function rcmp(a, b) { return 0; } -Miner.minerblock = MinerBlock; +Miner.MinerBlock = MinerBlock; -return Miner; -}; +module.exports = Miner; diff --git a/lib/bcoin/mtx.js b/lib/bcoin/mtx.js index 0d1d4d65..42429a3c 100644 --- a/lib/bcoin/mtx.js +++ b/lib/bcoin/mtx.js @@ -5,15 +5,13 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var bn = require('bn.js'); var utils = require('./utils'); var assert = utils.assert; var constants = bcoin.protocol.constants; -var network = bcoin.protocol.network; var Script = bcoin.script; -var Witness = bcoin.script.witness; +var Witness = bcoin.witness; var opcodes = constants.opcodes; /** @@ -1100,8 +1098,8 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) { if (options.confirmed && coin.height === -1) continue; - if (network.height !== -1 && coin.coinbase) { - if (network.height + 1 < coin.height + constants.tx.COINBASE_MATURITY) + if (options.height != null && coin.coinbase) { + if (options.height + 1 < coin.height + constants.tx.COINBASE_MATURITY) continue; } @@ -1147,12 +1145,12 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) { // Calculate max possible size after signing. size = tx.maxSize(options, true); - if (tryFree) { + if (tryFree && options.height != null) { // Note that this will only work // if the mempool's rolling reject // fee is zero (i.e. the mempool is // not full). - if (tx.isFree(network.height + 1, size)) { + if (tx.isFree(options.height + 1, size)) { fee = new bn(0); break; } @@ -1298,7 +1296,7 @@ MTX.prototype.sortMembers = function sortMembers() { MTX.prototype.avoidFeeSniping = function avoidFeeSniping(height) { if (height == null) - height = network.height; + height = bcoin.network.get().height; if (height === -1) height = 0; @@ -1403,5 +1401,4 @@ MTX.isMTX = function isMTX(obj) { && typeof obj.scriptInput === 'function'; }; -return MTX; -}; +module.exports = MTX; diff --git a/lib/bcoin/network.js b/lib/bcoin/network.js new file mode 100644 index 00000000..3b49239a --- /dev/null +++ b/lib/bcoin/network.js @@ -0,0 +1,111 @@ +/*! + * network.js - network object for bcoin + * Copyright (c) 2014-2015, Fedor Indutny (MIT License) + * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License). + * https://github.com/indutny/bcoin + */ + +var utils = require('./utils'); +var assert = utils.assert; +var network = require('./protocol/network'); + +/** + * Represents a key ring which amounts to an address. Used for {@link Wallet}. + * @exports Address + * @constructor + * @param {Object} options + * @param {String?} options.label + * @param {Boolean?} options.derived + * @param {HDPrivateKey|HDPublicKey} options.key + * @param {String?} options.path + * @param {Boolean?} options.change + * @param {Number?} options.index + * @param {String?} options.type - `"pubkeyhash"` or `"multisig"`. + * @param {Buffer[]} options.keys - Shared multisig keys. + * @param {Number?} options.m - Multisig `m` value. + * @param {Number?} options.n - Multisig `n` value. + * @param {Boolean?} options.witness - Whether witness programs are enabled. + */ + +function Network(options) { + var i, keys, key, value; + + if (typeof options === 'string') + options = network[options]; + + assert(options, 'Network requires a type or options.'); + + keys = Object.keys(options); + + for (i = 0; i < keys.length; i++) { + key = keys[i]; + value = options[key]; + this[key] = value; + } + + if (!Network[this.type]) + Network[this.type] = this; + + if (!Network.primary) + Network.primary = this.type; +} + +Network.primary = null; + +/** + * Test an object to see if it is an Address. + * @param {Object} obj + * @returns {Boolean} + */ + +Network.prototype.updateHeight = function updateHeight(height) { + this.height = height; +}; + +/** + * Return address ID (pubkeyhash address of pubkey). + * @returns {Base58Address} + */ + +Network.prototype.updateRate = function updateRate(rate) { + this.rate = rate; +}; + +/** + * Test an object to see if it is an Address. + * @param {Object} obj + * @returns {Boolean} + */ + +Network.set = function set(type) { + assert(type, 'Bad network.'); + + if (!Network[type]) + Network[type] = new Network(type); + + if (!Network.primary) + Network.primary = type; + + return Network[type]; +}; + +Network.get = function get(options) { + var net; + + if (!options) { + assert(Network.primary, 'No default network.'); + return Network[Network.primary]; + } + + if (options instanceof Network) + return options; + + if (typeof options === 'string') { + assert(Network[options], 'Network not created.'); + return Network[options]; + } + + assert(false, 'Unknown network.'); +}; + +module.exports = Network; diff --git a/lib/bcoin/node.js b/lib/bcoin/node.js index 46769abe..67173c06 100644 --- a/lib/bcoin/node.js +++ b/lib/bcoin/node.js @@ -5,8 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var EventEmitter = require('events').EventEmitter; var utils = require('./utils'); @@ -29,6 +28,7 @@ function Node(options) { options = {}; this.options = options; + this.network = bcoin.network.get(options.network); this.mempool = null; this.pool = null; @@ -39,5 +39,4 @@ function Node(options) { utils.inherits(Node, EventEmitter); -return Node; -}; +module.exports = Node; diff --git a/lib/bcoin/output.js b/lib/bcoin/output.js index 1a8e026d..4d230ffd 100644 --- a/lib/bcoin/output.js +++ b/lib/bcoin/output.js @@ -5,8 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var bn = require('bn.js'); var utils = require('./utils'); var assert = utils.assert; @@ -50,14 +49,6 @@ function Output(options, mutable) { assert(!this.mutable || !this.value.isNeg()); } -Output.prototype.__defineGetter__('type', function() { - return this.getType(); -}); - -Output.prototype.__defineGetter__('address', function() { - return this.getAddress(); -}); - /** * Get the script type. * @returns {String} type @@ -82,13 +73,13 @@ Output.prototype.getType = function getType() { * @returns {String?} address */ -Output.prototype.getAddress = function getAddress() { +Output.prototype.getAddress = function getAddress(network) { var address; if (this._address) return this._address; - address = this.script.getAddress(); + address = this.script.getAddress(network); if (!this.mutable) this._address = address; @@ -103,8 +94,8 @@ Output.prototype.getAddress = function getAddress() { * @returns {Boolean} Whether the output matched. */ -Output.prototype.test = function test(addressMap) { - var address = this.getAddress(); +Output.prototype.test = function test(addressMap, network) { + var address = this.getAddress(network); if (!address) return false; @@ -227,5 +218,4 @@ Output.isOutput = function isOutput(obj) { && typeof obj.getAddress === 'function'; }; -return Output; -}; +module.exports = Output; diff --git a/lib/bcoin/peer.js b/lib/bcoin/peer.js index a596bd4d..61d970a6 100644 --- a/lib/bcoin/peer.js +++ b/lib/bcoin/peer.js @@ -5,14 +5,12 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var EventEmitter = require('events').EventEmitter; var bn = require('bn.js'); var utils = require('./utils'); var assert = utils.assert; var constants = bcoin.protocol.constants; -var network = bcoin.protocol.network; /** * Represents a remote peer. @@ -78,11 +76,12 @@ function Peer(pool, options) { this.port = 0; this._createSocket = this.options.createSocket; this.priority = this.options.priority; - this.parser = new bcoin.protocol.parser(); - this.framer = new bcoin.protocol.framer(); this.chain = this.pool.chain; this.mempool = this.pool.mempool; this.bloom = this.pool.bloom; + this.network = this.chain.network; + this.parser = new bcoin.protocol.parser(this.chain.options); + this.framer = new bcoin.protocol.framer(this.chain.options); this.version = null; this.destroyed = false; this.ack = false; @@ -107,7 +106,7 @@ function Peer(pool, options) { assert(this.port != null); } else if (options.seed) { options.seed = utils.parseHost(options.seed); - options.seed.port = options.seed.port || network.port; + options.seed.port = options.seed.port || this.network.port; this.socket = this.createSocket(options.seed.port, options.seed.host); } @@ -1214,7 +1213,7 @@ Peer.prototype._handleAddr = function handleAddr(addrs) { ts: ts, services: addr.services, host: host, - port: addr.port || network.port, + port: addr.port || this.network.port, network: addr.network, bloom: addr.bloom, getutxo: addr.getutxo, @@ -1274,11 +1273,12 @@ Peer.prototype._handleGetAddr = function handleGetAddr() { hosts[ip] = true; items.push({ + network: this.network, ts: peer.ts, services: peer.version ? peer.version.services : null, ipv4: version === 4 ? ip : null, ipv6: version === 6 ? ip : null, - port: peer.socket.remotePort || network.port + port: peer.socket.remotePort || this.network.port }); if (items.length === 1000) @@ -1339,7 +1339,7 @@ Peer.prototype._handleAlert = function handleAlert(details) { var hash = utils.dsha256(details.payload); var signature = details.signature; - if (!bcoin.ec.verify(hash, signature, network.alertKey)) { + if (!bcoin.ec.verify(hash, signature, this.network.alertKey)) { bcoin.debug('Peer %s sent a phony alert packet.', this.host); // Let's look at it because why not? bcoin.debug(details); @@ -1445,5 +1445,4 @@ Peer.prototype.sendReject = function sendReject(obj, code, reason, score) { return this.pool.reject(this, obj, code, reason, score); }; -return Peer; -}; +module.exports = Peer; diff --git a/lib/bcoin/pool.js b/lib/bcoin/pool.js index a832bdbf..48a98b35 100644 --- a/lib/bcoin/pool.js +++ b/lib/bcoin/pool.js @@ -5,12 +5,10 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var EventEmitter = require('events').EventEmitter; var utils = require('./utils'); var assert = utils.assert; -var network = bcoin.protocol.network; var constants = bcoin.protocol.constants; var VerifyError = bcoin.errors.VerifyError; @@ -84,6 +82,8 @@ function Pool(options) { assert(this.chain, 'Pool requires a blockchain.'); + this.network = this.chain.network; + if (options.relay == null) { if (options.spv) options.relay = false; @@ -98,7 +98,7 @@ function Pool(options) { options.headers = false; } - seeds = (options.seeds || network.seeds).slice(); + seeds = (options.seeds || this.network.seeds).slice(); if (process.env.BCOIN_SEED) seeds.unshift(process.env.BCOIN_SEED); @@ -417,7 +417,7 @@ Pool.prototype.startServer = function startServer(callback) { data.address, data.port); }); - this.server.listen(network.port, '0.0.0.0', callback); + this.server.listen(this.network.port, '0.0.0.0', callback); }; /** @@ -2119,7 +2119,7 @@ Pool.prototype.addSeed = function addSeed(seed) { this.seeds.push({ host: seed.host, - port: seed.port || network.port + port: seed.port || this.network.port }); this.hosts[seed.host] = true; @@ -2321,5 +2321,4 @@ LoadRequest.prototype.finish = function finish() { } }; -return Pool; -}; +module.exports = Pool; diff --git a/lib/bcoin/profiler.js b/lib/bcoin/profiler.js index b7c94898..c09a052f 100644 --- a/lib/bcoin/profiler.js +++ b/lib/bcoin/profiler.js @@ -5,21 +5,25 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - /** * @exports profiler */ -var profiler = {}; +var profiler = exports; +var bcoin = require('../bcoin'); var utils = require('./utils'); var assert = utils.assert; var fs, v8profiler; -if (bcoin.profile && !bcoin.isBrowser) { - v8profiler = require('v8-' + 'profiler'); - fs = require('f' + 's'); +function ensure() { + if (v8profiler) + return; + + if (bcoin.profile && !bcoin.isBrowser) { + v8profiler = require('v8-' + 'profiler'); + fs = require('f' + 's'); + } } /** @@ -30,7 +34,7 @@ if (bcoin.profile && !bcoin.isBrowser) { */ function Profile(name) { - if (v8profiler) { + if (v8profiler && bcoin.profile) { name = 'profile-' + (name ? name + '-' : '') + Profile.uid++; bcoin.debug('Starting CPU profile: %s', name); this.profile = v8profiler.startProfiling(name, true); @@ -106,7 +110,7 @@ Profile.prototype.save = function save(callback) { */ function Snapshot(name) { - if (v8profiler) { + if (v8profiler && bcoin.profile) { name = 'snapshot-' + (name ? name + '-' : '') + Snapshot.uid++; bcoin.debug('Taking heap snapshot: %s', name); this.snapshot = v8profiler.takeSnapshot(name); @@ -197,6 +201,7 @@ Snapshot.prototype.save = function save(callback) { */ profiler.startProfiling = function startProfiling(name) { + ensure(); return new Profile(name); }; @@ -207,6 +212,7 @@ profiler.startProfiling = function startProfiling(name) { */ profiler.takeSnapshot = function takeSnapshot(name) { + ensure(); return new Snapshot(name); }; @@ -219,6 +225,8 @@ profiler.takeSnapshot = function takeSnapshot(name) { profiler.snapshot = function snapshot(name, callback) { var snapshot, mem; + ensure(); + if (typeof name === 'function') { callback = name; name = null; @@ -233,12 +241,9 @@ profiler.snapshot = function snapshot(name, callback) { utils.mb(mem.rss - mem.heapTotal)); } - if (!v8profiler) + if (!v8profiler || !bcoin.profile) return callback ? utils.nextTick(callback) : null; snapshot = new Snapshot(name); snapshot.save(callback); }; - -return profiler; -}; diff --git a/lib/bcoin/protocol/framer.js b/lib/bcoin/protocol/framer.js index ddf62384..3f444eaf 100644 --- a/lib/bcoin/protocol/framer.js +++ b/lib/bcoin/protocol/framer.js @@ -5,9 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - -var network = bcoin.protocol.network; +var bcoin = require('../../bcoin'); var constants = require('./constants'); var utils = require('../utils'); var assert = utils.assert; @@ -27,9 +25,11 @@ function Framer(options) { if (!(this instanceof Framer)) return new Framer(options); - options = options || {}; + if (!options) + options = {}; this.options = options; + this.network = bcoin.network.get(options.network); this.agent = new Buffer(options.USER_AGENT || constants.USER_AGENT, 'ascii'); } @@ -51,7 +51,7 @@ Framer.prototype.header = function header(cmd, payload) { assert(payload.length <= 0xffffffff); // Magic value - utils.writeU32(h, network.magic, 0); + utils.writeU32(h, this.network.magic, 0); // Command len = cmd.copy(h, 4); @@ -95,6 +95,7 @@ Framer.prototype.version = function version(options) { options = {}; options.agent = this.agent; + options.network = this.network; return this.packet('version', Framer.version(options)); }; @@ -386,6 +387,7 @@ Framer.prototype.addr = function addr(peers) { Framer.address = function address(data, full, writer) { var p = new BufferWriter(writer); + var network = bcoin.network.get(data.network); if (full) { if (!data.ts) @@ -434,6 +436,12 @@ Framer.version = function version(options, writer) { if (typeof agent === 'string') agent = new Buffer(agent, 'ascii'); + if (local.network == null) + local.network = options.network; + + if (remote.network == null) + remote.network = options.network; + if (local.services == null) local.services = constants.LOCAL_SERVICES; @@ -1127,6 +1135,7 @@ Framer.addr = function addr(peers, writer) { for (i = 0; i < peers.length; i++) { peer = peers[i]; Framer.address({ + network: peer.network, ts: peer.ts, services: peer.services, ipv6: peer.ipv6, @@ -1148,10 +1157,12 @@ Framer.addr = function addr(peers, writer) { * @returns {Buffer} Returns a BufferWriter if `writer` was passed in. */ -Framer.alert = function alert(data, writer) { +Framer.alert = function alert(data, network, writer) { var p, i, payload; var key = data.key; + network = bcoin.network.get(network); + if (!key && network.alertPrivateKey) key = network.alertPrivateKey; @@ -1507,5 +1518,4 @@ Framer.tx.cost = function txCost(tx) { return base * (scale - 1) + sizes.size; }; -return Framer; -}; +module.exports = Framer; diff --git a/lib/bcoin/protocol/index.js b/lib/bcoin/protocol/index.js index 3b61303c..e0ad4361 100644 --- a/lib/bcoin/protocol/index.js +++ b/lib/bcoin/protocol/index.js @@ -5,13 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - bcoin.protocol = {}; - - bcoin.protocol.constants = require('./constants'); - bcoin.protocol.network = require('./network').get(bcoin.networkType); - bcoin.protocol.framer = require('./framer')(bcoin); - bcoin.protocol.parser = require('./parser')(bcoin); - - return bcoin.protocol; -}; +exports.constants = require('./constants'); +exports.network = require('./network'); +exports.framer = require('./framer'); +exports.parser = require('./parser'); diff --git a/lib/bcoin/protocol/network.js b/lib/bcoin/protocol/network.js index b8ccbb11..02085d9f 100644 --- a/lib/bcoin/protocol/network.js +++ b/lib/bcoin/protocol/network.js @@ -25,18 +25,6 @@ var main, testnet, regtest, segnet3, segnet4; network.types = ['main', 'testnet', 'regtest', 'segnet3', 'segnet4']; -/** - * Get a new network object by type. - * @memberof module:network - * @param {String} type - Network type. - * @returns {Object} - */ - -network.get = function get(type) { - assert(network[type], 'Network not found.'); - return utils.merge({}, network, network[type]); -}; - /** * Main * @static diff --git a/lib/bcoin/protocol/parser.js b/lib/bcoin/protocol/parser.js index 572203d6..f6c522b4 100644 --- a/lib/bcoin/protocol/parser.js +++ b/lib/bcoin/protocol/parser.js @@ -5,13 +5,11 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../../bcoin'); var EventEmitter = require('events').EventEmitter; var utils = require('../utils'); var assert = utils.assert; var constants = require('./constants'); -var network = bcoin.protocol.network; var BufferReader = require('../reader'); /** @@ -23,9 +21,12 @@ var BufferReader = require('../reader'); * @emits Parser#packet */ -function Parser() { +function Parser(options) { if (!(this instanceof Parser)) - return new Parser(); + return new Parser(options); + + if (!options) + options = {}; EventEmitter.call(this); @@ -33,6 +34,7 @@ function Parser() { this.pendingTotal = 0; this.waiting = 24; this.packet = null; + this.network = bcoin.network.get(options.network); } utils.inherits(Parser, EventEmitter); @@ -126,7 +128,7 @@ Parser.prototype.parseHeader = function parseHeader(h) { magic = utils.readU32(h, 0); - if (magic !== network.magic) + if (magic !== this.network.magic) return this._error('Invalid magic value: ' + magic.toString(16)); // Count length of the cmd @@ -1225,5 +1227,4 @@ Parser.parseAlert = function parseAlert(p) { }; }; -return Parser; -}; +module.exports = Parser; diff --git a/lib/bcoin/script.js b/lib/bcoin/script.js index 4492a823..dbde00db 100644 --- a/lib/bcoin/script.js +++ b/lib/bcoin/script.js @@ -5,8 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var bn = require('bn.js'); var constants = bcoin.protocol.constants; var utils = require('./utils'); @@ -117,8 +116,8 @@ Witness.prototype.getInputType = function getInputType() { * @returns {String|null} */ -Witness.prototype.getInputAddress = function getInputAddress() { - return Script.getInputAddress(this.items, true); +Witness.prototype.getInputAddress = function getInputAddress(network) { + return Script.getInputAddress(this.items, network, true); }; Witness.prototype.getInputHash = function getInputHash() { @@ -2359,11 +2358,11 @@ Script.prototype.getSize = function getSize() { * @returns {Base58Address|null} */ -Script.prototype.getInputAddress = function getInputAddress() { - return Script.getInputAddress(this.code, false); +Script.prototype.getInputAddress = function getInputAddress(network) { + return Script.getInputAddress(this.code, network, false); }; -Script.getInputAddress = function getInputAddress(code, isWitness) { +Script.getInputAddress = function getInputAddress(code, network, isWitness) { if (Script.isPubkeyInput(code)) return; @@ -2372,9 +2371,10 @@ Script.getInputAddress = function getInputAddress(code, isWitness) { return bcoin.address.compileData( code[1], 'witnesspubkeyhash', - 0); + 0, + network); } - return bcoin.address.compileData(code[1], 'pubkeyhash'); + return bcoin.address.compileData(code[1], 'pubkeyhash', null, network); } if (Script.isMultisigInput(code, isWitness)) @@ -2385,9 +2385,10 @@ Script.getInputAddress = function getInputAddress(code, isWitness) { return bcoin.address.compileData( code[code.length - 1], 'witnessscripthash', - 0); + 0, + network); } - return bcoin.address.compileData(code[code.length - 1], 'scripthash'); + return bcoin.address.compileData(code[code.length - 1], 'scripthash', null, network); } }; @@ -2398,7 +2399,7 @@ Script.getInputAddress = function getInputAddress(code, isWitness) { * @returns {Base58Address|null} */ -Script.prototype.getAddress = function getAddress() { +Script.prototype.getAddress = function getAddress(network) { var program; if (this.isWitnessProgram()) { @@ -2408,22 +2409,23 @@ Script.prototype.getAddress = function getAddress() { return bcoin.address.compileHash( program.data, program.type, - program.version); + program.version, + network); } // Convert p2pk to p2pkh addresses if (this.isPubkey()) - return bcoin.address.compileData(this.code[0], 'pubkeyhash'); + return bcoin.address.compileData(this.code[0], 'pubkeyhash', null, network); if (this.isPubkeyhash()) - return bcoin.address.compileHash(this.code[2], 'pubkeyhash'); + return bcoin.address.compileHash(this.code[2], 'pubkeyhash', null, network); // Convert bare multisig to scripthash address if (this.isMultisig()) - return bcoin.address.compileData(this.encode(), 'scripthash'); + return bcoin.address.compileData(this.encode(), 'scripthash', null, network); if (this.isScripthash()) - return bcoin.address.compileHash(this.code[1], 'scripthash'); + return bcoin.address.compileHash(this.code[1], 'scripthash', null, network); }; /** @@ -4323,8 +4325,7 @@ Script.isScript = function isScript(obj) { && typeof obj.getSubscript === 'function'; }; -Script.witness = Witness; -Script.stack = Stack; +Script.Witness = Witness; +Script.Stack = Stack; -return Script; -}; +module.exports = Script; diff --git a/lib/bcoin/spvnode.js b/lib/bcoin/spvnode.js index 66223b3c..cf5e0b7c 100644 --- a/lib/bcoin/spvnode.js +++ b/lib/bcoin/spvnode.js @@ -5,11 +5,9 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var utils = require('./utils'); var assert = utils.assert; -var network = bcoin.protocol.network; /** * Create an spv node which only maintains @@ -53,28 +51,32 @@ SPVNode.prototype._init = function _init() { this.wallet = null; this.chain = new bcoin.chain({ + network: this.network, preload: this.options.preload, useCheckpoints: this.options.useCheckpoints, spv: true }); this.pool = new bcoin.pool({ + network: this.network, chain: this.chain, - witness: network.witness, + witness: this.network.witness, selfish: true, listen: false, spv: true }); this.walletdb = new bcoin.walletdb({ + network: this.network, verify: true }); this.http = new bcoin.http.server({ + network: this.network, node: this, key: this.options.sslKey, cert: this.options.sslCert, - port: this.options.httpPort || network.rpcPort, + port: this.options.httpPort || this.network.rpcPort, host: '0.0.0.0' }); @@ -294,5 +296,4 @@ SPVNode.prototype.getWallet = function getWallet(id, passphrase, callback) { return this.walletdb.get(id, passphrase, callback); }; -return SPVNode; -}; +module.exports = SPVNode; diff --git a/lib/bcoin/timedata.js b/lib/bcoin/timedata.js index 166808cd..790099ee 100644 --- a/lib/bcoin/timedata.js +++ b/lib/bcoin/timedata.js @@ -5,8 +5,7 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var EventEmitter = require('events').EventEmitter; var utils = require('./utils'); var assert = utils.assert; @@ -108,5 +107,4 @@ function compare(a, b) { return a - b; } -return TimeData; -}; +module.exports = TimeData; diff --git a/lib/bcoin/tx.js b/lib/bcoin/tx.js index c8ae440d..6c6f0f7a 100644 --- a/lib/bcoin/tx.js +++ b/lib/bcoin/tx.js @@ -5,15 +5,13 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var bn = require('bn.js'); var utils = require('./utils'); var assert = utils.assert; var constants = bcoin.protocol.constants; -var network = bcoin.protocol.network; var Script = bcoin.script; -var Stack = bcoin.script.stack; +var Stack = bcoin.stack; var BufferReader = require('./reader'); var BufferWriter = require('./writer'); @@ -696,13 +694,13 @@ TX.prototype.getOutputValue = function getOutputValue() { * @returns {Base58Address[]} addresses */ -TX.prototype.getInputAddresses = function getInputAddresses() { +TX.prototype.getInputAddresses = function getInputAddresses(network) { var table = {}; var addresses = []; var i, address; for (i = 0; i < this.inputs.length; i++) { - address = this.inputs[i].getAddress(); + address = this.inputs[i].getAddress(network); if (address && !table[address]) { table[address] = true; addresses.push(address); @@ -719,13 +717,13 @@ TX.prototype.getInputAddresses = function getInputAddresses() { * @returns {Base58Address[]} addresses */ -TX.prototype.getOutputAddresses = function getOutputAddresses() { +TX.prototype.getOutputAddresses = function getOutputAddresses(network) { var table = {}; var addresses = []; var i, address; for (i = 0; i < this.outputs.length; i++) { - address = this.outputs[i].getAddress(); + address = this.outputs[i].getAddress(network); if (address && !table[address]) { table[address] = true; addresses.push(address); @@ -742,9 +740,9 @@ TX.prototype.getOutputAddresses = function getOutputAddresses() { * @returns {Base58Address[]} addresses */ -TX.prototype.getAddresses = function getAddresses() { - var input = this.getInputAddresses(); - var output = this.getOutputAddresses(); +TX.prototype.getAddresses = function getAddresses(network) { + var input = this.getInputAddresses(network); + var output = this.getOutputAddresses(network); var i; for (i = 0; i < output.length; i++) { @@ -1365,7 +1363,7 @@ TX.prototype.getPriority = function getPriority(height, size) { if (height == null) { height = this.height; if (height === -1) - height = network.height + 1; + height = bcoin.network.get().height + 1; } if (size == null) @@ -1414,7 +1412,7 @@ TX.prototype.isFree = function isFree(height, size) { if (height == null) { height = this.height; if (height === -1) - height = network.height + 1; + height = bcoin.network.get().height + 1; } priority = this.getPriority(height, size).priority; @@ -1484,7 +1482,7 @@ TX.prototype.getMaxFee = function getMaxFee(size, rate) { TX.prototype.getConfirmations = function getConfirmations(height) { if (height == null) - height = network.height; + height = bcoin.network.get().height; if (this.height === -1) return 0; @@ -1848,5 +1846,4 @@ TX.isTX = function isTX(obj) { && typeof obj.getVirtualSize === 'function'; }; -return TX; -}; +module.exports = TX; diff --git a/lib/bcoin/txdb.js b/lib/bcoin/txdb.js index 4106c772..3832341d 100644 --- a/lib/bcoin/txdb.js +++ b/lib/bcoin/txdb.js @@ -5,8 +5,6 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - /* * Database Layout: * t/[hash] -> extended tx @@ -23,6 +21,7 @@ module.exports = function(bcoin) { * C/[id]/[hash]/[index] -> dummy (coin by address) */ +var bcoin = require('../bcoin'); var bn = require('bn.js'); var utils = require('./utils'); var assert = bcoin.utils.assert; @@ -56,6 +55,7 @@ function TXDB(db, options) { this.db = db; this.options = options; + this.network = bcoin.network.get(options.network); this.busy = false; this.jobs = []; this.locker = new bcoin.locker(this); @@ -82,8 +82,8 @@ TXDB.prototype.getMap = function getMap(tx, callback) { if (!this.options.indexAddress) return callback(); - input = tx.getInputAddresses(); - output = tx.getOutputAddresses(); + input = tx.getInputAddresses(this.network); + output = tx.getOutputAddresses(this.network); addresses = utils.uniq(input.concat(output)); function cb(err, table) { @@ -340,7 +340,7 @@ TXDB.prototype._add = function add(tx, map, callback, force) { if (tx.isCoinbase()) return next(); - address = input.getAddress(); + address = input.getAddress(self.network); // Only add orphans if this input is ours. if (self.options.mapAddress) { @@ -434,7 +434,7 @@ TXDB.prototype._add = function add(tx, map, callback, force) { // Add unspent outputs or resolve orphans utils.forEachSerial(tx.outputs, function(output, next, i) { - var address = output.getAddress(); + var address = output.getAddress(self.network); var key, coin; // Do not add unspents for outputs that aren't ours. @@ -688,7 +688,7 @@ TXDB.prototype._confirm = function _confirm(tx, map, callback, force) { } utils.forEachSerial(tx.outputs, function(output, next, i) { - var address = output.getAddress(); + var address = output.getAddress(self.network); // Only update coins if this output is ours. if (self.options.mapAddress) { @@ -849,7 +849,7 @@ TXDB.prototype._remove = function remove(tx, map, callback, force) { tx.inputs.forEach(function(input) { var key = input.prevout.hash + '/' + input.prevout.index; - var address = input.getAddress(); + var address = input.getAddress(self.network); if (tx.isCoinbase()) return; @@ -875,7 +875,7 @@ TXDB.prototype._remove = function remove(tx, map, callback, force) { tx.outputs.forEach(function(output, i) { var key = hash + '/' + i; - var address = output.getAddress(); + var address = output.getAddress(self.network); if (self.options.mapAddress) { if (!address || !map.table[address].length) @@ -1735,5 +1735,4 @@ TXDB.prototype.zap = function zap(address, now, age, callback, force) { }); }; -return TXDB; -}; +module.exports = TXDB; diff --git a/lib/bcoin/wallet.js b/lib/bcoin/wallet.js index 2b0d2cdf..c3bd3078 100644 --- a/lib/bcoin/wallet.js +++ b/lib/bcoin/wallet.js @@ -5,13 +5,11 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var EventEmitter = require('events').EventEmitter; var utils = require('./utils'); var assert = utils.assert; var constants = bcoin.protocol.constants; -var network = bcoin.protocol.network; var BufferWriter = require('./writer'); /** @@ -68,10 +66,12 @@ function Wallet(options) { options.master = bcoin.hd.fromAny(options.master); } - if (!options.master) - options.master = bcoin.hd.fromSeed(); - this.options = options; + this.network = bcoin.network.get(options.network); + + if (!options.master) + options.master = bcoin.hd.fromSeed(null, this.network); + this.provider = options.provider || null; this.master = options.master || null; this.addressMap = options.addressMap || {}; @@ -487,6 +487,7 @@ Wallet.prototype.deriveAddress = function deriveAddress(change, index) { key = this.accountKey.derive(data.path); options = { + network: this.network, key: key, change: data.change, index: data.index, @@ -1010,7 +1011,7 @@ Wallet.prototype.getRedeem = function getRedeem(hash, prefix) { return; } - addr = bcoin.address.compileHash(hash, prefix); + addr = bcoin.address.compileHash(hash, prefix, null, this.network); address = this.deriveAddress(addr); if (!address) @@ -1521,7 +1522,7 @@ Wallet.prototype.inspect = function inspect() { return { id: this.id, type: this.type, - network: network.type, + network: this.network.type, m: this.m, n: this.n, keyAddress: this._initialized @@ -1559,7 +1560,7 @@ Wallet.prototype.toJSON = function toJSON() { return { v: 3, name: 'wallet', - network: network.type, + network: this.network.type, id: this.id, type: this.type, m: this.m, @@ -1594,10 +1595,8 @@ Wallet.parseJSON = function parseJSON(json, passphrase) { assert.equal(json.v, 3); assert.equal(json.name, 'wallet'); - if (json.network) - assert.equal(json.network, network.type); - return { + network: json.network, id: json.id, type: json.type, m: json.m, @@ -1634,9 +1633,6 @@ Wallet._syncDepth = function _syncDepth(json, options) { assert.equal(json.v, 3); assert.equal(json.name, 'wallet'); - if (json.network) - assert.equal(json.network, network.type); - master = json.master; json.master = json.accountKey; wallet = new Wallet(json); @@ -1737,9 +1733,6 @@ Wallet._addKey = function _addKey(json, keys, remove) { if (!Array.isArray(keys)) keys = [keys]; - if (json.network) - assert.equal(json.network, network.type); - master = json.master; json.master = json.accountKey; wallet = new Wallet(json); @@ -1793,5 +1786,4 @@ Wallet.isWallet = function isWallet(obj) { && obj.deriveAddress === 'function'; }; -return Wallet; -}; +module.exports = Wallet; diff --git a/lib/bcoin/walletdb.js b/lib/bcoin/walletdb.js index 1a21a503..7b3ca979 100644 --- a/lib/bcoin/walletdb.js +++ b/lib/bcoin/walletdb.js @@ -5,8 +5,6 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - /* * Database Layout: * (inherits all from txdb) @@ -14,11 +12,11 @@ module.exports = function(bcoin) { * w/[id] -> wallet */ +var bcoin = require('../bcoin'); var EventEmitter = require('events').EventEmitter; var utils = require('./utils'); var assert = utils.assert; var DUMMY = new Buffer([0]); -var network = bcoin.protocol.network; /** * WalletDB @@ -100,6 +98,7 @@ WalletDB.prototype._init = function _init() { return; this.db = bcoin.ldb({ + network: this.network, name: this.options.name || 'wallet', location: this.options.location, db: this.options.db, @@ -116,6 +115,7 @@ WalletDB.prototype._init = function _init() { }); this.tx = new bcoin.txdb(this.db, { + network: this.network, indexExtra: true, indexAddress: true, mapAddress: true, @@ -616,7 +616,7 @@ WalletDB.prototype.create = function create(id, options, callback) { if (json) return callback(new Error('`' + id + '` already exists.'), null, json); - if (network.witness) + if (self.network.witness) options.witness = options.witness !== false; options.provider = new Provider(self); @@ -1169,5 +1169,4 @@ Provider.prototype.zap = function zap(now, age, callback) { WalletDB.Provider = Provider; -return WalletDB; -}; +module.exports = WalletDB; diff --git a/lib/bcoin/worker.js b/lib/bcoin/worker.js index 81f42334..fd14f626 100644 --- a/lib/bcoin/worker.js +++ b/lib/bcoin/worker.js @@ -5,24 +5,26 @@ * https://github.com/indutny/bcoin */ -var penv, env; +var bcoin, env; if (typeof importScripts !== 'undefined') { self.importScripts('/bcoin.js'); + bcoin = self.bcoin; self.onmessage = function onmessage(event) { self.onmessage = function() {}; - penv = JSON.parse(event.data); + env = JSON.parse(event.data); - env = self.bcoin.env(penv.BCOIN_WORKER_NETWORK); - env.workers.listen(+penv.BCOIN_WORKER_ID, { - debug: +penv.BCOIN_WORKER_DEBUG === 1 + bcoin.network.set(env.BCOIN_WORKER_NETWORK); + bcoin.workers.listen(+env.BCOIN_WORKER_ID, { + debug: +env.BCOIN_WORKER_DEBUG === 1 }); }; } else { - penv = process.env; - env = require('./env')(penv.BCOIN_WORKER_NETWORK); - env.workers.listen(+penv.BCOIN_WORKER_ID, { - debug: +penv.BCOIN_WORKER_DEBUG === 1 + env = process.env; + bcoin = require('../bcoin'); + bcoin.network.set(env.BCOIN_WORKER_NETWORK); + bcoin.workers.listen(+env.BCOIN_WORKER_ID, { + debug: +env.BCOIN_WORKER_DEBUG === 1 }); } diff --git a/lib/bcoin/workers.js b/lib/bcoin/workers.js index d890ee46..2795bcc9 100644 --- a/lib/bcoin/workers.js +++ b/lib/bcoin/workers.js @@ -5,12 +5,10 @@ * https://github.com/indutny/bcoin */ -module.exports = function(bcoin) { - +var bcoin = require('../bcoin'); var EventEmitter = require('events').EventEmitter; var bn = require('bn.js'); var constants = bcoin.protocol.constants; -var network = bcoin.protocol.network; var utils = require('./utils'); var global = utils.global; var assert = utils.assert; @@ -39,6 +37,7 @@ function Workers(options) { this.uid = 0; this.size = options.size || Workers.CORES; this.timeout = options.timeout || 60000; + this.network = bcoin.network.get(options.network); this.children = []; } @@ -63,7 +62,7 @@ Workers.prototype.spawn = function spawn(id) { bcoin.debug('Spawning worker process: %d', id); - child = new Worker(id); + child = new Worker(this, id); child.on('error', function(err) { bcoin.debug('Worker %d error: %s', child.id, err.message); @@ -213,23 +212,24 @@ Workers.prototype.mine = function mine(attempt, callback) { * @property {Number} id */ -function Worker(id) { +function Worker(pool, id) { var self = this; var penv, cp; if (!(this instanceof Worker)) - return new Worker(id); + return new Worker(pool, id); EventEmitter.call(this); this.id = id; + this.pool = pool; this.framer = new Framer(); this.parser = new Parser(); this.setMaxListeners(utils.MAX_SAFE_INTEGER); penv = { BCOIN_WORKER_ID: id + '', - BCOIN_WORKER_NETWORK: network.type, + BCOIN_WORKER_NETWORK: this.pool.network.type, BCOIN_WORKER_DEBUG: (bcoin.debugLogs || bcoin.debugFile) ? '1' : '0' }; @@ -881,12 +881,10 @@ function getCores() { return os.cpus().length; } -Workers.workers = Workers; -Workers.worker = Worker; -Workers.master = Master; -Workers.framer = Framer; -Workers.parser = Parser; +Workers.Worker = Worker; +Workers.Master = Master; +Workers.Framer = Framer; +Workers.Parser = Parser; Workers.listen = Master.listen; -return Workers; -}; +module.exports = Workers;