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

Wallet incremental fee #9615

Merged
merged 8 commits into from
Jan 30, 2017
Merged

Wallet incremental fee #9615

merged 8 commits into from
Jan 30, 2017

Conversation

morcos
Copy link
Member

@morcos morcos commented Jan 23, 2017

This is another couple of minor tweaks to bumpfee that I'd hope to merge for 0.14.
Built on top of #9589

Introduce WALLET_INCREMENTAL_RELAY_FEE
Have wallet's default bump value be higher than the default incrementalRelayFee to future proof against changes to incremental relay fee. Only applies when not setting the fee rate directly.
If we ever decide that we'd like to raise the default incrementalRelayFee or nodes on the network start doing it, it would be a shame if old software was generating replacements that didn't relay. 5000 satoshis/KB is a compromise between being sufficiently future proof and not losing too much precision in our ability to bump fees.

Incidentally I do think the incrementalRelayFee is too low and that the "cost" to the network of relaying a transaction around is above 1000 satoshi/KB and there is insufficient benefit on having that much precision to bumpfee and mempool limiting. I don't feel like getting in a big argument about changing the default though. But my recommendation would be to change the default to 5000 satoshis.

Change bumpfee result value from 'oldfee' to 'origfee'.
The result value indicates the actual fee on the transaction that was replaced. But there is an error message which uses the description 'oldfee' to refer to the original fee rate applied to the new transaction's estimated max size. It was confusing that two different uses of 'oldfee' had two different numeric values.

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK ec692cca0b5225d37c81b1d4fb7f450b20d10ce0 with two minor suggestions.

Also there an extra line at the end of the "Change bumpfee result value from 'oldfee' to 'origfee." (ec692cca0b5225d37c81b1d4fb7f450b20d10ce0) commit message which I think doesn't belong.

