use utxo object instead of tx refs.

This commit is contained in:
Christopher Jeffrey 2016-02-06 04:54:38 -08:00
parent 26f1e44eb3
commit 274c6e6864
9 changed files with 370 additions and 159 deletions

View File

@ -338,14 +338,19 @@ Address.prototype.ownOutput = function ownOutput(tx, index) {
var hash = this.getKeyHash();
var key = this.getPublicKey();
var keys = this.keys;
var outputs;
var outputs = tx.outputs;
outputs = tx.outputs.filter(function(output, i) {
if ((tx instanceof bcoin.output) || (tx instanceof bcoin.output.prev))
outputs = [tx];
outputs = outputs.filter(function(output, i) {
var s = output.script;
if (index != null && index !== i)
return false;
return output.testScript(key, hash, keys, scriptHash, null);
if (bcoin.script.isPubkey(s, key))
return true;
@ -375,17 +380,24 @@ Address.prototype.ownInput = function ownInput(tx, index) {
var key = this.getPublicKey();
var redeem = this.getScript();
var keys = this.keys;
var inputs;
var inputs = tx.inputs;
inputs = tx.inputs.filter(function(input, i) {
if (!input.prevout.tx && this.tx._all[input.prevout.hash])
input.prevout.tx = this.tx._all[input.prevout.hash];
if (tx instanceof bcoin.input) {
inputs = [tx];
tx = null;
}
if (tx)
this._wallet.fillPrevout(tx);
inputs = inputs.filter(function(input, i) {
if (index != null && index !== i)
return false;
if (input.prevout.tx)
return !!this.ownOutput(input.prevout.tx, input.prevout.index);
if (input.output)
return !!this.ownOutput(input.output);
return input.testScript(key, redeem, null);
// if (bcoin.script.isPubkeyInput(input.script, key, tx, i))
// return true;
@ -416,10 +428,10 @@ Address.prototype.scriptInputs = function scriptInputs(tx) {
var redeem = this.getScript();
return tx.inputs.reduce(function(total, input, i) {
if (!input.prevout.tx)
if (!input.output)
return total;
if (!self.ownOutput(input.prevout.tx, input.prevout.index))
if (!self.ownOutput(input.output))
return total;
if (tx.scriptInput(i, publicKey, redeem))
@ -438,10 +450,10 @@ Address.prototype.signInputs = function signInputs(tx, type) {
return 0;
return tx.inputs.reduce(function(total, input, i) {
if (!input.prevout.tx)
if (!input.output)
return total;
if (!self.ownOutput(input.prevout.tx, input.prevout.index))
if (!self.ownOutput(input.output))
return total;
if (tx.signInput(i, key, type))
@ -463,10 +475,10 @@ Address.prototype.sign = function sign(tx, type) {
// Add signature script to each input
return tx.inputs.reduce(function(total, input, i) {
// Filter inputs that this wallet own
if (!input.prevout.tx)
if (!input.output)
return total;
if (!self.ownOutput(input.prevout.tx, input.prevout.index))
if (!self.ownOutput(input.output))
return total;
if (tx.scriptSig(i, key, publicKey, redeem, type))

View File

@ -459,10 +459,10 @@ Block.prototype.verifyContext = function verifyContext() {
// We need the previous output in order
// to verify the script.
if (!input.prevout.tx)
if (!input.output)
continue;
assert(input.prevout.tx);
assert(input.output);
// Verify the script
if (!tx.verify(j, true, flags)) {

View File

@ -22,17 +22,21 @@ function Input(options) {
prevout = options.prevout || options.out;
this.tx = options.tx;
this.prevout = {
tx: prevout.tx || null,
hash: prevout.hash,
index: prevout.index
index: prevout.index,
rhash: prevout.rhash
};
if (options.output)
this.output = bcoin.output.prev(options.output);
if (utils.isBuffer(this.prevout.hash))
this.prevout.hash = utils.toHex(this.prevout.hash);
if (!this.prevout.rhash)
this.prevout.rhash = utils.toHex(this.prevout.hash);
this.script = options.script ? options.script.slice() : [];
this.sequence = options.sequence == null ? 0xffffffff : options.sequence;
@ -91,7 +95,7 @@ Input.prototype.__defineGetter__('key', function() {
return this.keys[0];
});
Input.prototype.__defineGetter__('hash', function() {
Input.prototype.__defineGetter__('hash160', function() {
return this.data.scriptHash || this.hashes[0];
});
@ -153,22 +157,12 @@ Input.prototype.__defineGetter__('text', function() {
return this.data.text;
});
Input.prototype.__defineGetter__('output', function() {
if (!this.prevout.tx)
return;
return this.prevout.tx.outputs[this.prevout.index];
});
Input.prototype.__defineGetter__('value', function() {
if (!this.output)
return;
return this.output.value;
});
Input.prototype.__defineGetter__('tx', function() {
return this.prevout.tx;
});
Input.prototype.__defineGetter__('addr', function() {
return this.address;
});
@ -238,7 +232,7 @@ Input.getData = function getData(input) {
def.prev = input.prevout.hash;
def.index = input.prevout.index;
if (+input.prevout.hash === 0) {
if (input.isCoinbase()) {
data = bcoin.script.getCoinbaseData(input.script);
return utils.merge(def, data, {
type: 'coinbase',
@ -307,45 +301,62 @@ Input.prototype.getLocktime = function getLocktime() {
return bcoin.script.getLocktime(redeem);
};
Input.prototype.createScript = function createScript(pub, redeem) {
return this.tx.scriptInput(this, pub, redeem);
};
Input.prototype.signatureHash = function signatureHash(s, type) {
return this.tx.signatureHash(this, s, type);
};
Input.prototype.createSignature = function createSignature(key, type) {
return this.tx.createSignature(this, key, type);
};
Input.prototype.sign = function sign(key, type) {
return this.tx.signInput(this, key, type);
};
Input.prototype.scriptSig = function scriptSig(key, pub, redeem, type) {
return this.tx.scriptSig(this, key, pub, redeem, type);
};
Input.prototype.isSigned = function isSigned(required) {
return this.tx.isSigned(this, required);
};
Input.prototype.verify = function verify(force, flags) {
return this.tx.verify(this, force, flags);
};
Input.prototype.isCoinbase = function isCoinbase() {
return this.tx.isCoinbase();
return +this.prevout.hash === 0;
};
Input.prototype.test = function test(addressTable, collect) {
return this.tx.testInputs(addressTable, this, collect);
Input.prototype.testScript = function testScript(key, redeem, type) {
// if (!type || type === 'pubkey') {
// if (key) {
// if (bcoin.script.isPubkeyInput(this.script, key, tx, i))
// return true;
// }
// }
if (!type || type === 'pubkeyhash') {
if (key) {
if (bcoin.script.isPubkeyhashInput(this.script, key))
return true;
}
}
// if (!type || type === 'multisig') {
// if (keys) {
// if (bcoin.script.isMultisigInput(input.script, keys, tx, i))
// return true;
// }
// }
if (!type || type === 'scripthash') {
if (redeem) {
if (bcoin.script.isScripthashInput(this.script, redeem))
return true;
}
}
return false;
};
Input.prototype.test = function test(addressTable) {
var data = this.getData();
var i;
if (data.scriptAddress) {
if (addressTable[data.scriptAddress] != null)
return true;
}
for (i = 0; i < data.addresses.length; i++) {
if (addressTable[data.addresses[i]] != null)
return true;
}
return false;
};
Input.prototype.getSigops = function getSigops(scriptHash, accurate) {
var n = bcoin.script.getSigops(this.script, accurate);
if (scriptHash && !this.tx.isCoinbase())
if (scriptHash && !this.isCoinbase())
n += bcoin.script.getScripthashSigops(this.script);
return n;
};
@ -356,7 +367,7 @@ Input.prototype.inspect = function inspect() {
: { type: 'unknown', value: '0.0' };
output.hash = this.prevout.hash;
output.rhash = utils.revHex(this.prevout.hash);
output.rhash = this.prevout.rhash;
output.index = this.prevout.index;
return {

View File

@ -142,7 +142,7 @@ Miner.prototype.addTX = function addTX(tx) {
var full, ts;
full = this.index.inputs.every(function(input) {
return !!input.prevout.tx;
return !!input.output;
});
// Cannot calculate fee if we don't have the prev_out.

View File

@ -6,6 +6,7 @@
var bn = require('bn.js');
var bcoin = require('../bcoin');
var inherits = require('inherits');
var utils = bcoin.utils;
var assert = utils.assert;
var constants = bcoin.protocol.constants;
@ -25,7 +26,6 @@ function Output(options) {
if (typeof value === 'number' && (value | 0) === value)
value = new bn(value);
this.tx = options.tx;
this.value = utils.satoshi(value || new bn(0));
this.script = options.script ? options.script.slice() : [];
@ -66,7 +66,7 @@ Output.prototype.__defineGetter__('key', function() {
return this.keys[0];
});
Output.prototype.__defineGetter__('hash', function() {
Output.prototype.__defineGetter__('hash160', function() {
return this.data.scriptHash || this.hashes[0];
});
@ -222,12 +222,53 @@ Output.prototype.getID = function getID() {
return '[' + this.type + ':' + hash.slice(0, 7) + ']';
};
Output.prototype.createScript = function createScript(options) {
return this.tx.scriptOutput(this, options);
Output.prototype.testScript = function testScript(key, hash, keys, scriptHash, type) {
if (!type || type === 'pubkey') {
if (key) {
if (bcoin.script.isPubkey(this.script, key))
return true;
}
}
if (!type || type === 'pubkeyhash') {
if (hash) {
if (bcoin.script.isPubkeyhash(this.script, hash))
return true;
}
}
if (!type || type === 'multisig') {
if (keys) {
if (bcoin.script.isMultisig(this.script, keys))
return true;
}
}
if (!type || type === 'scripthash') {
if (scriptHash) {
if (bcoin.script.isScripthash(this.script, scriptHash))
return true;
}
}
return false;
};
Output.prototype.test = function test(addressTable, collect) {
return this.tx.testOutputs(addressTable, this, collect);
Output.prototype.test = function test(addressTable) {
var data = this.getData();
var i;
if (data.scriptAddress) {
if (addressTable[data.scriptAddress] != null)
return true;
}
for (i = 0; i < data.addresses.length; i++) {
if (addressTable[data.addresses[i]] != null)
return true;
}
return false;
};
Output.prototype.getSigops = function getSigops(accurate) {
@ -251,8 +292,111 @@ Output.prototype.inspect = function inspect() {
};
};
// This is basically a UTXO/Coin object. It is immutable once instantiated. It
// needs to store 5 properties: the tx hash, output index, output value, output
// script, and the block height the transaction was mined (to later calculate
// age).
function Prevout(tx, index) {
var options;
if (!(this instanceof Prevout))
return new Prevout(tx, index);
if (tx instanceof Prevout)
return tx;
if (tx instanceof bcoin.tx) {
this.hash = tx.hash('hex');
this.index = index;
this.value = tx.outputs[index].value;
this.script = tx.outputs[index].script;
this.height = tx.getHeight();
} else {
options = tx;
this.hash = options.hash;
this.index = options.index;
this.value = options.value;
this.script = options.script;
this.height = options.height;
}
if (utils.isBuffer(this.hash))
this.hash = utils.toHex(this.hash);
assert(typeof this.hash === 'string');
assert(utils.isFinite(this.index));
assert(this.value instanceof bn);
assert(Array.isArray(this.script));
assert(utils.isFinite(this.height));
Object.freeze(this);
}
inherits(Prevout, Output);
Prevout.prototype.__defineGetter__('chain', function() {
return this._chain || bcoin.chain.global;
});
Prevout.prototype.getConfirmations = function getConfirmations() {
var top;
if (!this.chain)
return 0;
top = this.chain.height();
if (this.height === -1)
return 0;
return top - this.height + 1;
};
Prevout.prototype.__defineGetter__('confirmations', function() {
return this.getConfirmations();
});
Prevout.prototype.getAge = function getAge() {
var age = this.getConfirmations();
if (age === -1)
age = 0;
if (age !== 0)
age += 1;
return age;
};
Prevout.prototype.__defineGetter__('age', function() {
return this.getAge();
});
Prevout.prototype.toJSON = function toJSON() {
return {
hash: this.hash,
index: this.index,
value: utils.btc(this.value),
script: utils.toHex(bcoin.script.encode(this.script)),
height: this.height
};
};
Prevout.fromJSON = function fromJSON(json) {
return new Prevout({
hash: json.hash,
index: json.index,
value: utils.satoshi(json.value),
script: bcoin.script.decode(utils.toArray(json.script, 'hex')),
height: json.height
});
};
/**
* Expose
*/
module.exports = Output;
exports = Output;
exports.prev = Prevout;
module.exports = exports;

View File

@ -1307,12 +1307,16 @@ script.getInputData = function getData(s, prev) {
// We could call _getInputData, but
// we really only need the signatures.
if (output.type === 'pubkey') {
output.signatures = [s[0]];
if (s.length >= 1)
output.signatures = [s[0]];
} else if (output.type === 'pubkeyhash') {
output.signatures = [s[0]];
output.keys = [s[1]];
if (s.length >= 2) {
output.signatures = [s[0]];
output.keys = [s[1]];
}
} else if (output.type === 'multisig') {
output.signatures = s.slice(1);
if (s.length >= 2)
output.signatures = s.slice(1);
} else if (output.type === 'scripthash') {
// Scripthash is the only case where
// we get more data from the input
@ -1345,6 +1349,13 @@ script._getInputData = function _getInputData(s, type) {
assert(typeof type === 'string');
if (type === 'pubkey') {
if (s.length < 1) {
return {
type: 'pubkey',
side: 'input',
none: true
};
}
sig = s[0];
return {
type: 'pubkey',
@ -1355,6 +1366,13 @@ script._getInputData = function _getInputData(s, type) {
}
if (type === 'pubkeyhash') {
if (s.length < 2) {
return {
type: 'pubkeyhash',
side: 'input',
none: true
};
}
sig = s[0];
key = s[1];
hash = bcoin.wallet.key2hash(key);
@ -1370,6 +1388,13 @@ script._getInputData = function _getInputData(s, type) {
}
if (type === 'multisig') {
if (s.length < 2) {
return {
type: 'multisig',
side: 'input',
none: true
};
}
sig = s.slice(1);
return {
type: 'multisig',
@ -1381,6 +1406,13 @@ script._getInputData = function _getInputData(s, type) {
}
if (type === 'scripthash') {
if (s.length < 1) {
return {
type: 'scripthash',
side: 'input',
none: true
};
}
raw = s[s.length - 1];
redeem = script.decode(raw);
locktime = script.getLocktime(redeem);

View File

@ -86,6 +86,8 @@ TXPool.prototype.add = function add(tx, noWrite, strict) {
var i, input, key, unspent, index, orphan;
var out, key, orphans, some;
this._wallet.fillPrevout(tx);
if (strict) {
if (!this._wallet.ownInput(tx) && !this._wallet.ownOutput(tx))
return false;
@ -120,17 +122,14 @@ TXPool.prototype.add = function add(tx, noWrite, strict) {
key = input.prevout.hash + '/' + input.prevout.index;
unspent = this._unspent[key];
if (!input.prevout.tx && this._all[input.prevout.hash])
input.prevout.tx = this._all[input.prevout.hash];
if (unspent) {
// Add TX to inputs and spend money
index = tx._inputIndex(unspent.tx.hash('hex'), unspent.index);
index = tx._inputIndex(unspent.hash, unspent.index);
assert(index !== -1);
assert(tx.inputs[index] === input);
assert(tx.inputs[index].prevout.hash === unspent.tx.hash('hex'));
assert(tx.inputs[index].prevout.hash === unspent.hash);
assert(tx.inputs[index].prevout.index === unspent.index);
input.prevout.tx = unspent.tx;
input.output = unspent;
// Skip invalid transactions
if (!tx.verify(index))
@ -149,8 +148,8 @@ TXPool.prototype.add = function add(tx, noWrite, strict) {
// signature checking code to ownInput for p2sh and p2pk,
// we could in theory use ownInput here (and down below)
// instead.
if (input.prevout.tx) {
if (!this._wallet.ownOutput(input.prevout.tx, input.prevout.index))
if (input.output) {
if (!this._wallet.ownOutput(input.output))
continue;
}
@ -177,7 +176,7 @@ TXPool.prototype.add = function add(tx, noWrite, strict) {
assert(index !== -1);
assert(orphan.tx.inputs[index].prevout.hash === tx.hash('hex'));
assert(orphan.tx.inputs[index].prevout.index === i);
orphan.tx.inputs[index].prevout.tx = tx;
orphan.tx.inputs[index].output = bcoin.output.prev(tx, i);
// Verify that input script is correct, if not - add output to unspent
// and remove orphan from storage
@ -211,7 +210,7 @@ TXPool.prototype.add = function add(tx, noWrite, strict) {
delete this._orphans[key];
if (!orphans) {
this._unspent[key] = { tx: tx, index: i };
this._unspent[key] = bcoin.output.prev(tx, i);
updated = true;
}
}
@ -327,11 +326,11 @@ TXPool.prototype._addInput = function _addInput(tx, i, remove) {
var input = tx.inputs[i];
var prev, address;
if (!this._wallet.ownOutput(input.prevout.tx, input.prevout.index))
return;
assert(input.output);
if (!this._wallet.ownOutput(input.output))
return;
prev = input.output;
address = prev.getAddress();
@ -378,7 +377,7 @@ TXPool.prototype.getUnspent = function getUnspent(address) {
return Object.keys(this._unspent).map(function(key) {
return this._unspent[key];
}, this).filter(function(item) {
return address.ownOutput(item.tx, item.index);
return address.ownOutput(item);
});
};

View File

@ -128,14 +128,11 @@ TX.prototype.input = TX.prototype.addInput;
TX.prototype._addInput = function _addInput(options, index) {
var input, ex, i, prevout;
if (options instanceof TX)
options = { prevout: { tx: options, index: index } };
else if (typeof options === 'string' || utils.isBuffer(options))
options = { prevout: { hash: options, index: index } };
else if (!options.prevout)
options = { prevout: options, script: options.script, sequence: options.sequence };
else
options = options;
if (options instanceof TX) {
options = { tx: options, index: index };
} else if (typeof options === 'string' || utils.isBuffer(options)) {
options = { hash: options, index: index };
}
if (options.out)
options.prevout = options.out;
@ -143,16 +140,37 @@ TX.prototype._addInput = function _addInput(options, index) {
if (options.seq != null)
options.sequence = options.seq;
if (options.prevout.tx)
options.prevout.hash = options.prevout.tx.hash('hex');
if (!options.prevout) {
if (options instanceof bcoin.output.prev) {
options = {
prevout: { hash: options.hash, index: options.index },
output: options
};
} else if (options.tx) {
var prev = bcoin.output.prev(options.tx, options.index);
options = {
prevout: { hash: prev.hash, index: prev.index },
output: prev,
script: options.script,
sequence: options.sequence
};
} else if (options.hash) {
options = {
prevout: { hash: options.hash, index: options.index },
output: options.output,
script: options.script,
sequence: options.sequence
};
}
}
input = bcoin.input({
tx: this,
prevout: {
tx: options.prevout.tx,
hash: options.prevout.hash,
index: options.prevout.index
},
output: options.output,
script: options.script,
sequence: options.sequence
});
@ -161,8 +179,8 @@ TX.prototype._addInput = function _addInput(options, index) {
i = this._inputIndex(input.prevout.hash, input.prevout.index);
if (i !== -1) {
ex = this.inputs[i];
input.prevout.tx = input.prevout.tx || ex.prevout.tx;
input.sequence = input.sequence || ex.sequence;
input.output = input.output || ex.output;
input.sequence = input.sequence != null ? input.sequence : ex.sequence;
input.script = input.script.length ? input.script : ex.script;
this.inputs[i] = input;
} else {
@ -886,10 +904,6 @@ TX.prototype.verify = function verify(index, force, flags) {
if (!input.output)
return false;
// Somethis is very wrong if this is
// not the case.
assert.equal(input.prevout.tx.hash('hex'), input.prevout.hash);
return bcoin.script.verify(input.script, input.output.script, this, i, flags);
}, this);
};
@ -1015,7 +1029,7 @@ TX.prototype.getInputs = function getInputs(unspent, address, fee) {
// Oldest unspents first
unspent = unspent.slice().sort(function(a, b) {
return b.tx.getConfirmations() - a.tx.getConfirmations();
return a.height - b.height;
});
function addInput(unspent) {
@ -1289,7 +1303,7 @@ TX.prototype.getTargetLocktime = function getTargetLocktime() {
TX.prototype.testInputs = function testInputs(addressTable, index, collect) {
var inputs = [];
var i, input, j, addresses, scriptAddress;
var i, input;
if (typeof addressTable === 'string')
addressTable = [addressTable];
@ -1313,24 +1327,10 @@ TX.prototype.testInputs = function testInputs(addressTable, index, collect) {
input = this.inputs[i];
addresses = input.getAddresses();
if (addresses) {
for (j = 0; j < addresses.length; j++) {
if (addressTable[addresses[j]] != null) {
if (!collect)
return true;
inputs.push(input);
}
}
}
scriptAddress = input.getScriptAddress();
if (scriptAddress) {
if (addressTable[scriptAddress] != null) {
if (!collect)
return true;
inputs.push(input);
}
if (input.test(addressTable)) {
if (!collect)
return true;
inputs.push(input);
}
}
@ -1345,7 +1345,7 @@ TX.prototype.testInputs = function testInputs(addressTable, index, collect) {
TX.prototype.testOutputs = function testOutputs(addressTable, index, collect) {
var outputs = [];
var i, output, data, j, addresses, scriptAddress;
var i, output;
if (typeof addressTable === 'string')
addressTable = [addressTable];
@ -1369,24 +1369,10 @@ TX.prototype.testOutputs = function testOutputs(addressTable, index, collect) {
output = this.outputs[i];
addresses = output.getAddresses();
if (addresses) {
for (j = 0; j < addresses.length; j++) {
if (addressTable[addresses[j]] != null) {
if (!collect)
return true;
outputs.push(output);
}
}
}
scriptAddress = output.getScriptAddress();
if (scriptAddress) {
if (addressTable[scriptAddress] != null) {
if (!collect)
return true;
outputs.push(output);
}
if (output.test(addressTable)) {
if (!collect)
return true;
outputs.push(output);
}
}
@ -1438,7 +1424,7 @@ TX.prototype.hasPrevout = function hasPrevout() {
return false;
return this.inputs.every(function(input) {
return !!input.prevout.tx;
return !!input.output;
});
};
@ -1458,9 +1444,9 @@ TX.prototype.fillPrevout = function fillPrevout(txs) {
}
inputs = this.inputs.filter(function(input) {
if (!input.prevout.tx && txs[input.prevout.hash])
input.prevout.tx = txs[input.prevout.hash];
return !!input.prevout.tx;
if (!input.output && txs[input.prevout.hash])
input.output = bcoin.output.prev(txs[input.prevout.hash], input.prevout.index);
return !!input.output;
}, this);
return inputs.length === this.inputs.length;
@ -1646,10 +1632,10 @@ TX.prototype.getPriority = function getPriority() {
for (i = 0; i < this.inputs.length; i++) {
input = this.inputs[i];
if (!input.prevout.tx)
if (!input.output)
return constants.tx.freeThreshold.clone();
age = input.prevout.tx.getConfirmations();
age = input.output.getConfirmations();
if (age === -1)
age = 0;
@ -1749,7 +1735,8 @@ TX.prototype.inspect = function inspect() {
copy.fee = utils.btc(this.getFee());
copy.height = this.getHeight();
copy.confirmations = this.getConfirmations();
// copy.priority = this.getPriority().toString(10);
if (this.hasPrevout())
copy.priority = this.getPriority().toString(10);
copy.date = new Date((copy.ts || 0) * 1000).toISOString();
if (copy.hardFee)
copy.hardFee = utils.btc(copy.hardFee);

View File

@ -813,11 +813,39 @@ Wallet.prototype.getAddress = function getAddress() {
};
Wallet.prototype.ownInput = function ownInput(tx, index) {
if (tx instanceof bcoin.input) {
var input = tx;
var scriptAddress = input.getScriptAddress();
if (this._addressTable[scriptAddress] != null)
return true;
var addresses = input.getAddresses();
var address;
for (var i = 0; i < addresses.length; i++) {
address = addresses[i];
if (this._addressTable[address] != null)
return true;
}
return false;
}
this.fillPrevout(tx);
return tx.testInputs(this._addressTable, index, true);
};
Wallet.prototype.ownOutput = function ownOutput(tx, index) {
if ((tx instanceof bcoin.output) || (tx instanceof bcoin.output.prev)) {
var output = tx;
var scriptAddress = output.getScriptAddress();
if (this._addressTable[scriptAddress] != null)
return true;
var addresses = output.getAddresses();
var address;
for (var i = 0; i < addresses.length; i++) {
address = addresses[i];
if (this._addressTable[address] != null)
return true;
}
return false;
}
return tx.testOutputs(this._addressTable, index, true);
};
@ -831,13 +859,11 @@ Wallet.prototype.fill = function fill(tx, address, fee) {
unspent = this.getUnspent();
items = unspent.filter(function(item) {
var output = item.tx.outputs[item.index];
if (bcoin.script.isScripthash(output.script))
items = unspent.filter(function(coin) {
if (bcoin.script.isScripthash(coin.script))
return this.type === 'scripthash';
if (bcoin.script.isMultisig(output.script))
if (bcoin.script.isMultisig(coin.script))
return this.type === 'multisig';
return true;