diff --git a/lib/blockchain/chain.js b/lib/blockchain/chain.js index f8f73466..46480802 100644 --- a/lib/blockchain/chain.js +++ b/lib/blockchain/chain.js @@ -15,7 +15,7 @@ var ChainDB = require('./chaindb'); var common = require('./common'); var consensus = require('../protocol/consensus'); var util = require('../utils/util'); -var Locker = require('../utils/locker'); +var Lock = require('../utils/lock'); var LRU = require('../utils/lru'); var ChainEntry = require('./chainentry'); var CoinView = require('../coins/coinview'); @@ -41,7 +41,7 @@ var VerifyResult = errors.VerifyResult; * to the instantiated ChainDB. * @property {Number} total * @property {Number} orphanLimit - * @property {Locker} locker + * @property {Lock} locker * @property {Object} invalid * @property {Number} bestHeight * @property {ChainEntry?} tip @@ -80,7 +80,7 @@ function Chain(options) { this.db = new ChainDB(this); this.total = 0; this.orphanLimit = options.orphanLimit || (20 << 20); - this.locker = new Locker(true); + this.locker = new Lock(true); this.invalid = new LRU(100); this.bestHeight = -1; this.tip = null; diff --git a/lib/env.js b/lib/env.js index a6cce8c9..d824561d 100644 --- a/lib/env.js +++ b/lib/env.js @@ -76,6 +76,7 @@ function Environment() { this.require('bip150', './net/bip150'); this.require('bip151', './net/bip151'); this.require('bip152', './net/bip152'); + this.require('dns', './net/dns'); this.require('packets', './net/packets'); this.require('peer', './net/peer'); this.require('pool', './net/pool'); @@ -127,6 +128,7 @@ function Environment() { this.require('base58', './utils/base58'); this.require('co', './utils/co'); this.require('encoding', './utils/encoding'); + this.require('lock', './utils/lock'); this.require('reader', './utils/reader'); this.require('staticwriter', './utils/staticwriter'); this.require('util', './utils/util'); diff --git a/lib/http/rpc.js b/lib/http/rpc.js index 21f708c7..e0388293 100644 --- a/lib/http/rpc.js +++ b/lib/http/rpc.js @@ -22,7 +22,7 @@ var Block = require('../primitives/block'); var Headers = require('../primitives/headers'); var Input = require('../primitives/input'); var KeyRing = require('../primitives/keyring'); -var Locker = require('../utils/locker'); +var Lock = require('../utils/lock'); var MerkleBlock = require('../primitives/merkleblock'); var MTX = require('../primitives/mtx'); var Network = require('../protocol/network'); @@ -57,7 +57,7 @@ function RPC(node) { this.walletdb = node.walletdb; this.logger = node.logger; - this.locker = new Locker(); + this.locker = new Lock(); this.feeRate = null; this.mining = false; diff --git a/lib/mempool/mempool.js b/lib/mempool/mempool.js index f31776f4..7c2f17e8 100644 --- a/lib/mempool/mempool.js +++ b/lib/mempool/mempool.js @@ -18,7 +18,7 @@ var Bloom = require('../utils/bloom'); var Address = require('../primitives/address'); var Coin = require('../primitives/coin'); var Script = require('../script/script'); -var Locker = require('../utils/locker'); +var Lock = require('../utils/lock'); var Outpoint = require('../primitives/outpoint'); var TX = require('../primitives/tx'); var Coin = require('../primitives/coin'); @@ -48,7 +48,7 @@ var VerifyResult = errors.VerifyResult; * @property {Object} db * @property {Number} size * @property {Number} totalOrphans - * @property {Locker} locker + * @property {Lock} locker * @property {Number} freeCount * @property {Number} lastTime * @property {Number} maxSize @@ -77,7 +77,7 @@ function Mempool(options) { this.network = this.chain.network; this.logger = options.logger || this.chain.logger; - this.locker = new Locker(true); + this.locker = new Lock(true); this.size = 0; this.totalOrphans = 0; diff --git a/lib/net/peer.js b/lib/net/peer.js index d657c999..10be8808 100644 --- a/lib/net/peer.js +++ b/lib/net/peer.js @@ -18,7 +18,7 @@ var packets = require('./packets'); var consensus = require('../protocol/consensus'); var common = require('./common'); var InvItem = require('../primitives/invitem'); -var Locker = require('../utils/locker'); +var Lock = require('../utils/lock'); var Bloom = require('../utils/bloom'); var BIP151 = require('./bip151'); var BIP150 = require('./bip150'); @@ -84,7 +84,7 @@ function Peer(pool) { this.chain = this.pool.chain; this.mempool = this.pool.mempool; this.network = this.chain.network; - this.locker = new Locker(); + this.locker = new Lock(); this.next = null; this.prev = null; diff --git a/lib/net/pool.js b/lib/net/pool.js index 7091bec4..4281f8b5 100644 --- a/lib/net/pool.js +++ b/lib/net/pool.js @@ -20,7 +20,7 @@ var Address = require('../primitives/address'); var BIP150 = require('./bip150'); var Bloom = require('../utils/bloom'); var ec = require('../crypto/ec'); -var Locker = require('../utils/locker'); +var Lock = require('../utils/lock'); var Network = require('../protocol/network'); var Peer = require('./peer'); var request = require('../http/request'); @@ -110,7 +110,7 @@ function Pool(options) { this.createSocket = tcp.createSocket; this.createServer = tcp.createServer; this.resolve = dns.resolve; - this.locker = new Locker(); + this.locker = new Lock(); this.authdb = null; this.identityKey = null; this.proxyServer = null; diff --git a/lib/node/spvnode.js b/lib/node/spvnode.js index 71f0d0e7..4d374eaf 100644 --- a/lib/node/spvnode.js +++ b/lib/node/spvnode.js @@ -9,7 +9,7 @@ var util = require('../utils/util'); var co = require('../utils/co'); -var Locker = require('../utils/locker'); +var Lock = require('../utils/lock'); var Node = require('./node'); var Chain = require('../blockchain/chain'); var Pool = require('../net/pool'); @@ -110,8 +110,8 @@ function SPVNode(options) { } this.rescanJob = null; - this.scanLock = new Locker(); - this.watchLock = new Locker(); + this.scanLock = new Lock(); + this.watchLock = new Lock(); this._init(); } diff --git a/lib/utils/async.js b/lib/utils/async.js index df2dd83e..d6ae2f95 100644 --- a/lib/utils/async.js +++ b/lib/utils/async.js @@ -8,7 +8,7 @@ var util = require('./util'); var co = require('./co'); -var Locker = require('./locker'); +var Lock = require('./lock'); var assert = require('assert'); var EventEmitter = require('events').EventEmitter; @@ -26,7 +26,7 @@ function AsyncObject() { EventEmitter.call(this); - this._asyncLock = new Locker(); + this._asyncLock = new Lock(); this.loading = false; this.closing = false; diff --git a/lib/utils/index.js b/lib/utils/index.js index 6f2c7143..ceeb7666 100644 --- a/lib/utils/index.js +++ b/lib/utils/index.js @@ -9,8 +9,8 @@ exports.co = require('./co'); exports.encoding = require('./encoding'); exports.IP = require('./ip'); exports.lazy = require('./lazy'); -exports.Locker = require('./locker'); -exports.MappedLocker = exports.Locker.Mapped; +exports.Lock = require('./lock'); +exports.MappedLock = exports.Lock.Mapped; exports.LRU = require('./lru'); exports.List = require('./list'); exports.murmur3 = require('./murmur3'); diff --git a/lib/utils/locker.js b/lib/utils/lock.js similarity index 79% rename from lib/utils/locker.js rename to lib/utils/lock.js index 0d8a1a3c..e632aea9 100644 --- a/lib/utils/locker.js +++ b/lib/utils/lock.js @@ -1,5 +1,5 @@ /*! - * locker.js - lock and queue for bcoin + * lock.js - lock and queue for bcoin * Copyright (c) 2014-2015, Fedor Indutny (MIT License) * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License). * https://github.com/bcoin-org/bcoin @@ -11,15 +11,15 @@ var assert = require('assert'); /** * Represents a mutex lock for locking asynchronous object methods. - * @exports Locker + * @exports Lock * @constructor * @param {Boolean?} named - Whether to * maintain a map of queued jobs by job name. */ -function Locker(named) { - if (!(this instanceof Locker)) - return Locker.create(named); +function Lock(named) { + if (!(this instanceof Lock)) + return Lock.create(named); this.named = named === true; @@ -28,7 +28,7 @@ function Locker(named) { this.busy = false; this.destroyed = false; - this.map = {}; + this.map = Object.create(null); this.pending = 0; this.current = null; @@ -36,26 +36,26 @@ function Locker(named) { } /** - * Create a closure scoped locker. + * Create a closure scoped lock. * @param {Boolean?} named * @returns {Function} Lock method. */ -Locker.create = function create(named) { - var locker = new Locker(named); +Lock.create = function create(named) { + var lock = new Lock(named); return function lock(arg1, arg2) { - return locker.lock(arg1, arg2); + return lock.lock(arg1, arg2); }; }; /** - * Test whether the locker has a pending + * Test whether the lock has a pending * job or a job in progress (by name). * @param {String} name * @returns {Boolean} */ -Locker.prototype.has = function has(name) { +Lock.prototype.has = function has(name) { assert(this.named, 'Must use named jobs.'); if (this.current === name) @@ -65,24 +65,24 @@ Locker.prototype.has = function has(name) { }; /** - * Test whether the locker has + * Test whether the lock has * a pending job by name. * @param {String} name * @returns {Boolean} */ -Locker.prototype.hasPending = function hasPending(name) { +Lock.prototype.hasPending = function hasPending(name) { assert(this.named, 'Must use named jobs.'); return this.map[name] > 0; }; /** - * Test whether the locker is + * Test whether the lock is * busy with a named job. * @returns {Boolean} */ -Locker.prototype.isBusy = function isBusy() { +Lock.prototype.isBusy = function isBusy() { assert(this.named, 'Must use named jobs.'); if (this.current) return true; @@ -91,7 +91,7 @@ Locker.prototype.isBusy = function isBusy() { /** * Lock the parent object and all its methods - * which use the locker. Begin to queue calls. + * which use the lock. Begin to queue calls. * @param {String?} name - Job name. * @param {Boolean?} force - Bypass the lock. * @returns {Promise} - Returns {Function}, must be @@ -99,7 +99,7 @@ Locker.prototype.isBusy = function isBusy() { * to resolve the queue. */ -Locker.prototype.lock = function lock(arg1, arg2) { +Lock.prototype.lock = function lock(arg1, arg2) { var self = this; var name, force; @@ -112,7 +112,7 @@ Locker.prototype.lock = function lock(arg1, arg2) { } if (this.destroyed) - return Promise.reject(new Error('Locker is destroyed.')); + return Promise.reject(new Error('Lock is destroyed.')); if (force) { assert(this.busy); @@ -142,7 +142,7 @@ Locker.prototype.lock = function lock(arg1, arg2) { * @private */ -Locker.prototype.unlock = function unlock() { +Lock.prototype.unlock = function unlock() { var job; assert(this.destroyed || this.busy); @@ -181,13 +181,13 @@ Locker.prototype.unlock = function unlock() { * @returns {Promise} */ -Locker.prototype.wait = function wait() { +Lock.prototype.wait = function wait() { var self = this; assert(this.named, 'Must use named jobs.'); if (this.destroyed) - return Promise.reject(new Error('Locker is destroyed.')); + return Promise.reject(new Error('Lock is destroyed.')); if (!this.isBusy()) { assert(this.waiting.length === 0); @@ -204,7 +204,7 @@ Locker.prototype.wait = function wait() { * @private */ -Locker.prototype.drain = function drain() { +Lock.prototype.drain = function drain() { var i, jobs, job; if (this.waiting.length === 0) @@ -221,14 +221,14 @@ Locker.prototype.drain = function drain() { }; /** - * Destroy the locker. Purge all pending calls. + * Destroy the lock. Purge all pending calls. */ -Locker.prototype.destroy = function destroy() { - var err = new Error('Locker was destroyed.'); +Lock.prototype.destroy = function destroy() { + var err = new Error('Lock was destroyed.'); var i, jobs, job; - assert(!this.destroyed, 'Locker is already destroyed.'); + assert(!this.destroyed, 'Lock is already destroyed.'); this.destroyed = true; @@ -266,25 +266,25 @@ function MappedLock() { if (!(this instanceof MappedLock)) return MappedLock.create(); - this.jobs = {}; - this.busy = {}; + this.jobs = Object.create(null); + this.busy = Object.create(null); this.destroyed = false; } /** - * Create a closure scoped locker. + * Create a closure scoped lock. * @returns {Function} Lock method. */ MappedLock.create = function create() { - var locker = new MappedLock(); + var lock = new MappedLock(); return function lock(key, force) { - return locker.lock(key, force); + return lock.lock(key, force); }; }; /** - * Test whether the locker has a pending job by name. + * Test whether the lock has a pending job by name. * @param {String} name * @returns {Boolean} */ @@ -294,7 +294,7 @@ MappedLock.prototype.has = function has(name) { }; /** - * Test whether the locker is busy . + * Test whether the lock is busy . * @returns {Boolean} */ @@ -304,7 +304,7 @@ MappedLock.prototype.isBusy = function isBusy() { /** * Lock the parent object and all its methods - * which use the locker with a specified key. + * which use the lock with a specified key. * Begin to queue calls. * @param {String|Number} key * @param {Boolean?} force - Force a call. @@ -317,7 +317,7 @@ MappedLock.prototype.lock = function lock(key, force) { var self = this; if (this.destroyed) - return Promise.reject(new Error('Locker is destroyed.')); + return Promise.reject(new Error('Lock is destroyed.')); if (key == null) return Promise.resolve(nop); @@ -374,16 +374,16 @@ MappedLock.prototype.unlock = function unlock(key) { }; /** - * Destroy the locker. Purge all pending calls. + * Destroy the lock. Purge all pending calls. */ MappedLock.prototype.destroy = function destroy() { - var err = new Error('Locker was destroyed.'); + var err = new Error('Lock was destroyed.'); var map = this.jobs; var keys = Object.keys(map); var i, j, key, jobs, job; - assert(!this.destroyed, 'Locker is already destroyed.'); + assert(!this.destroyed, 'Lock is already destroyed.'); this.destroyed = true; @@ -401,7 +401,7 @@ MappedLock.prototype.destroy = function destroy() { }; /** - * Locker Job + * Lock Job * @exports Job * @constructor * @param {Function} resolve @@ -425,7 +425,7 @@ function nop() {} * Expose */ -exports = Locker; +exports = Lock; exports.Mapped = MappedLock; module.exports = exports; diff --git a/lib/utils/lru.js b/lib/utils/lru.js index 589cf05f..a7bffd30 100644 --- a/lib/utils/lru.js +++ b/lib/utils/lru.js @@ -27,7 +27,7 @@ function LRU(capacity, getSize) { this.capacity = capacity; this.getSize = getSize; - this.map = {}; + this.map = Object.create(null); this.size = 0; this.items = 0; this.head = null; diff --git a/lib/wallet/common.js b/lib/wallet/common.js index 1eee4b20..a2906e9d 100644 --- a/lib/wallet/common.js +++ b/lib/wallet/common.js @@ -19,6 +19,9 @@ common.isName = function isName(key) { if (typeof key !== 'string') return false; + if (key === '__proto__') + return false; + if (!/^[\-\._0-9A-Za-z]+$/.test(key)) return false; diff --git a/lib/wallet/masterkey.js b/lib/wallet/masterkey.js index 60fba3d7..57aa2de9 100644 --- a/lib/wallet/masterkey.js +++ b/lib/wallet/masterkey.js @@ -7,7 +7,7 @@ 'use strict'; var util = require('../utils/util'); -var Locker = require('../utils/locker'); +var Lock = require('../utils/lock'); var co = require('../utils/co'); var crypto = require('../crypto/crypto'); var assert = require('assert'); @@ -48,7 +48,7 @@ function MasterKey(options) { this.timer = null; this.until = 0; this._onTimeout = this.lock.bind(this); - this.locker = new Locker(this); + this.locker = new Lock(this); if (options) this.fromOptions(options); diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index 9e8b6ba7..d25ec457 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -12,7 +12,7 @@ var EventEmitter = require('events').EventEmitter; var Network = require('../protocol/network'); var util = require('../utils/util'); var encoding = require('../utils/encoding'); -var Locker = require('../utils/locker'); +var Lock = require('../utils/lock'); var co = require('../utils/co'); var crypto = require('../crypto/crypto'); var BufferReader = require('../utils/reader'); @@ -68,9 +68,9 @@ function Wallet(db, options) { this.db = db; this.network = db.network; this.logger = db.logger; - this.readLock = new Locker.Mapped(); - this.writeLock = new Locker(); - this.fundLock = new Locker(); + this.readLock = new Lock.Mapped(); + this.writeLock = new Lock(); + this.fundLock = new Lock(); this.indexCache = new LRU(10000); this.accountCache = new LRU(10000); this.pathCache = new LRU(100000); diff --git a/lib/wallet/walletdb.js b/lib/wallet/walletdb.js index c536bb08..0a517a75 100644 --- a/lib/wallet/walletdb.js +++ b/lib/wallet/walletdb.js @@ -11,7 +11,7 @@ var assert = require('assert'); var AsyncObject = require('../utils/async'); var util = require('../utils/util'); var co = require('../utils/co'); -var Locker = require('../utils/locker'); +var Lock = require('../utils/lock'); var LRU = require('../utils/lru'); var encoding = require('../utils/encoding'); var crypto = require('../crypto/crypto'); @@ -75,9 +75,9 @@ function WalletDB(options) { // We need one read lock for `get` and `create`. // It will hold locks specific to wallet ids. - this.readLock = new Locker.Mapped(); - this.writeLock = new Locker(); - this.txLock = new Locker(); + this.readLock = new Lock.Mapped(); + this.writeLock = new Lock(); + this.txLock = new Lock(); this.widCache = new LRU(10000); this.pathMapCache = new LRU(100000);