[29.x] backports + final changes for 29.3 #34268

pull glozow wants to merge 10 commits into bitcoin:29.x from glozow:2026-01-29.3-backports changing 18 files +264 −30
  1. glozow commented at 10:47 pm on January 12, 2026: member

    Backports:

    And final changes for 29.3rc1

  2. miner: fix `addPackageTxs` unsigned integer overflow
    Github-Pull: #33475
    Rebased-From: b807dfcdc5929c314d43b790c9e705d5bf0a86e8
    2e4688618b
  3. Remove unreliable seed from chainparams.cpp, and the associated README
    Github-Pull: #33723
    Rebased-From: b0c706795ce6a3a00bf068a81ee99fef2ee9bf7e
    7a71850a6d
  4. guix: Fix `osslsigncode` tests
    Github-Pull: #34227
    Rebased-From: 194114daf385a5db50e1507fda79a1a93240d494
    daef5852f0
  5. glozow added the label Backport on Jan 12, 2026
  6. DrahtBot commented at 10:47 pm on January 12, 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/34268.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK achow101, janb84, sedited

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

  7. in src/wallet/wallet.cpp:1710 in 689fccc62c
    1707+    for (const CTxIn& txin : tx.vin) {
    1708+        const CWalletTx* prev = GetWalletTx(txin.prevout.hash);
    1709+        if (prev && txin.prevout.n < prev->tx->vout.size() && IsMine(prev->tx->vout[txin.prevout.n])) {
    1710+            return true;
    1711+        }
    1712+    }
    


    glozow commented at 11:13 pm on January 12, 2026:
    29.x doesn’t have the changes from #27286, so I did this instead. cc @achow101

    achow101 commented at 0:01 am on January 13, 2026:

    Simpler to use IsMine here, but this is also acceptable. It’s basically the same process.

    0    for (const CTxIn& txin : tx.vin) {
    1        if (IsMine(txin.prevout)) {
    2            return true;
    3        }
    4    }
    

    glozow commented at 0:10 am on January 13, 2026:
    Thanks, took this instead
  8. glozow force-pushed on Jan 13, 2026
  9. glozow commented at 0:10 am on January 13, 2026: member
    I dropped 113a4228229baedda2a730e097f2d59ad58a4b0d since it was causing a failure and didn’t seem necessary to backport.
  10. fanquake added this to the milestone 29.3 on Jan 13, 2026
  11. in doc/release-notes.md:84 in 00a8f410bc outdated
    79@@ -51,8 +80,17 @@ Credits
    80 
    81 Thanks to everyone who directly contributed to this release:
    82 
    83+- Anthony Towns
    


    fanquake commented at 10:39 am on January 13, 2026:
    SatsAndSports missing here (#33723).

    glozow commented at 5:10 pm on January 13, 2026:
    Thank you, added
  12. glozow force-pushed on Jan 13, 2026
  13. glozow marked this as ready for review on Jan 13, 2026
  14. in test/functional/wallet_listtransactions.py:123 in f70a3dded7
    118@@ -114,6 +119,9 @@ def run_test(self):
    119         self.run_invalid_parameters_test()
    120         self.test_op_return()
    121 
    122+        if self.options.descriptors:
    123+            self.test_from_me_status_change()
    


    achow101 commented at 9:49 pm on January 13, 2026:

    In f70a3dded750b30d66f98126c12dff1fd96b5799 “test: Test wallet ‘from me’ status change”

    Instead of disabling this test for legacy wallets, the following diff can adapt it to be usable for both wallet types:

     0diff --git a/test/functional/wallet_listtransactions.py b/test/functional/wallet_listtransactions.py
     1index 5c2cfbf85d1..6a76bcc5e7c 100755
     2--- a/test/functional/wallet_listtransactions.py
     3+++ b/test/functional/wallet_listtransactions.py
     4@@ -119,8 +119,7 @@ class ListTransactionsTest(BitcoinTestFramework):
     5         self.run_invalid_parameters_test()
     6         self.test_op_return()
     7 
     8-        if self.options.descriptors:
     9-            self.test_from_me_status_change()
    10+        self.test_from_me_status_change()
    11 
    12     def run_rbf_opt_in_test(self):
    13         """Test the opt-in-rbf flag for sent and received transactions."""
    14@@ -345,8 +344,7 @@ class ListTransactionsTest(BitcoinTestFramework):
    15         # Run twice, once for a transaction in the mempool, again when it confirms
    16         for confirm in [False, True]:
    17             key = get_generate_key()
    18-            descriptor = descsum_create(f"wpkh({key.privkey})")
    19-            default_wallet.importdescriptors([{"desc": descriptor, "timestamp": "now"}])
    20+            default_wallet.importprivkey(key.privkey)
    21 
    22             send_res = default_wallet.send(outputs=[{key.p2wpkh_addr: 1}, {wallet.getnewaddress(): 1}])
    23             assert_equal(send_res["complete"], True)
    24@@ -370,8 +368,7 @@ class ListTransactionsTest(BitcoinTestFramework):
    25                 self.nodes[0].setmocktime(int(time.time()) + MAX_FUTURE_BLOCK_TIME + 1)
    26                 self.generate(self.nodes[0], 10, sync_fun=self.no_op)
    27 
    28-            import_res = wallet.importdescriptors([{"desc": descriptor, "timestamp": "now"}])
    29-            assert_equal(import_res[0]["success"], True)
    30+            wallet.importprivkey(key.privkey)
    31             # TODO: We should check that the fee matches, but since the transaction spends inputs
    32             # not known to the wallet, it is incorrectly calculating the fee.
    33             # assert_equal(wallet.gettransaction(txid)["fee"], fee)
    

    glozow commented at 6:26 am on January 14, 2026:
    taken
  15. in test/functional/wallet_anchor.py:68 in b605cc8c73 outdated
    63+        self.nodes[0].createwallet(wallet_name="anchor", disable_private_keys=True)
    64+        wallet = self.nodes[0].get_wallet_rpc("anchor")
    65+
    66+        if self.options.descriptors:
    67+            import_res = wallet.importdescriptors([{"desc": descsum_create(f"addr({ANCHOR_ADDRESS})"), "timestamp": "now"}])
    68+            assert_equal(import_res[0]["success"], True)
    


    achow101 commented at 10:09 pm on January 13, 2026:

    In b605cc8c73a10162f47e0aeb361144e4913a2a54 “test: Add a test for anchor outputs in the wallet”

    Using wallet.importaddress(ANCHOR_ADDRESS, rescan=False) instead of importdescriptors here allows this test case to work for both descriptors and legacy wallets.


    glozow commented at 6:28 pm on January 14, 2026:
    Somehow missed this last push. Thanks, taken!
  16. in test/functional/wallet_anchor.py:121 in b605cc8c73
    116+
    117+    def run_test(self):
    118+        self.default_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
    119+        self.test_0_value_anchor_listunspent()
    120+        if self.options.descriptors:
    121+            self.test_cannot_sign_anchors()
    


    achow101 commented at 10:11 pm on January 13, 2026:

    In b605cc8c73a10162f47e0aeb361144e4913a2a54 “test: Add a test for anchor outputs in the wallet”

    The following diff allows this test to work for both descriptors and legacy wallets

     0diff --git a/test/functional/wallet_anchor.py b/test/functional/wallet_anchor.py
     1index 49ec75928c0..0b08986d00d 100755
     2--- a/test/functional/wallet_anchor.py
     3+++ b/test/functional/wallet_anchor.py
     4@@ -92,12 +92,15 @@ class WalletAnchorTest(BitcoinTestFramework):
     5         for disable_privkeys in [False, True]:
     6             self.nodes[0].createwallet(wallet_name=f"anchor_spend_{disable_privkeys}", disable_private_keys=disable_privkeys)
     7             wallet = self.nodes[0].get_wallet_rpc(f"anchor_spend_{disable_privkeys}")
     8-            import_res = wallet.importdescriptors([
     9-                {"desc": descsum_create(f"addr({ANCHOR_ADDRESS})"), "timestamp": "now"},
    10-                {"desc": descsum_create(f"raw({PAY_TO_ANCHOR.hex()})"), "timestamp": "now"}
    11-            ])
    12-            assert_equal(import_res[0]["success"], disable_privkeys)
    13-            assert_equal(import_res[1]["success"], disable_privkeys)
    14+            if self.options.descriptors:
    15+                import_res = wallet.importdescriptors([
    16+                    {"desc": descsum_create(f"addr({ANCHOR_ADDRESS})"), "timestamp": "now"},
    17+                    {"desc": descsum_create(f"raw({PAY_TO_ANCHOR.hex()})"), "timestamp": "now"}
    18+                ])
    19+                assert_equal(import_res[0]["success"], disable_privkeys)
    20+                assert_equal(import_res[1]["success"], disable_privkeys)
    21+            else:
    22+                wallet.importaddress(ANCHOR_ADDRESS)
    23 
    24         anchor_txid = self.default_wallet.sendtoaddress(ANCHOR_ADDRESS, 1)
    25         self.generate(self.nodes[0], 1)
    26@@ -109,16 +112,19 @@ class WalletAnchorTest(BitcoinTestFramework):
    27         assert_equal(utxos[0]["address"], ANCHOR_ADDRESS)
    28         assert_equal(utxos[0]["amount"], 1)
    29 
    30-        assert_raises_rpc_error(-4, "Missing solving data for estimating transaction size", wallet.send, [{self.default_wallet.getnewaddress(): 0.9999}])
    31+        if self.options.descriptors:
    32+            assert_raises_rpc_error(-4, "Missing solving data for estimating transaction size", wallet.send, [{self.default_wallet.getnewaddress(): 0.9999}])
    33+            assert_raises_rpc_error(-4, "Unable to determine the size of the transaction, the wallet contains unsolvable descriptors", wallet.sendall, recipients=[self.default_wallet.getnewaddress()])
    34+        else:
    35+            assert_raises_rpc_error(-4, "Insufficient funds", wallet.send, [{self.default_wallet.getnewaddress(): 0.9999}])
    36+            assert_raises_rpc_error(-6, "Total value of UTXO pool too low to pay for transaction. Try using lower feerate or excluding uneconomic UTXOs with 'send_max' option.", wallet.sendall, recipients=[self.default_wallet.getnewaddress()])
    37         assert_raises_rpc_error(-4, "Error: Private keys are disabled for this wallet", wallet.sendtoaddress, self.default_wallet.getnewaddress(), 0.9999)
    38         assert_raises_rpc_error(-4, "Unable to determine the size of the transaction, the wallet contains unsolvable descriptors", wallet.sendall, recipients=[self.default_wallet.getnewaddress()], inputs=utxos)
    39-        assert_raises_rpc_error(-4, "Unable to determine the size of the transaction, the wallet contains unsolvable descriptors", wallet.sendall, recipients=[self.default_wallet.getnewaddress()])
    40 
    41     def run_test(self):
    42         self.default_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
    43         self.test_0_value_anchor_listunspent()
    44-        if self.options.descriptors:
    45-            self.test_cannot_sign_anchors()
    46+        self.test_cannot_sign_anchors()
    47 
    48 if __name__ == '__main__':
    49     WalletAnchorTest(__file__).main()
    

    glozow commented at 6:26 am on January 14, 2026:
    Thanks! taken
  17. achow101 commented at 10:17 pm on January 13, 2026: member
    Release notes should probably say #34156 and #34215 rather than #34222
  18. glozow force-pushed on Jan 14, 2026
  19. test: Test wallet 'from me' status change
    If something is imported into the wallet, it can change the 'from me'
    status of a transaction. This status is only visible through
    gettransaction's "fee" field which is only shown for transactions that
    are 'from me'.
    
    Github-Pull: #33268
    Rebased-From: e76c2f7a4111f87080e31539f83c21390fcd8f3b
    71633a9b5c
  20. wallet: Determine IsFromMe by checking for TXOs of inputs
    Instead of checking whether the total amount of inputs known by the
    wallet is greater than 0, we should be checking for whether the input is
    known by the wallet. This enables us to determine whether a transaction
    spends an of output with an amount of 0, which is necessary for marking
    0-value dust outputs as spent.
    
    Github-Pull: #33268
    Rebased-From: 39a7dbdd277d1dea9a70314d8cc5ae057999ee88
    bab1ac827b
  21. wallet: Throw an error in sendall if the tx size cannot be calculated
    Github-Pull: #33268
    Rebased-From: c40dc822d74aea46e4a21774ca282e008f609c2a
    c6e7765c0a
  22. glozow force-pushed on Jan 14, 2026
  23. test: Add a test for anchor outputs in the wallet
    Github-Pull: #33268
    Rebased-From: 609d265ebc51abfe9a9ce570da647b6839dc1214
    f4b78c42e5
  24. [doc] update release notes for 29.3rc1 e973b61dbb
  25. [build] bump version to 29.3rc1 e9c978391f
  26. [doc] generate manpages 29.3rc1 b834447fb2
  27. glozow force-pushed on Jan 14, 2026
  28. achow101 commented at 6:37 pm on January 14, 2026: member
    ACK b834447fb2f2073e25164a80ba197a3120610b92
  29. glozow requested review from sedited on Jan 14, 2026
  30. janb84 commented at 7:24 pm on January 14, 2026: contributor

    ACK b834447fb2f2073e25164a80ba197a3120610b92

    Listed backported pr files are all there except for https://github.com/bitcoin/bitcoin/commit/113a4228229baedda2a730e097f2d59ad58a4b0d as stated and miner.cpp slightly deviates from the PR because of rebase with old code. Version is correctly bumped.

    (Sorry the diff from the release-notes.mo threw me off, showing most was new)

  31. glozow commented at 9:19 pm on January 14, 2026: member

    (Sorry the diff from the release-notes.mo threw me off, showing most was new)

    That’s fine, and probably would have been better to leave the comment up.

    Context: #33623 isn’t a backport; it was directly merged to 29.x

  32. sedited approved
  33. sedited commented at 1:36 am on January 15, 2026: contributor

    ACK b834447fb2f2073e25164a80ba197a3120610b92

    Reproduced locally too

  34. fanquake merged this on Jan 15, 2026
  35. fanquake closed this on Jan 15, 2026

  36. glozow deleted the branch on Jan 16, 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-01-21 12:13 UTC

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