fix tx pool addition and tx verification.

This commit is contained in:
Christopher Jeffrey 2016-01-03 01:34:50 -08:00
parent 73262b74ba
commit 3e5995f741
2 changed files with 35 additions and 20 deletions

View File

@ -65,7 +65,7 @@ TXPool.prototype._init = function init() {
TXPool.prototype.add = function add(tx, noWrite) {
var hash = tx.hash('hex');
var ownInput, ownOutput, updated;
var updated;
var i, input, key, unspent, index, orphan;
var out, key, orphans, some;
@ -87,8 +87,6 @@ TXPool.prototype.add = function add(tx, noWrite) {
}
this._all[hash] = tx;
ownInput = this._wallet.ownInput(tx);
ownOutput = this._wallet.ownOutput(tx);
updated = false;
// Consume unspent money or add orphans
@ -99,7 +97,12 @@ TXPool.prototype.add = function add(tx, noWrite) {
if (unspent) {
// Add TX to inputs and spend money
index = tx._input(unspent.tx, unspent.index);
index = tx._inputIndex(unspent.tx.hash('hex'), unspent.index);
assert(index !== -1);
assert(tx.inputs[index] === input);
assert(tx.inputs[index].out.hash === unspent.tx.hash('hex'));
assert(tx.inputs[index].out.index === unspent.index);
input.out.tx = unspent.tx;
// Skip invalid transactions
if (!tx.verify(index))
@ -110,10 +113,17 @@ TXPool.prototype.add = function add(tx, noWrite) {
continue;
}
// Only add orphans if this input is
// ours or the tx has outputs that are ours.
if (!ownOutput && (!ownInput || !~ownInput.indexOf(input)))
continue;
// Only add orphans if this input is ours.
// If there is no previous output, there's no way to truly
// verify this is ours, so we assume it is. If we add the
// signature checking code to ownInput for p2sh and p2pk,
// we could in theory use ownInput here (and down below)
// instead.
// if (this._wallet.ownInput(input.out.tx, input.out.index))
if (tx.inputs[i].out.tx) {
if (!this._wallet.ownOutput(input.out.tx, input.out.index))
continue;
}
// Add orphan, if no parent transaction is yet known
orphan = { tx: tx, index: input.out.index };
@ -123,19 +133,22 @@ TXPool.prototype.add = function add(tx, noWrite) {
this._orphans[key] = [orphan];
}
if (!ownOutput) {
if (!this._wallet.ownOutput(tx)) {
if (updated)
this.emit('update', this._lastTs, tx);
// Save spending TXs without adding unspents
if (this._wallet.ownInput(tx)) {
this._storeTX(hash, tx, noWrite);
}
// if (this._wallet.ownInput(tx))
this._storeTX(hash, tx, noWrite);
return;
}
function checkOrphan(orphan) {
var index = orphan.tx._input(tx, orphan.index);
var index = orphan.tx._inputIndex(tx.hash('hex'), orphan.index);
assert(index !== -1);
assert(orphan.tx.inputs[index].out.hash === tx.hash('hex'));
assert(orphan.tx.inputs[index].out.index === i);
orphan.tx.inputs[index].out.tx = tx;
// Verify that input script is correct, if not - add output to unspent
// and remove orphan from storage
@ -151,7 +164,7 @@ TXPool.prototype.add = function add(tx, noWrite) {
out = tx.outputs[i];
// Do not add unspents for outputs that aren't ours.
if (!~ownOutput.indexOf(out))
if (!this._wallet.ownOutput(tx, i))
continue;
key = hash + '/' + i;

View File

@ -77,8 +77,8 @@ TX.prototype.hash = function hash(enc) {
return enc === 'hex' ? utils.toHex(h) : h;
};
TX.prototype.render = function render() {
if (this.network && this._raw)
TX.prototype.render = function render(force) {
if (!force && this.network && this._raw)
return this._raw.slice();
return bcoin.protocol.framer.tx(this);
};
@ -124,7 +124,7 @@ TX.prototype._input = function _input(obj, index) {
});
// Try modifying existing input first
i = this._inputIndex(hash, index);
i = this._inputIndex(input.out.hash, input.out.index);
if (i !== -1) {
ex = this.inputs[i];
input.out.tx = input.out.tx || ex.out.tx;
@ -489,8 +489,7 @@ TX.prototype.subscriptHash = function subscriptHash(index, s, type) {
copy.outputs.forEach(function(output, i) {
if (i !== index) {
output.script = [];
output.value = utils.toArray('ffffffffffffffff', 'hex');
output.value.toArray = function() { return this; };
output.value = new bn('ffffffffffffffff', 'hex');
}
});
copy.inputs.forEach(function(input, i) {
@ -504,7 +503,7 @@ TX.prototype.subscriptHash = function subscriptHash(index, s, type) {
copy.inputs[0].script = s;
}
verifyStr = copy.render();
verifyStr = copy.render(true);
utils.writeU32(verifyStr, type, verifyStr.length);
@ -930,6 +929,9 @@ TX.fromJSON = function fromJSON(json) {
data.network = json.network;
data.relayedBy = json.relayedBy;
data._raw = raw;
data._size = raw.length;
tx = new TX(data);
tx.ts = json.ts;
tx.block = json.block || null;