tx: refactor address getting.

This commit is contained in:
Christopher Jeffrey 2017-01-07 22:42:57 -08:00
parent 0eef277984
commit a4602a22cb
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -916,7 +916,7 @@ TX.prototype._getInputAddresses = function getInputAddresses(view) {
var i, address, hash, input, coin; var i, address, hash, input, coin;
if (this.isCoinbase()) if (this.isCoinbase())
return [addrs, table]; return new AddrResult(addrs, table);
for (i = 0; i < this.inputs.length; i++) { for (i = 0; i < this.inputs.length; i++) {
input = this.inputs[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) { TX.prototype._getAddresses = function getAddresses(view) {
var inputs = this._getInputAddresses(view); var input = this._getInputAddresses(view);
var output = this.getOutputAddresses(); var output = this.getOutputAddresses();
var addrs = inputs[0]; var addrs = input.addrs;
var table = inputs[1]; var table = input.table;
var i, hash; var i, address, hash;
for (i = 0; i < output.length; i++) { for (i = 0; i < output.length; i++) {
hash = output[i].getHash('hex'); address = output[i];
hash = address.getHash('hex');
if (!table[hash]) { if (!table[hash]) {
table[hash] = true; table[hash] = true;
addrs.push(output[i]); addrs.push(address);
} }
} }
return [addrs, table]; return input;
}; };
/** /**
* Get all input addresses. * Get all input addresses.
* @private * @param {CoinView|null} view
* @param {CoinView} view
* @returns {Address[]} addresses * @returns {Address[]} addresses
*/ */
TX.prototype.getInputAddresses = function getInputAddresses(view) { 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() { TX.prototype.getOutputAddresses = function getOutputAddresses() {
return this._getOutputAddresses()[0]; return this._getOutputAddresses().addrs;
}; };
/** /**
* Get all addresses. * Get all addresses.
* @param {CoinView} view * @param {CoinView|null} view
* @returns {Address[]} addresses * @returns {Address[]} addresses
*/ */
TX.prototype.getAddresses = function getAddresses(view) { TX.prototype.getAddresses = function getAddresses(view) {
return this._getAddresses(view)[0]; return this._getAddresses(view).addrs;
}; };
/** /**
* Get all input address hashes. * Get all input address hashes.
* @param {CoinView} view * @param {CoinView|null} view
* @returns {Hash[]} hashes * @returns {Hash[]} hashes
*/ */
TX.prototype.getInputHashes = function getInputHashes(view, enc) { TX.prototype.getInputHashes = function getInputHashes(view, enc) {
var i, input, table; var hashes = [];
var i, input, address;
if (enc === 'hex') { if (enc === 'hex') {
table = this._getInputAddresses(view)[1]; input = this._getInputAddresses(view);
return Object.keys(table); return Object.keys(input.table);
} }
input = this.getInputAddresses(view); input = this.getInputAddresses(view);
for (i = 0; i < input.length; i++) for (i = 0; i < input.length; i++) {
input[i] = input[i].getHash(); 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) { TX.prototype.getOutputHashes = function getOutputHashes(enc) {
var i, output, table; var hashes = [];
var i, output, address;
if (enc === 'hex') { if (enc === 'hex') {
table = this._getOutputAddresses()[1]; output = this._getOutputAddresses();
return Object.keys(table); return Object.keys(output.table);
} }
output = this.getOutputAddresses(); output = this.getOutputAddresses();
for (i = 0; i < output.length; i++) for (i = 0; i < output.length; i++) {
output[i] = output[i].getHash(); address = output[i];
hashes.push(address.getHash());
}
return output; return hashes;
}; };
/** /**
* Get all address hashes. * Get all address hashes.
* @param {CoinView} view * @param {CoinView|null} view
* @returns {Hash[]} hashes * @returns {Hash[]} hashes
*/ */
TX.prototype.getHashes = function getHashes(view, enc) { TX.prototype.getHashes = function getHashes(view, enc) {
var i, hashes, table; var hashes = [];
var i, result, address;
if (enc === 'hex') { if (enc === 'hex') {
table = this._getAddresses(view)[1]; result = this._getAddresses(view);
return Object.keys(table); return Object.keys(result.table);
} }
hashes = this.getAddresses(view); result = this.getAddresses(view);
for (i = 0; i < hashes.length; i++) for (i = 0; i < result.length; i++) {
hashes[i] = hashes[i].getHash(); address = result[i];
hashes.push(address.getHash());
}
return hashes; return hashes;
}; };
/** /**
* Test whether the transaction has * Test whether the transaction has
* all coins available/filled. * all coins available.
* @param {CoinView} view * @param {CoinView} view
* @returns {Boolean} * @returns {Boolean}
*/ */
@ -1102,7 +1111,7 @@ TX.prototype.hasCoins = function hasCoins(view) {
for (i = 0; i < this.inputs.length; i++) { for (i = 0; i < this.inputs.length; i++) {
input = this.inputs[i]; input = this.inputs[i];
if (!view.getOutput(input)) if (!view.hasEntry(input))
return false; 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 * @example
* tx.isFinal(network.height + 1, util.now()); * tx.isFinal(chain.height + 1, network.now());
* @param {Number} height - Height at which to test. This * @param {Number} height - Height at which to test. This
* is usually the chain height, or the chain height + 1 * is usually the chain height, or the chain height + 1
* when the transaction entered the mempool. * when the transaction entered the mempool.
@ -1125,13 +1135,13 @@ TX.prototype.hasCoins = function hasCoins(view) {
*/ */
TX.prototype.isFinal = function isFinal(height, ts) { TX.prototype.isFinal = function isFinal(height, ts) {
var threshold = consensus.LOCKTIME_THRESHOLD; var THRESHOLD = consensus.LOCKTIME_THRESHOLD;
var i, input; var i, input;
if (this.locktime === 0) if (this.locktime === 0)
return true; return true;
if (this.locktime < (this.locktime < threshold ? height : ts)) if (this.locktime < (this.locktime < THRESHOLD ? height : ts))
return true; return true;
for (i = 0; i < this.inputs.length; i++) { 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} index - Index of input being verified.
* @param {Number} locktime - Locktime to verify against. * @param {Number} locktime - Locktime to verify against.
* @returns {Boolean} * @returns {Boolean}
*/ */
TX.prototype.verifyLocktime = function verifyLocktime(index, locktime) { TX.prototype.verifyLocktime = function verifyLocktime(index, locktime) {
var threshold = consensus.LOCKTIME_THRESHOLD; var THRESHOLD = consensus.LOCKTIME_THRESHOLD;
var input = this.inputs[index]; var input = this.inputs[index];
if (!((this.locktime < threshold && locktime < threshold) assert(input, 'Input does not exist.');
|| (this.locktime >= threshold && locktime >= threshold))) { assert(locktime >= 0, 'Locktime must be non-negative.');
if (!((this.locktime < THRESHOLD && locktime < THRESHOLD)
|| (this.locktime >= THRESHOLD && locktime >= THRESHOLD))) {
return false; 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} index - Index of input being verified.
* @param {Number} locktime - Sequence locktime to verify against. * @param {Number} locktime - Sequence locktime to verify against.
* @returns {Boolean} * @returns {Boolean}
@ -1182,6 +1197,9 @@ TX.prototype.verifySequence = function verifySequence(index, locktime) {
var input = this.inputs[index]; var input = this.inputs[index];
var mask, sequence, predicate; var mask, sequence, predicate;
assert(input, 'Input does not exist.');
assert(locktime >= 0, 'Locktime must be non-negative.');
if ((locktime & DISABLE_FLAG) !== 0) if ((locktime & DISABLE_FLAG) !== 0)
return true; return true;
@ -1248,8 +1266,10 @@ TX.prototype.getScripthashSigops = function getScripthashSigops(view) {
if (!coin) if (!coin)
continue; continue;
if (coin.script.isScripthash()) if (!coin.script.isScripthash())
total += coin.script.getScripthashSigops(input.script); continue;
total += coin.script.getScripthashSigops(input.script);
} }
return total; return total;
@ -2624,6 +2644,11 @@ function RawTX(total, witness) {
this.witness = witness; this.witness = witness;
} }
function AddrResult(addrs, table) {
this.addrs = addrs;
this.table = table;
}
/* /*
* Expose * Expose
*/ */