diff --git a/browser/wsproxy.js b/browser/wsproxy.js index 700c1380..46807708 100644 --- a/browser/wsproxy.js +++ b/browser/wsproxy.js @@ -100,7 +100,7 @@ WSProxy.prototype._handleConnect = function _handleConnect(ws, port, host, nonce pow.writeString(host, 'ascii'); pow = pow.render(); - if (util.cmp(crypto.hash256(pow), this.target) > 0) { + if (crypto.hash256(pow).compare(this.target) > 0) { this.log('Client did not solve proof of work (%s).', state.host); ws.emit('tcp close'); ws.disconnect(); diff --git a/lib/blockchain/chain.js b/lib/blockchain/chain.js index 51abcf3c..0dd3c0ff 100644 --- a/lib/blockchain/chain.js +++ b/lib/blockchain/chain.js @@ -366,7 +366,7 @@ Chain.prototype.verify = co(function* verify(block, prev, flags) { true); } - if (!util.equal(commit, block.createCommitmentHash())) { + if (!commit.equals(block.createCommitmentHash())) { throw new VerifyError(block, 'invalid', 'bad-witness-merkle-match', diff --git a/lib/crypto/crypto.js b/lib/crypto/crypto.js index 637636c6..9a098a8d 100644 --- a/lib/crypto/crypto.js +++ b/lib/crypto/crypto.js @@ -219,7 +219,7 @@ crypto.createMerkleTree = function createMerkleTree(leaves) { right = nodes[j + k]; if (k === i + 1 && k + 1 === size - && left.compare(right) === 0) { + && left.equals(right)) { malleated = true; } diff --git a/lib/crypto/ec-secp256k1.js b/lib/crypto/ec-secp256k1.js index e26c0c5b..3b1ad4f4 100644 --- a/lib/crypto/ec-secp256k1.js +++ b/lib/crypto/ec-secp256k1.js @@ -259,12 +259,12 @@ ec.isLowS = function isLowS(sig) { return false; } - if (util.equal(s, ZERO_S)) + if (s.equals(ZERO_S)) return false; // If S is greater than half the order, // it's too high. - if (util.cmp(s, HALF_ORDER) > 0) + if (s.compare(HALF_ORDER) > 0) return false; return true; diff --git a/lib/db/memdb.js b/lib/db/memdb.js index 542c6ee1..d3a4a645 100644 --- a/lib/db/memdb.js +++ b/lib/db/memdb.js @@ -27,7 +27,7 @@ function MemDB(location) { this.location = location || 'memory'; this.options = {}; - this.tree = new RBT(util.cmp, true); + this.tree = new RBT(cmp, true); } /** @@ -679,6 +679,14 @@ IteratorOptions.prototype.fromOptions = function fromOptions(options) { return this; }; +/* + * Helpers + */ + +function cmp(a, b) { + return a.compare(b); +} + /* * Expose */ diff --git a/lib/hd/private.js b/lib/hd/private.js index f7b18ee2..6001ba7b 100644 --- a/lib/hd/private.js +++ b/lib/hd/private.js @@ -404,10 +404,10 @@ HDPrivateKey.prototype.equal = function equal(obj) { return this.network === obj.network && this.depth === obj.depth - && util.equal(this.parentFingerPrint, obj.parentFingerPrint) + && this.parentFingerPrint.equals(obj.parentFingerPrint) && this.childIndex === obj.childIndex - && util.equal(this.chainCode, obj.chainCode) - && util.equal(this.privateKey, obj.privateKey); + && this.chainCode.equals(obj.chainCode) + && this.privateKey.equals(obj.privateKey); }; /** @@ -426,7 +426,7 @@ HDPrivateKey.prototype.compare = function compare(key) { if (cmp !== 0) return cmp; - cmp = util.cmp(this.parentFingerPrint, key.parentFingerPrint); + cmp = this.parentFingerPrint.compare(key.parentFingerPrint); if (cmp !== 0) return cmp; @@ -436,12 +436,12 @@ HDPrivateKey.prototype.compare = function compare(key) { if (cmp !== 0) return cmp; - cmp = util.cmp(this.chainCode, key.chainCode); + cmp = this.chainCode.compare(key.chainCode); if (cmp !== 0) return cmp; - cmp = util.cmp(this.privateKey, key.privateKey); + cmp = this.privateKey.compare(key.privateKey); if (cmp !== 0) return cmp; diff --git a/lib/hd/public.js b/lib/hd/public.js index d4f8c167..a4af6eba 100644 --- a/lib/hd/public.js +++ b/lib/hd/public.js @@ -320,10 +320,10 @@ HDPublicKey.prototype.equal = function equal(obj) { return this.network === obj.network && this.depth === obj.depth - && util.equal(this.parentFingerPrint, obj.parentFingerPrint) + && this.parentFingerPrint.equals(obj.parentFingerPrint) && this.childIndex === obj.childIndex - && util.equal(this.chainCode, obj.chainCode) - && util.equal(this.publicKey, obj.publicKey); + && this.chainCode.equals(obj.chainCode) + && this.publicKey.equals(obj.publicKey); }; /** @@ -342,7 +342,7 @@ HDPublicKey.prototype.compare = function compare(key) { if (cmp !== 0) return cmp; - cmp = util.cmp(this.parentFingerPrint, key.parentFingerPrint); + cmp = this.parentFingerPrint.compare(key.parentFingerPrint); if (cmp !== 0) return cmp; @@ -352,12 +352,12 @@ HDPublicKey.prototype.compare = function compare(key) { if (cmp !== 0) return cmp; - cmp = util.cmp(this.chainCode, key.chainCode); + cmp = this.chainCode.compare(key.chainCode); if (cmp !== 0) return cmp; - cmp = util.cmp(this.publicKey, key.publicKey); + cmp = this.publicKey.compare(key.publicKey); if (cmp !== 0) return cmp; diff --git a/lib/net/bip150.js b/lib/net/bip150.js index 6fc3bd1d..7c3963ee 100644 --- a/lib/net/bip150.js +++ b/lib/net/bip150.js @@ -125,7 +125,7 @@ BIP150.prototype.challenge = function challenge(hash) { assert(!this.challengeReceived, 'Peer challenged twice.'); this.challengeReceived = true; - if (util.equal(hash, encoding.ZERO_HASH)) + if (hash.equals(encoding.ZERO_HASH)) throw new Error('Auth failure.'); msg = this.hash(this.input.sid, type, this.publicKey); @@ -160,7 +160,7 @@ BIP150.prototype.reply = function reply(data) { assert(!this.replyReceived, 'Peer replied twice.'); this.replyReceived = true; - if (util.equal(data, encoding.ZERO_SIG64)) + if (data.equals(encoding.ZERO_SIG64)) throw new Error('Auth failure.'); if (!this.peerIdentity) diff --git a/lib/net/bip151.js b/lib/net/bip151.js index b3d5ce32..630fca60 100644 --- a/lib/net/bip151.js +++ b/lib/net/bip151.js @@ -434,7 +434,7 @@ BIP151.prototype.encinit = function encinit(publicKey, cipher) { BIP151.prototype.encack = function encack(publicKey) { assert(this.initSent, 'Unsolicited ACK.'); - if (util.equal(publicKey, encoding.ZERO_KEY)) { + if (publicKey.equals(encoding.ZERO_KEY)) { assert(this.handshake, 'No initialization before rekey.'); if (this.bip150 && this.bip150.auth) { diff --git a/lib/net/peer.js b/lib/net/peer.js index cb068d60..fbdaf2c1 100644 --- a/lib/net/peer.js +++ b/lib/net/peer.js @@ -1825,8 +1825,8 @@ Peer.prototype.handlePong = co(function* handlePong(packet) { return; } - if (!util.equal(nonce, this.challenge)) { - if (util.equal(nonce, encoding.ZERO_U64)) { + if (!nonce.equals(this.challenge)) { + if (nonce.equals(encoding.ZERO_U64)) { this.logger.debug('Peer sent a zero nonce (%s).', this.hostname()); this.challenge = null; return; diff --git a/lib/net/proxysocket.js b/lib/net/proxysocket.js index 7ae8681e..e59df7e8 100644 --- a/lib/net/proxysocket.js +++ b/lib/net/proxysocket.js @@ -129,7 +129,7 @@ ProxySocket.prototype.connect = function connect(port, host) { nonce++; assert(nonce <= 0xffffffff, 'Could not create socket.'); pow.writeUInt32LE(nonce, 0, true); - } while (util.cmp(crypto.hash256(pow), this.target) > 0); + } while (crypto.hash256(pow).compare(this.target) > 0); util.log('Solved proof of work: %d', nonce); } diff --git a/lib/primitives/address.js b/lib/primitives/address.js index 0f5fe116..1374dcd4 100644 --- a/lib/primitives/address.js +++ b/lib/primitives/address.js @@ -108,10 +108,10 @@ Address.prototype.isNull = function isNull() { var i; if (this.hash.length === 20) - return util.equal(this.hash, encoding.ZERO_HASH160); + return this.hash.equals(encoding.ZERO_HASH160); if (this.hash.length === 32) - return util.equal(this.hash, encoding.ZERO_HASH); + return this.hash.equals(encoding.ZERO_HASH); for (i = 0; i < this.hash.length; i++) { if (this.hash[i] !== 0) diff --git a/lib/primitives/keyring.js b/lib/primitives/keyring.js index d069f499..4990bec2 100644 --- a/lib/primitives/keyring.js +++ b/lib/primitives/keyring.js @@ -637,16 +637,16 @@ KeyRing.prototype.ownHash = function ownHash(hash) { if (!hash) return false; - if (util.equal(hash, this.getKeyHash())) + if (hash.equals(this.getKeyHash())) return true; if (this.script) { - if (util.equal(hash, this.getScriptHash())) + if (hash.equals(this.getScriptHash())) return true; } if (this.witness) { - if (util.equal(hash, this.getNestedHash())) + if (hash.equals(this.getNestedHash())) return true; } @@ -682,15 +682,15 @@ KeyRing.prototype.ownOutput = function ownOutput(tx, index) { KeyRing.prototype.getRedeem = function(hash) { if (this.witness) { - if (util.equal(hash, this.getNestedHash())) + if (hash.equals(this.getNestedHash())) return this.getProgram(); } if (this.script) { - if (util.equal(hash, this.getScriptHash160())) + if (hash.equals(this.getScriptHash160())) return this.script; - if (util.equal(hash, this.getScriptHash256())) + if (hash.equals(this.getScriptHash256())) return this.script; } diff --git a/lib/primitives/merkleblock.js b/lib/primitives/merkleblock.js index 4bf455bb..bf19896a 100644 --- a/lib/primitives/merkleblock.js +++ b/lib/primitives/merkleblock.js @@ -234,7 +234,7 @@ MerkleBlock.prototype.extractTree = function extractTree() { left = traverse(height - 1, pos * 2); if (pos * 2 + 1 < width(height - 1)) { right = traverse(height - 1, pos * 2 + 1); - if (util.equal(right, left)) + if (right.equals(left)) failed = true; } else { right = left; diff --git a/lib/primitives/mtx.js b/lib/primitives/mtx.js index 0576643c..e49e1daf 100644 --- a/lib/primitives/mtx.js +++ b/lib/primitives/mtx.js @@ -515,7 +515,7 @@ MTX.prototype.scriptVector = function scriptVector(prev, vector, ring) { // P2PK if (prev.isPubkey()) { - if (!util.equal(prev.get(0), ring.publicKey)) + if (!prev.get(0).equals(ring.publicKey)) return false; vector.set(0, opcodes.OP_0); @@ -525,7 +525,7 @@ MTX.prototype.scriptVector = function scriptVector(prev, vector, ring) { // P2PKH if (prev.isPubkeyhash()) { - if (!util.equal(prev.get(2), ring.getKeyHash())) + if (!prev.get(2).equals(ring.getKeyHash())) return false; vector.set(0, opcodes.OP_0); @@ -653,7 +653,7 @@ MTX.prototype.signVector = function signVector(prev, vector, sig, ring) { // P2PK if (prev.isPubkey()) { // Make sure the pubkey is ours. - if (!util.equal(ring.publicKey, prev.get(0))) + if (!ring.publicKey.equals(prev.get(0))) return false; // Already signed. @@ -672,7 +672,7 @@ MTX.prototype.signVector = function signVector(prev, vector, sig, ring) { // P2PKH if (prev.isPubkeyhash()) { // Make sure the pubkey hash is ours. - if (!util.equal(ring.getKeyHash(), prev.get(2))) + if (!ring.getKeyHash().equals(prev.get(2))) return false; // Already signed. @@ -1867,7 +1867,7 @@ function sortOutputs(a, b) { if (cmp !== 0) return cmp; - return util.cmp(a.script.toRaw(), b.script.toRaw()); + return a.script.raw.compare(b.script.raw); } /* diff --git a/lib/primitives/netaddress.js b/lib/primitives/netaddress.js index 105da261..f59b0bbf 100644 --- a/lib/primitives/netaddress.js +++ b/lib/primitives/netaddress.js @@ -183,7 +183,7 @@ NetAddress.prototype.equal = function equal(addr) { */ NetAddress.prototype.compare = function compare(addr) { - var cmp = util.cmp(this.raw, addr.raw); + var cmp = this.raw.compare(addr.raw); if (cmp !== 0) return cmp; diff --git a/lib/script/script.js b/lib/script/script.js index 4f786445..a46d0252 100644 --- a/lib/script/script.js +++ b/lib/script/script.js @@ -896,7 +896,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers v1 = stack.top(-2); v2 = stack.top(-1); - res = util.equal(v1, v2); + res = v1.equals(v2); stack.pop(); stack.pop(); @@ -1348,7 +1348,7 @@ Script.prototype.removeData = function removeData(data) { if (!op.isMinimal()) continue; - if (util.equal(op.data, data)) + if (op.data.equals(data)) index.push(i); } @@ -1382,7 +1382,7 @@ Script.prototype.indexOf = function indexOf(data) { if (!op.data) continue; - if (util.equal(op.data, data)) + if (op.data.equals(data)) return i; } @@ -2349,7 +2349,7 @@ Script.getCoinbaseHeight = function getCoinbaseHeight(raw) { // Ensure the miner serialized the // number in the most minimal fashion. - if (!util.equal(data, op.data)) + if (!data.equals(op.data)) return -1; return height.toNumber(); @@ -2867,7 +2867,7 @@ Script.verify = function verify(input, witness, output, tx, i, value, flags) { hadWitness = true; // Input script must be exactly one push of the redeem script. - if (!util.equal(input.raw, Opcode.fromPush(raw).toRaw())) + if (!input.raw.equals(Opcode.fromPush(raw).toRaw())) throw new ScriptError('WITNESS_MALLEATED_P2SH'); // Verify the program in the redeem script. @@ -2924,7 +2924,7 @@ Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i, val witnessScript = stack.pop(); - if (!util.equal(crypto.sha256(witnessScript), program.data)) + if (!crypto.sha256(witnessScript).equals(program.data)) throw new ScriptError('WITNESS_PROGRAM_MISMATCH'); redeem = new Script(witnessScript); @@ -3084,7 +3084,7 @@ Script.verifyMast = function verifyMast(program, stack, output, flags, tx, i, va mastRoot.writeBytes(scriptRoot); mastRoot = crypto.hash256(mastRoot.render()); - if (!util.equal(mastRoot, program.data)) + if (!mastRoot.equals(program.data)) throw new ScriptError('WITNESS_PROGRAM_MISMATCH'); if (version === 0) { @@ -3230,7 +3230,7 @@ Script.isScript = function isScript(obj) { function sortKeys(keys) { return keys.slice().sort(function(a, b) { - return util.cmp(a, b); + return a.compare(b); }); } diff --git a/lib/script/sigcache.js b/lib/script/sigcache.js index 116609c3..688f86fc 100644 --- a/lib/script/sigcache.js +++ b/lib/script/sigcache.js @@ -147,7 +147,7 @@ function SigCacheEntry(sig, key) { */ SigCacheEntry.prototype.equal = function equal(sig, key) { - return util.equal(this.sig, sig) && util.equal(this.key, key); + return this.sig.equals(sig) && this.key.equals(key); }; /* diff --git a/lib/utils/util.js b/lib/utils/util.js index 8196ab89..52029453 100644 --- a/lib/utils/util.js +++ b/lib/utils/util.js @@ -63,14 +63,10 @@ util.isBrowser = * @const {String} */ -if (os.homedir) { +util.HOME = '/'; + +if (os.homedir) util.HOME = os.homedir(); -} else { - util.HOME = process.env.HOME - || process.env.USERPROFILE - || process.env.HOMEPATH - || '/'; -} /** * Global NOP function. @@ -161,39 +157,6 @@ util.isHex = function isHex(obj) { && obj.length % 2 === 0; }; -/** - * Test whether two buffers are equal. - * @param {Buffer?} a - * @param {Buffer?} b - * @returns {Boolean} - */ - -util.equal = function equal(a, b) { - var i; - - if (a == null) - return false; - - if (b == null) - return false; - - assert(Buffer.isBuffer(a)); - assert(Buffer.isBuffer(b)); - - if (a.compare) - return a.compare(b) === 0; - - if (a.length !== b.length) - return false; - - for (i = 0; i < a.length; i++) { - if (a[i] !== b[i]) - return false; - } - - return true; -}; - /** * Call `setImmediate`, `process.nextTick`, * or `setInterval` depending. @@ -483,27 +446,6 @@ util.error = function error() { process.stderr.write(msg + '\n'); }; -/** - * Unique-ify an array of strings. - * @param {String[]} obj - * @returns {String[]} - */ - -util.uniq = function uniq(obj) { - var table = {}; - var out = []; - var i = 0; - - for (; i < obj.length; i++) { - if (!table[obj[i]]) { - out.push(obj[i]); - table[obj[i]] = true; - } - } - - return out; -}; - /** * Get current time in unix time (seconds). * @returns {Number} @@ -632,10 +574,6 @@ util.cmp = function cmp(a, b) { return a.compare(b); }; -// Warning: polymorphism. -if (!Buffer.prototype.compare) - util.cmp = util.strcmp; - /** * Convert bytes to mb. * @param {Number} size @@ -648,28 +586,28 @@ util.mb = function mb(size) { /** * Inheritance. - * @param {Function} obj - Constructor to inherit. - * @param {Function} from - Parent constructor. + * @param {Function} child - Constructor to inherit. + * @param {Function} parent - Parent constructor. */ -util.inherits = function inherits(obj, from) { +util.inherits = function inherits(child, parent) { var f; - obj.super_ = from; + child.super_ = parent; if (Object.setPrototypeOf) { - Object.setPrototypeOf(obj.prototype, from.prototype); - Object.defineProperty(obj.prototype, 'constructor', { - value: obj, + Object.setPrototypeOf(child.prototype, parent.prototype); + Object.defineProperty(child.prototype, 'constructor', { + value: child, enumerable: false }); return; } if (Object.create) { - obj.prototype = Object.create(from.prototype, { + child.prototype = Object.create(parent.prototype, { constructor: { - value: obj, + value: child, enumerable: false } }); @@ -677,9 +615,9 @@ util.inherits = function inherits(obj, from) { } f = function() {}; - f.prototype = from.prototype; - obj.prototype = new f; - obj.prototype.constructor = obj; + f.prototype = parent.prototype; + child.prototype = new f(); + child.prototype.constructor = child; }; /** @@ -690,15 +628,17 @@ util.inherits = function inherits(obj, from) { */ util.indexOf = function indexOf(obj, data) { - var i; + var i, chunk; assert(Array.isArray(obj)); assert(Buffer.isBuffer(data)); for (i = 0; i < obj.length; i++) { - if (!Buffer.isBuffer(obj[i])) - continue; - if (util.equal(obj[i], data)) + chunk = obj[i]; + + assert(Buffer.isBuffer(chunk)); + + if (chunk.equals(data)) return i; } @@ -939,40 +879,15 @@ util.binaryInsert = function binaryInsert(items, item, compare, uniq) { util.binaryRemove = function binaryRemove(items, item, compare) { var i = util.binarySearch(items, item, compare, false); + if (i === -1) return false; + items.splice(i, 1); + return true; }; -/** - * Unique-ify and sort an array of buffers. - * @param {Buffer[]} items - * @returns {Buffer[]} - */ - -util.uniqBuffer = function uniqBuffer(items) { - var out = []; - var i, j, item; - - for (i = 0; i < items.length; i++) { - item = items[i]; - j = util.binarySearch(out, item, util.cmp, true); - - if (j < out.length && util.cmp(out[j], item) === 0) - continue; - - if (j === 0) - out.unshift(item); - else if (j === out.length) - out.push(item); - else - out.splice(j, 0, item); - } - - return out; -}; - /** * Normalize a path. * @param {String} path diff --git a/lib/wallet/txdb.js b/lib/wallet/txdb.js index 510641e1..21fb38f7 100644 --- a/lib/wallet/txdb.js +++ b/lib/wallet/txdb.js @@ -657,7 +657,7 @@ TXDB.prototype.removeBlock = co(function* removeBlock(hash, height) { size = data.readUInt32LE(40, true); assert(size > 0); - assert(util.equal(data.slice(-32), hash)); + assert(data.slice(-32).equals(hash)); if (size === 1) { this.del(key); diff --git a/test/wallet-test.js b/test/wallet-test.js index 11bf291d..f8f4fc9c 100644 --- a/test/wallet-test.js +++ b/test/wallet-test.js @@ -1237,7 +1237,7 @@ describe('Wallet', function() { assert(path.data && path.encrypted); d2 = path.data; - assert(!util.equal(d1, d2)); + assert(!d1.equals(d2)); k = yield w.getKey(addr); assert(!k);