mtx: refactor coin selection.

This commit is contained in:
Christopher Jeffrey 2017-01-07 00:18:45 -08:00
parent 3b45648750
commit bea77b0ec7
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 28 additions and 24 deletions

View File

@ -1220,19 +1220,16 @@ MTX.prototype.fund = co(function* fund(coins, options) {
this.subtractFee(select.fee, select.subtractFee);
// Add a change output.
this.addOutput({
address: select.changeAddress,
value: select.change
});
change = this.outputs[this.outputs.length - 1];
change = new Output();
change.value = select.change;
change.script.fromAddress(select.changeAddress);
if (change.isDust(policy.MIN_RELAY)) {
// Do nothing. Change is added to fee.
this.outputs.pop();
this.changeIndex = -1;
assert.equal(this.getFee(), select.fee + select.change);
} else {
this.outputs.push(change);
this.changeIndex = this.outputs.length - 1;
assert.equal(this.getFee(), select.fee);
}
@ -1442,7 +1439,7 @@ function CoinSelector(tx, options) {
this.shouldSubtract = false;
this.subtractFee = null;
this.height = -1;
this.confirmations = -1;
this.depth = -1;
this.hardFee = -1;
this.rate = MTX.MIN_FEE;
this.maxFee = -1;
@ -1484,7 +1481,13 @@ CoinSelector.prototype.fromOptions = function fromOptions(options) {
if (options.confirmations != null) {
assert(util.isNumber(options.confirmations));
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) {
@ -1597,9 +1600,9 @@ CoinSelector.prototype.isSpendable = function isSpendable(coin) {
return false;
}
if (this.confirmations > 0) {
if (this.depth > 0) {
if (coin.height === -1)
return this.confirmations <= 0;
return this.depth <= 0;
conf = this.height - coin.height;
@ -1608,7 +1611,7 @@ CoinSelector.prototype.isSpendable = function isSpendable(coin) {
conf += 1;
if (conf < this.confirmations)
if (conf < this.depth)
return false;
}
@ -1676,7 +1679,7 @@ CoinSelector.prototype.select = co(function* select(coins) {
if (this.hardFee !== -1)
this.selectHard(this.hardFee);
else
yield this.selectEstimate(MTX.MIN_FEE);
yield this.selectEstimate();
if (!this.isFull()) {
// Still failing to get enough funds.
@ -1694,28 +1697,29 @@ CoinSelector.prototype.select = co(function* select(coins) {
/**
* 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;
// Initial fee.
this.fee = fee;
this.fee = MTX.MIN_FEE;
// Transfer `total` funds maximum.
this.fund();
// Add dummy output (for `change`) to
// 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,
// use a fake p2pkh output to gauge size.
script: this.changeAddress
? Script.fromAddress(this.changeAddress)
: Script.fromPubkeyhash(encoding.ZERO_HASH160),
value: 0
});
// we use a fake p2pkh output to gauge size.
output.script.fromPubkeyhash(encoding.ZERO_HASH160);
}
this.tx.outputs.push(output);
// Keep recalculating fee and funding
// until we reach some sort of equilibrium.

View File

@ -1434,7 +1434,7 @@ Wallet.prototype._fund = co(function* fund(tx, options) {
yield tx.fund(coins, {
selection: options.selection,
round: options.round,
confirmations: options.confirmations,
depth: options.confirmations,
hardFee: options.hardFee,
subtractFee: options.subtractFee,
changeAddress: account.change.getAddress(),