fix tx pool addition and tx verification.
This commit is contained in:
parent
73262b74ba
commit
3e5995f741
@ -65,7 +65,7 @@ TXPool.prototype._init = function init() {
|
|||||||
|
|
||||||
TXPool.prototype.add = function add(tx, noWrite) {
|
TXPool.prototype.add = function add(tx, noWrite) {
|
||||||
var hash = tx.hash('hex');
|
var hash = tx.hash('hex');
|
||||||
var ownInput, ownOutput, updated;
|
var updated;
|
||||||
var i, input, key, unspent, index, orphan;
|
var i, input, key, unspent, index, orphan;
|
||||||
var out, key, orphans, some;
|
var out, key, orphans, some;
|
||||||
|
|
||||||
@ -87,8 +87,6 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
|||||||
}
|
}
|
||||||
this._all[hash] = tx;
|
this._all[hash] = tx;
|
||||||
|
|
||||||
ownInput = this._wallet.ownInput(tx);
|
|
||||||
ownOutput = this._wallet.ownOutput(tx);
|
|
||||||
updated = false;
|
updated = false;
|
||||||
|
|
||||||
// Consume unspent money or add orphans
|
// Consume unspent money or add orphans
|
||||||
@ -99,7 +97,12 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
|||||||
|
|
||||||
if (unspent) {
|
if (unspent) {
|
||||||
// Add TX to inputs and spend money
|
// 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
|
// Skip invalid transactions
|
||||||
if (!tx.verify(index))
|
if (!tx.verify(index))
|
||||||
@ -110,10 +113,17 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only add orphans if this input is
|
// Only add orphans if this input is ours.
|
||||||
// ours or the tx has outputs that are ours.
|
// If there is no previous output, there's no way to truly
|
||||||
if (!ownOutput && (!ownInput || !~ownInput.indexOf(input)))
|
// verify this is ours, so we assume it is. If we add the
|
||||||
continue;
|
// 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
|
// Add orphan, if no parent transaction is yet known
|
||||||
orphan = { tx: tx, index: input.out.index };
|
orphan = { tx: tx, index: input.out.index };
|
||||||
@ -123,19 +133,22 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
|||||||
this._orphans[key] = [orphan];
|
this._orphans[key] = [orphan];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ownOutput) {
|
if (!this._wallet.ownOutput(tx)) {
|
||||||
if (updated)
|
if (updated)
|
||||||
this.emit('update', this._lastTs, tx);
|
this.emit('update', this._lastTs, tx);
|
||||||
|
|
||||||
// Save spending TXs without adding unspents
|
// Save spending TXs without adding unspents
|
||||||
if (this._wallet.ownInput(tx)) {
|
// if (this._wallet.ownInput(tx))
|
||||||
this._storeTX(hash, tx, noWrite);
|
this._storeTX(hash, tx, noWrite);
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkOrphan(orphan) {
|
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
|
// Verify that input script is correct, if not - add output to unspent
|
||||||
// and remove orphan from storage
|
// and remove orphan from storage
|
||||||
@ -151,7 +164,7 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
|||||||
out = tx.outputs[i];
|
out = tx.outputs[i];
|
||||||
|
|
||||||
// Do not add unspents for outputs that aren't ours.
|
// Do not add unspents for outputs that aren't ours.
|
||||||
if (!~ownOutput.indexOf(out))
|
if (!this._wallet.ownOutput(tx, i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
key = hash + '/' + i;
|
key = hash + '/' + i;
|
||||||
|
|||||||
@ -77,8 +77,8 @@ TX.prototype.hash = function hash(enc) {
|
|||||||
return enc === 'hex' ? utils.toHex(h) : h;
|
return enc === 'hex' ? utils.toHex(h) : h;
|
||||||
};
|
};
|
||||||
|
|
||||||
TX.prototype.render = function render() {
|
TX.prototype.render = function render(force) {
|
||||||
if (this.network && this._raw)
|
if (!force && this.network && this._raw)
|
||||||
return this._raw.slice();
|
return this._raw.slice();
|
||||||
return bcoin.protocol.framer.tx(this);
|
return bcoin.protocol.framer.tx(this);
|
||||||
};
|
};
|
||||||
@ -124,7 +124,7 @@ TX.prototype._input = function _input(obj, index) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Try modifying existing input first
|
// Try modifying existing input first
|
||||||
i = this._inputIndex(hash, index);
|
i = this._inputIndex(input.out.hash, input.out.index);
|
||||||
if (i !== -1) {
|
if (i !== -1) {
|
||||||
ex = this.inputs[i];
|
ex = this.inputs[i];
|
||||||
input.out.tx = input.out.tx || ex.out.tx;
|
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) {
|
copy.outputs.forEach(function(output, i) {
|
||||||
if (i !== index) {
|
if (i !== index) {
|
||||||
output.script = [];
|
output.script = [];
|
||||||
output.value = utils.toArray('ffffffffffffffff', 'hex');
|
output.value = new bn('ffffffffffffffff', 'hex');
|
||||||
output.value.toArray = function() { return this; };
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
copy.inputs.forEach(function(input, i) {
|
copy.inputs.forEach(function(input, i) {
|
||||||
@ -504,7 +503,7 @@ TX.prototype.subscriptHash = function subscriptHash(index, s, type) {
|
|||||||
copy.inputs[0].script = s;
|
copy.inputs[0].script = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyStr = copy.render();
|
verifyStr = copy.render(true);
|
||||||
|
|
||||||
utils.writeU32(verifyStr, type, verifyStr.length);
|
utils.writeU32(verifyStr, type, verifyStr.length);
|
||||||
|
|
||||||
@ -930,6 +929,9 @@ TX.fromJSON = function fromJSON(json) {
|
|||||||
data.network = json.network;
|
data.network = json.network;
|
||||||
data.relayedBy = json.relayedBy;
|
data.relayedBy = json.relayedBy;
|
||||||
|
|
||||||
|
data._raw = raw;
|
||||||
|
data._size = raw.length;
|
||||||
|
|
||||||
tx = new TX(data);
|
tx = new TX(data);
|
||||||
tx.ts = json.ts;
|
tx.ts = json.ts;
|
||||||
tx.block = json.block || null;
|
tx.block = json.block || null;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user