refactor tx.utxos().
This commit is contained in:
parent
389ee296b0
commit
b14c4daee0
@ -655,73 +655,69 @@ TX.prototype.maxSize = function maxSize() {
|
|||||||
return size;
|
return size;
|
||||||
};
|
};
|
||||||
|
|
||||||
TX.prototype.utxos = function utxos(unspent) {
|
TX.prototype.getUnspent = function getUnspent(unspent) {
|
||||||
|
var tx = this.clone();
|
||||||
|
|
||||||
// NOTE: tx should be prefilled with all outputs
|
// NOTE: tx should be prefilled with all outputs
|
||||||
var cost = this.funds('out');
|
var cost = tx.funds('out');
|
||||||
|
|
||||||
// Use initial fee for starters
|
// Use initial fee for starters
|
||||||
var fee = 1;
|
var fee = 1;
|
||||||
|
|
||||||
// total = cost + fee
|
// total = cost + fee
|
||||||
var total = cost.add(new bn(TX.fee));
|
var total = cost.addn(TX.fee);
|
||||||
|
|
||||||
var inputs = this.inputs.slice();
|
var inputs = [];
|
||||||
var utxos = [];
|
|
||||||
|
|
||||||
var lastAdded = 0;
|
var lastAdded = 0;
|
||||||
|
|
||||||
var byteSize, addFee, change;
|
var byteSize, addFee, change;
|
||||||
|
|
||||||
function addInput(unspent, i) {
|
function addInput(unspent) {
|
||||||
// Add new inputs until TX will have enough funds to cover both
|
// Add new inputs until TX will have enough funds to cover both
|
||||||
// minimum post cost and fee
|
// minimum post cost and fee
|
||||||
var index = this._input(unspent);
|
var index = tx._input(unspent);
|
||||||
utxos.push(this.inputs[index]);
|
inputs.push(tx.inputs[index]);
|
||||||
lastAdded++;
|
lastAdded++;
|
||||||
return this.funds('in').cmp(total) < 0;
|
return tx.funds('in').cmp(total) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transfer `total` funds maximum
|
// Transfer `total` funds maximum
|
||||||
// var unspent = wallet.unspent();
|
// var unspent = wallet.unspent();
|
||||||
unspent.every(addInput, this);
|
unspent.every(addInput);
|
||||||
|
|
||||||
// Add dummy output (for `change`) to calculate maximum TX size
|
// Add dummy output (for `change`) to calculate maximum TX size
|
||||||
this.output({ address: null, value: new bn(0) });
|
tx.output({ address: null, value: new bn(0) });
|
||||||
|
|
||||||
// Change fee value if it is more than 1024 bytes
|
// Change fee value if it is more than 1024 bytes
|
||||||
// (10000 satoshi for every 1024 bytes)
|
// (10000 satoshi for every 1024 bytes)
|
||||||
do {
|
do {
|
||||||
// Calculate maximum possible size after signing
|
// Calculate maximum possible size after signing
|
||||||
byteSize = this.maxSize();
|
byteSize = tx.maxSize();
|
||||||
|
|
||||||
addFee = Math.ceil(byteSize / 1024) - fee;
|
addFee = Math.ceil(byteSize / 1024) - fee;
|
||||||
total.iadd(new bn(addFee * TX.fee));
|
total.iaddn(addFee * TX.fee);
|
||||||
fee += addFee;
|
fee += addFee;
|
||||||
|
|
||||||
// Failed to get enough funds, add more inputs
|
// Failed to get enough funds, add more inputs
|
||||||
if (this.funds('in').cmp(total) < 0)
|
if (tx.funds('in').cmp(total) < 0)
|
||||||
unspent.slice(lastAdded).every(addInput, this);
|
unspent.slice(lastAdded).every(addInput);
|
||||||
} while (this.funds('in').cmp(total) < 0 && lastAdded < unspent.length);
|
} while (tx.funds('in').cmp(total) < 0 && lastAdded < unspent.length);
|
||||||
|
|
||||||
// Still failing to get enough funds
|
// Still failing to get enough funds
|
||||||
if (this.funds('in').cmp(total) < 0) {
|
if (tx.funds('in').cmp(total) < 0) {
|
||||||
this.inputs = inputs;
|
|
||||||
this.total = total;
|
this.total = total;
|
||||||
this.outputs.pop();
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// How much money is left after sending outputs
|
// How much money is left after sending outputs
|
||||||
change = this.funds('in').sub(total);
|
change = tx.funds('in').sub(total);
|
||||||
|
|
||||||
// Clear the tx of everything we added.
|
|
||||||
this.inputs = inputs;
|
|
||||||
this.total = total;
|
this.total = total;
|
||||||
this.outputs.pop();
|
|
||||||
|
|
||||||
// Return necessary utxos and change.
|
// Return necessary inputs and change.
|
||||||
return {
|
return {
|
||||||
utxos: utxos,
|
inputs: inputs,
|
||||||
change: change,
|
change: change,
|
||||||
cost: cost,
|
cost: cost,
|
||||||
fee: total.sub(cost),
|
fee: total.sub(cost),
|
||||||
@ -730,22 +726,25 @@ TX.prototype.utxos = function utxos(unspent) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TX.prototype.fillUnspent = function fillUnspent(unspent, changeAddress) {
|
TX.prototype.fillUnspent = function fillUnspent(unspent, changeAddress) {
|
||||||
var result = unspent.utxos ? unspent : this.utxos(unspent);
|
var result = unspent.cost ? unspent : this.getUnspent(unspent);
|
||||||
|
|
||||||
this.changeAddress = changeAddress
|
|
||||||
|| this.changeAddress
|
|
||||||
|| utxos[0].output.addr;
|
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
result.utxos.forEach(function(input) {
|
this.changeAddress = changeAddress
|
||||||
|
|| this.changeAddress
|
||||||
|
|| result.inputs[0].output.addr;
|
||||||
|
|
||||||
|
result.inputs.forEach(function(input) {
|
||||||
this.input(input);
|
this.input(input);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
if (result.change.cmpn(TX.dust) < 0) {
|
if (result.change.cmpn(TX.dust) < 0) {
|
||||||
// Do nothing. Change is added to fee.
|
// Do nothing. Change is added to fee.
|
||||||
assert(this.getFee().cmp(result.fee.add(result.change)) === 0);
|
assert.equal(
|
||||||
|
this.getFee().toNumber(),
|
||||||
|
result.fee.add(result.change).toNumber()
|
||||||
|
);
|
||||||
this.changeOutput = null;
|
this.changeOutput = null;
|
||||||
} else {
|
} else {
|
||||||
if (!this.changeAddress)
|
if (!this.changeAddress)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user