Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rpc] [wallet] Allow specifying the output index when using bumpfee #12096

Closed
wants to merge 2 commits into from

Conversation

@kallewoof
Copy link
Member

@kallewoof kallewoof commented Jan 5, 2018

No description provided.

@fanquake fanquake added the Wallet label Jan 5, 2018
@promag
Copy link
Member

@promag promag commented Jan 5, 2018

Missing test.

@sipa
Copy link
Member

@sipa sipa commented Jan 5, 2018

This decreases the output? In some cases that may desirable, but in general I think that's very unexpected (I would think it would add a new input instead).

@kallewoof
Copy link
Member Author

@kallewoof kallewoof commented Jan 5, 2018

If you don't have a change address chance are fairly high that you're simply moving coins (e.g. between wallets). Especially if you only have one utxo in, you may not want to associate other utxo's with it for privacy reasons.

@wtogami
Copy link
Contributor

@wtogami wtogami commented Jan 5, 2018

"single output transactions are special in that the exact amount doesn't usually matter (the user is emptying a wallet or using coin control to move UTXOs)."

I would argue that this is not stated strongly enough. If they previously paid to a single output then it is almost always true that they do not care about the particular amount. This is especially true as the previous amount was subject to an arbitrary, variable fee.

Valid use cases where this behavior is necessary, where you really don't want to require adding more inputs in order to bumpfee:

  • Emptying a wallet
  • Emptying particular UTXO's

I would further suggest if the receiver was expecting a particular amount then you would expect there to be a change output.

@sipa
Copy link
Member

@sipa sipa commented Jan 5, 2018

@kallewoof You're right that in most cases right now that you don't care about the amount if there is only one output, but there is certainly no guarantee. The coin selection algorithm even explicitly tries to find a solution without change first - it's just pretty terrible at its job current (#10637 will make it succeed much more often).

@ryanofsky
Copy link
Contributor

@ryanofsky ryanofsky commented Jan 5, 2018

I think this could be generalized and also be made safer by adding an reduce_output option to bumpfee (could also call it something like output_number or txout). This way you'd be able to bump single output transactions by specifying reduce_output: 0, but there'd be no risk of someone accidentally decreasing the amount they are trying to send by bumping the fee in other cases.

@kallewoof
Copy link
Member Author

@kallewoof kallewoof commented Jan 5, 2018

