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: Add feeRate argument to bumpFee RPC #16492

Closed
wants to merge 5 commits into from

Conversation

ezegom
Copy link
Contributor

@ezegom ezegom commented Jul 30, 2019

Fixes #16203.

On PR #15996, the totalfee argument in bumpfee gets deprecated. The feeRate argument in bumpfee serves as a replacement to totalFee.

Small changes to CreateRateBumpTransaction

  • If the coin_control passed in has a feeRate set then we check if the feeRate is OK and if so, create the bump transaction. The logic to verify if the feeRate is good should be identical to the logic that verifies the totalFee value.
  • If the coin_control does not have a feeRate set then we estimate the fee as we used to.

@ezegom ezegom closed this Jul 30, 2019
@ezegom ezegom reopened this Jul 30, 2019
@fanquake fanquake changed the title <WIP> Add feeRate argument to bumpFee RPC WIP: Add feeRate argument to bumpFee RPC Jul 30, 2019
@ezegom ezegom force-pushed the feerate_bumpfee branch from 0d8adc9 to c828209 Compare July 30, 2019 14:05
@instagibbs
Copy link
Member

concept ACK

@@ -57,6 +57,58 @@ static feebumper::Result PreconditionChecks(interfaces::Chain::Lock& locked_chai
return feebumper::Result::OK;
}

