test: wallet: Check fallbackfee default argument behavior. #34382

pull davidgumberg wants to merge 3 commits into bitcoin:master from davidgumberg:2026-01-22-fallbackfee_experiments changing 1 files +54 −11
  1. davidgumberg commented at 9:15 PM on January 22, 2026: contributor

    In an unmerged branch of #32636 (https://github.com/bitcoin/bitcoin/commit/097e00f90765915b0f8353a4eb5ebb18ceae2a66) I unintentionally broke default -fallbackfee behavior, but this was not caught by any tests. See #32636 (review).

    Something like the following diff does not cause any test failures on master despite causing a behavior change:

    diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
    index bc27018cd2..079610fba0 100644
    --- a/src/wallet/wallet.cpp
    +++ b/src/wallet/wallet.cpp
    @@ -3048,24 +3048,24 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
         if (const auto arg{args.GetArg("-fallbackfee")}) {
             std::optional<CAmount> fallback_fee = ParseMoney(*arg);
             if (!fallback_fee) {
                 error = strprintf(_("Invalid amount for %s=<amount>: '%s'"), "-fallbackfee", *arg);
                 return nullptr;
             } else if (fallback_fee.value() > HIGH_TX_FEE_PER_KB) {
                 warnings.push_back(AmountHighWarn("-fallbackfee") + Untranslated(" ") +
                                    _("This is the transaction fee you may pay when fee estimates are not available."));
             }
             walletInstance->m_fallback_fee = CFeeRate{fallback_fee.value()};
    +        // Disable fallback fee in case value was set to 0, enable if non-null value
    +        walletInstance->m_allow_fallback_fee = walletInstance->m_fallback_fee.GetFeePerK() != 0;
         }
    
    -    // Disable fallback fee in case value was set to 0, enable if non-null value
    -    walletInstance->m_allow_fallback_fee = walletInstance->m_fallback_fee.GetFeePerK() != 0;
    

    This PR adds a functional test check that when no -fallbackfee argument is set and fee estimation is not possible, that sending fails because -fallbackfee is disabled by default.

  2. DrahtBot added the label Tests on Jan 22, 2026
  3. DrahtBot commented at 9:15 PM on January 22, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

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

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK w0xlt, ismaelsadeeq, maflcko
    Approach ACK polespinasa

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

    LLM Linter (✨ experimental)

    Possible typos and grammar issues:

    • """Test wallet fallbackfee.""" -> """Test wallet fallback fee.""" [“fallbackfee” is merged; it may confuse readers since the standard term is “fallback fee”.]
    • Use the largest fallbackfee value that doesn't trigger a warning. -> Use the largest fallback fee value that doesn't trigger a warning. [Same “fallbackfee” spelling issue; hampers clarity with the intended term.]

    <sup>2026-03-26 02:51:41</sup>

  4. davidgumberg force-pushed on Jan 22, 2026
  5. DrahtBot added the label CI failed on Jan 22, 2026
  6. furszy commented at 9:23 PM on January 22, 2026: member

    not related, but the fee arg changes remind me to #29278. Writing it so we don't forget it.

  7. DrahtBot removed the label CI failed on Jan 22, 2026
  8. w0xlt commented at 10:48 PM on January 22, 2026: contributor

    ACK 28a64d4ef8b872e3687350f93fd3dd78717f795f

    nit: This snippet could go in the second commit instead.

            # Sending a transaction with a fallback fee set succeeds. Use the
            # largest fallbackfee value that doesn't trigger a warning.
            self.restart_node(0, extra_args=[f"-fallbackfee={HIGH_TX_FEE_PER_KB}"])
            self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
            self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1}))
            self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1})
    
  9. davidgumberg commented at 1:59 AM on January 23, 2026: contributor

    nit: This snippet could go in the second commit instead.

    This replaces the default sendtoaddress test which gets deleted in the first commit, so to be atomic I think it should probably stay in the first commit.

  10. in test/functional/wallet_fallbackfee.py:47 in 699e2b4dde
      45 |  
      46 | +        # Sending a transaction with a fallback fee set succeeds. Use the
      47 | +        # largest fallbackfee value that doesn't trigger a warning.
      48 | +        self.restart_node(0, extra_args=[f"-fallbackfee={HIGH_TX_FEE_PER_KB}"])
      49 | +        self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
      50 | +        self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1}))
    


    polespinasa commented at 5:54 PM on February 24, 2026:

    Should the feerate used for the transaction created by fundrawtransaction be exactly what fallbackfee set?

    If that the case it is not what is happening here:

    $ ./build/test/functional/wallet_fallbackfee.py 
    2026-02-24T17:51:00.304094Z TestFramework (INFO): PRNG seed is: 7181096759883981303
    2026-02-24T17:51:00.304546Z TestFramework (INFO): Initializing test directory /tmp/bitcoin_func_test_99f1niyg
    2026-02-24T17:51:01.927838Z TestFramework (ERROR): Unexpected exception
    Traceback (most recent call last):
      File "/home/sliv3r/Documentos/Projectes/BitcoinCore/bitcoin/test/functional/test_framework/test_framework.py", line 142, in main
        self.run_test()
      File "/home/sliv3r/Documentos/Projectes/BitcoinCore/bitcoin/./build/test/functional/wallet_fallbackfee.py", line 53, in run_test
        assert_equal(tx2['fee'], HIGH_TX_FEE_PER_KB)
      File "/home/sliv3r/Documentos/Projectes/BitcoinCore/bitcoin/test/functional/test_framework/util.py", line 80, in assert_equal
        raise AssertionError("not(%s)" % " == ".join(str(arg) for arg in (thing1, thing2) + args))
    AssertionError: not(0.00141000 == 0.01)
    
    

    Code:

    $ git diff
    diff --git a/test/functional/wallet_fallbackfee.py b/test/functional/wallet_fallbackfee.py
    index 64df3931f9..2af2a84cd3 100755
    --- a/test/functional/wallet_fallbackfee.py
    +++ b/test/functional/wallet_fallbackfee.py
    @@ -8,7 +8,10 @@ from decimal import Decimal
     
     from test_framework.blocktools import COINBASE_MATURITY
     from test_framework.test_framework import BitcoinTestFramework
    -from test_framework.util import assert_raises_rpc_error
    +from test_framework.util import (
    +    assert_raises_rpc_error,
    +    assert_equal,
    +)
     
     HIGH_TX_FEE_PER_KB = Decimal('0.01')
     
    @@ -44,9 +47,10 @@ class WalletRBFTest(BitcoinTestFramework):
             # largest fallbackfee value that doesn't trigger a warning.
             self.restart_node(0, extra_args=[f"-fallbackfee={HIGH_TX_FEE_PER_KB}"])
             self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
    -        self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1}))
    +        tx2 = self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1}))
             self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1})
     
    +        assert_equal(tx2['fee'], HIGH_TX_FEE_PER_KB)
             # Starting a node with a large fallback fee set...
             excessive_fallback = HIGH_TX_FEE_PER_KB + Decimal('0.00000001')
             self.restart_node(0, extra_args=[f"-fallbackfee={excessive_fallback}"])
    
    

    rkrux commented at 1:15 PM on February 25, 2026:

    This appears to be incorrect comparison.

    tx2['fee'] is absolute fee whereas HIGH_TX_FEE_PER_KB is feerate.


    polespinasa commented at 6:45 PM on February 25, 2026:

    Oh you are right, my bad sorry. It does work as expected:

    $ git diff
    diff --git a/test/functional/wallet_fallbackfee.py b/test/functional/wallet_fallbackfee.py
    index 64df3931f9..c91caadce5 100755
    --- a/test/functional/wallet_fallbackfee.py
    +++ b/test/functional/wallet_fallbackfee.py
    @@ -8,7 +8,12 @@ from decimal import Decimal
     
     from test_framework.blocktools import COINBASE_MATURITY
     from test_framework.test_framework import BitcoinTestFramework
    -from test_framework.util import assert_raises_rpc_error
    +from test_framework.util import (
    +    assert_raises_rpc_error,
    +    assert_equal,
    +)
    +
    +from test_framework.messages import CTransaction, from_hex
     
     HIGH_TX_FEE_PER_KB = Decimal('0.01')
     
    @@ -44,7 +49,11 @@ class WalletRBFTest(BitcoinTestFramework):
             # largest fallbackfee value that doesn't trigger a warning.
             self.restart_node(0, extra_args=[f"-fallbackfee={HIGH_TX_FEE_PER_KB}"])
             self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
    -        self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1}))
    +        tx2 = self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1}))
    +        tx = CTransaction()
    +        tx = from_hex(tx, tx2['hex'])
    +        assert_equal(round(Decimal((tx2['fee']*1000)/(tx.get_vsize())),2), HIGH_TX_FEE_PER_KB)
    +
             self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1})
     
             # Starting a node with a large fallback fee set...
    
    

    I wonder what is the precision that fallbackfee has?


    davidgumberg commented at 11:53 PM on March 24, 2026:

    It seems -fallbackfee can only be used with 8 decimal points of precision in terms of BTC/kvB, i.e. increments of 1 sat/kvB:

    https://github.com/bitcoin/bitcoin/blob/28a64d4ef8b872e3687350f93fd3dd78717f795f/src/wallet/wallet.cpp#L3048-L3049

    https://github.com/bitcoin/bitcoin/blob/28a64d4ef8b872e3687350f93fd3dd78717f795f/src/util/moneystr.cpp#L45

    https://github.com/bitcoin/bitcoin/blob/28a64d4ef8b872e3687350f93fd3dd78717f795f/src/util/moneystr.cpp#L57-L79

    Since nMult reaches zero, and then the break is hit, and if we exit the for loop without having reached the NULL string terminator.

  11. in test/functional/wallet_fallbackfee.py:46 in 699e2b4dde
      44 |          assert_raises_rpc_error(-6, "Fee estimation failed", lambda: self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1}))
      45 |  
      46 | +        # Sending a transaction with a fallback fee set succeeds. Use the
      47 | +        # largest fallbackfee value that doesn't trigger a warning.
      48 | +        self.restart_node(0, extra_args=[f"-fallbackfee={HIGH_TX_FEE_PER_KB}"])
      49 | +        self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
    


    polespinasa commented at 5:57 PM on February 24, 2026:

    Maybe we can actually assert here that the feerate used is set because of fallback being used:

    $ git diff
    diff --git a/test/functional/wallet_fallbackfee.py b/test/functional/wallet_fallbackfee.py
    index 64df3931f9..98344e804f 100755
    --- a/test/functional/wallet_fallbackfee.py
    +++ b/test/functional/wallet_fallbackfee.py
    @@ -8,7 +8,10 @@ from decimal import Decimal
     
     from test_framework.blocktools import COINBASE_MATURITY
     from test_framework.test_framework import BitcoinTestFramework
    -from test_framework.util import assert_raises_rpc_error
    +from test_framework.util import (
    +    assert_raises_rpc_error,
    +    assert_equal
    +)
     
     HIGH_TX_FEE_PER_KB = Decimal('0.01')
     
    @@ -43,7 +46,7 @@ class WalletRBFTest(BitcoinTestFramework):
             # Sending a transaction with a fallback fee set succeeds. Use the
             # largest fallbackfee value that doesn't trigger a warning.
             self.restart_node(0, extra_args=[f"-fallbackfee={HIGH_TX_FEE_PER_KB}"])
    -        self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
    +        assert_equal(self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1, verbose=True)['fee_reason'], f"Fallback fee")
             self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1}))
             self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1})
     
    
    

    rkrux commented at 1:21 PM on February 25, 2026:

    +1 for this suggestion, adds robustness in testing.


    davidgumberg commented at 12:46 AM on March 25, 2026:

    Thanks for the suggestion, done.

  12. in test/functional/wallet_fallbackfee.py:48 in 699e2b4dde
      46 | +        # Sending a transaction with a fallback fee set succeeds. Use the
      47 | +        # largest fallbackfee value that doesn't trigger a warning.
      48 | +        self.restart_node(0, extra_args=[f"-fallbackfee={HIGH_TX_FEE_PER_KB}"])
      49 | +        self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
      50 | +        self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1}))
      51 | +        self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1})
    


    polespinasa commented at 6:00 PM on February 24, 2026:

    Same as #34382 (review) we could check the fee reason

    $ git diff
    diff --git a/test/functional/wallet_fallbackfee.py b/test/functional/wallet_fallbackfee.py
    index 64df3931f9..61bc4cdc8a 100755
    --- a/test/functional/wallet_fallbackfee.py
    +++ b/test/functional/wallet_fallbackfee.py
    @@ -8,7 +8,10 @@ from decimal import Decimal
     
     from test_framework.blocktools import COINBASE_MATURITY
     from test_framework.test_framework import BitcoinTestFramework
    -from test_framework.util import assert_raises_rpc_error
    +from test_framework.util import (
    +    assert_raises_rpc_error,
    +    assert_equal
    +)
     
     HIGH_TX_FEE_PER_KB = Decimal('0.01')
     
    @@ -45,7 +48,7 @@ class WalletRBFTest(BitcoinTestFramework):
             self.restart_node(0, extra_args=[f"-fallbackfee={HIGH_TX_FEE_PER_KB}"])
             self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
             self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1}))
    -        self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1})
    +        assert_equal(self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1}, verbose=True)["fee_reason"], f"Fallback fee")
     
             # Starting a node with a large fallback fee set...
             excessive_fallback = HIGH_TX_FEE_PER_KB + Decimal('0.00000001')
    
    

    davidgumberg commented at 12:46 AM on March 25, 2026:

    Thanks, fixed.

  13. polespinasa commented at 6:01 PM on February 24, 2026: member

    Approach ACK 28a64d4ef8b872e3687350f93fd3dd78717f795f

    Just left some ideas for improving the test

  14. in test/functional/wallet_fallbackfee.py:16 in 28a64d4ef8
      11 |  from test_framework.util import assert_raises_rpc_error
      12 |  
      13 | +HIGH_TX_FEE_PER_KB = Decimal('0.01')
      14 | +
      15 | +
      16 |  class WalletRBFTest(BitcoinTestFramework):
    


    rkrux commented at 1:30 PM on February 25, 2026:

    Can take this PR as an opportunity to rename this class. I don't see any RBF stuff happening, Idk why it is called so.

    --- a/test/functional/wallet_fallbackfee.py
    +++ b/test/functional/wallet_fallbackfee.py
    @@ -13,7 +13,7 @@ from test_framework.util import assert_raises_rpc_error
     HIGH_TX_FEE_PER_KB = Decimal('0.01')
     
     
    -class WalletRBFTest(BitcoinTestFramework):
    +class WalletFallbackFeeTest(BitcoinTestFramework):
         def set_test_params(self):
             self.num_nodes = 1
             self.setup_clean_chain = True
    @@ -59,4 +59,4 @@ class WalletRBFTest(BitcoinTestFramework):
             self.stop_node(0, expected_stderr=expected_error)
     
     if __name__ == '__main__':
    -    WalletRBFTest(__file__).main()
    +    WalletFallbackFeeTest(__file__).main()
    (END)
    

    davidgumberg commented at 12:46 AM on March 25, 2026:

    Thanks, looking back at the PR that introduced this test (https://github.com/bitcoin/bitcoin/pull/11882), it seems this is a holdover from an older version of the PR that had two separate -fallbackfee arguments one for RBF and one for non-RBF which were later consolidated.

    I've gone ahead and removed mention of RBF.

  15. in test/functional/wallet_fallbackfee.py:56 in 28a64d4ef8
      54 | +        excessive_fallback = HIGH_TX_FEE_PER_KB + Decimal('0.00000001')
      55 | +        self.restart_node(0, extra_args=[f"-fallbackfee={excessive_fallback}"])
      56 | +        # Works...
      57 | +        self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
      58 | +        self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1}))
      59 | +        self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1})
    


    rkrux commented at 1:50 PM on February 25, 2026:

    Opinionated suggestion: I have seen these 3 RPCs 4 times in the test. Consider the following diff that reads slightly better but doesn't really reduce the lines.

    diff --git a/test/functional/wallet_fallbackfee.py b/test/functional/wallet_fallbackfee.py
    index 64df3931f9..9c8316a100 100755
    --- a/test/functional/wallet_fallbackfee.py
    +++ b/test/functional/wallet_fallbackfee.py
    @@ -12,6 +12,11 @@ from test_framework.util import assert_raises_rpc_error
     
     HIGH_TX_FEE_PER_KB = Decimal('0.01')
     
    +TRANSACTION_RPCS = [
    +    lambda node: node.sendtoaddress(node.getnewaddress(), 1),
    +    lambda node: node.fundrawtransaction(node.createrawtransaction([], {node.getnewaddress(): 1})),
    +    lambda node: node.sendmany("", {node.getnewaddress(): 1}),
    +]
     
     class WalletRBFTest(BitcoinTestFramework):
         def set_test_params(self):
    @@ -30,30 +35,26 @@ class WalletRBFTest(BitcoinTestFramework):
             self.restart_node(0)
     
             # Sending a transaction with no -fallbackfee setting fails, since the default value is 0.
    -        assert_raises_rpc_error(-6, "Fee estimation failed", lambda: self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1))
    -        assert_raises_rpc_error(-4, "Fee estimation failed", lambda: self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1})))
    -        assert_raises_rpc_error(-6, "Fee estimation failed", lambda: self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1}))
    +        for rpc in TRANSACTION_RPCS:
    +            assert_raises_rpc_error(None, "Fee estimation failed", lambda: rpc(self.nodes[0]))
     
             # Sending a tx with explicitly disabled fallback fee fails.
             self.restart_node(0, extra_args=["-fallbackfee=0"])
    -        assert_raises_rpc_error(-6, "Fee estimation failed", lambda: self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1))
    -        assert_raises_rpc_error(-4, "Fee estimation failed", lambda: self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1})))
    -        assert_raises_rpc_error(-6, "Fee estimation failed", lambda: self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1}))
    +        for rpc in TRANSACTION_RPCS:
    +            assert_raises_rpc_error(None, "Fee estimation failed", lambda: rpc(self.nodes[0]))
     
             # Sending a transaction with a fallback fee set succeeds. Use the
             # largest fallbackfee value that doesn't trigger a warning.
             self.restart_node(0, extra_args=[f"-fallbackfee={HIGH_TX_FEE_PER_KB}"])
    -        self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
    -        self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1}))
    -        self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1})
    +        for rpc in TRANSACTION_RPCS:
    +            rpc(self.nodes[0])
     
             # Starting a node with a large fallback fee set...
             excessive_fallback = HIGH_TX_FEE_PER_KB + Decimal('0.00000001')
             self.restart_node(0, extra_args=[f"-fallbackfee={excessive_fallback}"])
             # Works...
    -        self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
    -        self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1}))
    -        self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1})
    +        for rpc in TRANSACTION_RPCS:
    +            rpc(self.nodes[0])
             # But results in a warning message.
             expected_error = "Warning: -fallbackfee is set very high! This is the transaction fee you may pay when fee estimates are not available."
             self.stop_node(0, expected_stderr=expected_error)
    
    

    davidgumberg commented at 12:48 AM on March 25, 2026:

    Thanks for the suggestion, but I'm not sure I agree with this exactly as you've suggested it since it makes the test somewhat inflexible. e.g. It conflicts with the suggestion above: #34382 (review)) where the success checks are made stricter than the failure check.

    But I have taken inspiration from your suggestion and refactored the success and failure checks into their own methods which I think makes the test a lot more legible:

    https://github.com/bitcoin/bitcoin/blob/1e55691b73a1b185dfe21c72b9549cc7d837e294/test/functional/wallet_fallbackfee.py#L23-L38

    I feel that reading this now, I am much more focused on the valid / invalid conditions for fallback fees instead of the myriad RPC's that exercise them which I took to be the spirit of your suggestion.

  16. ismaelsadeeq approved
  17. ismaelsadeeq commented at 9:43 AM on March 12, 2026: member

    ACK 28a64d4ef8b872e3687350f93fd3dd78717f795f

    In an unmerged branch of #32636 (https://github.com/bitcoin/bitcoin/commit/097e00f90765915b0f8353a4eb5ebb18ceae2a66) I unintentionally broke default -fallbackfee behavior, but this was not caught by any tests. See #32636 (review).

    The linked comment is incorrect, should be #32636 (review)

    Apart from that I think review comments from @polespinasa and @rkrux are nice to haves that can be done in a follow-up.

    I've verified that with diff

    diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
    index bc27018cd2..30dd68b155 100644
    --- a/src/wallet/wallet.cpp
    +++ b/src/wallet/wallet.cpp
    @@ -3055,10 +3055,11 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
                                    _("This is the transaction fee you may pay when fee estimates are not available."));
             }
             walletInstance->m_fallback_fee = CFeeRate{fallback_fee.value()};
    +
    +        // Disable fallback fee in case value was set to 0, enable if non-null value
    +        walletInstance->m_allow_fallback_fee = walletInstance->m_fallback_fee.GetFeePerK() != 0;
         }
    
    -    // Disable fallback fee in case value was set to 0, enable if non-null value
    -    walletInstance->m_allow_fallback_fee = walletInstance->m_fallback_fee.GetFeePerK() != 0;
    
         if (const auto arg{args.GetArg("-discardfee")}) {
             std::optional<CAmount> discard_fee = ParseMoney(*arg);
    
    2026-03-12T09:38:56.622703Z TestFramework (INFO): PRNG seed is: 2067377870230985435
    2026-03-12T09:38:56.623048Z TestFramework (INFO): Initializing test directory /tmp/bitcoin_func_test_u50t3b7q
    2026-03-12T09:38:57.392184Z TestFramework (ERROR): Unexpected exception
    Traceback (most recent call last):
      File "/home/ismaelsadeeq/bitcoin-dev/bitcoin-core/bitcoin/test/functional/test_framework/test_framework.py", line 142, in main
        self.run_test()
      File "/home/ismaelsadeeq/bitcoin-dev/bitcoin-core/bitcoin/build_dev_mode/test/functional/wallet_fallbackfee.py", line 33, in run_test
        assert_raises_rpc_error(-6, "Fee estimation failed", lambda: self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1))
      File "/home/ismaelsadeeq/bitcoin-dev/bitcoin-core/bitcoin/test/functional/test_framework/util.py", line 157, in assert_raises_rpc_error
        assert try_rpc(code, message, fun, *args, **kwds), "No exception raised"
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    AssertionError: No exception raised
    2026-03-12T09:38:57.442873Z TestFramework (INFO): Not stopping nodes as test failed. The dangling processes will be cleaned up later.
    2026-03-12T09:38:57.442944Z TestFramework (WARNING): Not cleaning up dir /tmp/bitcoin_func_test_u50t3b7q
    2026-03-12T09:38:57.442968Z TestFramework (ERROR): Test failed. Test logging available at /tmp/bitcoin_func_test_u50t3b7q/test_framework.log
    2026-03-12T09:38:57.443015Z TestFramework (ERROR):
    2026-03-12T09:38:57.443071Z TestFramework (ERROR): Hint: Call /home/ismaelsadeeq/bitcoin-dev/bitcoin-core/bitcoin/test/functional/combine_logs.py '/tmp/bitcoin_func_test_u50t3b7q' to consolidate all logs
    2026-03-12T09:38:57.443091Z TestFramework (ERROR):
    2026-03-12T09:38:57.443108Z TestFramework (ERROR): If this failure happened unexpectedly or intermittently, please file a bug and provide a link or upload of the combined log.
    2026-03-12T09:38:57.443136Z TestFramework (ERROR): https://github.com/bitcoin/bitcoin/issues
    2026-03-12T09:38:57.443153Z TestFramework (ERROR):
    [node 0] Cleaning up leftover process
    

    While on master it passes.

  18. DrahtBot requested review from polespinasa on Mar 12, 2026
  19. achow101 commented at 8:51 PM on March 13, 2026: member

    nice to haves that can be done in a follow-up.

    This PR is small enough and not so significant that it needs followups. If those changes are going to be done, then they should be done in this PR.

  20. davidgumberg force-pushed on Mar 25, 2026
  21. davidgumberg force-pushed on Mar 25, 2026
  22. DrahtBot added the label CI failed on Mar 25, 2026
  23. davidgumberg commented at 1:24 AM on March 25, 2026: contributor

    Pushed to address feedback from @rkrux and @polespinasa, I've also fixed the issue in the PR description as suggested by @ismaelsadeeq.

  24. in test/functional/wallet_fallbackfee.py:61 in 5fe602cfc6 outdated
      66 | +
      67 | +        # Sending a transaction with a fallback fee set succeeds. Use the
      68 | +        # largest fallbackfee value that doesn't trigger a warning.
      69 | +        self.restart_node(0, extra_args=[f"-fallbackfee={HIGH_TX_FEE_PER_KB}"])
      70 | +        self.sending_succeeds(node)
      71 | +        self.stop_node(0, expected_stderr='')
    


    davidgumberg commented at 1:25 AM on March 25, 2026:

    Note for reviewers, this does nothing differently from restarting the node at the start of the next test, but I wanted to make the expected_stderr check more explicit.

  25. test: wallet: refactor: fallbackfee extract common send failure checks. d28c989243
  26. test: wallet: -fallbackfee default is 0
    Also check more RPC's for success and check that we are using
    `-fallbackfee`.
    6664e41e56
  27. test: wallet: Warning for excessive fallback fee. 3dcdb2b9ba
  28. in test/functional/wallet_fallbackfee.py:32 in 95356ce196 outdated
      33 | +        # Sending a tx with explicitly disabled fallback fee fails.
      34 |          self.restart_node(0, extra_args=["-fallbackfee=0"])
      35 | -        assert_raises_rpc_error(-6, "Fee estimation failed", lambda: self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1))
      36 | -        assert_raises_rpc_error(-4, "Fee estimation failed", lambda: self.nodes[0].fundrawtransaction(self.nodes[0].createrawtransaction([], {self.nodes[0].getnewaddress(): 1})))
      37 | -        assert_raises_rpc_error(-6, "Fee estimation failed", lambda: self.nodes[0].sendmany("", {self.nodes[0].getnewaddress(): 1}))
      38 | +        self.sending_fails(node)
    


    DrahtBot commented at 6:21 AM on March 25, 2026:
     test  2026-03-25T01:29:58.093548Z TestFramework (ERROR): Unexpected exception: 
                                       Traceback (most recent call last):
                                         File "/home/admin/actions-runner/_work/bitcoin/bitcoin/test/functional/test_framework/test_framework.py", line 142, in main
                                           self.run_test()
                                         File "/home/admin/actions-runner/_work/bitcoin/bitcoin/ci_build/test/functional/wallet_fallbackfee.py", line 32, in run_test
                                           self.sending_fails(node)
                                                              ^^^^
                                       NameError: name 'node' is not defined. Did you mean: 'None'?
    

    ismaelsadeeq commented at 3:31 PM on March 25, 2026:

    Good bot. The node is not defined in this commit. "test: wallet: refactor: fallbackfee extract common send failure checks." 95356ce19660a255f6be8e7684441284774785a7

    Which is why the test for each commit job fails.

            self.sending_fails(self.nodes[0])
    

    davidgumberg commented at 2:51 AM on March 26, 2026:

    Woops, fixed.

  29. davidgumberg force-pushed on Mar 26, 2026
  30. DrahtBot removed the label CI failed on Mar 26, 2026
  31. w0xlt commented at 9:50 PM on March 26, 2026: contributor

    reACK 3dcdb2b9ba18a848d7108d754a60a9ed5530f7a4

  32. DrahtBot requested review from ismaelsadeeq on Mar 26, 2026
  33. ismaelsadeeq approved
  34. ismaelsadeeq commented at 2:30 PM on March 29, 2026: member

    reACK 3dcdb2b9ba18a848d7108d754a60a9ed5530f7a4 👾

  35. maflcko commented at 9:38 AM on March 30, 2026: member

    review ACK 3dcdb2b9ba18a848d7108d754a60a9ed5530f7a4 🐞

    <details><summary>Show signature</summary>

    Signature:

    untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
    RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
    trusted comment: review ACK 3dcdb2b9ba18a848d7108d754a60a9ed5530f7a4 🐞
    e+WHtYeMsWc4MOTzkdIfRhkwQH71JSENYXlcntv9fvgPS+sIOcH+VoZE31Eq//xsPLvhHw2r8JdDEDtV2w0NDA==
    

    </details>

  36. fanquake merged this on Mar 30, 2026
  37. fanquake closed this on Mar 30, 2026

  38. polespinasa commented at 3:05 PM on March 30, 2026: member

    ACK 3dcdb2b9ba18a848d7108d754a60a9ed5530f7a4


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-04-17 06:12 UTC

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