wallet, rpc: remove settxfee and paytxfee #32138

pull polespinasa wants to merge 2 commits into bitcoin:master from polespinasa:deletesettxfee changing 27 files +121 −255
  1. polespinasa commented at 6:30 pm on March 25, 2025: member

    Summary

    This PR removes the settxfee RPC and paytxfee setting (Bitcoin Core 31.0). These two features were deprecated in #31278.

  2. DrahtBot commented at 6:30 pm on March 25, 2025: contributor

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

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32138.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK w0xlt, achow101
    Concept ACK theStack, Bicaru20
    Stale ACK nebula-21

    If your review is incorrectly listed, please copy-paste <!–meta-tag:bot-skip–> into the comment that the bot should ignore.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #34603 (wallet: Fix detection of symlinks on Windows by achow101)
    • #34418 (qa: Make wallet_multiwallet.py Windows crossbuild-compatible by hodlinator)
    • #34049 (rpc: Disallow captures in RPCMethodImpl by ajtowns)
    • #29278 (Wallet: Add maxfeerate wallet startup option by ismaelsadeeq)
    • #17580 (refactor: Add ALLOW_LIST flags and enforce usage in CheckArgFlags by ryanofsky)

    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.

    LLM Linter (✨ experimental)

    Possible places where named args for integral literals may be used (e.g. func(x, /*named_arg=*/0) in C++, and func(x, named_arg=0) in Python):

    • self.nodes[2].sendtoaddress(address, 10, “”, “”, False, fee_rate=fee_rate_sat_vb) in test/functional/wallet_basic.py
    • self.nodes[2].sendtoaddress(address, 10, “”, “”, True, fee_rate=fee_rate_sat_vb) in test/functional/wallet_basic.py
    • self.nodes[2].sendmany(’’, {address: 10}, 0, “”, [], fee_rate=fee_rate_sat_vb) in test/functional/wallet_basic.py
    • self.nodes[2].sendmany(’’, {address: 10}, 0, “”, [address], fee_rate=fee_rate_sat_vb) in test/functional/wallet_basic.py

    2026-02-13 09:53:51

  3. DrahtBot added the label CI failed on Mar 25, 2025
  4. DrahtBot commented at 6:43 pm on March 25, 2025: contributor

    🚧 At least one of the CI tasks failed. Debug: https://github.com/bitcoin/bitcoin/runs/39393296960

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  5. DrahtBot added this to the milestone 31.0 on Mar 25, 2025
  6. DrahtBot marked this as a draft on Mar 25, 2025
  7. polespinasa force-pushed on Mar 25, 2025
  8. polespinasa renamed this:
    wallet, rpc: (v31.0) remove settxfee and paytxfee (work in progress)
    wallet, rpc: (v31.0) remove settxfee and paytxfee
    on Mar 25, 2025
  9. polespinasa marked this as ready for review on Mar 25, 2025
  10. polespinasa commented at 6:56 pm on March 25, 2025: member
    Note to self: re-check all tests
  11. maflcko commented at 7:10 pm on March 25, 2025: member
    Please leave this in draft. 31.0 is half a year out, so starting review on this is questionable and won’t help to get it merged earlier anyway
  12. polespinasa renamed this:
    wallet, rpc: (v31.0) remove settxfee and paytxfee
    wallet, rpc: (v31.0) remove settxfee and paytxfee (work in progress)
    on Mar 25, 2025
  13. polespinasa marked this as a draft on Mar 25, 2025
  14. DrahtBot removed the label CI failed on Mar 25, 2025
  15. fanquake renamed this:
    wallet, rpc: (v31.0) remove settxfee and paytxfee (work in progress)
    wallet, rpc: remove settxfee and paytxfee
    on Mar 26, 2025
  16. laanwj added the label Wallet on Mar 26, 2025
  17. laanwj added the label RPC/REST/ZMQ on Mar 26, 2025
  18. DrahtBot added the label Needs rebase on Mar 27, 2025
  19. polespinasa commented at 7:25 am on June 24, 2025: member
    Will re-open closer to 31.0 release
  20. polespinasa closed this on Jun 24, 2025

  21. maflcko commented at 11:18 am on August 26, 2025: member
    Seems fine to pick this up now, if you want.
  22. polespinasa reopened this on Aug 26, 2025

  23. polespinasa force-pushed on Aug 26, 2025
  24. polespinasa force-pushed on Aug 26, 2025
  25. polespinasa marked this as ready for review on Aug 26, 2025
  26. DrahtBot removed the label Needs rebase on Aug 26, 2025
  27. polespinasa force-pushed on Aug 26, 2025
  28. polespinasa commented at 6:08 pm on August 26, 2025: member
    5ba260ca74 Rebased on top of master 6ca6f3b37b
  29. polespinasa force-pushed on Aug 26, 2025
  30. DrahtBot added the label CI failed on Aug 26, 2025
  31. DrahtBot commented at 6:11 pm on August 26, 2025: contributor

    🚧 At least one of the CI tasks failed. Task lint: https://github.com/bitcoin/bitcoin/runs/48937774714 LLM reason (✨ experimental): Lint failure caused by an invalid Python shebang in test/functional/wallet_txn_clone.py (syntax error).

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  32. DrahtBot removed the label CI failed on Aug 26, 2025
  33. maflcko commented at 8:48 am on August 28, 2025: member
    What is the point of keeping m_pay_tx_fee. It is just dead code now, no?
  34. polespinasa commented at 6:17 pm on August 28, 2025: member

    It is just dead code now, no? @maflcko I think you’re right. Will squash after review, think it’s easier this way.

  35. in src/wallet/wallet.h: in d3ed01fbc8 outdated
    101@@ -102,7 +102,7 @@ void NotifyWalletLoaded(WalletContext& context, const std::shared_ptr<CWallet>&
    102 std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
    103 
    104 //! -paytxfee default (paytxfee RPC was removed in v31.0)
    105-constexpr CAmount DEFAULT_PAY_TX_FEE = 0;
    106+//constexpr CAmount DEFAULT_PAY_TX_FEE = 0;
    


    polespinasa commented at 6:25 pm on August 28, 2025:
    forgot to remove the line, will do next push
  36. maflcko commented at 2:43 pm on September 1, 2025: member

    Will squash after review, think it’s easier this way.

    I’d say to either squash now, or create meaningful separate commits. E.g:

    • First, remove from rpc (settxfee, paytxfee result)
    • Then, remove from cli (-paytxfee, tests only)
    • Then, remove from cli (-paytxfee, code, and remaining leftovers)
  37. polespinasa force-pushed on Sep 2, 2025
  38. theStack commented at 2:27 pm on January 5, 2026: contributor

    Concept ACK

    This should have a release note, and IIUC, the following part of the PR description doesn’t apply anymore:

    This PR does not remove the internal implementation of the default value of paytxfee=0 but removes the option for users to modify it.

  39. fanquake added the label Needs release note on Jan 5, 2026
  40. nebula-21 commented at 0:04 am on January 18, 2026: none

    ACK 76a5e97671177e6f0f08bfd7c2ce13e7b273415d

    Tested behavior before and after this PR, code lgtm.

    Prior to this PR, settxfee was callable (with deprecation warning). With this PR it is fully removed and returns “Method not found”:

    0$ bitcoin-cli settxfee 0.001
    1error code: -32601
    2error message:
    3Method not found
    

    The -paytxfee startup option is also rejected after this PR:

    0$ bitcoind -paytxfee=0.001
    1Error: Error parsing command line arguments: Invalid parameter -paytxfee=0.001
    
  41. DrahtBot requested review from theStack on Jan 18, 2026
  42. in doc/release-notes-32138.md:3 in 76a5e97671
    0@@ -0,0 +1,3 @@
    1+RPC and Startup Option
    2+---
    3+The `-paytxfee` startup option and the `settxfee` RPC are now deleted after being deprected in Bitcoin Core 30.0. They used to allow the user to set a static fee rate for wallet transactions, which could potentially lead to overpaying or underpaying. Users should instead rely on fee estimation or specify a fee rate per transaction using the `fee_rate` argument in RPCs such as `fundrawtransaction`, `sendtoaddress`, `send`, `sendall`, and `sendmany`. (#32138)
    


    w0xlt commented at 4:18 am on January 27, 2026:
    0The `-paytxfee` startup option and the `settxfee` RPC are now deleted after being deprecated in Bitcoin Core 30.0. They used to allow the user to set a static fee rate for wallet transactions, which could potentially lead to overpaying or underpaying. Users should instead rely on fee estimation or specify a fee rate per transaction using the `fee_rate` argument in RPCs such as `fundrawtransaction`, `sendtoaddress`, `send`, `sendall`, and `sendmany`. (#32138)
    

    polespinasa commented at 4:12 pm on January 28, 2026:
    Done
  43. w0xlt commented at 4:27 am on January 27, 2026: contributor

    There is still a reference to the removed m_pay_tx_fee here:

     0--- a/src/wallet/coincontrol.h
     1+++ b/src/wallet/coincontrol.h
     2@@ -93,7 +93,7 @@ public:
     3     bool m_allow_other_inputs = true;
     4     //! Override automatic min/max checks on fee, m_feerate must be set if true
     5     bool fOverrideFeeRate = false;
     6-    //! Override the wallet's m_pay_tx_fee if set
     7+    //! Override the default wallet fee rate if set
     8     std::optional<CFeeRate> m_feerate;
     9     //! Override the default confirmation target if set
    10     std::optional<unsigned int> m_confirm_target;
    

    There’s also a remaining reference in src/qt/bitcoinstrings.cpp, although that file is auto-generated.

    0--- a/src/qt/bitcoinstrings.cpp
    1+++ b/src/qt/bitcoinstrings.cpp
    2@@ -14,7 +14,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "%s is set very high!"),
    3 QT_TRANSLATE_NOOP("bitcoin-core", "%s is set very high! Fees this large could be paid on a single transaction."),
    4 QT_TRANSLATE_NOOP("bitcoin-core", "%s request to listen on port %u. This port is considered \"bad\" and thus it is unlikely that any peer will connect to it. See doc/p2p-bad-ports.md for details and a full list."),
    5 QT_TRANSLATE_NOOP("bitcoin-core", "-maxmempool must be at least %d MB"),
    6-QT_TRANSLATE_NOOP("bitcoin-core", "-paytxfee is deprecated and will be fully removed in v31.0."),
    7 QT_TRANSLATE_NOOP("bitcoin-core", "A fatal internal error occurred, see debug.log for details: "),
    8 QT_TRANSLATE_NOOP("bitcoin-core", "Assumeutxo data not found for the given blockhash '%s'."),
    
  44. polespinasa force-pushed on Jan 28, 2026
  45. polespinasa commented at 4:13 pm on January 28, 2026: member

    There’s also a remaining reference in src/qt/bitcoinstrings.cpp, although that file is auto-generated.

    Is this something I should take into account? Or will it get solved automatically?

  46. achow101 commented at 5:54 pm on January 28, 2026: member

    There’s also a remaining reference in src/qt/bitcoinstrings.cpp, although that file is auto-generated.

    Is this something I should take into account? Or will it get solved automatically?

    No those are cleaned up by the pre-release translations update

  47. w0xlt commented at 6:05 pm on January 28, 2026: contributor
    ACK d51f551101a66adbaeebbc0b56270e154a77c399
  48. DrahtBot requested review from nebula-21 on Jan 28, 2026
  49. nebula-21 commented at 6:33 pm on January 30, 2026: none
    re-ACK d51f551101a66adbaeebbc0b56270e154a77c399
  50. DrahtBot added the label Needs rebase on Feb 4, 2026
  51. polespinasa force-pushed on Feb 5, 2026
  52. polespinasa force-pushed on Feb 5, 2026
  53. DrahtBot added the label CI failed on Feb 5, 2026
  54. DrahtBot commented at 8:59 am on February 5, 2026: contributor

    🚧 At least one of the CI tasks failed. Task lint: https://github.com/bitcoin/bitcoin/actions/runs/21705105705/job/62594128574 LLM reason (✨ experimental): Lint check failed due to undocumented argument -paytxfee.

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  55. polespinasa commented at 8:59 am on February 5, 2026: member

    Rebased to fix conflicts with master.

    The conflict was caused by #32636 when moving the load args code to it’s own function CWallet::LoadWalletArgs.

  56. DrahtBot removed the label Needs rebase on Feb 5, 2026
  57. DrahtBot removed the label CI failed on Feb 5, 2026
  58. in test/functional/wallet_create_tx.py:74 in 2d09b4077d
    68@@ -68,20 +69,22 @@ def test_tx_size_too_large(self):
    69                 lambda: self.nodes[0].fundrawtransaction(hexstring=raw_tx),
    70             )
    71 
    72-        self.log.info('Check maxtxfee in combination with settxfee')
    73-        self.restart_node(0, expected_stderr='Warning: -paytxfee is deprecated and will be fully removed in v31.0.')
    74-        self.nodes[0].settxfee(0.01)
    75+        # Hit maxtxfee with explicit fee rate
    76+        self.log.info('Check maxtxfee in combination with explicit fee_rate=1000 sat/vB')
    77+        self.restart_node(0)
    


    achow101 commented at 9:56 pm on February 5, 2026:

    In 2d09b4077d270a2caa94aee555fc2fe91e0bcc6e “wallet, rpc:remove settxfee and paytxfee”

    This restart_node is no longer necessary.


    polespinasa commented at 3:09 pm on February 12, 2026:
    good catch thanks
  59. polespinasa force-pushed on Feb 12, 2026
  60. polespinasa commented at 3:09 pm on February 12, 2026: member

    I think the “need release note” label can be removed :)

    Force pushed to remove an unnecessary restart_node see #32138 (review)

     0$ git diff 2d09b4..a31455db31
     1diff --git a/test/functional/wallet_create_tx.py b/test/functional/wallet_create_tx.py
     2index 810b5a8423..a62759761f 100755
     3--- a/test/functional/wallet_create_tx.py
     4+++ b/test/functional/wallet_create_tx.py
     5@@ -71,7 +71,6 @@ class CreateTxWalletTest(BitcoinTestFramework):
     6 
     7         # Hit maxtxfee with explicit fee rate
     8         self.log.info('Check maxtxfee in combination with explicit fee_rate=1000 sat/vB')
     9-        self.restart_node(0)
    10 
    11         fee_rate_sats_per_vb = Decimal('0.01') * Decimal(1e8) / 1000  # Convert 0.01 BTC/kvB to sat/vB
    
  61. Bicaru20 commented at 7:19 pm on February 12, 2026: none

    In the enumeration that give the reason for returned fee estimate (in block_policy_estimator.h), I noticed that there is a PAYTXFEE element. I believe that since paytxfee is being deleted, this element should be erased. I eliminated the code where FeeReason::PAYTXFEE was present. Here I leave the code I changed:

     0diff --git a/src/common/messages.cpp b/src/common/messages.cpp
     1index 123db93cf6..ec20eeb2aa 100644
     2--- a/src/common/messages.cpp
     3+++ b/src/common/messages.cpp
     4@@ -33,7 +33,6 @@ std::string StringForFeeReason(FeeReason reason)
     5         {FeeReason::DOUBLE_ESTIMATE, "Double Target 95% Threshold"},
     6         {FeeReason::CONSERVATIVE, "Conservative Double Target longer horizon"},
     7         {FeeReason::MEMPOOL_MIN, "Mempool Min Fee"},
     8-        {FeeReason::PAYTXFEE, "PayTxFee set"},
     9         {FeeReason::FALLBACK, "Fallback fee"},
    10         {FeeReason::REQUIRED, "Minimum Required Fee"},
    11     };
    12diff --git a/src/policy/fees/block_policy_estimator.h b/src/policy/fees/block_policy_estimator.h
    13index 505eed0867..ae7b440607 100644
    14--- a/src/policy/fees/block_policy_estimator.h
    15+++ b/src/policy/fees/block_policy_estimator.h
    16@@ -64,7 +64,6 @@ enum class FeeReason {
    17     DOUBLE_ESTIMATE,
    18     CONSERVATIVE,
    19     MEMPOOL_MIN,
    20-    PAYTXFEE,
    21     FALLBACK,
    22     REQUIRED,
    23 };
    24diff --git a/src/test/fuzz/fees.cpp b/src/test/fuzz/fees.cpp
    25index f295dd12c8..1bd5c67a20 100644
    26--- a/src/test/fuzz/fees.cpp
    27+++ b/src/test/fuzz/fees.cpp
    28@@ -26,6 +26,6 @@ FUZZ_TARGET(fees)
    29         const CAmount rounded_fee = fee_filter_rounder.round(current_minimum_fee);
    30         assert(MoneyRange(rounded_fee));
    31     }
    32-    const FeeReason fee_reason = fuzzed_data_provider.PickValueInArray({FeeReason::NONE, FeeReason::HALF_ESTIMATE, FeeReason::FULL_ESTIMATE, FeeReason::DOUBLE_ESTIMATE, FeeReason::CONSERVATIVE, FeeReason::MEMPOOL_MIN, FeeReason::PAYTXFEE, FeeReason::FALLBACK, FeeReason::REQUIRED});
    33+    const FeeReason fee_reason = fuzzed_data_provider.PickValueInArray({FeeReason::NONE, FeeReason::HALF_ESTIMATE, FeeReason::FULL_ESTIMATE, FeeReason::DOUBLE_ESTIMATE, FeeReason::CONSERVATIVE, FeeReason::MEMPOOL_MIN, FeeReason::FALLBACK, FeeReason::REQUIRED});
    34     (void)StringForFeeReason(fee_reason);
    35 }
    36diff --git a/src/wallet/fees.cpp b/src/wallet/fees.cpp
    37index d5e7140a2a..e2bb222791 100644
    38--- a/src/wallet/fees.cpp
    39+++ b/src/wallet/fees.cpp
    40@@ -37,7 +37,6 @@ CFeeRate GetMinimumFeeRate(const CWallet& wallet, const CCoinControl& coin_contr
    41     CFeeRate feerate_needed;
    42     if (coin_control.m_feerate) { // 1.
    43         feerate_needed = *(coin_control.m_feerate);
    44-        if (feeCalc) feeCalc->reason = FeeReason::PAYTXFEE;
    45         // Allow to override automatic min/max check over coin control instance
    46         if (coin_control.fOverrideFeeRate) return feerate_needed;
    47     }
    

    I run the unit tests: And the functional:

  62. wallet, rpc:remove settxfee and paytxfee 331a5279d2
  63. release note 24f93c9af7
  64. polespinasa force-pushed on Feb 13, 2026
  65. polespinasa commented at 9:54 am on February 13, 2026: member

    Thanks for the review, nice catch @Bicaru20 :)

    Force pushed to add the changes proposed in #32138 (comment)

    see the diff here https://github.com/bitcoin/bitcoin/compare/5772c2ea4cefc09a3e6341d20b2172247b3f7982..24f93c9af7f6627cd7d09a1a5f10667846b048eb

  66. w0xlt commented at 10:33 pm on February 16, 2026: contributor
    reACK 24f93c9af7f6627cd7d09a1a5f10667846b048eb
  67. DrahtBot requested review from nebula-21 on Feb 16, 2026
  68. achow101 commented at 0:01 am on February 19, 2026: member
    ACK 24f93c9af7f6627cd7d09a1a5f10667846b048eb
  69. achow101 merged this on Feb 19, 2026
  70. achow101 closed this on Feb 19, 2026

  71. polespinasa deleted the branch on Feb 19, 2026

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-02-22 00:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me