tx: add bip69 sorting.
This commit is contained in:
parent
2deccde29e
commit
13d14b0130
@ -1166,6 +1166,40 @@ TX.prototype.fill = function fill(unspent, address, fee) {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki
|
||||||
|
TX.prototype.sortMembers = function sortMembers() {
|
||||||
|
var changeOutput;
|
||||||
|
|
||||||
|
if (this.changeIndex !== -1) {
|
||||||
|
changeOutput = this.outputs[this.changeIndex];
|
||||||
|
assert(changeOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inputs = this.inputs.slice().sort(function(a, b) {
|
||||||
|
var res = new bn(a.prevout.hash, 'hex').cmp(new bn(b.prevout.hash, 'hex'));
|
||||||
|
if (res !== 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return a.prevout.index - b.prevout.index;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.outputs = this.outputs.slice().sort(function(a, b) {
|
||||||
|
var res = a.value.cmp(b.value);
|
||||||
|
if (res !== 0)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
a = bcoin.script.encode(a.script);
|
||||||
|
b = bcoin.script.encode(b.script);
|
||||||
|
|
||||||
|
return new bn(a).cmp(b);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.changeIndex !== -1) {
|
||||||
|
this.changeIndex = this.outputs.indexOf(changeOutput);
|
||||||
|
assert(this.changeIndex !== -1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Legacy
|
// Legacy
|
||||||
TX.prototype.fillUnspent = TX.prototype.fill;
|
TX.prototype.fillUnspent = TX.prototype.fill;
|
||||||
TX.prototype.fillInputs = TX.prototype.fill;
|
TX.prototype.fillInputs = TX.prototype.fill;
|
||||||
@ -1258,7 +1292,7 @@ TX.prototype.getFunds = function getFunds(side) {
|
|||||||
// Legacy
|
// Legacy
|
||||||
TX.prototype.funds = TX.prototype.getFunds;
|
TX.prototype.funds = TX.prototype.getFunds;
|
||||||
|
|
||||||
TX.prototype.getTargetTime = function getTargetTime() {
|
TX.prototype.getTargetLocktime = function getTargetLocktime() {
|
||||||
var bestValue = 0;
|
var bestValue = 0;
|
||||||
var i, locktime, bestType;
|
var i, locktime, bestType;
|
||||||
|
|
||||||
|
|||||||
@ -392,27 +392,35 @@ Wallet.prototype.createTX = function createTX(outputs, fee) {
|
|||||||
if (!Array.isArray(outputs))
|
if (!Array.isArray(outputs))
|
||||||
outputs = [outputs];
|
outputs = [outputs];
|
||||||
|
|
||||||
|
// Add the outputs
|
||||||
outputs.forEach(function(output) {
|
outputs.forEach(function(output) {
|
||||||
tx.addOutput(output);
|
tx.addOutput(output);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fill the inputs with unspents
|
||||||
if (!this.fill(tx, null, fee))
|
if (!this.fill(tx, null, fee))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Sort members a la BIP69
|
||||||
|
tx.sortMembers();
|
||||||
|
|
||||||
// Find the necessary locktime if there is
|
// Find the necessary locktime if there is
|
||||||
// a checklocktimeverify script in the unspents.
|
// a checklocktimeverify script in the unspents.
|
||||||
target = tx.getTargetTime();
|
target = tx.getTargetLocktime();
|
||||||
|
|
||||||
// No target value. The unspents have an
|
// No target value. The unspents have an
|
||||||
// incompatible locktime type.
|
// incompatible locktime type.
|
||||||
if (!target)
|
if (!target)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Set the locktime to target value or
|
||||||
|
// `height - whatever` to avoid fee snipping.
|
||||||
if (target.value > 0)
|
if (target.value > 0)
|
||||||
tx.setLocktime(target.value);
|
tx.setLocktime(target.value);
|
||||||
else
|
else
|
||||||
tx.avoidFeeSnipping();
|
tx.avoidFeeSnipping();
|
||||||
|
|
||||||
|
// Sign the inputs
|
||||||
this.sign(tx);
|
this.sign(tx);
|
||||||
|
|
||||||
return tx;
|
return tx;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user