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