From 5cab304a590c88b02029229b88dfea26d1dd04d5 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Thu, 31 Mar 2016 05:14:54 -0700 Subject: [PATCH] more coin selection. --- lib/bcoin/mtx.js | 66 ++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/lib/bcoin/mtx.js b/lib/bcoin/mtx.js index b5bc3884..d81abdda 100644 --- a/lib/bcoin/mtx.js +++ b/lib/bcoin/mtx.js @@ -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,