mtx: refactor coin selection.
This commit is contained in:
parent
3b45648750
commit
bea77b0ec7
@ -1220,19 +1220,16 @@ MTX.prototype.fund = co(function* fund(coins, options) {
|
|||||||
this.subtractFee(select.fee, select.subtractFee);
|
this.subtractFee(select.fee, select.subtractFee);
|
||||||
|
|
||||||
// Add a change output.
|
// Add a change output.
|
||||||
this.addOutput({
|
change = new Output();
|
||||||
address: select.changeAddress,
|
change.value = select.change;
|
||||||
value: select.change
|
change.script.fromAddress(select.changeAddress);
|
||||||
});
|
|
||||||
|
|
||||||
change = this.outputs[this.outputs.length - 1];
|
|
||||||
|
|
||||||
if (change.isDust(policy.MIN_RELAY)) {
|
if (change.isDust(policy.MIN_RELAY)) {
|
||||||
// Do nothing. Change is added to fee.
|
// Do nothing. Change is added to fee.
|
||||||
this.outputs.pop();
|
|
||||||
this.changeIndex = -1;
|
this.changeIndex = -1;
|
||||||
assert.equal(this.getFee(), select.fee + select.change);
|
assert.equal(this.getFee(), select.fee + select.change);
|
||||||
} else {
|
} else {
|
||||||
|
this.outputs.push(change);
|
||||||
this.changeIndex = this.outputs.length - 1;
|
this.changeIndex = this.outputs.length - 1;
|
||||||
assert.equal(this.getFee(), select.fee);
|
assert.equal(this.getFee(), select.fee);
|
||||||
}
|
}
|
||||||
@ -1442,7 +1439,7 @@ function CoinSelector(tx, options) {
|
|||||||
this.shouldSubtract = false;
|
this.shouldSubtract = false;
|
||||||
this.subtractFee = null;
|
this.subtractFee = null;
|
||||||
this.height = -1;
|
this.height = -1;
|
||||||
this.confirmations = -1;
|
this.depth = -1;
|
||||||
this.hardFee = -1;
|
this.hardFee = -1;
|
||||||
this.rate = MTX.MIN_FEE;
|
this.rate = MTX.MIN_FEE;
|
||||||
this.maxFee = -1;
|
this.maxFee = -1;
|
||||||
@ -1484,7 +1481,13 @@ CoinSelector.prototype.fromOptions = function fromOptions(options) {
|
|||||||
if (options.confirmations != null) {
|
if (options.confirmations != null) {
|
||||||
assert(util.isNumber(options.confirmations));
|
assert(util.isNumber(options.confirmations));
|
||||||
assert(options.confirmations >= -1);
|
assert(options.confirmations >= -1);
|
||||||
this.confirmations = options.confirmations;
|
this.depth = options.confirmations;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.depth != null) {
|
||||||
|
assert(util.isNumber(options.depth));
|
||||||
|
assert(options.depth >= -1);
|
||||||
|
this.depth = options.depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.hardFee != null) {
|
if (options.hardFee != null) {
|
||||||
@ -1597,9 +1600,9 @@ CoinSelector.prototype.isSpendable = function isSpendable(coin) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.confirmations > 0) {
|
if (this.depth > 0) {
|
||||||
if (coin.height === -1)
|
if (coin.height === -1)
|
||||||
return this.confirmations <= 0;
|
return this.depth <= 0;
|
||||||
|
|
||||||
conf = this.height - coin.height;
|
conf = this.height - coin.height;
|
||||||
|
|
||||||
@ -1608,7 +1611,7 @@ CoinSelector.prototype.isSpendable = function isSpendable(coin) {
|
|||||||
|
|
||||||
conf += 1;
|
conf += 1;
|
||||||
|
|
||||||
if (conf < this.confirmations)
|
if (conf < this.depth)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1676,7 +1679,7 @@ CoinSelector.prototype.select = co(function* select(coins) {
|
|||||||
if (this.hardFee !== -1)
|
if (this.hardFee !== -1)
|
||||||
this.selectHard(this.hardFee);
|
this.selectHard(this.hardFee);
|
||||||
else
|
else
|
||||||
yield this.selectEstimate(MTX.MIN_FEE);
|
yield this.selectEstimate();
|
||||||
|
|
||||||
if (!this.isFull()) {
|
if (!this.isFull()) {
|
||||||
// Still failing to get enough funds.
|
// Still failing to get enough funds.
|
||||||
@ -1694,28 +1697,29 @@ CoinSelector.prototype.select = co(function* select(coins) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize selection based on size estimate.
|
* Initialize selection based on size estimate.
|
||||||
* @param {Amount} fee
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CoinSelector.prototype.selectEstimate = co(function* selectEstimate(fee) {
|
CoinSelector.prototype.selectEstimate = co(function* selectEstimate() {
|
||||||
|
var output = new Output();
|
||||||
var size;
|
var size;
|
||||||
|
|
||||||
// Initial fee.
|
// Initial fee.
|
||||||
this.fee = fee;
|
this.fee = MTX.MIN_FEE;
|
||||||
|
|
||||||
// Transfer `total` funds maximum.
|
// Transfer `total` funds maximum.
|
||||||
this.fund();
|
this.fund();
|
||||||
|
|
||||||
// Add dummy output (for `change`) to
|
// Add dummy output (for `change`) to
|
||||||
// calculate maximum TX size.
|
// calculate maximum TX size.
|
||||||
this.tx.addOutput({
|
if (this.changeAddress) {
|
||||||
|
output.script.fromAddress(this.changeAddress);
|
||||||
|
} else {
|
||||||
// In case we don't have a change address,
|
// In case we don't have a change address,
|
||||||
// use a fake p2pkh output to gauge size.
|
// we use a fake p2pkh output to gauge size.
|
||||||
script: this.changeAddress
|
output.script.fromPubkeyhash(encoding.ZERO_HASH160);
|
||||||
? Script.fromAddress(this.changeAddress)
|
}
|
||||||
: Script.fromPubkeyhash(encoding.ZERO_HASH160),
|
|
||||||
value: 0
|
this.tx.outputs.push(output);
|
||||||
});
|
|
||||||
|
|
||||||
// Keep recalculating fee and funding
|
// Keep recalculating fee and funding
|
||||||
// until we reach some sort of equilibrium.
|
// until we reach some sort of equilibrium.
|
||||||
|
|||||||
@ -1434,7 +1434,7 @@ Wallet.prototype._fund = co(function* fund(tx, options) {
|
|||||||
yield tx.fund(coins, {
|
yield tx.fund(coins, {
|
||||||
selection: options.selection,
|
selection: options.selection,
|
||||||
round: options.round,
|
round: options.round,
|
||||||
confirmations: options.confirmations,
|
depth: options.confirmations,
|
||||||
hardFee: options.hardFee,
|
hardFee: options.hardFee,
|
||||||
subtractFee: options.subtractFee,
|
subtractFee: options.subtractFee,
|
||||||
changeAddress: account.change.getAddress(),
|
changeAddress: account.change.getAddress(),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user