test: Add multiple transactions and error handling tests for getreceivedbyaddress #34188

pull b-l-u-e wants to merge 1 commits into bitcoin:master from b-l-u-e:test-wallet-getreceivedbyaddress changing 1 files +12 −1
  1. b-l-u-e commented at 5:56 am on January 2, 2026: contributor
    This PR adds comprehensive functional test coverage for the getreceivedbyaddress RPC method.
  2. bensig commented at 8:18 am on January 2, 2026: contributor

    ACK 0d0b34d

    Built with wallet support and ran on macOS - all 4 test scenarios pass.

    Good coverage of minconf behavior, multiple transactions, error handling, and coinbase maturity.

    nit: Copyright header says 2017-2022 but this is a new file - might want to update to 2026-present or similar.

  3. b-l-u-e commented at 8:51 am on January 2, 2026: contributor

    nit: Copyright header says 2017-2022 but this is a new file - might want to update to 2026-present or similar.

    Aah thank you I will update

  4. DrahtBot commented at 8:51 am on January 2, 2026: 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/34188.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK maflcko, rkrux, fjahr, achow101
    Stale ACK bensig

    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:

    • #30972 (Wallet: “listreceivedby*” fix by BrandonOdiwuor)

    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.

  5. maflcko commented at 8:53 am on January 2, 2026: member
    How is this different from test/functional/wallet_listreceivedby.py? Can you explain what exact coverage is missing and what exact coverage is added?
  6. b-l-u-e force-pushed on Jan 2, 2026
  7. b-l-u-e commented at 10:38 am on January 2, 2026: contributor

    How is this different from test/functional/wallet_listreceivedby.py? Can you explain what exact coverage is missing and what exact coverage is added?

    the test adds two important coverage areas that are missing in wallet_listreceivedby.py

    multiple transactions to the same address , which is a use case not covered in the existing test. The existing test only sends a single transaction (0.1 BTC) to an address.

    invalid address format error - tests error -5 “Invalid Bitcoin address” for malformed address strings. The existing test only covers error -4 “Address not found in wallet” this completes the error handling coverage.

    test file provides better organization and focuses specifically on getreceivedbyaddress , there is some overlap with basic functionality, but the new test adds valuable coverage that was missing.

  8. maflcko commented at 11:28 am on January 2, 2026: member
    My preference would be to keep related functionality checks for related RPCs in the same file, not create a separate file for each RPC. This will also avoid checking the same overlap several times redundantly.
  9. DrahtBot added the label CI failed on Jan 2, 2026
  10. DrahtBot removed the label CI failed on Jan 2, 2026
  11. DrahtBot added the label Tests on Jan 2, 2026
  12. b-l-u-e force-pushed on Jan 2, 2026
  13. b-l-u-e renamed this:
    test: Add functional test for getreceivedbyaddress RPC
    test: Add multiple transactions and error handling tests for getreceivedbyaddress
    on Jan 2, 2026
  14. fanquake commented at 3:12 pm on January 2, 2026: member

    https://github.com/bitcoin/bitcoin/actions/runs/20658978454/job/59322217188?pr=34188#step:6:145:

    0 The subject line of commit hash 1538fc6d86d1d439646ab724ca7a721867213b14 is followed by a non-empty line. Subject lines should always be followed by a blank line.
    
  15. DrahtBot added the label CI failed on Jan 2, 2026
  16. DrahtBot commented at 4:26 pm on January 2, 2026: contributor

    🚧 At least one of the CI tasks failed. Task lint: https://github.com/bitcoin/bitcoin/actions/runs/20658978454/job/59322217188 LLM reason (✨ experimental): Commit message formatting failed lint check (missing blank line after the subject), causing the CI to fail.

    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.

  17. b-l-u-e force-pushed on Jan 2, 2026
  18. in test/functional/wallet_listreceivedby.py:193 in 9944a4c71e
    187@@ -176,7 +188,10 @@ def run_test(self):
    188         label = "label"
    189         address = self.nodes[0].getnewaddress(label)
    190 
    191-        reward = Decimal("25")
    192+        # Calculate expected reward based on block height (50 BTC halved every 150 blocks)
    193+        block_height = self.nodes[0].getblockcount()
    194+        halvings = block_height // 150
    


    fjahr commented at 11:23 pm on January 3, 2026:
    I don’t see much value in this, instead of hardcoding the reward you are hardcoding the halving interval while adding 3 LOC that don’t contribute anything to the actual test.

    b-l-u-e commented at 12:56 pm on January 4, 2026:
    thanks @fjahr. i added the calculation thinking it would make the test more robust but it doesn’t..reverted back
  19. b-l-u-e force-pushed on Jan 4, 2026
  20. b-l-u-e requested review from fjahr on Jan 4, 2026
  21. in test/functional/wallet_listreceivedby.py:131 in 66bd4bf02d
    123@@ -124,6 +124,18 @@ def run_test(self):
    124         # Trying to getreceivedby for an address the wallet doesn't own should return an error
    125         assert_raises_rpc_error(-4, "Address not found in wallet", self.nodes[0].getreceivedbyaddress, addr)
    126 
    127+        # Test multiple transactions to the same address
    128+        addr_multiple = self.nodes[1].getnewaddress()
    129+        self.nodes[0].sendtoaddress(addr_multiple, Decimal("0.1"))
    130+        self.nodes[0].sendtoaddress(addr_multiple, Decimal("0.2"))
    131+        self.sync_all()
    


    rkrux commented at 12:37 pm on January 5, 2026:

    This is not necessary when the blocks are being generated right after.

    0-        self.sync_all()
    

    b-l-u-e commented at 3:04 pm on January 15, 2026:
    i reverted the change back since the test failed without self.sync_all(), node 1 didn’t have both transactions in its mempool when blocks were generated only the first transaction 0.1 BTC was included instead of both 0.3 BTC the total. Adding self.sync_all() makes sures that both transactions are being propagated before block generation.
  22. in test/functional/wallet_listreceivedby.py:128 in 66bd4bf02d
    123@@ -124,6 +124,18 @@ def run_test(self):
    124         # Trying to getreceivedby for an address the wallet doesn't own should return an error
    125         assert_raises_rpc_error(-4, "Address not found in wallet", self.nodes[0].getreceivedbyaddress, addr)
    126 
    127+        # Test multiple transactions to the same address
    128+        addr_multiple = self.nodes[1].getnewaddress()
    


    rkrux commented at 12:40 pm on January 5, 2026:

    While it’s easy to understand in this PR, this address name can be confusing for readers when it’s read later. Consider:

     0diff --git a/test/functional/wallet_listreceivedby.py b/test/functional/wallet_listreceivedby.py
     1index 52a503b9d5..8169f9f28c 100755
     2--- a/test/functional/wallet_listreceivedby.py
     3+++ b/test/functional/wallet_listreceivedby.py
     4@@ -125,12 +125,11 @@ class ReceivedByTest(BitcoinTestFramework):
     5         assert_raises_rpc_error(-4, "Address not found in wallet", self.nodes[0].getreceivedbyaddress, addr)
     6 
     7         # Test multiple transactions to the same address
     8-        addr_multiple = self.nodes[1].getnewaddress()
     9-        self.nodes[0].sendtoaddress(addr_multiple, Decimal("0.1"))
    10-        self.nodes[0].sendtoaddress(addr_multiple, Decimal("0.2"))
    11+        addr_with_multiple_txs = self.nodes[1].getnewaddress()
    12+        self.nodes[0].sendtoaddress(addr_with_multiple_txs, Decimal("0.1"))
    13+        self.nodes[0].sendtoaddress(addr_with_multiple_txs, Decimal("0.2"))
    14         self.generate(self.nodes[1], 10)
    15-        balance = self.nodes[1].getreceivedbyaddress(addr_multiple)
    16+        balance = self.nodes[1].getreceivedbyaddress(addr_with_multiple_txs)
    17         assert_equal(balance, Decimal("0.3"))
    18 
    19         # Test invalid address format error
    
  23. in test/functional/wallet_listreceivedby.py:159 in 66bd4bf02d


    rkrux commented at 12:42 pm on January 5, 2026:

    Nit because this PR is not touching this line but there seems to be an incorrect naming here in the comment that can fixed in this PR because it’s related to the same RPC:

    0@@ -156,7 +155,7 @@ class ReceivedByTest(BitcoinTestFramework):
    1                             {"label": label},
    2                             received_by_label_json)
    3 
    4-        # getreceivedbyaddress should return same balance because of 0 confirmations
    5+        # getreceivedbylabel should return same balance because of 0 confirmations
    6         balance = self.nodes[1].getreceivedbylabel(label)
    7         assert_equal(balance, balance_by_label)
    

    rkrux commented at 12:44 pm on January 5, 2026:

    In commit message 66bd4bf02dcfebee9be9846583d11f5b39dc281d because it’s outdated now:

    0- Update coinbase reward calculation to be dynamic
    
  24. rkrux changes_requested
  25. rkrux commented at 12:46 pm on January 5, 2026: contributor

    Concept ACK 66bd4bf02dcfebee9be9846583d11f5b39dc281d

    0https://maflcko.github.io/b-c-cov/total.coverage/src/wallet/rpc/coins.cpp.gcov.html
    

    Although there isn’t increased coverage due to the multiple transactions on same address test but logically it’s good to have such a test. The invalid address test should increase the coverage.

  26. b-l-u-e force-pushed on Jan 5, 2026
  27. b-l-u-e requested review from rkrux on Jan 5, 2026
  28. fanquake commented at 4:31 pm on January 9, 2026: member

    https://github.com/bitcoin/bitcoin/actions/runs/20722345957/job/59492260670?pr=34188#step:14:221:

     0Traceback (most recent call last):
     1  File "D:\a\bitcoin\bitcoin\build\test\functional\test_framework\test_framework.py", line 142, in main
     2    self.run_test()
     3    ~~~~~~~~~~~~~^^
     4  File "D:\a\bitcoin\bitcoin\build\test\functional\feature_bip68_sequence.py", line 66, in run_test
     5    self.test_sequence_lock_confirmed_inputs()
     6    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
     7  File "D:\a\bitcoin\bitcoin\build\test\functional\feature_bip68_sequence.py", line 149, in test_sequence_lock_confirmed_inputs
     8    num_inputs = random.randint(1, min(10, available_utxos))
     9  File "C:\hostedtoolcache\windows\Python\3.14.2\x64\Lib\random.py", line 341, in randint
    10    raise ValueError(f"empty range in randint({a}, {b})")
    11ValueError: empty range in randint(1, 0)
    
  29. b-l-u-e force-pushed on Jan 15, 2026
  30. b-l-u-e commented at 9:04 am on January 15, 2026: contributor

    https://github.com/bitcoin/bitcoin/actions/runs/20722345957/job/59492260670?pr=34188#step:14:221:

     0Traceback (most recent call last):
     1  File "D:\a\bitcoin\bitcoin\build\test\functional\test_framework\test_framework.py", line 142, in main
     2    self.run_test()
     3    ~~~~~~~~~~~~~^^
     4  File "D:\a\bitcoin\bitcoin\build\test\functional\feature_bip68_sequence.py", line 66, in run_test
     5    self.test_sequence_lock_confirmed_inputs()
     6    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
     7  File "D:\a\bitcoin\bitcoin\build\test\functional\feature_bip68_sequence.py", line 149, in test_sequence_lock_confirmed_inputs
     8    num_inputs = random.randint(1, min(10, available_utxos))
     9  File "C:\hostedtoolcache\windows\Python\3.14.2\x64\Lib\random.py", line 341, in randint
    10    raise ValueError(f"empty range in randint({a}, {b})")
    11ValueError: empty range in randint(1, 0)
    

    the issue has been fixed in #34244. I rebased the PR.

  31. fjahr commented at 1:36 pm on January 15, 2026: contributor

    the issue has been fixed in #34244. I rebased the PR.

    Just FYI, since this was an unrelated test failure in a file you are not touching, in the future you can either ask for someone to rerun the CI job for you or you can push a rebase proactively to retrigger the CI and see if the error really persists.

  32. fjahr commented at 1:39 pm on January 15, 2026: contributor

    But now there is a CI failure that seems related:

    0 test  2026-01-15T10:18:10.109856Z TestFramework (ERROR): Unexpected exception 
    1                                   Traceback (most recent call last):
    2                                     File "/home/admin/actions-runner/_work/_temp/test/functional/test_framework/test_framework.py", line 142, in main
    3                                       self.run_test()
    4                                     File "/home/admin/actions-runner/_work/_temp/build/test/functional/wallet_listreceivedby.py", line 133, in run_test
    5                                       assert_equal(balance, Decimal("0.3"))
    6                                     File "/home/admin/actions-runner/_work/_temp/test/functional/test_framework/util.py", line 80, in assert_equal
    7                                       raise AssertionError("not(%s)" % " == ".join(str(arg) for arg in (thing1, thing2) + args))
    8                                   AssertionError: not(0.10000000 == 0.3)
    
  33. b-l-u-e force-pushed on Jan 15, 2026
  34. b-l-u-e commented at 3:12 pm on January 15, 2026: contributor

    But now there is a CI failure that seems related:

    0 test  2026-01-15T10:18:10.109856Z TestFramework (ERROR): Unexpected exception 
    1                                   Traceback (most recent call last):
    2                                     File "/home/admin/actions-runner/_work/_temp/test/functional/test_framework/test_framework.py", line 142, in main
    3                                       self.run_test()
    4                                     File "/home/admin/actions-runner/_work/_temp/build/test/functional/wallet_listreceivedby.py", line 133, in run_test
    5                                       assert_equal(balance, Decimal("0.3"))
    6                                     File "/home/admin/actions-runner/_work/_temp/test/functional/test_framework/util.py", line 80, in assert_equal
    7                                       raise AssertionError("not(%s)" % " == ".join(str(arg) for arg in (thing1, thing2) + args))
    8                                   AssertionError: not(0.10000000 == 0.3)
    

    CI failed coz without self.sync_all() node 1 didn’t have both transactions in its mempool when blocks were generated. so only the first transaction (0.1 BTC) was included causing getreceivedbyaddress to return 0.1 instead of 0.3. so i added back self.sync_all() after both transactions to ensure theres proper propagation before block generation

  35. in test/functional/wallet_listreceivedby.py:131 in fa45a3b2cc
    123@@ -124,6 +124,18 @@ def run_test(self):
    124         # Trying to getreceivedby for an address the wallet doesn't own should return an error
    125         assert_raises_rpc_error(-4, "Address not found in wallet", self.nodes[0].getreceivedbyaddress, addr)
    126 
    127+        # Test multiple transactions to the same address
    128+        addr_with_multiple_txs = self.nodes[1].getnewaddress()
    129+        self.nodes[0].sendtoaddress(addr_with_multiple_txs, Decimal("0.1"))
    130+        self.nodes[0].sendtoaddress(addr_with_multiple_txs, Decimal("0.2"))
    131+        self.sync_all()
    


    fjahr commented at 3:55 pm on January 15, 2026:

    You probably wouldn’t need it if you would generate the blocks with self.nodes[0] because that node is also sending the funds. Alternatively you could also do this. But either way seems fine.

    0self.generate(self.nodes[1], 10, sync_fun=lambda: self.sync_all(self.nodes[0:1]))
    

    b-l-u-e commented at 6:50 pm on January 15, 2026:

    You probably wouldn’t need it if you would generate the blocks with self.nodes[0] because that node is also sending the funds. Alternatively you could also do this. But either way seems fine.

    0self.generate(self.nodes[1], 10, sync_fun=lambda: self.sync_all(self.nodes[0:1]))
    

    went with this approach of generating blocks with self.nodes[0] since node has the transactions.

  36. fjahr commented at 3:56 pm on January 15, 2026: contributor

    utACK fa45a3b2cc6b71be4e0bd334536fcad99bacc7b6

    Could make minor improvements to the sync but this looks ok for me as well.

  37. b-l-u-e force-pushed on Jan 15, 2026
  38. fjahr commented at 9:34 pm on January 15, 2026: contributor

    utACK dec4887be09870789296866e0f18a3772fac8ef5

    Just addressed my comment since last review.

  39. DrahtBot removed the label CI failed on Jan 15, 2026
  40. test: Add getreceivedbyaddress coverage to wallet_listreceivedby
    - Add test for multiple transactions to same address
    - Add test for invalid address format error
    d45ec3fba9
  41. in test/functional/wallet_listreceivedby.py:131 in dec4887be0
    123@@ -124,6 +124,17 @@ def run_test(self):
    124         # Trying to getreceivedby for an address the wallet doesn't own should return an error
    125         assert_raises_rpc_error(-4, "Address not found in wallet", self.nodes[0].getreceivedbyaddress, addr)
    126 
    127+        # Test multiple transactions to the same address
    128+        addr_with_multiple_txs = self.nodes[1].getnewaddress()
    129+        self.nodes[0].sendtoaddress(addr_with_multiple_txs, Decimal("0.1"))
    130+        self.nodes[0].sendtoaddress(addr_with_multiple_txs, Decimal("0.2"))
    131+        self.generate(self.nodes[0], 10)
    


    maflcko commented at 3:02 pm on January 16, 2026:
    why generate 10 blocks, when 1 would be sufficient?

    b-l-u-e commented at 8:06 pm on January 18, 2026:
    i had used 10 blocks thinking would provide better test coverage.. since getreceivedbyaddress defaults to minconf=1……I’ve updated it to generate 1 block.. thank you..
  42. b-l-u-e force-pushed on Jan 18, 2026
  43. b-l-u-e requested review from maflcko on Jan 18, 2026
  44. maflcko commented at 7:23 am on January 19, 2026: member
    lgtm ACK d45ec3fba905e8d2b77d61514632ec70e02ad431
  45. DrahtBot requested review from fjahr on Jan 19, 2026
  46. rkrux approved
  47. rkrux commented at 9:46 am on January 19, 2026: contributor
    lgtm ACK d45ec3fba905e8d2b77d61514632ec70e02ad431
  48. fjahr commented at 11:06 am on January 19, 2026: contributor
    reACK d45ec3fba905e8d2b77d61514632ec70e02ad431
  49. achow101 commented at 0:24 am on January 20, 2026: member
    ACK d45ec3fba905e8d2b77d61514632ec70e02ad431
  50. achow101 merged this on Jan 20, 2026
  51. achow101 closed this on Jan 20, 2026

  52. b-l-u-e deleted the branch on Jan 20, 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-02 06:13 UTC

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