@@ -2823,8 +2827,17 @@ UniValue bumpfee(const JSONRPCRequest& request)
// new fee rate must be at least old rate + minimum incremental relay rate
if (nNewFeeRate.GetFeePerK() < nOldFeeRate.GetFeePerK() + ::incrementalRelayFee.GetFeePerK()) {
nNewFeeRate = CFeeRate(nOldFeeRate.GetFeePerK() + ::incrementalRelayFee.GetFeePerK());
if (specifiedConfirmTarget || payTxFee.GetFeePerK() == 0) {
// In the default case where the user is depending on the wallet
// to smartly pick the fee, the wallet should have its own
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe s/should have its own minimum incremental fee/uses a conservative WALLET_INCREMENTAL_RELAY_FEE value/. Saying "should" could suggest that the wallet doesn't already do this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do


if (totalFee > 0) {
CAmount minTotalFee = nOldFeeRate.GetFee(maxNewTxSize) + ::incrementalRelayFee.GetFee(maxNewTxSize);
if (totalFee < minTotalFee) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid totalFee, must be at least %s (oldFee %s + relayFee %s)", FormatMoney(minTotalFee), nOldFeeRate.GetFee(maxNewTxSize), ::incrementalRelayFee.GetFee(maxNewTxSize)));
CAmount recommendedTotalFee = nOldFeeRate.GetFee(maxNewTxSize) + walletIncrementalRelayFee.GetFee(maxNewTxSize);
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid totalFee, must be at least %s (oldFee %s + incrementalFee %s), recommended %s (incrementalFee %s)",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another another way to avoid the ambiguity of having different "oldfee" values might be to phrase error message to in terms of fee rates, rather than fees:

nNewFee = totalFee;
nNewFeeRate = CFeeRate(totalFee, maxNewTxSize);
CFeeRate minFeeRate = CFeeRate(nOldFeeRate.GetFeePerK() + ::incrementalRelayFee.GetFeePerK());
if (nNewFeeRate < minFeeRate) {
    CAmount recommendedTotalFee = nOldFeeRate.GetFee(maxNewTxSize) + walletIncrementalRelayFee.GetFee(maxNewTxSize);
    throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Insufficient totalFee rate %s %s/kB, must be at least %s %s/kB (old rate %s %s/kB + incremental rate %s %s/kB), recommended %s %s (incremental fee %s %s)",
                                                        FormatMoney(nNewFeeRate.GetFeePerK()), CURRENCY_UNIT,
                                                        FormatMoney(minFeeRate.GetFeePerK()), CURRENCY_UNIT,
                                                        FormatMoney(nOldFeeRate.GetFeePerK()), CURRENCY_UNIT,
                                                        FormatMoney(::incrementalRelayFee.GetFeePerK()), CURRENCY_UNIT,
                                                        FormatMoney(recommendedTotalFee), CURRENCY_UNIT,
                                                        walletIncrementalRelayFee.GetFee(maxNewTxSize)));
}

I think this would make more sense anyway, because whatever client code is calling this will probably be deriving totalFee values based on fee rates, and this error message is more explicit about the minimum fee rate required.

(Also think saying insufficient fee is better than saying invalid fee, to be more specific).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm... I feel like if the option is total fee (not rate) then we should give the error message in fee (not rate). I don't feel strongly about that.., but its not really relevant to the gist of this PR anyway, so I'll leave it alone for now. BTW, CFeeRate has a ToString().

I will make the change to Insufficient totalFee though..

@jonasschnelli
Copy link
Contributor

Concept ACK.

@morcos
Copy link
Member Author

morcos commented Jan 24, 2017

Please tag 0.14

@@ -2823,8 +2827,17 @@ UniValue bumpfee(const JSONRPCRequest& request)
// new fee rate must be at least old rate + minimum incremental relay rate
if (nNewFeeRate.GetFeePerK() < nOldFeeRate.GetFeePerK() + ::incrementalRelayFee.GetFeePerK()) {
nNewFeeRate = CFeeRate(nOldFeeRate.GetFeePerK() + ::incrementalRelayFee.GetFeePerK());
if (specifiedConfirmTarget || payTxFee.GetFeePerK() == 0) {
Copy link
Member

@sdaftuar sdaftuar Jan 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want this logic to apply even if the user didn't specify a confirmation target -- just as long as paytxfee is 0. EDIT: I misread the code above, this logic does correctly do what is intended here, though I still think this is complication is unnecessary.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, on further thought, we might as well have this apply even if payTxFee is set... There's no philosophical difference in my mind between being willing to exceed it by incrementalRelayFee vs. walletIncrementalRelayFee.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok took this advice

@morcos
Copy link
Member Author

morcos commented Jan 26, 2017

Rebased on new #9589 and simplified the logic per @sdaftuar's comment

Use the wallet's fee calculation logic to properly clamp fee against minimums and maximums when calculating the fee for a bumpfee transaction.  Unless totalFee is explictly given, in which case, manually check against min, but do nothing to adjust given fee.

In all cases do a final check against maxTxFee (after adding any incremental amount).
@morcos
Copy link
Member Author

morcos commented Jan 26, 2017

Still just the last 2 commits are part of this PR, updated because of #9589 again and added check that walletIncrementalRelayFee is always at least as big as global policy incrementalRelayFee

@sdaftuar
Copy link
Member

utACK de798cb


if (totalFee > 0) {
CAmount minTotalFee = nOldFeeRate.GetFee(maxNewTxSize) + ::incrementalRelayFee.GetFee(maxNewTxSize);
if (totalFee < minTotalFee) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid totalFee, must be at least %s (oldFee %s + relayFee %s)", FormatMoney(minTotalFee), nOldFeeRate.GetFee(maxNewTxSize), ::incrementalRelayFee.GetFee(maxNewTxSize)));
CAmount recommendedTotalFee = nOldFeeRate.GetFee(maxNewTxSize) + walletIncrementalRelayFee.GetFee(maxNewTxSize);
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Insufficient totalFee, must be at least %s (oldFee %s + incrementalFee %s), recommended %s (incrementalFee %s)",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is undefined behavior (though I'm no expert on tinyformat) - you're printing CAmounts with %s. I also find it super strange to print both Bitcoin and Satoshis side-by-side with no unit information.

Have wallet's default bump value be higher than the default incrementalRelayFee to future proof against changes to incremental relay fee.  Only applies when not setting the fee rate directly.
The result value indicates the actual fee on the transaction that was replaced. But there is an error message which uses the description 'oldfee' to refer to the original fee rate applied to the new transaction's estimated max size.  It was confusing that two different uses of 'oldfee' had two different numeric values.
@morcos
Copy link
Member Author

morcos commented Jan 26, 2017

ok fixed and squashed 51c67f4 -> 4b189c1

(removed the unnecessary recommended amount from the error message as well)

@TheBlueMatt
Copy link
Contributor

utACK 4b189c1

@laanwj laanwj added this to the 0.14.0 milestone Jan 26, 2017
@sdaftuar
Copy link
Member

utACK 4b189c1

@laanwj laanwj merged commit 4b189c1 into bitcoin:master Jan 30, 2017
laanwj added a commit that referenced this pull request Jan 30, 2017
4b189c1 Change bumpfee result value from 'oldfee' to 'origfee'. (Alex Morcos)
0c0c63f Introduce WALLET_INCREMENTAL_RELAY_FEE (Alex Morcos)
e8021ec Use CWallet::GetMinimumFee in bumpfee (Alex Morcos)
ae9719a Refactor GetMinimumFee to give option of providing targetFee (Alex Morcos)
fe8e8ef [rpc] Add incremental relay fee to getnetworkinfo (Alex Morcos)
6b331e6 Fix to have miner test aware of new separate block min tx fee (Alex Morcos)
de6400d Fix missing use of dustRelayFee (Alex Morcos)
5b15870 Use incrementalRelayFee for BIP 125 replacement (Alex Morcos)
codablock pushed a commit to codablock/dash that referenced this pull request Jan 23, 2018
4b189c1 Change bumpfee result value from 'oldfee' to 'origfee'. (Alex Morcos)
0c0c63f Introduce WALLET_INCREMENTAL_RELAY_FEE (Alex Morcos)
e8021ec Use CWallet::GetMinimumFee in bumpfee (Alex Morcos)
ae9719a Refactor GetMinimumFee to give option of providing targetFee (Alex Morcos)
fe8e8ef [rpc] Add incremental relay fee to getnetworkinfo (Alex Morcos)
6b331e6 Fix to have miner test aware of new separate block min tx fee (Alex Morcos)
de6400d Fix missing use of dustRelayFee (Alex Morcos)
5b15870 Use incrementalRelayFee for BIP 125 replacement (Alex Morcos)
andvgal pushed a commit to energicryptocurrency/gen2-energi that referenced this pull request Jan 6, 2019
4b189c1 Change bumpfee result value from 'oldfee' to 'origfee'. (Alex Morcos)
0c0c63f Introduce WALLET_INCREMENTAL_RELAY_FEE (Alex Morcos)
e8021ec Use CWallet::GetMinimumFee in bumpfee (Alex Morcos)
ae9719a Refactor GetMinimumFee to give option of providing targetFee (Alex Morcos)
fe8e8ef [rpc] Add incremental relay fee to getnetworkinfo (Alex Morcos)
6b331e6 Fix to have miner test aware of new separate block min tx fee (Alex Morcos)
de6400d Fix missing use of dustRelayFee (Alex Morcos)
5b15870 Use incrementalRelayFee for BIP 125 replacement (Alex Morcos)
CryptoCentric pushed a commit to absolute-community/absolute that referenced this pull request Feb 27, 2019
4b189c1 Change bumpfee result value from 'oldfee' to 'origfee'. (Alex Morcos)
0c0c63f Introduce WALLET_INCREMENTAL_RELAY_FEE (Alex Morcos)
e8021ec Use CWallet::GetMinimumFee in bumpfee (Alex Morcos)
ae9719a Refactor GetMinimumFee to give option of providing targetFee (Alex Morcos)
fe8e8ef [rpc] Add incremental relay fee to getnetworkinfo (Alex Morcos)
6b331e6 Fix to have miner test aware of new separate block min tx fee (Alex Morcos)
de6400d Fix missing use of dustRelayFee (Alex Morcos)
5b15870 Use incrementalRelayFee for BIP 125 replacement (Alex Morcos)
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants