coinselect
Advanced tools
Comparing version 3.1.1 to 3.1.2
@@ -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 @@ |
@@ -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 @@ |
11
break.js
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 = [] |
{ | ||
"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", |
16
split.js
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 @@ |
41
utils.js
@@ -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 | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
10262
196