From a4602a22cb1ed3a389f8f601b538bcbe5bc35874 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sat, 7 Jan 2017 22:42:57 -0800 Subject: [PATCH] tx: refactor address getting. --- lib/primitives/tx.js | 123 ++++++++++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 49 deletions(-) diff --git a/lib/primitives/tx.js b/lib/primitives/tx.js index 509d990d..7ca53442 100644 --- a/lib/primitives/tx.js +++ b/lib/primitives/tx.js @@ -916,7 +916,7 @@ TX.prototype._getInputAddresses = function getInputAddresses(view) { var i, address, hash, input, coin; if (this.isCoinbase()) - return [addrs, table]; + return new AddrResult(addrs, table); for (i = 0; i < this.inputs.length; i++) { input = this.inputs[i]; @@ -934,7 +934,7 @@ TX.prototype._getInputAddresses = function getInputAddresses(view) { } } - return [addrs, table]; + return new AddrResult(addrs, table); }; /** @@ -963,7 +963,7 @@ TX.prototype._getOutputAddresses = function getOutputAddresses() { } } - return [addrs, table]; + return new AddrResult(addrs, table); }; /** @@ -974,33 +974,33 @@ TX.prototype._getOutputAddresses = function getOutputAddresses() { */ TX.prototype._getAddresses = function getAddresses(view) { - var inputs = this._getInputAddresses(view); + var input = this._getInputAddresses(view); var output = this.getOutputAddresses(); - var addrs = inputs[0]; - var table = inputs[1]; - var i, hash; + var addrs = input.addrs; + var table = input.table; + var i, address, hash; for (i = 0; i < output.length; i++) { - hash = output[i].getHash('hex'); + address = output[i]; + hash = address.getHash('hex'); if (!table[hash]) { table[hash] = true; - addrs.push(output[i]); + addrs.push(address); } } - return [addrs, table]; + return input; }; /** * Get all input addresses. - * @private - * @param {CoinView} view + * @param {CoinView|null} view * @returns {Address[]} addresses */ TX.prototype.getInputAddresses = function getInputAddresses(view) { - return this._getInputAddresses(view)[0]; + return this._getInputAddresses(view).addrs; }; /** @@ -1009,39 +1009,42 @@ TX.prototype.getInputAddresses = function getInputAddresses(view) { */ TX.prototype.getOutputAddresses = function getOutputAddresses() { - return this._getOutputAddresses()[0]; + return this._getOutputAddresses().addrs; }; /** * Get all addresses. - * @param {CoinView} view + * @param {CoinView|null} view * @returns {Address[]} addresses */ TX.prototype.getAddresses = function getAddresses(view) { - return this._getAddresses(view)[0]; + return this._getAddresses(view).addrs; }; /** * Get all input address hashes. - * @param {CoinView} view + * @param {CoinView|null} view * @returns {Hash[]} hashes */ TX.prototype.getInputHashes = function getInputHashes(view, enc) { - var i, input, table; + var hashes = []; + var i, input, address; if (enc === 'hex') { - table = this._getInputAddresses(view)[1]; - return Object.keys(table); + input = this._getInputAddresses(view); + return Object.keys(input.table); } input = this.getInputAddresses(view); - for (i = 0; i < input.length; i++) - input[i] = input[i].getHash(); + for (i = 0; i < input.length; i++) { + address = input[i]; + hashes.push(address.getHash()); + } - return input; + return hashes; }; /** @@ -1050,46 +1053,52 @@ TX.prototype.getInputHashes = function getInputHashes(view, enc) { */ TX.prototype.getOutputHashes = function getOutputHashes(enc) { - var i, output, table; + var hashes = []; + var i, output, address; if (enc === 'hex') { - table = this._getOutputAddresses()[1]; - return Object.keys(table); + output = this._getOutputAddresses(); + return Object.keys(output.table); } output = this.getOutputAddresses(); - for (i = 0; i < output.length; i++) - output[i] = output[i].getHash(); + for (i = 0; i < output.length; i++) { + address = output[i]; + hashes.push(address.getHash()); + } - return output; + return hashes; }; /** * Get all address hashes. - * @param {CoinView} view + * @param {CoinView|null} view * @returns {Hash[]} hashes */ TX.prototype.getHashes = function getHashes(view, enc) { - var i, hashes, table; + var hashes = []; + var i, result, address; if (enc === 'hex') { - table = this._getAddresses(view)[1]; - return Object.keys(table); + result = this._getAddresses(view); + return Object.keys(result.table); } - hashes = this.getAddresses(view); + result = this.getAddresses(view); - for (i = 0; i < hashes.length; i++) - hashes[i] = hashes[i].getHash(); + for (i = 0; i < result.length; i++) { + address = result[i]; + hashes.push(address.getHash()); + } return hashes; }; /** * Test whether the transaction has - * all coins available/filled. + * all coins available. * @param {CoinView} view * @returns {Boolean} */ @@ -1102,7 +1111,7 @@ TX.prototype.hasCoins = function hasCoins(view) { for (i = 0; i < this.inputs.length; i++) { input = this.inputs[i]; - if (!view.getOutput(input)) + if (!view.hasEntry(input)) return false; } @@ -1110,9 +1119,10 @@ TX.prototype.hasCoins = function hasCoins(view) { }; /** - * Check finality of transaction by examining nLockTime and nSequences. + * Check finality of transaction by examining + * nLocktime and nSequence values. * @example - * tx.isFinal(network.height + 1, util.now()); + * tx.isFinal(chain.height + 1, network.now()); * @param {Number} height - Height at which to test. This * is usually the chain height, or the chain height + 1 * when the transaction entered the mempool. @@ -1125,13 +1135,13 @@ TX.prototype.hasCoins = function hasCoins(view) { */ TX.prototype.isFinal = function isFinal(height, ts) { - var threshold = consensus.LOCKTIME_THRESHOLD; + var THRESHOLD = consensus.LOCKTIME_THRESHOLD; var i, input; if (this.locktime === 0) return true; - if (this.locktime < (this.locktime < threshold ? height : ts)) + if (this.locktime < (this.locktime < THRESHOLD ? height : ts)) return true; for (i = 0; i < this.inputs.length; i++) { @@ -1144,18 +1154,22 @@ TX.prototype.isFinal = function isFinal(height, ts) { }; /** - * Verify the nLockTime of a transaction. + * Verify the absolute locktime of a transaction. + * Called by OP_CHECKLOCKTIMEVERIFY. * @param {Number} index - Index of input being verified. * @param {Number} locktime - Locktime to verify against. * @returns {Boolean} */ TX.prototype.verifyLocktime = function verifyLocktime(index, locktime) { - var threshold = consensus.LOCKTIME_THRESHOLD; + var THRESHOLD = consensus.LOCKTIME_THRESHOLD; var input = this.inputs[index]; - if (!((this.locktime < threshold && locktime < threshold) - || (this.locktime >= threshold && locktime >= threshold))) { + assert(input, 'Input does not exist.'); + assert(locktime >= 0, 'Locktime must be non-negative.'); + + if (!((this.locktime < THRESHOLD && locktime < THRESHOLD) + || (this.locktime >= THRESHOLD && locktime >= THRESHOLD))) { return false; } @@ -1169,7 +1183,8 @@ TX.prototype.verifyLocktime = function verifyLocktime(index, locktime) { }; /** - * Verify the nSequence locktime of a transaction. + * Verify the relative locktime of an input. + * Called by OP_CHECKSEQUENCEVERIFY. * @param {Number} index - Index of input being verified. * @param {Number} locktime - Sequence locktime to verify against. * @returns {Boolean} @@ -1182,6 +1197,9 @@ TX.prototype.verifySequence = function verifySequence(index, locktime) { var input = this.inputs[index]; var mask, sequence, predicate; + assert(input, 'Input does not exist.'); + assert(locktime >= 0, 'Locktime must be non-negative.'); + if ((locktime & DISABLE_FLAG) !== 0) return true; @@ -1248,8 +1266,10 @@ TX.prototype.getScripthashSigops = function getScripthashSigops(view) { if (!coin) continue; - if (coin.script.isScripthash()) - total += coin.script.getScripthashSigops(input.script); + if (!coin.script.isScripthash()) + continue; + + total += coin.script.getScripthashSigops(input.script); } return total; @@ -2624,6 +2644,11 @@ function RawTX(total, witness) { this.witness = witness; } +function AddrResult(addrs, table) { + this.addrs = addrs; + this.table = table; +} + /* * Expose */