hard fee calculation.
This commit is contained in:
parent
3c8442b1bb
commit
7b27f5dc9b
@ -41,6 +41,10 @@ function TX(data, block) {
|
|||||||
|
|
||||||
this._lock = this.lock;
|
this._lock = this.lock;
|
||||||
|
|
||||||
|
this._fee = !(data instanceof bcoin.tx)
|
||||||
|
? data.fee
|
||||||
|
: data._fee;
|
||||||
|
|
||||||
if (data.inputs) {
|
if (data.inputs) {
|
||||||
data.inputs.forEach(function(input) {
|
data.inputs.forEach(function(input) {
|
||||||
this.input(input, null);
|
this.input(input, null);
|
||||||
@ -781,7 +785,7 @@ TX.prototype.maxSize = function maxSize() {
|
|||||||
return total;
|
return total;
|
||||||
};
|
};
|
||||||
|
|
||||||
TX.prototype.getUnspent = function getUnspent(unspent) {
|
TX.prototype.getUnspent = function getUnspent(unspent, hardFee) {
|
||||||
var tx = this.clone();
|
var tx = this.clone();
|
||||||
var cost = tx.funds('out');
|
var cost = tx.funds('out');
|
||||||
var fee = 1;
|
var fee = 1;
|
||||||
@ -790,48 +794,59 @@ TX.prototype.getUnspent = function getUnspent(unspent) {
|
|||||||
var lastAdded = 0;
|
var lastAdded = 0;
|
||||||
var size, addFee, change;
|
var size, addFee, change;
|
||||||
|
|
||||||
|
if (!hardFee)
|
||||||
|
hardFee = this._fee;
|
||||||
|
|
||||||
|
if (hardFee) {
|
||||||
|
total = cost.add(hardFee);
|
||||||
|
this._fee = hardFee;
|
||||||
|
}
|
||||||
|
|
||||||
function addInput(unspent) {
|
function addInput(unspent) {
|
||||||
// Add new inputs until TX will have enough funds to cover both
|
// Add new inputs until TX will have enough
|
||||||
// minimum post cost and fee
|
// funds to cover both minimum post cost
|
||||||
|
// and fee.
|
||||||
var index = tx._input(unspent);
|
var index = tx._input(unspent);
|
||||||
inputs.push(tx.inputs[index]);
|
inputs.push(tx.inputs[index]);
|
||||||
lastAdded++;
|
lastAdded++;
|
||||||
return tx.funds('in').cmp(total) < 0;
|
return tx.funds('in').cmp(total) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transfer `total` funds maximum
|
// Transfer `total` funds maximum.
|
||||||
// var unspent = wallet.unspent();
|
|
||||||
unspent.every(addInput);
|
unspent.every(addInput);
|
||||||
|
|
||||||
// Add dummy output (for `change`) to calculate maximum TX size
|
if (!hardFee) {
|
||||||
tx.output({
|
// Add dummy output (for `change`) to
|
||||||
script: [],
|
// calculate maximum TX size.
|
||||||
value: new bn(0)
|
tx.output({
|
||||||
});
|
script: [],
|
||||||
|
value: new bn(0)
|
||||||
|
});
|
||||||
|
|
||||||
// Change fee value if it is more than 1024 bytes
|
// Change fee value if it is more than 1024
|
||||||
// (10000 satoshi for every 1024 bytes)
|
// bytes (10000 satoshi for every 1024 bytes).
|
||||||
do {
|
do {
|
||||||
// Calculate maximum possible size after signing
|
// Calculate max possible size after signing.
|
||||||
size = tx.maxSize();
|
size = tx.maxSize();
|
||||||
|
|
||||||
addFee = Math.ceil(size / 1024) - fee;
|
addFee = Math.ceil(size / 1024) - fee;
|
||||||
total.iaddn(addFee * constants.tx.fee);
|
total.iaddn(addFee * constants.tx.fee);
|
||||||
fee += addFee;
|
fee += addFee;
|
||||||
|
|
||||||
// Failed to get enough funds, add more inputs
|
// Failed to get enough funds, add more inputs.
|
||||||
if (tx.funds('in').cmp(total) < 0)
|
if (tx.funds('in').cmp(total) < 0)
|
||||||
unspent.slice(lastAdded).every(addInput);
|
unspent.slice(lastAdded).every(addInput);
|
||||||
} while (tx.funds('in').cmp(total) < 0 && lastAdded < unspent.length);
|
} while (tx.funds('in').cmp(total) < 0 && lastAdded < unspent.length);
|
||||||
|
}
|
||||||
|
|
||||||
// Expose `total`
|
// Expose `total`. Useful for error messages.
|
||||||
this.total = total;
|
this.total = total;
|
||||||
|
|
||||||
// Still failing to get enough funds
|
// Still failing to get enough funds.
|
||||||
if (tx.funds('in').cmp(total) < 0)
|
if (tx.funds('in').cmp(total) < 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// How much money is left after sending outputs
|
// How much money is left after filling outputs.
|
||||||
change = tx.funds('in').sub(total);
|
change = tx.funds('in').sub(total);
|
||||||
|
|
||||||
// Return necessary inputs and change.
|
// Return necessary inputs and change.
|
||||||
@ -844,8 +859,8 @@ TX.prototype.getUnspent = function getUnspent(unspent) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
TX.prototype.fillUnspent = function fillUnspent(unspent, changeAddress) {
|
TX.prototype.fillUnspent = function fillUnspent(unspent, changeAddress, fee) {
|
||||||
var result = unspent.cost ? unspent : this.getUnspent(unspent);
|
var result = this.getUnspent(unspent, fee);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
return result;
|
return result;
|
||||||
@ -884,6 +899,9 @@ TX.prototype._recalculateFee = function recalculateFee() {
|
|||||||
var output = this.changeOutput;
|
var output = this.changeOutput;
|
||||||
var size, real, fee;
|
var size, real, fee;
|
||||||
|
|
||||||
|
if (this._fee)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!output) {
|
if (!output) {
|
||||||
this.output({
|
this.output({
|
||||||
address: this.changeAddress,
|
address: this.changeAddress,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user