//! Check if the user provided a valid feeRate
static feebumper::Result CheckFeeRate(const CWallet* wallet, const CWalletTx& wtx, const CFeeRate& newFeerate, const int64_t maxTxSize, std::vector<std::string>& errors) {
// check that fee rate is higher than mempool's minimum fee
Copy link
Member

Choose a reason for hiding this comment

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

is this block of code cribbed from somewhere to compare with?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this code is from the CreateTotalBumpTransaction method

// calculate the old fee and fee-rate
old_fee = wtx.GetDebit(ISMINE_SPENDABLE) - wtx.tx->GetValueOut();
CFeeRate nOldFeeRate(old_fee, txSize);
// The wallet uses a conservative WALLET_INCREMENTAL_RELAY_FEE value to
// future proof against changes to network wide policy for incremental relay
// fee that our node may not be aware of.
CFeeRate nodeIncrementalRelayFee = wallet->chain().relayIncrementalFee();
CFeeRate walletIncrementalRelayFee = CFeeRate(WALLET_INCREMENTAL_RELAY_FEE);
if (nodeIncrementalRelayFee > walletIncrementalRelayFee) {
walletIncrementalRelayFee = nodeIncrementalRelayFee;
}
CAmount minTotalFee = nOldFeeRate.GetFee(maxNewTxSize) + nodeIncrementalRelayFee.GetFee(maxNewTxSize);
if (total_fee < minTotalFee) {
errors.push_back(strprintf("Insufficient totalFee, must be at least %s (oldFee %s + incrementalFee %s)",
FormatMoney(minTotalFee), FormatMoney(nOldFeeRate.GetFee(maxNewTxSize)), FormatMoney(nodeIncrementalRelayFee.GetFee(maxNewTxSize))));
return Result::INVALID_PARAMETER;
}
CAmount requiredFee = GetRequiredFee(*wallet, maxNewTxSize);
if (total_fee < requiredFee) {
errors.push_back(strprintf("Insufficient totalFee (cannot be less than required fee %s)",
FormatMoney(requiredFee)));
return Result::INVALID_PARAMETER;
}
// Check that in all cases the new fee doesn't violate maxTxFee
const CAmount max_tx_fee = wallet->m_default_max_tx_fee;
if (new_fee > max_tx_fee) {
errors.push_back(strprintf("Specified or calculated fee %s is too high (cannot be higher than -maxtxfee %s)",
FormatMoney(new_fee), FormatMoney(max_tx_fee)));
return Result::WALLET_ERROR;
}
// check that fee rate is higher than mempool's minimum fee
// (no point in bumping fee if we know that the new tx won't be accepted to the mempool)
// This may occur if the user set TotalFee or paytxfee too low, if fallbackfee is too low, or, perhaps,
// in a rare situation where the mempool minimum fee increased significantly since the fee estimation just a
// moment earlier. In this case, we report an error to the user, who may use total_fee to make an adjustment.
CFeeRate minMempoolFeeRate = wallet->chain().mempoolMinFee();
CFeeRate nNewFeeRate = CFeeRate(total_fee, maxNewTxSize);
if (nNewFeeRate.GetFeePerK() < minMempoolFeeRate.GetFeePerK()) {
errors.push_back(strprintf(
"New fee rate (%s) is lower than the minimum fee rate (%s) to get into the mempool -- "
"the totalFee value should be at least %s to add transaction",
FormatMoney(nNewFeeRate.GetFeePerK()),
FormatMoney(minMempoolFeeRate.GetFeePerK()),
FormatMoney(minMempoolFeeRate.GetFee(maxNewTxSize))));
return Result::WALLET_ERROR;
}

CAmount minTotalFee = nOldFeeRate.GetFee(maxTxSize) + incrementalRelayFee.GetFee(maxTxSize);

if (new_total_fee < minTotalFee) {
errors.push_back(strprintf("Insufficient totalFee %s, must be at least %s (oldFee %s + incrementalFee %s)",
Copy link
Member

Choose a reason for hiding this comment

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

totalFee isn't a thing

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll rewrite these error messages.

@promag
Copy link
Contributor

promag commented Jul 31, 2019

Concept ACK. Some notes:

  • try to keep commits organized
  • please see git log and pick one of the commit message format

@ezegom
Copy link
Contributor Author

ezegom commented Jul 31, 2019

Concept ACK. Some notes:

  • try to keep commits organized
  • please see git log and pick one of the commit message format

@promag Thanks for your feedback.
I'll change the commits from "<rpc>" to "rpc:". My bad, should've taken a look at the git log before assuming this style.
Regarding the organization, what do you feel is not organized?

@maflcko
Copy link
Member

maflcko commented Jul 31, 2019

Could rebase on master and modify the release notes in the section "removed or deprecated rpcs"?

@ezegom ezegom force-pushed the feerate_bumpfee branch 3 times, most recently from 5e564f6 to 9bc7a55 Compare August 1, 2019 13:43
Copy link
Member

@Sjors Sjors left a comment

Choose a reason for hiding this comment

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

Concept ACK.

In the description, if you replace "Draft commit for issue" with "Fixes" then Github will automatically close that issue when this PR is merged, which saves maintainers some effort.

Regarding the organization, what do you feel is not organized?

You should use git interactive rebase to reduce the number of commits, for example:

This makes it easier to review a pull request one commit at a time.

  • commit Changes the verbosity of msbuild: move to separate pull request

@@ -176,7 +188,6 @@ def test_bumpfee_with_descendant_fails(rbf_node, rbf_node_address, dest_address)
rbf_node.sendrawtransaction(tx["hex"])
assert_raises_rpc_error(-8, "Transaction has descendants in the wallet", rbf_node.bumpfee, parent_id)


Copy link
Member

Choose a reason for hiding this comment

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

Nit: avoid dropping or adding whitespace in code that you're not touching.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

@ezegom ezegom force-pushed the feerate_bumpfee branch 2 times, most recently from 27fb2f1 to e1fd79a Compare August 2, 2019 13:26
@ezegom
Copy link
Contributor Author

ezegom commented Aug 2, 2019

Thanks @Sjors,
I cleaned up the commits accordingly.

@ezegom ezegom force-pushed the feerate_bumpfee branch 3 times, most recently from 48d3691 to 002dbde Compare August 2, 2019 14:24
Copy link
Member

@Sjors Sjors left a comment

Choose a reason for hiding this comment

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

Thanks for condensing the commits.

You can probably remove the WIP and Draft status; those are meant to prevent too detailed review, but it's too late for that :-)

There's still quite a bit of duplicate code between CheckFeeRate and CreateTotalBumpTransaction. Can you add an additional commit, similar to rpc: bumpfee move feeRate estimation logic into sepparate method, where you move this to a helper function? I'll review the actual functionality in more detail after that.

There's a couple of places where you or your editor fixed stuff in code that you're not otherwise touching. This increases review burden, because it's harder to see what changes are relevant, so is best avoided. I left a bunch of inline comments for that.

Couple more nits:

  • commit rpc: test bumpfee feeRate argument should be named [test] rpc bumpfee feeRate argument

@@ -92,7 +92,9 @@ Deprecated or removed RPCs
--------------------------

- The `totalFee` option of the `bumpfee` RPC has been deprecated and will be
removed in 0.20. To continue using this option start with
removed in 0.20. The `feeRate` option is now the preferred way to specify
the fee for the bump transaction.
Copy link
Member

Choose a reason for hiding this comment

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

Nit: bumped

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I initially wrote it as 'bumped' but went with 'bump'. My thought was that the bumped transaction is the one we are replacing, and the bump transaction is the new one?

Copy link
Contributor

@promag promag Aug 2, 2019

Choose a reason for hiding this comment

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

the fee for the new transaction.

See

"\nBumps the fee of an opt-in-RBF transaction T, replacing it with a new transaction B.\n"

Copy link
Contributor Author

@ezegom ezegom Aug 2, 2019

Choose a reason for hiding this comment

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

thats better, fixed.

@@ -3361,7 +3361,7 @@ static UniValue bumpfee(const JSONRPCRequest& request)
if (fee_rate <= 0) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid feeRate %s (must be greater than 0)", fee_rate.ToString()));
}
coin_control.m_feerate = fee_rate;
coin_control.m_feerate = fee_rate;
Copy link
Member

Choose a reason for hiding this comment

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

Nit: move whitespace fix to commit where the whitespace mistake was made

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

@@ -3278,7 +3278,7 @@ static UniValue bumpfee(const JSONRPCRequest& request)
"All inputs in the original transaction will be included in the replacement transaction.\n"
"The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n"
"By default, the new fee will be calculated automatically using estimatesmartfee.\n"
"The user can specify a confirmation target for estimatesmartfee.\n"
Copy link
Member

Choose a reason for hiding this comment

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

Nit: don't remove whitespace here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

@@ -304,7 +361,8 @@ Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCo
return Result::OK;
}

bool SignTransaction(CWallet* wallet, CMutableTransaction& mtx) {
Copy link
Member

Choose a reason for hiding this comment

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

Nit: you're not touching this function, so don't fix the brackets please

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed :)

@@ -4,16 +4,16 @@

#include <consensus/validation.h>
#include <interfaces/chain.h>
#include <wallet/coincontrol.h>
Copy link
Member

Choose a reason for hiding this comment

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

nit: don't fix the include order; that's best done when you add a new include

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

@@ -71,8 +152,7 @@ bool TransactionCanBeBumped(const CWallet* wallet, const uint256& txid)
return res == feebumper::Result::OK;
}

Result CreateTotalBumpTransaction(const CWallet* wallet, const uint256& txid, const CCoinControl& coin_control, CAmount total_fee, std::vector<std::string>& errors,
CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx)
Result CreateTotalBumpTransaction(const CWallet* wallet, const uint256& txid, const CCoinControl& coin_control, CAmount total_fee, std::vector<std::string>& errors, CAmount& old_fee, CAmount& new_fee, CMutableTransaction& mtx)
Copy link
Member

Choose a reason for hiding this comment

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

nit: don't fix things you're not otherwise touching

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed this too

FormatMoney(new_fee), FormatMoney(max_tx_fee)));
return Result::WALLET_ERROR;
}
const CAmount max_tx_fee = wallet->m_default_max_tx_fee;
Copy link
Member

