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;
|
||||
};
|
||||
|
||||
// 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
|
||||
TX.prototype.fillUnspent = TX.prototype.fill;
|
||||
TX.prototype.fillInputs = TX.prototype.fill;
|
||||
@ -1258,7 +1292,7 @@ TX.prototype.getFunds = function getFunds(side) {
|
||||
// Legacy
|
||||
TX.prototype.funds = TX.prototype.getFunds;
|
||||
|
||||
TX.prototype.getTargetTime = function getTargetTime() {
|
||||
TX.prototype.getTargetLocktime = function getTargetLocktime() {
|
||||
var bestValue = 0;
|
||||
var i, locktime, bestType;
|
||||
|
||||
|
||||
@ -392,27 +392,35 @@ Wallet.prototype.createTX = function createTX(outputs, fee) {
|
||||
if (!Array.isArray(outputs))
|
||||
outputs = [outputs];
|
||||
|
||||
// Add the outputs
|
||||
outputs.forEach(function(output) {
|
||||
tx.addOutput(output);
|
||||
});
|
||||
|
||||
// Fill the inputs with unspents
|
||||
if (!this.fill(tx, null, fee))
|
||||
return;
|
||||
|
||||
// Sort members a la BIP69
|
||||
tx.sortMembers();
|
||||
|
||||
// Find the necessary locktime if there is
|
||||
// a checklocktimeverify script in the unspents.
|
||||
target = tx.getTargetTime();
|
||||
target = tx.getTargetLocktime();
|
||||
|
||||
// No target value. The unspents have an
|
||||
// incompatible locktime type.
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
// Set the locktime to target value or
|
||||
// `height - whatever` to avoid fee snipping.
|
||||
if (target.value > 0)
|
||||
tx.setLocktime(target.value);
|
||||
else
|
||||
tx.avoidFeeSnipping();
|
||||
|
||||
// Sign the inputs
|
||||
this.sign(tx);
|
||||
|
||||
return tx;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user