mtx: allow passing of preferred inputs to coin selector.

This commit is contained in:
Christopher Jeffrey 2018-07-10 19:24:53 -07:00
parent 97e4d09baf
commit e15d7917fa
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -1592,10 +1592,13 @@ class CoinSelector {
this.maxFee = -1; this.maxFee = -1;
this.round = false; this.round = false;
this.changeAddress = null; this.changeAddress = null;
this.inputs = new Map();
// Needed for size estimation. // Needed for size estimation.
this.estimate = null; this.estimate = null;
this.injectInputs();
if (options) if (options)
this.fromOptions(options); this.fromOptions(options);
} }
@ -1687,9 +1690,35 @@ class CoinSelector {
this.estimate = options.estimate; this.estimate = options.estimate;
} }
if (options.inputs) {
assert(Array.isArray(options.inputs));
for (let i = 0; i < options.inputs.length; i++) {
const prevout = options.inputs[i];
assert(prevout && typeof prevout === 'object');
const {hash, index} = prevout;
assert(typeof hash === 'string');
assert(typeof index === 'number');
this.inputs.set(Outpoint.toKey(hash, index), i);
}
}
return this; return this;
} }
/**
* Attempt to inject existing inputs.
* @private
*/
injectInputs() {
if (this.tx.inputs.length > 0) {
for (let i = 0; i < this.tx.inputs.length; i++) {
const {prevout} = this.tx.inputs[i];
this.inputs.set(prevout.toKey(), i);
}
}
}
/** /**
* Initialize the selector with coins to select from. * Initialize the selector with coins to select from.
* @param {Coin[]} coins * @param {Coin[]} coins
@ -1749,6 +1778,9 @@ class CoinSelector {
*/ */
isSpendable(coin) { isSpendable(coin) {
if (this.tx.view.hasEntry(coin))
return false;
if (this.height === -1) if (this.height === -1)
return true; return true;
@ -1799,6 +1831,33 @@ class CoinSelector {
*/ */
fund() { fund() {
// Ensure all preferred inputs first.
if (this.inputs.size > 0) {
const coins = [];
for (let i = 0; i < this.inputs.size; i++)
coins.push(null);
for (const coin of this.coins) {
const {hash, index} = coin;
const key = Outpoint.toKey(hash, index);
const i = this.inputs.get(key);
if (i != null) {
coins[i] = coin;
this.inputs.delete(key);
}
}
if (this.inputs.size > 0)
throw new Error('Could not resolve preferred inputs.');
for (const coin of coins) {
this.tx.addCoin(coin);
this.chosen.push(coin);
}
}
while (this.index < this.coins.length) { while (this.index < this.coins.length) {
const coin = this.coins[this.index++]; const coin = this.coins[this.index++];