add subtract fee option.

This commit is contained in:
Christopher Jeffrey 2016-02-12 02:44:11 -08:00
parent 686dcbcdd9
commit c4818c4bc8

View File

@ -1014,22 +1014,31 @@ TX.prototype.maxSize = function maxSize() {
};
TX.prototype.getInputs = function getInputs(unspent, address, fee) {
var self = this;
var tx = this.clone();
var cost = tx.getOutputValue();
var outputValue = tx.getOutputValue();
var totalkb = 1;
var total = cost.addn(constants.tx.minFee);
var inputs = [];
var lastAdded = 0;
var size, newkb, change;
if (fee)
total = cost.add(fee);
var minFee = constants.tx.minFee;
var dustThreshold = constants.tx.dustThreshold;
var i, size, newkb, change;
// Oldest unspents first
unspent = unspent.slice().sort(function(a, b) {
return a.height - b.height;
});
function total() {
if (self.subtractFee)
return outputValue;
return outputValue.add(fee);
}
function isFull() {
return tx.getInputValue().cmp(total()) >= 0;
}
function addCoins() {
var i, index;
@ -1042,15 +1051,20 @@ TX.prototype.getInputs = function getInputs(unspent, address, fee) {
lastAdded++;
// Stop once we're full.
if (tx.getInputValue().cmp(total) >= 0)
if (isFull())
break;
}
}
// Transfer `total` funds maximum.
addCoins();
if (fee) {
// Transfer `total` funds maximum.
addCoins();
} else {
fee = new bn(minFee);
// Transfer `total` funds maximum.
addCoins();
if (!fee) {
// Add dummy output (for `change`) to
// calculate maximum TX size.
tx.addOutput({
@ -1058,17 +1072,6 @@ TX.prototype.getInputs = function getInputs(unspent, address, fee) {
value: new bn(0)
});
// if (this.subtractFee) {
// var f = new bn((Math.ceil(tx.maxSize() / 1024) - 1) * constants.tx.minFee);
// for (var j = 0; j < this.outputs.length; j++) {
// if (this.outputs[j].value.cmp(f.addn(constants.tx.dustThreshold)) >= 0) {
// this.outputs[j].value = this.outputs[j].value.sub(f);
// break;
// }
// }
// total = tx.getInputValue();
// }
// Change fee value if it is more than 1024
// bytes (10000 satoshi for every 1024 bytes).
do {
@ -1076,30 +1079,42 @@ TX.prototype.getInputs = function getInputs(unspent, address, fee) {
size = tx.maxSize();
newkb = Math.ceil(size / 1024) - totalkb;
total.iaddn(newkb * constants.tx.minFee);
fee.iaddn(newkb * minFee);
totalkb += newkb;
// Failed to get enough funds, add more inputs.
if (tx.getInputValue().cmp(total) < 0)
if (!isFull())
addCoins();
} while (tx.getInputValue().cmp(total) < 0 && lastAdded < unspent.length);
} while (!isFull() && lastAdded < unspent.length);
}
if (tx.getInputValue().cmp(total) < 0) {
if (!isFull()) {
// Still failing to get enough funds.
inputs = null;
} else {
// How much money is left after filling outputs.
change = tx.getInputValue().sub(total);
change = tx.getInputValue().sub(total());
// Attempt to subtract fee.
if (this.subtractFee) {
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)
inputs = null;
}
}
// Return necessary inputs and change.
return {
inputs: inputs,
change: change,
cost: cost,
fee: total.sub(cost),
total: total,
fee: fee,
total: total(),
kb: totalkb,
unspent: unspent.slice(0, lastAdded)
};
@ -1144,6 +1159,8 @@ TX.prototype.fill = function fill(unspent, address, fee) {
});
this.changeIndex = this.outputs.length - 1;
assert.equal(this.getFee().toNumber(), result.fee.toNumber());
}
return result;
@ -1209,9 +1226,6 @@ TX.prototype._recalculateFee = function recalculateFee() {
real = Math.ceil(size / 1024) * constants.tx.minFee;
fee = this.getFee().toNumber();
// if (this.hardFee)
// real = this.hardFee;
if (real === fee) {
if (this.changeIndex === -1)
this.outputs.pop();