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); 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.

View File

@ -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(),