coinselect
Advanced tools
+5
-4
@@ -5,8 +5,9 @@ var utils = require('./utils') | ||
| module.exports = function accumulative (utxos, outputs, feeRate) { | ||
| var outAccum = utils.sum(outputs) | ||
| if (!isFinite(utils.uintOrNaN(feeRate))) return {} | ||
| var bytesAccum = utils.transactionBytes([], outputs) | ||
| // accumulators | ||
| var bytesAccum = utils.transactionBytes([], outputs) | ||
| // accumulate inputs until we reach the target or run out | ||
| var inAccum = 0 | ||
| var inputs = [] | ||
| var outAccum = utils.sumOrNaN(outputs) | ||
@@ -17,3 +18,3 @@ for (var i = 0; i < utxos.length; ++i) { | ||
| bytesAccum += utils.inputBytes(utxo) | ||
| inAccum += utxo.value | ||
| inAccum += utils.uintOrNaN(utxo.value) | ||
| inputs.push(utxo) | ||
@@ -20,0 +21,0 @@ |
+8
-5
@@ -5,9 +5,11 @@ var utils = require('./utils') | ||
| module.exports = function blackjack (utxos, outputs, feeRate) { | ||
| var outAccum = utils.sum(outputs) | ||
| var threshold = utils.dustThreshold({}, feeRate) | ||
| if (!isFinite(utils.uintOrNaN(feeRate))) return {} | ||
| var bytesAccum = utils.transactionBytes([], outputs) | ||
| // accumulate inputs until we bust | ||
| var inAccum = 0 | ||
| var bytesAccum = utils.transactionBytes([], outputs) | ||
| var inputs = [] | ||
| var outAccum = utils.sumOrNaN(outputs) | ||
| var threshold = utils.dustThreshold({}, feeRate) | ||
@@ -18,8 +20,9 @@ for (var i = 0; i < utxos.length; ++i) { | ||
| var fee = feeRate * (bytesAccum + inputBytes) | ||
| var inputValue = utils.uintOrNaN(input.value) | ||
| // would it waste value? | ||
| if ((inAccum + input.value) > (outAccum + fee + threshold)) continue | ||
| if ((inAccum + inputValue) > (outAccum + fee + threshold)) continue | ||
| bytesAccum += inputBytes | ||
| inAccum += input.value | ||
| inAccum += inputValue | ||
| inputs.push(input) | ||
@@ -26,0 +29,0 @@ |
+6
-5
| var utils = require('./utils') | ||
| module.exports = function broken (utxos, output, feeRate) { | ||
| if (!isFinite(output.value)) throw new TypeError('Expected Satoshi value, got ' + output.value) | ||
| if (!isFinite(utils.uintOrNaN(feeRate))) return {} | ||
| var inAccum = utils.sum(utxos) | ||
| var bytesAccum = utils.transactionBytes(utxos, []) | ||
| var value = utils.uintOrNaN(output.value) | ||
| if (!isFinite(value)) return { fee: feeRate * bytesAccum } | ||
| var inAccum = utils.sumOrNaN(utxos) | ||
| var outputBytes = utils.outputBytes(output) | ||
| var value = output.value | ||
| var bytesAccum = utils.transactionBytes(utxos, []) | ||
| var outAccum = 0 | ||
@@ -12,0 +13,0 @@ var outputs = [] |
+1
-2
| { | ||
| "name": "coinselect", | ||
| "version": "3.1.1", | ||
| "version": "3.1.2", | ||
| "description": "A transaction input selection module for bitcoin.", | ||
@@ -39,3 +39,2 @@ "keywords": [ | ||
| "scripts": { | ||
| "prepublish": "npm run test", | ||
| "coverage": "nyc --check-coverage --branches 100 --functions 100 tape test/*.js", | ||
@@ -42,0 +41,0 @@ "standard": "standard", |
+8
-8
| var utils = require('./utils') | ||
| module.exports = function split (utxos, outputs, feeRate) { | ||
| if (!isFinite(utils.uintOrNaN(feeRate))) return {} | ||
| var bytesAccum = utils.transactionBytes(utxos, outputs) | ||
@@ -8,6 +10,6 @@ var fee = feeRate * bytesAccum | ||
| var inAccum = utils.sum(utxos) | ||
| var outAccum = utils.sum(outputs) | ||
| var inAccum = utils.sumOrNaN(utxos) | ||
| var outAccum = utils.sumForgiving(outputs) | ||
| var remaining = inAccum - outAccum - fee | ||
| if (remaining <= 0) return { fee: fee } | ||
| if (!isFinite(remaining) || remaining <= 0) return { fee: fee } | ||
@@ -20,4 +22,4 @@ var splitOutputsCount = outputs.reduce(function (a, x) { | ||
| // ensure every output is either user defined, or over the threshold | ||
| if (outputs.some(function (x) { | ||
| return !isFinite(x.value) && (splitValue <= utils.dustThreshold(x, feeRate)) | ||
| if (!outputs.every(function (x) { | ||
| return x.value !== undefined || (splitValue > utils.dustThreshold(x, feeRate)) | ||
| })) return { fee: fee } | ||
@@ -27,5 +29,3 @@ | ||
| outputs = outputs.map(function (x) { | ||
| if (isFinite(x.value)) return x | ||
| return { value: splitValue } | ||
| return x.value !== undefined ? x : { value: splitValue } | ||
| }) | ||
@@ -32,0 +32,0 @@ |
+27
-14
@@ -27,21 +27,32 @@ // baseline estimates, used to improve performance | ||
| function sum (range) { | ||
| function uintOrNaN (v) { | ||
| if (typeof v !== 'number') return NaN | ||
| if (!isFinite(v)) return NaN | ||
| if (v >>> 0 !== v) return NaN | ||
| return v | ||
| } | ||
| function sumForgiving (range) { | ||
| return range.reduce(function (a, x) { return a + (x.value >>> 0) }, 0) | ||
| } | ||
| function sumOrNaN (range) { | ||
| return range.reduce(function (a, x) { return a + uintOrNaN(x.value) }, 0) | ||
| } | ||
| var BLANK_OUTPUT = outputBytes({}) | ||
| function worthChange (inputs, outputs, feeRate) { | ||
| function finalize (inputs, outputs, feeRate) { | ||
| if (!isFinite(feeRate)) return {} | ||
| var bytesAccum = transactionBytes(inputs, outputs) | ||
| var fee = feeRate * (bytesAccum + BLANK_OUTPUT) | ||
| var remainder = sum(inputs) - (sum(outputs) + fee) | ||
| var feeAfterExtraOutput = feeRate * (bytesAccum + BLANK_OUTPUT) | ||
| var remainderAfterExtraOutput = sumOrNaN(inputs) - (sumOrNaN(outputs) + feeAfterExtraOutput) | ||
| if (remainder <= dustThreshold({}, feeRate)) return null | ||
| return { value: remainder } | ||
| } | ||
| // is it worth a change output? | ||
| if (remainderAfterExtraOutput > dustThreshold({}, feeRate)) { | ||
| outputs = outputs.concat({ value: remainderAfterExtraOutput }) | ||
| } | ||
| function finalize (inputs, outputs, feeRate) { | ||
| // was too much left over? | ||
| var change = worthChange(inputs, outputs, feeRate) | ||
| if (change) outputs = outputs.concat(change) | ||
| var fee = sumOrNaN(inputs) - sumOrNaN(outputs) | ||
| if (!isFinite(fee)) return { fee: feeRate * bytesAccum } | ||
@@ -51,3 +62,3 @@ return { | ||
| outputs: outputs, | ||
| fee: sum(inputs) - sum(outputs) | ||
| fee: fee | ||
| } | ||
@@ -61,4 +72,6 @@ } | ||
| outputBytes: outputBytes, | ||
| sum: sum, | ||
| transactionBytes: transactionBytes | ||
| sumOrNaN: sumOrNaN, | ||
| sumForgiving: sumForgiving, | ||
| transactionBytes: transactionBytes, | ||
| uintOrNaN: uintOrNaN | ||
| } |
10262
7.49%196
8.29%