forked from bitcoinjs/coinselect
-
Notifications
You must be signed in to change notification settings - Fork 28
/
accumulative.js
41 lines (32 loc) · 1.14 KB
/
accumulative.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var utils = require('./utils')
var ext = require('./bn-extensions')
// add inputs until we reach or surpass the target value (or deplete)
// worst-case: O(n)
module.exports = function accumulative (utxos, outputs, feeRate) {
if (!utils.uintOrNull(feeRate)) return {}
var bytesAccum = utils.transactionBytes([], outputs)
var inAccum = ext.BN_ZERO
var inputs = []
var outAccum = utils.sumOrNaN(outputs)
for (var i = 0; i < utxos.length; ++i) {
var utxo = utxos[i]
var utxoBytes = utils.inputBytes(utxo)
var utxoFee = ext.mul(feeRate, utxoBytes)
var utxoValue = utils.uintOrNull(utxo.value)
// skip detrimental input
if (ext.gt(utxoFee, utxoValue)) {
if (i === utxos.length - 1) {
return { fee: ext.mul(feeRate, ext.add(bytesAccum, utxoBytes)) }
}
continue
}
bytesAccum = ext.add(bytesAccum, utxoBytes)
inAccum = ext.add(inAccum, utxoValue)
inputs.push(utxo)
var fee = ext.mul(feeRate, bytesAccum)
// go again?
if (ext.lt(inAccum, ext.add(outAccum, fee))) continue
return utils.finalize(inputs, outputs, feeRate)
}
return { fee: ext.mul(feeRate, bytesAccum) }
}