Skip to content

Commit

Permalink
mtx: allow multiple indicies for subtractIndex.
Browse files Browse the repository at this point in the history
  • Loading branch information
chjj committed Nov 4, 2017
1 parent 4ff9374 commit d489238
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 48 deletions.
93 changes: 47 additions & 46 deletions lib/primitives/mtx.js
Original file line number Diff line number Diff line change
Expand Up @@ -1222,42 +1222,28 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
return selector.select(coins);
};

/**
* Attempt to subtract a fee from a single output.
* @param {Number} index
* @param {Amount} fee
*/

MTX.prototype.subtractIndex = function subtractIndex(index, fee) {
assert(typeof index === 'number');
assert(typeof fee === 'number');

const output = this.outputs[index];

if (!output)
throw new Error('Subtraction index does not exist.');

if (output.value < fee + output.getDustThreshold())
throw new Error('Could not subtract fee.');

output.value -= fee;
};

/**
* Attempt to subtract a fee from all outputs evenly.
* @param {Amount} fee
* @param {Set|null} set
*/

MTX.prototype.subtractFee = function subtractFee(fee) {
MTX.prototype.subtractFee = function subtractFee(fee, set) {
assert(typeof fee === 'number');

let outputs = 0;

for (const output of this.outputs) {
for (let i = 0; i < this.outputs.length; i++) {
const output = this.outputs[i];

if (set && !set.has(i))
continue;

// Ignore nulldatas and
// other OP_RETURN scripts.
if (output.script.isUnspendable())
continue;

outputs += 1;
}

Expand All @@ -1268,7 +1254,12 @@ MTX.prototype.subtractFee = function subtractFee(fee) {
const share = (fee - left) / outputs;

// First pass, remove even shares.
for (const output of this.outputs) {
for (let i = 0; i < this.outputs.length; i++) {
const output = this.outputs[i];

if (set && !set.has(i))
continue;

if (output.script.isUnspendable())
continue;

Expand All @@ -1280,7 +1271,12 @@ MTX.prototype.subtractFee = function subtractFee(fee) {

// Second pass, remove the remainder
// for the one unlucky output.
for (const output of this.outputs) {
for (let i = 0; i < this.outputs.length; i++) {
const output = this.outputs[i];

if (set && !set.has(i))
continue;

if (output.script.isUnspendable())
continue;

Expand Down Expand Up @@ -1313,13 +1309,8 @@ MTX.prototype.fund = async function fund(coins, options) {
this.addCoin(coin);

// Attempt to subtract fee.
if (select.subtractFee) {
const index = select.subtractIndex;
if (index !== -1)
this.subtractIndex(index, select.fee);
else
this.subtractFee(select.fee);
}
if (select.subtractFee)
this.subtractFee(select.fee, select.subtractIndex);

// Add a change output.
const output = new Output();
Expand Down Expand Up @@ -1554,7 +1545,7 @@ function CoinSelector(tx, options) {

this.selection = 'value';
this.subtractFee = false;
this.subtractIndex = -1;
this.subtractIndex = null;
this.height = -1;
this.depth = -1;
this.hardFee = -1;
Expand Down Expand Up @@ -1610,22 +1601,32 @@ CoinSelector.prototype.fromOptions = function fromOptions(options) {
}

if (options.subtractFee != null) {
if (typeof options.subtractFee === 'number') {
assert(util.isInt(options.subtractFee));
assert(options.subtractFee >= -1);
this.subtractIndex = options.subtractFee;
this.subtractFee = this.subtractIndex !== -1;
} else {
assert(typeof options.subtractFee === 'boolean');
this.subtractFee = options.subtractFee;
}
assert(typeof options.subtractFee === 'boolean');
this.subtractFee = options.subtractFee;
}

if (options.subtractIndex != null) {
assert(util.isInt(options.subtractIndex));
assert(options.subtractIndex >= -1);
this.subtractIndex = options.subtractIndex;
this.subtractFee = this.subtractIndex !== -1;
let indicies = null;

if (typeof options.subtractIndex === 'number') {
indicies = [options.subtractIndex];
} else {
assert(Array.isArray(options.subtractIndex));
indicies = options.subtractIndex;
}

if (indicies.length > 0) {
const set = new Set();

for (const index of indicies) {
assert(util.isU32(index));
assert(index < this.tx.outputs.length);
set.add(index);
}

this.subtractIndex = set;
this.subtractFee = true;
}
}

if (options.height != null) {
Expand Down
4 changes: 2 additions & 2 deletions lib/wallet/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
selection: valid.str('selection'),
smart: valid.bool('smart'),
subtractFee: valid.bool('subtractFee'),
subtractIndex: valid.i32('subtractIndex'),
subtractIndex: valid.get('subtractIndex'),
depth: valid.u32(['confirmations', 'depth']),
outputs: []
};
Expand Down Expand Up @@ -431,7 +431,7 @@ HTTPServer.prototype.initRouter = function initRouter() {
selection: valid.str('selection'),
smart: valid.bool('smart'),
subtractFee: valid.bool('subtractFee'),
subtractIndex: valid.i32('subtractIndex'),
subtractIndex: valid.get('subtractIndex'),
depth: valid.u32(['confirmations', 'depth']),
outputs: []
};
Expand Down

0 comments on commit d489238

Please sign in to comment.