Skip to content

Commit

Permalink
Merge PR #901 from 'nodech/mtx-fund-2'
Browse files Browse the repository at this point in the history
  • Loading branch information
nodech committed Aug 27, 2024
2 parents d754b86 + 15e9b8f commit e88734f
Show file tree
Hide file tree
Showing 2 changed files with 686 additions and 27 deletions.
83 changes: 56 additions & 27 deletions lib/primitives/mtx.js
Original file line number Diff line number Diff line change
Expand Up @@ -1409,12 +1409,13 @@ class CoinSelector {
/**
* Create a coin selector.
* @constructor
* @param {TX} tx
* @param {MTX} tx
* @param {Object?} options
*/

constructor(tx, options) {
this.tx = tx.clone();
this.view = tx.view;
this.coins = [];
this.outputValue = 0;
this.index = 0;
Expand Down Expand Up @@ -1538,11 +1539,13 @@ class CoinSelector {

if (options.inputs) {
assert(Array.isArray(options.inputs));

const lastIndex = this.inputs.size;
for (let i = 0; i < options.inputs.length; i++) {
const prevout = options.inputs[i];
assert(prevout && typeof prevout === 'object');
const {hash, index} = prevout;
this.inputs.set(Outpoint.toKey(hash, index), i);
this.inputs.set(Outpoint.toKey(hash, index), lastIndex + i);
}
}

Expand Down Expand Up @@ -1676,31 +1679,7 @@ class CoinSelector {

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);
}
}
this.resolveInputCoins();

if (this.isFull())
return;
Expand Down Expand Up @@ -1803,6 +1782,56 @@ class CoinSelector {
this.fee = this.hardFee;
this.fund();
}

resolveInputCoins() {
if (this.inputs.size === 0)
return;

const coins = [];

for (let i = 0 ; i < this.inputs.size; i++) {
coins.push(null);
}

// first resolve from coinview if possible.
for (const key of this.inputs.keys()) {
const prevout = Outpoint.fromKey(key);

if (this.view.hasEntry(prevout)) {
const coinEntry = this.view.getEntry(prevout);
const i = this.inputs.get(key);

if (i != null) {
assert(!coins[i]);
coins[i] = coinEntry.toCoin(prevout);
this.inputs.delete(key);
}
}
}

// Now try to resolve from the passed coins array.
if (this.inputs.size > 0) {
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) {
assert(!coins[i]);
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);
}
}
}

/**
Expand Down
Loading

0 comments on commit e88734f

Please sign in to comment.