Choose a reason for hiding this comment

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

nit: don't fix this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@ezegom
Copy link
Contributor Author

ezegom commented Aug 2, 2019

@Sjors I should be done with your comments, let me know if there is anything missing. Only thing missing is to get rid of the code re-use on CreateTotalTransaction.

@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 2, 2019

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #16690 (Prepare release notes for 0.19 by harding)
  • #11413 ([wallet] [rpc] sendtoaddress/sendmany: Add explicit feerate option by kallewoof)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@ezegom ezegom changed the title WIP: Add feeRate argument to bumpFee RPC rpc: Add feeRate argument to bumpFee RPC Aug 2, 2019
@ezegom ezegom marked this pull request as ready for review August 2, 2019 22:10
if (options.exists("confTarget") && (options.exists("totalFee") || options.exists("feeRate"))) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "confTarget can't be set with totalFee or feeRate. Please provide either a conftarget for fee estimation, or an explicit total fee or fee rate for the transaction.");
} else if (options.exists("feeRate") && options.exists("totalFee")) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "feeRate can't be set along with totalFee. Please provide either a total fee or a fee rate (in satoshis per K) for the transaction.");
Copy link
Member

Choose a reason for hiding this comment

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

Where else are we using satoshis per Kb? Seems like we're using BTC/kB everywhere else unless I'm missing a use?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are correct, I used Satoshis per kB on my first iteration of this feature and forgot to change the error message. nice catch

@instagibbs
Copy link
Member

(couldn't reach you on IRC) still working on this?

@DrahtBot
Copy link
Contributor

Needs rebase

@fanquake
Copy link
Member

Taken over in #16727.

@fanquake fanquake closed this Aug 27, 2019
laanwj added a commit that referenced this pull request Oct 2, 2019
c812aba test bumpfee fee_rate argument (ezegom)
9f25de3 rpc bumpfee check fee_rate argument (ezegom)
88e5f99 rpc bumpfee: add fee_rate argument (ezegom)
1a4c791 rpc bumpfee: move feerate estimation logic into separate method (ezegom)

Pull request description:

  Taking over for #16492 which seems to have gone inactive.

  Only minor commit cleanups, rebase, and some help text fixes on top of previous PR. Renamed `feeRate` to `fee_rate` to reflect updated guidelines.

ACKs for top commit:
  Sjors:
    Code review ACK c812aba
  laanwj:
    ACK c812aba

Tree-SHA512: 5f7f51bd780a573ccef1ccd72b0faf3e5d143f6551060a667560c5163f7d9480e17e73775d1d7bcac0463f3b6b4328f0cff7b27e39483bddc42a530f4583ce30
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Dec 16, 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.

allow feerate argument in bumpfee in addition to confTarget
8 participants