more coin selection.

This commit is contained in:
Christopher Jeffrey 2016-03-31 05:14:54 -07:00
parent e907f35267
commit 5cab304a59

View File

@ -786,12 +786,11 @@ MTX.prototype.maxSize = function maxSize(maxM, maxN) {
};
MTX.prototype.selectCoins = function selectCoins(coins, options) {
var dustThreshold = constants.tx.dustThreshold;
var tx = this.clone();
var outputValue = tx.getOutputValue();
var chosen = [];
var lastAdded = 0;
var i, size, change, fee;
var tryFree, minValue, i, size, change, fee;
assert(tx.inputs.length === 0);
@ -802,6 +801,8 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
};
}
tryFree = options.free;
if (!options.selection || options.selection === 'age') {
// Oldest unspents first
coins = coins.slice().sort(function(a, b) {
@ -871,12 +872,12 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
// Calculate max possible size after signing.
size = tx.maxSize(options.m, options.n);
if (options.free) {
if (tryFree) {
if (tx.isFree(network.height + 1, size)) {
fee = new bn(0);
break;
}
options.free = false;
tryFree = false;
}
if (options.accurate)
@ -892,40 +893,39 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
if (!isFull()) {
// Still failing to get enough funds.
chosen = null;
} else {
// How much money is left after filling outputs.
change = tx.getInputValue().sub(total());
// Attempt to subtract fee.
if (options.subtractFee != null) {
if (typeof options.subtractFee === 'number') {
i = options.subtractFee;
assert(tx.outputs[i], 'Subtraction index does not exist.');
if (tx.outputs[i].value.cmp(fee.addn(dustThreshold)) >= 0)
tx.outputs[i].value.isub(fee);
else
chosen = null;
} else {
for (i = 0; i < tx.outputs.length; i++) {
if (tx.outputs[i].value.cmp(fee.addn(dustThreshold)) >= 0) {
tx.outputs[i].value.isub(fee);
break;
}
}
// Could not subtract fee
if (i === tx.outputs.length)
chosen = null;
}
}
}
if (!chosen) {
err = new Error('Could not select coins.');
err.requiredFunds = total();
throw err;
}
// How much money is left after filling outputs.
change = tx.getInputValue().sub(total());
// Attempt to subtract fee.
if (options.subtractFee != null) {
minValue = fee.addn(constants.tx.dustThreshold);
if (typeof options.subtractFee === 'number') {
i = options.subtractFee;
if (i > tx.outputs.length - 1)
throw new Error('Subtraction index does not exist.');
if (tx.outputs[i].value.cmp(minValue) < 0)
throw new Error('Could not subtract fee.');
tx.outputs[i].value.isub(fee);
} else {
for (i = 0; i < tx.outputs.length; i++) {
if (tx.outputs[i].value.cmp(minValue) >= 0) {
tx.outputs[i].value.isub(fee);
break;
}
}
if (i === tx.outputs.length)
throw new Error('Could not subtract fee.');
}
}
// Return necessary inputs and change.
return {
coins: chosen,