I don't think it makes sense to arbitrarily add inputs to bumpfee. I don't even know if RBF allows it (since you're suggesting it, I guess it does -- I thought I tried and failed).

Maybe a bump_from_output flag in options that did this behavior.

Edit: @ryanofsky That looks good to me.

@sipa
Copy link
Member

@sipa sipa commented Jan 5, 2018

I don't see why RBF wouldn't allow it, as long as all transactions you're replacing have been marked as replaceable.

I like the idea of explicitly marking an output that can be reduced.

Over time (especially after #10637), I think we'll inevitably need a way to bump transactions that don't have change. Depending on feerates and your wallet's UTXO set distribution, a large fraction of transactions may be created without change.

@instagibbs
Copy link
Member

@instagibbs instagibbs commented Jan 5, 2018

does the wallet track which outputs had subtractFeeFromOutput? In that case further reduction seems completely fine as well.

test/functional/bumpfee.py Outdated
rawtx = node.createrawtransaction([tx_input], {dest_address: Decimal("0.00099000")})
signedtx = node.signrawtransaction(rawtx)
txid = node.sendrawtransaction(signedtx["hex"])
bumped_tx = node.bumpfee(txid)

This comment has been minimized.

@promag

promag Jan 5, 2018
Member

Check new output is less than 0.00099?

This comment has been minimized.

@kallewoof

kallewoof Jan 9, 2018
Author Member

Thanks, good point - fixing.

@promag
Copy link
Member

@promag promag commented Jan 5, 2018

Agree that there are cases where the output(s) can't be reduced. In the cases it can be reduced, should it be re-funded?

@sdaftuar
Copy link
Member

@sdaftuar sdaftuar commented Jan 5, 2018

I don't think it makes sense to arbitrarily add inputs to bumpfee. I don't even know if RBF allows it (since you're suggesting it, I guess it does -- I thought I tried and failed).

@kallewoof Currently our relay policy (and BIP 125) require that if you add a new input, it must be already confirmed -- perhaps you tested with an unconfirmed input?

(The idea behind that requirement was to ensure the new transaction was more likely to be mined than the ones it was replacing; now that we use ancestor feerate mining, we could perhaps relax this requirement and compare ancestor feerates of everything instead to ensure the new transaction has a higher mining score.)

@jtimon
Copy link
Member

@jtimon jtimon commented Jan 8, 2018

concept ack after the current coin selection stop trying 1 output (I assume #10637 solves that?).

@gmaxwell
Copy link
Contributor

@gmaxwell gmaxwell commented Jan 8, 2018

NAK. The only time it would be acceptable to reduce the output is if the transaction was created as subtract fee from output. Bumping should add additional inputs as required.

@promag
Copy link
Member

@promag promag commented Jan 8, 2018

@gmaxwell even with an option to allow the subtract, default to false (since there is no subtract from output record)?

@gmaxwell
Copy link
Contributor

@gmaxwell gmaxwell commented Jan 8, 2018

if it were behind a bunch of warnings, ... but even though if substract from wasn't initially selected should only be a last resort if it can't bump otherwise. The wallet shouldn't quietly direct the user into behavior that might cause them to get criminally prosecuted.

@gmaxwell
Copy link
Contributor

@gmaxwell gmaxwell commented Jan 9, 2018

@wtogami The wallet has explicit information about transactions created where the user requested subtracting fees from amounts. Using that information would be fine but you cannot use the lack of a change output to detect this, when 2^inputs * fees_saved_from_excluding_an_output is large relative to the amount being paid an exact match frequently exists. And the PR pieter linked to will usually find it.

@kallewoof
Copy link
Member Author

@kallewoof kallewoof commented Jan 9, 2018

Summary:

  • Do not implicitly assume a single-output-no-change transaction can be altered due to better coin selection in the future.
  • Require the user to select the output if the user does not want additional inputs to be added to cover increased fees.
  • (Allow adding additional inputs to cover increased fees -- separate PR)

For this PR, that translates to:

  • Fail if no output is explicitly chosen (pre-merge behavior)
  • Reduce single output to cover fees if user has explicitly picked it
  • Allow user to arbitrarily pick the output that is reduced for existing multi-output transactions (i.e. not restricted to change output).
@kallewoof kallewoof force-pushed the kallewoof:better-bumpfee branch 4 times, most recently Jan 9, 2018
@kallewoof kallewoof changed the title [rpc] [wallet] Allow single-output transactions in bumpfee [rpc] [wallet] Allow specifying the output index when using bumpfee Jan 9, 2018
@kallewoof
Copy link
Member Author

@kallewoof kallewoof commented Jan 9, 2018

  • Self-review: RPC command help needs update to reflect change
src/wallet/feebumper.cpp Outdated
}
}
if (nOutput == -1) {
errors.push_back("Transaction does not have a change output");
errors.push_back("Transaction does not have a change output (use reduce_output=0 to use the single output)");

This comment has been minimized.

@MarcoFalke

MarcoFalke Jan 13, 2018
Member

This error will also display in the gui. Not sure if it makes sense there to mention reduce_output

This comment has been minimized.

@kallewoof

kallewoof Jan 13, 2018
Author Member

Oh. Hm..

This comment has been minimized.

@sipa

sipa Feb 20, 2018
Member

It also sounds confusing when there isn't a single output?

This comment has been minimized.

@kallewoof

kallewoof Feb 20, 2018
Author Member

I'll just revert it.

@@ -3257,6 +3262,9 @@ UniValue bumpfee(const JSONRPCRequest& request)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
}
}
if (options.exists("reduce_output")) {
reduce_output = options["reduce_output"].get_int64();
}

This comment has been minimized.

@MarcoFalke

MarcoFalke Jan 13, 2018
Member

This will segfault on OOB

This comment has been minimized.

@kallewoof

kallewoof Jan 13, 2018
Author Member

Oops. Added bounds check in feebumper::CreateTransaction.

This comment has been minimized.

@promag

promag Jan 18, 2018
Member

Where?

This comment has been minimized.

@promag

promag Jan 18, 2018
Member

Also add assert_raises_rpc_error tests for:

  • when not a number;
  • when reduce_output < 0 and >= len(vout).

For instance, see 7f67dd0.

This comment has been minimized.

@kallewoof

kallewoof Jan 18, 2018
Author Member

No idea how that happened, but my changes are gone. Fixing, again.

This comment has been minimized.

@luke-jr

luke-jr Feb 26, 2018
Member

Needs a lower bounds check here too, to avoid accepting -1.

@kallewoof kallewoof force-pushed the kallewoof:better-bumpfee branch Jan 17, 2018
@kallewoof kallewoof force-pushed the kallewoof:better-bumpfee branch Dec 10, 2018
@kallewoof kallewoof force-pushed the kallewoof:better-bumpfee branch to d5a711e Jan 15, 2019
@kallewoof kallewoof force-pushed the kallewoof:better-bumpfee branch from d5a711e to 61a0412 Feb 25, 2019
@kallewoof kallewoof force-pushed the kallewoof:better-bumpfee branch from 61a0412 to 52442ef Feb 25, 2019
@kallewoof kallewoof force-pushed the kallewoof:better-bumpfee branch from 52442ef to 7c4555e Mar 23, 2019
@kallewoof kallewoof force-pushed the kallewoof:better-bumpfee branch from 7c4555e to e82c8ff Apr 16, 2019
@@ -200,8 +207,8 @@ Result CreateTotalBumpTransaction(const CWallet* wallet, const uint256& txid, co
}


Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCoinControl& coin_control, std::vector<std::string>& errors,
CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx)
Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCoinControl& coin_control, int32_t reduce_output,

This comment has been minimized.

@luke-jr

luke-jr Apr 16, 2019
Member

Nit: Extra space on the end

@@ -223,8 +230,9 @@ Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCo

// Fill in recipients(and preserve a single change key if there is one)
std::vector<CRecipient> recipients;
const auto* change_output = reduce_output > -1 && (size_t)reduce_output < wtx.tx->vout.size() ? &wtx.tx->vout[reduce_output] : nullptr;

This comment has been minimized.

@luke-jr

luke-jr Apr 16, 2019
Member

CreateTotalBumpTransaction returns an error if reduce_output is out of range. This code just ignores it. Probably should be consistent.

This comment has been minimized.

@instagibbs

instagibbs Apr 16, 2019
Member

"change" is really over-loaded here, please call it something else

This comment has been minimized.

@kallewoof

kallewoof Apr 24, 2019
Author Member

@luke-jr Agreed - now consistent.

@instagibbs Renamed to reduce_output_vout.

for (const auto& output : wtx.tx->vout) {
if (!wallet->IsChange(output)) {
if (change_output ? output != *change_output : !wallet->IsChange(output)) {

This comment has been minimized.

@luke-jr

luke-jr Apr 16, 2019
Member

Couldn't this result in the reduce_output getting increased? That could be a serious problem in some cases...

This comment has been minimized.

@kallewoof

kallewoof Apr 24, 2019
Author Member

I'm not sure I follow. In which case would reduce_output increase?

kallewoof added 2 commits Jan 5, 2018
Currently, bumpfee cannot be used to bump a single output transaction. This should be possible, as single output transactions are special in that the exact amount doesn't usually matter (the user is emptying a wallet or using coin control to move UTXOs).
@kallewoof kallewoof force-pushed the kallewoof:better-bumpfee branch from e82c8ff to 086313c Apr 24, 2019
@DrahtBot
Copy link
Contributor

@DrahtBot DrahtBot commented Apr 27, 2019

Needs rebase
@kallewoof
Copy link
Member Author

@kallewoof kallewoof commented Jun 19, 2019

Rebase is becoming overwhelming on this. Closing until further notice (may rewrite the code).

@kallewoof kallewoof closed this Jun 19, 2019
@kallewoof kallewoof deleted the kallewoof:better-bumpfee branch Oct 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet