Commit Graph

7190 Commits

Author SHA1 Message Date
merge-script
e3554bf361 Merge bitcoin/bitcoin#35579: wallet: reserve walletrescan before checking wallet is at the tip
9e62e4b1f3 test: slow down rescaning process (Pol Espinasa)
336f5a738b wallet: reserve walletrescan before checking wallet is at the tip (Pol Espinasa)

Pull request description:

  `ImportDescriptors` rpc has a race condition where two imports running in parallel can both succeed or fail one of them.

  The race happens when there are two threads A and B trying to importdescriptors at the same time.

  1. Thread A calls `BlockUntilSyncedToCurrentChain()` (holding `cs_wallet` fast, no contention) and then `reserve()`, acquiring the `WalletRescanReserver`. It proceeds to `ProcessDescriptorImport()`, which holds `cs_wallet` for an extended time (specially on slow machines) while importing descriptors.

  2. B reaches `BlockUntilSyncedToCurrentChain()`, which internally does `WITH_LOCK(cs_wallet, ...)`. Since A holds `cs_wallet`, B blocks here for the entire duration of Thread A's descriptors import.

  3. Then A finishes importing, releases `cs_wallet`, rescans (fast in regtest), and sets `fScanningWallet = false`.

  4. B can now continue in `BlockUntilSyncedToCurrentChain()` acquiring `cs_wallet`, and then calls `reserve()` which succeeds because `fScanningWallet` is already `false`. Both imports succeed.

  I don't think the behavior is problematic at all from a usability PoV, but it can be a bad UX if some imports fails and other's no. It also makes testing difficult as race conditions are not easy to test.

  This PR fixes it by calling `reserver.reserve()` before `cs_wallet` is locked, so multiple threads will be aware of currently imports before being stuck at any point. So only one `importdescriptor` call can be done at the same time.

  I think this should fix https://github.com/bitcoin/bitcoin/issues/35544#issuecomment-4763488259

ACKs for top commit:
  achow101:
    ACK 9e62e4b1f3
  nebula-21:
    ACK 9e62e4b1f3
  w0xlt:
    lgtm reACK 9e62e4b1f3

Tree-SHA512: be0027e1a7b77252ed9fb514c3b3311d6905903d4b0bfc1021a1e1c2bb06872ef599647ff8a4536929240717ae9db62fb75374f629cd3046c7192e2b8b4d7344
2026-07-14 09:45:16 +02:00
Ryan Ofsky
c0e91efdb3 Merge bitcoin/bitcoin#35295: validation: fetch block input prevouts in parallel during ConnectBlock
dc1c17c085 doc: add release notes (Andrew Toth)
0e10937184 fuzz: add coins_view_stacked fuzz harness to test concurrent leveldb reads (Andrew Toth)
ce610a6ff4 fuzz: update harnesses to cover CoinsViewOverlay::StartFetching (Andrew Toth)
760fb22dc3 test: add unit tests for CoinsViewOverlay::StartFetching (Andrew Toth)
d69a3b20de doc: update CoinsViewOverlay docstring to describe parallel fetching (Andrew Toth)
ab2a379237 coins: fetch inputs in parallel (Andrew Toth)
fdf283036a coins: add ready flag to InputToFetch (Andrew Toth)
ede11b8314 validation: collect block inputs in CoinsViewOverlay before ConnectBlock (Andrew Toth)
f82043af50 coins: introduce thread pool in CoinsViewOverlay (Andrew Toth)
5bf1c32008 validation: add -prevoutfetchthreads configuration option (Andrew Toth)

Pull request description:

  This PR is a continuation of https://github.com/bitcoin/bitcoin/pull/31132. All outstanding issues raised there have been resolved, but the volume of stale comments can make that change difficult to review.

  Currently, when connecting a block, each input prevout is looked up one at a time. For every input we first check the in-memory coins cache, and on a miss we make a synchronous round-trip to the chainstate LevelDB to read the coin from disk. Because these lookups happen serially as the block is being validated, the disk read latency stacks up and dominates the time spent in `ConnectBlock` whenever many inputs are not already in the cache.

  This PR moves those disk reads onto a pool of worker threads that run in parallel with block connection. Before entering `ConnectBlock` the block is handed to a `CoinsViewOverlay`, which kicks off the workers to begin fetching all of the block's prevouts from disk and warming the cache. The main validation thread continues to do exactly the same work it does today, hitting the cache for each input in order. The only difference is that by the time it asks, the coin is much more likely to already be there. There are no validation logic or consensus behavior changes. This is purely a parallelization of an existing read pattern.

  The number of fetcher threads is configurable via `-prevoutfetchthreads=<n>`, defaulting to 8 and capped at 16. Setting it to 0 disables input fetching entirely and reverts to the previous serial behavior.

  We have measured large performance gains for IBD and `-reindex-chainstate`, as well as worst-case steady-state block connection at the tip. l0rinc ran many thorough benchmarking passes on the original PR across multiple machines, storage types, dbcache sizes[^1], operating systems[^2], and fetcher thread counts[^3]. Many other contributors also posted their benchmark results in the original PR. IBD speedups range from 1.18× to over 3× faster[^4]. Worst-case block connection time for network-attached storage was over 2× faster[^5]. Flamegraph comparisons before and after this change are available[^6].

  On safety: `ConnectBlock` runs while holding `cs_main`, so nothing else in the node can mutate the chainstate while the fetchers are reading it.

  On LevelDB: [concurrent reads are fully supported](https://github.com/bitcoin/bitcoin/blob/master/src/leveldb/include/leveldb/db.h#L44) and [documented as such](https://github.com/bitcoin/bitcoin/blob/master/src/leveldb/doc/index.md#concurrency). We already rely on this in production today against our other LevelDB-backed databases. The `txindex` DB is read by multiple simultaneous HTTP RPC worker threads via the `getrawtransaction` RPC. The `blockfilterindex` DB is called concurrently from both the P2P `cfilters` / `cfheaders` / `cfcheckpt` message handlers on the `msghand` thread, and from the `getblockfilter` RPC on the HTTP RPC worker threads. We have not yet been issuing concurrent reads against the chainstate DB, but there is no LevelDB-side reason we can't. In fact, the chainstate DB is already being touched by more than one thread on master, because LevelDB schedules its own background compaction work.

  For reviewers:

  The main change is `CoinsViewOverlay` gets 1 new public and 2 new private methods.

  - `StartFetching`: public method called in lieu of `CreateResetGuard` before we enter `ConnectBlock`. It still returns a `ResetGuard` so the view is `Reset` before the block it is working on leaves scope. This kicks off worker threads who each just run `while (ProcessInput()) {}` and then return.
  - `StopFetching`: private method called on `Reset` whenever the guard leaves scope or `Flush`. Stops all threads and clears multi threaded state.
  - `ProcessInput`: private method that fetches a single input prevout. Returns `true` if an input was fetched and `false` otherwise. This is the only method on `CoinsViewOverlay` that is called concurrently by multiple threads. Every other method on the overlay is still called synchronously on the main thread.

  The `CoinsViewOverlay::FetchCoinFromBase` method is also extended to lookup the coins fetched from `ProcessInput` first before falling back to `base->PeekCoin`.

  Mutating methods `Reset` and `Flush` are overridden in `CoinsViewOverlay` to call `StopFetching` first.

  [^1]: https://github.com/bitcoin/bitcoin/pull/31132#pullrequestreview-3515011880
  [^2]: https://github.com/bitcoin/bitcoin/pull/31132#issuecomment-3767758819
  [^3]: https://github.com/bitcoin/bitcoin/pull/31132#issuecomment-3617721711
  [^4]: https://github.com/bitcoin/bitcoin/pull/31132#issuecomment-3678847806
  [^5]: https://github.com/bitcoin/bitcoin/pull/31132#issuecomment-4071032270
  [^6]: https://github.com/bitcoin/bitcoin/pull/31132#issuecomment-3617315125

ACKs for top commit:
  l0rinc:
    reACK dc1c17c085
  willcl-ark:
    ACK dc1c17c085
  theStack:
    re-ACK dc1c17c085
  ryanofsky:
    Code review ACK dc1c17c085 with changes to StopFetching and AllInputsConsumed checking behavior since last review.

Tree-SHA512: 89c1c2890f65aac5cd546edc44504956c47b6fada256d3b86ced47e6dd8c72f633a4357753b3b9805b9ba6ed02790822090d70578aba2964baf50d7eb956864c
2026-07-08 20:49:48 -04:00
Ava Chow
f0da26cfc8 Merge bitcoin/bitcoin#34997: p2p: Don't participate in addr relay with feelers
b0735336ee p2p: Don't participate in addr relay with feeler connections (Daniela Brozzoni)

Pull request description:

  Feeler connections are short-lived connection made to check that a node is alive, useful for test-before-evict, and for moving addresses from the new to the tried table.

  We currently send a GETADDR message to feelers, but then disconnect before being able to receive a response. This GETADDR is not useful and can be removed.

  I couldn't find any previous discussion about this, but I found PR #22777, that similarly made sure that we don't ask for tx relay to feelers.

  ---

  I noticed this behavior on my peer-observer instance: I would see the number of sent GETADDR messages increase over time, but the number of ADDR messages with >100 addresses received (which are likely GETADDR responses and not self announcements relays) wouldn't increase as much. I later realized that it was my node opening feeler connections, sending a GETADDR, and closing the connection.

  You can see the same behavior using this command - the node is making feeler connections, sending getaddr to them, closing before receiving the addr response:

  ```
  ~ ₿ tail -f ~/.bitcoin/debug.log | grep -E "(Making feeler connection|Added connection to|sending getaddr|feeler connection completed|Received addr: [0-9]{2,} addresses)"

  2026-04-02T13:25:50Z [net] Making feeler connection to xyz.onion:8333
  2026-04-02T13:26:06Z [net] Added connection to xyz.onion:8333 peer=27
  2026-04-02T13:26:08Z [net] sending getaddr (0 bytes) peer=27
  2026-04-02T13:26:08Z [net] feeler connection completed, disconnecting peer=27, peeraddr=xyz.onion:8333
  ```

  On a node that accepts inbounds connections, this command can be used to see in the logs all the nodes that connected, sent a getaddr, and disconnected before receiving a reply. It is possible that these nodes connected to us as a feeler:
  ```
  ~ ₿ cat .bitcoin/debug.log | awk '

    /received: getaddr/ {
        split($0, a, "peer=")
        got_getaddr[a[2]] = $0
    }

    /sending addr/ {
        split($0, a, "peer=")
        sent_addr[a[2]] = 1
    }

    /socket closed/ {
        split($0, a, "peer=")
        id = a[2]

        if (id in got_getaddr && !(id in sent_addr)) {
            print "possible feeler: " got_getaddr[id]
            print "                 " $0
        }

        delete got_getaddr[id]
        delete sent_addr[id]
    }
  '

  possible feeler: 2026-04-01T21:45:13Z [net] received: getaddr (0 bytes) peer=2311974
                   2026-04-01T21:45:13Z [net] socket closed, disconnecting peer=2311974
  possible feeler: 2026-04-02T00:18:58Z [net] received: getaddr (0 bytes) peer=2426389
                   2026-04-02T00:18:58Z [net] socket closed, disconnecting peer=2426389
  ...
  ```

  Then, you can manually inspect one of them:
  ```
  ~ ₿ cat .bitcoin/debug.log | grep -E "peer=2311974"
  2026-04-01T21:45:13Z [net] Added connection peer=2311974
  2026-04-01T21:45:13Z [net] received: version (102 bytes) peer=2311974
  2026-04-01T21:45:13Z [net] sending version (102 bytes) peer=2311974
  2026-04-01T21:45:13Z [net] send version message: version 70016, blocks=943279, txrelay=0, peer=2311974
  2026-04-01T21:45:13Z [net] sending wtxidrelay (0 bytes) peer=2311974
  2026-04-01T21:45:13Z [net] sending sendaddrv2 (0 bytes) peer=2311974
  2026-04-01T21:45:13Z [net] sending verack (0 bytes) peer=2311974
  2026-04-01T21:45:13Z [net] receive version message: /Satoshi:27.0.0/: version 70016, blocks=943279, us=x.x.x.x:8333, txrelay=0, peer=2311974
  2026-04-01T21:45:13Z [net] received: wtxidrelay (0 bytes) peer=2311974
  2026-04-01T21:45:13Z [net] received: sendaddrv2 (0 bytes) peer=2311974
  2026-04-01T21:45:13Z [net] received: verack (0 bytes) peer=2311974
  2026-04-01T21:45:13Z New inbound v1 peer connected: version: 70016, blocks=943279, peer=2311974
  2026-04-01T21:45:13Z [net] sending sendcmpct (9 bytes) peer=2311974
  2026-04-01T21:45:13Z [net] sending ping (8 bytes) peer=2311974
  2026-04-01T21:45:13Z [net] sending getheaders (1029 bytes) peer=2311974
  2026-04-01T21:45:13Z [net] initial getheaders (943278) to peer=2311974 (startheight:943279)
  2026-04-01T21:45:13Z [net] received: getaddr (0 bytes) peer=2311974
  2026-04-01T21:45:13Z [net] Advertising address x.x.x.x:8333 to peer=2311974
  2026-04-01T21:45:13Z [net] socket closed, disconnecting peer=2311974
  2026-04-01T21:45:13Z [net] Resetting socket for peer=2311974
  2026-04-01T21:45:13Z [net] sending addrv2 (24665 bytes) peer=2311974
  2026-04-01T21:45:13Z [net] Cleared nodestate for peer=2311974
  ```

ACKs for top commit:
  0xB10C:
    ACK b0735336ee
  achow101:
    ACK b0735336ee
  andrewtoth:
    ACK b0735336ee
  stratospher:
    ACK b073533. didn't see any addr message from feelers in my node's last 24 hours/it would disconnect before addr message is received. so consistent with today's behaviour.

Tree-SHA512: 1ac220dfd8361c4687399546a0d968d268e447446053fb8b90ba6b987482cc038e2ad94e670f33181d08d6d0c576882328bb5d0a8b8b1175a5e2ec31ff051833
2026-07-08 11:49:10 -07:00
merge-script
3f3e644beb Merge bitcoin/bitcoin#35678: private broadcast: define and use new RPC_LIMIT_EXCEEDED error code ( + other follow-ups)
8ac222484c private broadcast: remove no-op [[nodiscard]] (stickies-v)
191bdcba26 test: align test better with described scenario (stickies-v)
7ad311be18 test: use BOOST_CHECK_EQUAL for PrivateBroadcast::AddResult (stickies-v)
82a02a2a22 rpc: define and use new  RPC_LIMIT_EXCEEDED error code (stickies-v)

Pull request description:

  The server isn't running out of memory when the private broadcast transaction queue is full. Add and use a new `-37` (`RPC_LIMIT_EXCEEDED`) code that can be used whenever a resource is bound and currently at capacity.

  Addresses https://github.com/bitcoin/bitcoin/pull/35406#discussion_r3535904571

  Also includes commits to address other outstanding suggestions/nits from #35406:
  - no-op `[[nodiscard]]`: https://github.com/bitcoin/bitcoin/pull/35406#discussion_r3535923165
  - use `BOOST_CHECK_EQUAL`: https://github.com/bitcoin/bitcoin/pull/35406#discussion_r3384040078
  - improve clarity remove-add test case: https://github.com/bitcoin/bitcoin/pull/35406#discussion_r3519358990

ACKs for top commit:
  instagibbs:
    ACK 8ac222484c
  andrewtoth:
    ACK 8ac222484c
  sedited:
    ACK 8ac222484c

Tree-SHA512: c5e0220060770032f3fea54beaabd1d14179a18df3c3e9c25e9f547ad893cea91e2f4b180dd28ad20f09a3cb6b063fad267caab792ee9727f52a2d49f4508523
2026-07-08 09:56:02 +02:00
Ava Chow
e3b026bf56 Merge bitcoin/bitcoin#34020: mining: add getTransactions(ByWitnessID) IPC methods
9784818442 mining: add getTransactionsByWitnessID() IPC method (Sjors Provoost)
d282ae6883 mining: add getTransactionsByTxID() IPC method (Sjors Provoost)
0d5e4d4712 test: restart node after IPC option override test (Sjors Provoost)
f16b3613cd ipc: Serialize null CTransactionRef as empty Data (Sjors Provoost)
0f466e1094 mempool: add lookup by witness hash (Sjors Provoost)

Pull request description:

  For Stratum v2 custom job declaration to be bandwidth efficient, the pool can request[^0] only the transactions that it doesn't know about.

  The spec doesn't specify how this is achieved, but one method is to call the `getrawtransaction` RPC on each transaction id listed in [DeclareMiningJob](https://stratumprotocol.org/specification/06-Job-Declaration-Protocol?query=DeclareMiningJob#644-declareminingjob-client-server) (or a subset if the pool software maintains a cache). Using RPC is inefficient, made worse by the need to make multiple calls. It also doesn't support queuing by witness id (yet, see #34013).

  This PR introduces two new IPC methods:

  - `getTransactionsById()`: takes a list of `Txid`'s
  - `getTransactionsByWitnessID()`: : takes a list of `Wtxid`'s

  Both return a list of serialised transactions. An empty element is returned for transactions that were not found.

  Unlike the RPC counterpart, the IPC methods do not take advantage of `-txindex`. This could be done in a followup. For `Wtxid` that would involve adding a `-witnesstxindex`.

  I thought about having a single (or overloaded) `getTransactions()` that works with both `Txid` and `Wtxid`, but I prefer that clients are intentional about which one they want.

  A unit and functional test cover the new functionality.

  Sv2 probably only needs `getTransactionsByWitnessID()`, but it's easy enough to just add both.

  To rest with Rust use:
  - https://github.com/2140-dev/bitcoin-capnp-types/pull/11

  [^0]: there's two reasons the pool requests these transactions: to approve the template and to broadcast the block if a solution is found (the miner will also broadcast via their template provider). See also https://github.com/stratum-mining/sv2-spec/issues/170

ACKs for top commit:
  achow101:
    ACK 9784818442
  sedited:
    Re-ACK 9784818442
  ViniciusCestarii:
    Re-ACK  9784818442
  ismaelsadeeq:
    Code review ACK 9784818442

Tree-SHA512: 3c6ceb572ab7d8bd090a8f31b5e331304a7a19a3d1f1551c9c2e1ee41339d76f96ca6c41bd634c87fca0a969e7d9bfa6a16c26fb06c0dd2315f6ca1c76a16a31
2026-07-07 14:29:10 -07:00
stickies-v
82a02a2a22 rpc: define and use new RPC_LIMIT_EXCEEDED error code
The server isn't running out of memory when the private broadcast
transaction queue is full. Add a new RPC_LIMIT_EXCEEDED code that
can be used whenever a resource is bound and currently at capacity.
2026-07-07 16:24:31 +01:00
merge-script
4498fa5d5b Merge bitcoin/bitcoin#35406: private broadcast: limit outstanding txs to count of 10,000
4e29de719e private broadcast: add release note for limited cap (Gregory Sanders)
cbf8c107c1 Release cs_main between individual private tx re-attempts (Greg Sanders)
5aea3d0373 private broadcast: limit outstanding txs to count of 10,000 (Gregory Sanders)

Pull request description:

  Add a belt-and-suspenders feature, limit the amount of memory and cpu possible when unlucky or simply misconfigured. The worst case limit is roughly 400kB * 10,000 = 4GB, regardless of usage pattern.

  Before this change, sheer volume of broadcasts, mismatches in standardness rules, or simply fee mismatches may result in unbounded growth of memory usage. As the feature may be expanded in the future, explicit bounds helps reasoning going forward.

ACKs for top commit:
  frankomosh:
    tACK 4e29de719e. Ran private_broadcast_tests and p2p_private_broadcast_cap.py. Great to have an explicit bound as the belt-and-suspenders against unbounded queue growth.
  vasild:
    ACK 4e29de719e
  andrewtoth:
    ACK 4e29de719e
  stickies-v:
    ACK 4e29de719e

Tree-SHA512: 18161755f37d07cca185a09e782dbe2fd0025b8befd4f6660e988865cc3a9b705d41769b816161e8142fe6ce31a56e0288bd78efc25135cedfc47fc855011799
2026-07-07 15:10:13 +01:00
Ava Chow
69fc991791 Merge bitcoin/bitcoin#32606: p2p: Drop unsolicited CMPCTBLOCK from non-HB peer and when blocksonly
55e3a57f22 qa: Avoid UTXO reuse between test functions (Hodlinator)
9c5dd2926a p2p: Ignore CMPCTBLOCK from peer that hasn't sent SENDCMPCT (David Gumberg)
bf9884f4e5 p2p: make blocksonly nodes ignore CMPCTBLOCK messages (David Gumberg)
92cea63c71 test: (Un)solicited invalid cb -> get disconnected. (David Gumberg)
e845e26344 test: p2p: Nodes ignore unsolicited CMPCTBLOCK's (David Gumberg)
8313591715 p2p: Drop unsolicited CMPCTBLOCK from non-HB peer (David Gumberg)
44f377a71f refactor: test: Static assert_highbandwidth_states (David Gumberg)
25457a3272 test: Tighten getblocktxn checks in parallel cb reconstruction test. (David Gumberg)
51dd90fb50 refactor: Merge announce_cmpct_block() defs into one (Hodlinator)

Pull request description:

  Processing unsolicited `CMPCTBLOCK`'s from a peer that has not been marked high bandwidth is not well-specified behavior in BIP-0152, in fact the BIP seems to imply that it is not permitted:

  > "[...] method is not useful for compact blocks because `cmpctblock` blocks can be sent unsolicitedly in high-bandwidth mode"

  See https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki#separate-version-for-segregated-witness

  This PR disables processing of CMPCTBLOCK messages in three cases:
  $1$. When the block is unsolicited and from a non-HB peer.
  $2$. When this node is running in `-blocksonly` mode.
  $3$. When the peer has not advertised `CMPCTBLOCK` support with a `SENDCMPCT` message.

  Not processing unsolicited blocks slightly raises the cost of discovering a peer's mempool via `CMPCTBLOCK` as described in #28272. As pointed out there, getting an HB slot is relatively easy, so this does not prevent an attacker from doing this, it just slightly raises the bar.

  Probably more important is not processing `CMPCTBLOCK` messages as a `-blocksonly` node. A blocksonly node has a lot less surface area for leaking its mempool since it does no transaction relay, and leaking a blocksonly node's mempool is pretty dangerous since it is very likely to be the origin for all of the transactions in its mempool.

ACKs for top commit:
  achow101:
    ACK 55e3a57f22
  w0xlt:
    reACK 55e3a57f22
  hodlinator:
    re-ACK 55e3a57f22
  polespinasa:
    lgtm ACK 55e3a57f22

Tree-SHA512: 118bea55adca01dbd6467ba5ae3adf420d960794a6a2c40dd30fcc7d79aa944e01af0f6dd6bd6ff6d33dc9155171f6f4f497cbd7e8eb6d3c4c89e12740b51c05
2026-07-06 15:52:10 -07:00
Daniela Brozzoni
b0735336ee p2p: Don't participate in addr relay with feeler connections
Feeler connections are short-lived connections made to check that a node
is alive, useful for test-before-evict from addrman, and for moving
addresses from the new to the tried table.

We currently send a GETADDR message to feelers, but then disconnect
before being able to receive a response. This wastes some bandwidth, so
we can avoid sending the GETADDR altogether.

Not sending the initial GETADDR will effectively disable addr relay:
we initialize addr relay for the peer when we send GETADDR, and the peer
initializes addr relay to us when they receive it. So the
peer will not relay any announcement to us, and we will not relay any
to them either. This is ok, since the use of feelers is to test if there
is a bitcoin node behind an address, not exchange addresses with them.
2026-07-06 16:02:30 +02:00
merge-script
302733fd96 Merge bitcoin/bitcoin#35652: init: fix reindex deadlock by waking cv after interrupt
c1313b199f init: wake genesis wait after ImportBlocks() returns (ismaelsadeeq)

Pull request description:

  During startup with `-reindex`, the block index and chainstate are wiped, and
  the normal `LoadGenesisBlock()` startup path is skipped while block files are
  being indexed. The init thread can then wait for genesis to be processed via the
  tip-block condition variable.

  If shutdown is requested after the init thread enters that wait but before the
  import thread activates genesis, the reindex scan can return early without
  calling the later `LoadGenesisBlock()` fallback or `ActivateBestChains()`.
  Because no block tip is connected, the block-tip notification never fires. The
  wait predicate would accept `ShutdownRequested(node)`, but it is not evaluated
  again unless the condition variable is notified.

  Notify the tip-block condition variable after `ImportBlocks()` returns so the
  genesis wait can observe shutdown and exit cleanly.

  Described in detail https://github.com/bitcoin/bitcoin/pull/35621#issuecomment-4876059120

  The current test covers the path, but won't fail deterministically. You can use L0rinc suggested patch for a deterministic patch that demonstrate the deadlock on master https://github.com/bitcoin/bitcoin/pull/35652#pullrequestreview-4627988553

ACKs for top commit:
  maflcko:
    review ACK c1313b199f 🦁
  mzumsande:
    Code Review ACK [c1313b1](c1313b199f)
  sedited:
    tACK c1313b199f

Tree-SHA512: b17faaa2042882f2acebf688f4a28fd6bb11cc5d7f978991fe2bcba7a9df6ed82a0a2811f2e71a929189570a7926f148afdbeef5c1ca57a081e3bb914c2f6fe2
2026-07-06 15:58:54 +02:00
ismaelsadeeq
c1313b199f init: wake genesis wait after ImportBlocks() returns
If shutdown interrupts ImportBlocks() before genesis activation,
no blockTip notification is sent. The wait predicate allows
shutdown to occur, but the condition variable is never
notified, so init can remain stuck waiting for genesis activation.

Notify the tip condition variable after ImportBlocks() returns so
interrupted imports wake the wait and let it observe the shutdown request.

Add test coverage for interrupting startup after reindex block files import
begins, which exercises the path where ImportBlocks() can return before genesis
activation.
2026-07-06 13:37:09 +01:00
merge-script
2063f02bd5 Merge bitcoin/bitcoin#35510: test: SOCKS5 proxy: expect that connection may be reset during SOCKS5 handshake or data forwarding
9a8ef9b0a3 test: SOCKS5 proxy: expect that connection may be reset during handshake (Vasil Dimov)
eb3208364a test: SOCKS5 proxy: expect that connection may be reset when forwarding (Vasil Dimov)

Pull request description:

  The `forward_sockets()` function used by the SOCKS5 proxy forwards data between two connected sockets. It might happen that one of those sockets gets closed/reset abruptly, without sending EOF first. This is to be expected if e.g. `bitcoind` is shutdown and shouldn't result in noisy harmless messages like:

  ```
  2026-06-03T13:23:56.966859Z TestFramework.socks5 (ERROR): socks5 request handling failed (running True)
  Traceback (most recent call last):
    File ".../socks5.py", line 199, in handle
      forward_sockets(self.conn, conn_to, self.wakeup_socket_pair[1], self.serv)
      ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File ".../socks5.py", line 76, in forward_sockets
      data = s.recv(4096)
  ConnectionResetError: [Errno 104] Connection reset by peer
  ```

  Instead turn this into a debug log message with a nice prefix containing enough information to identify the two forwarded sockets.

  ---

  Also expect that the connection might be closed during the SOCKS5 handshake and only log a debug message if that happens.

ACKs for top commit:
  optout21:
    crACK 9a8ef9b0a3
  danielabrozzoni:
    reACK 9a8ef9b0a3
  sedited:
    ACK 9a8ef9b0a3

Tree-SHA512: 24e25a30529eda3536ebf472f63a93fd80fff46273054a7075490c88737f8870c0141b2bc99d9ef39e6b4f592af2801350fdfbc71927f573738b4a14f5fd7ce0
2026-07-04 17:19:35 +02:00
merge-script
0a1bbec688 Merge bitcoin/bitcoin#32489: wallet: Add exportwatchonlywallet RPC to export a watchonly version of a wallet
a15bdc0598 doc: update offline-signing-tutorial to use exportwatchonlywallet rpc (Pol Espinasa)
a388076401 test: Test for exportwatchonlywallet (Ava Chow)
d053e3e5c8 wallet, rpc: Add exportwatchonlywallet RPC (Ava Chow)
444878efef wallet: Add CWallet::ExportWatchOnly (Ava Chow)
f9273f01db wallet: Move listdescriptors retrieving from RPC to CWallet (Ava Chow)
a1c83789a7 wallet: Write new descriptor's cache in AddWalletDescriptor (Ava Chow)
1e996640e6 wallet: Use Descriptor::CanSelfExpand() in CanGetAddresses() (Ava Chow)
d2ee9227da descriptor: Add CanSelfExpand() (Ava Chow)

Pull request description:

  Currently, if a user wants to use an airgapped setup, they need to manually create the watchonly wallet that will live on the online node by importing the public descriptors. This PR introduces `exportwatchonlywallet` which will create a wallet file with the public descriptors to avoid exposing the specific internals to the user. Additionally, this RPC will copy any existing labels, transactions, and wallet flags. This ensures that the exported watchonly wallet is almost entirely a copy of the original wallet but without private keys.

ACKs for top commit:
  polespinasa:
    lgtm ACK a15bdc0598
  Sjors:
    re-utACK a15bdc0598
  pablomartin4btc:
    re-ACK [a15bdc0](a15bdc0598)
  w0xlt:
    lgtm reACK a15bdc0598

Tree-SHA512: cfc59415ad9aa13d1445cf2a85db1c051215496b6edcf5a8db463499b2b51b92ee7bf840b709035dff7635f9d0c533423bceb58c851f220500e1ea254d12f3b8
2026-07-03 10:58:52 +01:00
Ava Chow
a388076401 test: Test for exportwatchonlywallet 2026-07-02 14:49:37 -07:00
Sebastian Falbesoner
91586f701e test: introduce NodeSigner, run feature_taproot.py without wallet compiled
Introduce a new simple `NodeSigner` wallet replacement that delegates
signing to a specified node via the `signrawtransactionwithkey` RPC,
and plug in that new class to the functional test feature_taproot.py,
so that it can be ran without the Bitcoin Core wallet compiled.
2026-07-01 00:21:11 +02:00
Sebastian Falbesoner
771200ca43 test: return full keypair from getnewdestination helper
This can be useful for spending funds that are received at the created
address. Preparatory for the next commit, which modifies the taproot
functional test to work without the Bitcoin Core wallet compiled in.
2026-06-30 23:18:12 +02:00
Gregory Sanders
5aea3d0373 private broadcast: limit outstanding txs to count of 10,000
Add a belt-and-suspenders feature, limit the amount of
memory and cpu possible when unlucky or simply misconfigured.
The worst case limit is roughly 400kB * 10,000 = 4GB, regardless
of usage pattern.

Before this change, sheer volume of broadcasts, mismatches in
standardness rules, or simply fee mismatches may result in unbounded
growth of memory usage. As the feature may be expanded in
the future, explicit bounds helps reasoning going forward.
2026-06-30 14:53:59 -04:00
merge-script
dc282ff31d Merge bitcoin/bitcoin#35597: logging: More fully remove libevent log category
3765b428d1 logging: More fully remove libevent log category (Ryan Ofsky)

Pull request description:

  Libevent log category was partially removed in 39e9099da5, and this commit extends that with the following changes:

  - Stops showing libevent in the list of supported log categories in `bitcoind -help` and `bitcoin-cli help logging` output.
  - Stops returning `"libevent": false` in `logging` RPC output.

  It's not good to treat libevent as a supported log category when it can't be enabled and trying to enable it results in warnings.

  There's also no need to define an unused LIBEVENT constant value and keep more complicated logic for dealing with deprecated log categories, so this change also simplifies code internally.

ACKs for top commit:
  l0rinc:
    code review ACK 3765b428d1
  pinheadmz:
    ACK 3765b428d1
  sedited:
    ACK 3765b428d1

Tree-SHA512: 09e9514f905bb0a79d870689af491886baaa31fa19f2ad6aef4283fa20c2fa6ce8d384178139227aeeabffabff6e83d254114daaeefbbfe2c6172b9da8871298
2026-06-30 18:00:09 +02:00
Andrew Toth
f82043af50 coins: introduce thread pool in CoinsViewOverlay
Introduce a ThreadPool shared pointer to CoinsViewOverlay. A pool managed
externally can be passed in the constructor.

A global thread pool is used in fuzz harnesses since iterations can happen
faster than the OS can create and tear down thread pools.
This can cause a memory leak when fuzzing.

Co-authored-by: l0rinc <pap.lorinc@gmail.com>
2026-06-29 21:07:26 -04:00
ekzyis
a318f43254 bitcoin-util: Add netmagic command 2026-06-30 00:33:00 +02:00
Ava Chow
e1290ce7f7 Merge bitcoin/bitcoin#35543: test: introduce ExtendedPrivateKey and ExtendedPublicKey classes
8791c4764c test: use ExtendedPrivateKey in wallet_taproot.py (rkrux)
89ceafafb9 test: use ExtendedPrivateKey in wallet_listdescriptors.py (rkrux)
bbfffcab58 test: use ExtendedPrivateKey in wallet_send.py (rkrux)
2ab6e590f7 test: use ExtendedPrivateKey in wallet_keypool.py (rkrux)
9e20118720 test: use ExtendedPrivateKey in wallet_fundrawtransaction.py (rkrux)
06af0cddbb test: use ExtendedPrivateKey in wallet_descriptor.py (rkrux)
4100fac20e test: use ExtendedPrivateKey in wallet_createwallet.py (rkrux)
ff3f6def9a test: use ExtendedPrivateKey in wallet_bumpfee.py (rkrux)
003f2a01f6 test: use ExtendedPrivateKey in feature_notifications.py (rkrux)
f988e6d6e6 test: use ExtendedPrivateKey in wallet_importdescriptors.py (rkrux)
d2a03d50ac test: add extendedkey.py unit tests by using BIP32 test vectors (rkrux)
afdb378082 test: introduce ExtendedPrivateKey and ExtendedPublicKey classes (rkrux)
4dbaa7cc65 test: generalise byte_to_base58 utility function to allow more version types (rkrux)

Pull request description:

  Many a times there has been a need to come up with dynamic xprvs and xpubs
  in the functional tests, but the lack of code that creates them dynamically has
  led to the presence of several hardcoded keys in the testing framework. This
  is not developer friendly and not self-documenting, clutters the testing code,
  and makes it difficult to update the tests in the future.

  This PR introduces two utility classes ExtendedPrivateKey and
  ExtendedPublicKey that allows the developer to create them on the fly
  to be used in the tests. I have intentionally not introduced any library for this
  purpose and have reused the existing libraries and functions in the framework.
  The implementation is supposed to provide basic functionality for creating
  xprv randomly or from a fixed seed, creating corresponding xpub, and
  deriving child xprvs and xpubs at custom derivation paths.

  I've updated many tests to show how these can be used, there are more
  tests as well that can be updated in the future to completely remove such
  non-deterministic hardcoded keys.

ACKs for top commit:
  achow101:
    ACK 8791c4764c
  w0xlt:
    ACK 8791c4764c

Tree-SHA512: f8ec4e09eaa6cc44b0f1c9a91337e570b12fb882c258be89b470de1a8cecf9d2fd40d9f02ee739dcbf639462ea7710aa145a3726f0f537f5a1f1e7772e5b019d
2026-06-26 15:56:05 -07:00
merge-script
295ce6f45c Merge bitcoin/bitcoin#35576: test: raise feature_reindex RPC timeout
9e6546c517 test: raise reindex mining RPC timeout (Lőrinc)

Pull request description:

  **Problem:** I often hit a timeout in `feature_reindex.py` when running functional tests locally in parallel in debug mode (especially on battery or in power-saving mode).
  **Fix:** Increase the test-local RPC timeout for the reindex mining setup.

ACKs for top commit:
  mercie-ux:
    ACK 9e6546c517
  sedited:
    ACK 9e6546c517

Tree-SHA512: d3541dd6752f943921a030393b00e684b3b5d00b93aa0b2b1f85c017698bdfe2216d7f5441bb7dd5f153453385e4df6f9cc8055589e57bca83fa48f0b7de4252
2026-06-25 09:30:50 +01:00
Pol Espinasa
9e62e4b1f3 test: slow down rescaning process 2026-06-25 08:18:10 +02:00
merge-script
633044f143 Merge bitcoin/bitcoin#35266: rpc, wallet: add an option to not load the wallet after migrating
0cdd817a82 add release note (Pol Espinasa)
517d37ce3e test: tests wallet migration with load_wallet disabled (Pol Espinasa)
b98dd63da7 rpc: Add load_wallet argument to migratewallet RPC (Pol Espinasa)
4acd063ba6 wallet: make loading the wallet after migrating optional (Pol Espinasa)
97d08d62ba refactor: store wallet names to MigrationResult (Pol Espinasa)

Pull request description:

  This PR is motivated by this [Stack Exchange question](https://bitcoin.stackexchange.com/questions/130713/bitcoin-core-quickest-method-legacy-descriptor-wallet-migration).

  Long story short, someone who has a node pruned before his legacy wallet birthday, is unable to migrate the wallet as it is not possible to load it.

  Loading is not necessary for migration, and migrating without wanting to use the wallet in that node is a valid use-case.

  This PR adds a new RPC argument to `migratewallet` that allow the user disabling the wallet loading.
  Second commits adds tests for it.

  Follow-up: Add an option to the GUI to not load the wallet after migrating.

ACKs for top commit:
  achow101:
    ACK 0cdd817a82
  w0xlt:
    ACK 0cdd817a82
  pablomartin4btc:
    ACK 0cdd817a82

Tree-SHA512: 8389599e63603b1a532e1bfba0b6c652653386c001f5a881bd49843302b74ff4dbaa4131b5b377c24f483d42e0e70a92b96f760244e3c2e2b44ce08cd04ca1e0
2026-06-24 21:28:55 +02:00
Ryan Ofsky
3765b428d1 logging: More fully remove libevent log category
Libevent log category was partially removed in 39e9099da5, and this
commit extends that with the following changes:

- Stops showing libevent in the list of supported log categories in
  `bitcoind -help` and `bitcoin-cli help logging` output.

- Stops returning `"libevent": false` in `logging` RPC output.

It's not good to treat libevent as a supported log category when it
can't be enabled and trying to enable it results in warnings.

There's also no need to define an unused LIBEVENT constant value and
keep more complicated logic for dealing with deprecated log categories,
so this change also simplifies code internally.

Co-authored-by: David Gumberg <davidzgumberg@gmail.com>
Co-authored-by: l0rinc <pap.lorinc@gmail.com>
2026-06-23 22:10:34 -04:00
Ava Chow
d84fc352cb Merge bitcoin/bitcoin#35550: net_processing: fix BIP152 first integer interpretation
abc33ff043 test: announce field must be 0 or 1 in sendcmpct (brunoerg)
2d0dce0af5 net_processing: fix BIP152 first integer interpretation (brunoerg)

Pull request description:

  Fixes #35542

  According to the BIP152, the first integer in `sendcmpct` message shall be interpreted as a boolean (and MUST have a value of either 1 or 0). We currently correctly interpret it as boolean, however, we accept any value >=1 and treat it as `true`, deviating from the specification. This PR fixes it.

ACKs for top commit:
  edilmedeiros:
    utACK abc33ff043
  davidgumberg:
    crACK abc33ff043 Seems reasonable to comply with BIP152 strictly, test looks good as well.
  Sjors:
    ACK abc33ff043
  jonatack:
    re-ACK abc33ff043
  achow101:
    ACK abc33ff043
  w0xlt:
    ACK abc33ff043

Tree-SHA512: 77fed86d4de81f7c35ff002b6e1b2a90882ea55f159075da4d34a619d1075f625fca34f929cdd981f1b2eb06f76b64f42cda46502dcd1b4a634c690b0882ec7c
2026-06-23 16:19:13 -07:00
Ava Chow
fafff08e1f Merge bitcoin/bitcoin#35403: mining: pr 33966 followups (disentangle miner startup defaults)
b847626562 test: refresh MiniWallet after node restart (Sjors Provoost)
f4e643cb15 test: merge mining options in package feerate check (Sjors Provoost)
280ce6a0ae miner: ensure block_max_weight is flattened before limit checks (Sjors Provoost)
65bd3164fb mining: clarify test_block_validity comment (Sjors Provoost)
978e7216e6 test: use shared default_ipc_timeout (Sjors Provoost)

Pull request description:

  This implement the suggested followups from #33966. Each commit links  to the original comment.

  The most important change is the extra asserts added in `miner: ensure block_max_weight is flattened before limit checks`.

ACKs for top commit:
  achow101:
    ACK b847626562
  enirox001:
    tACK b847626562
  sedited:
    ACK b847626562
  w0xlt:
    ACK b847626562

Tree-SHA512: 47678eaed604228269bd892ccf8ff58804745bbc7675b4a93528da9a9292a2eb1e0562cdb8341edac77178563420885b48282bb9e5c2b997b28f2fc64ceeff3d
2026-06-23 15:07:29 -07:00
merge-script
fa8e4700ba Merge bitcoin/bitcoin#35424: doc, wallet: align external signer documentation, reject sendtoaddress/sendmany
2fe34808fa wallet: reject sendtoaddress and sendmany for external signers (Sjors Provoost)
bd5a32f7db doc: add taproot descriptor to getdescriptors example (woltx)
7131c82937 doc: clarify which commands receive --chain, --fingerprint and --stdin (woltx)
4fdd4d8d29 doc: replace stale signtransaction wording with current signtx flow (woltx)
fab92257fe doc, rpc: document enumerate model field and fingerprint deduplication (woltx)

Pull request description:

  This PR aligns the external signer documentation with current behavior, and makes one previously implicit behavior explicit.
  Per review feedback, each commit fixes a limited set of issues:

  * **doc, rpc: document enumerate model field and fingerprint deduplication** — the `enumerate` response uses the optional `model` field, which Bitcoin Core maps to the `name` field of the `enumeratesigners` RPC result. Duplicate fingerprints are skipped, and wallet operations require exactly one connected signer.

  * **doc: replace stale signtransaction wording with current signtx flow** — spending from an external signer wallet uses `send`/`sendall` (and `bumpfee` for fee-bumping), which invoke `<cmd> --stdin` and pass the `signtx` subcommand and PSBT over stdin.

  * **doc: clarify which commands receive --chain, --fingerprint and --stdin** — mark `--chain` and `--fingerprint` as required except for `enumerate`, keep `--stdin` required for protocol flexibility, and match the order and form of the actual invocations in the usage examples.

  * **doc: add taproot descriptor to getdescriptors example** — show the BIP86 `tr()` descriptor alongside the other address types.

  * **wallet: reject sendtoaddress and sendmany for external signers** — return a specific error instead of the misleading "Private keys are disabled for this wallet", with functional test coverage. Cherry-picked from #33112 (thanks Sjors).

  How the documentation went stale:

  * The `enumerate` example has shown a `name` field since external signer support landed in #16546, but the implementation has always read `model`.

   * `sendtoaddress`/`sendmany` external signer support was effectively precluded by #21201, which was merged a few days before #16546, so the interaction was missed in review and the documented `signtransaction` flow never existed in this form.

  * Fingerprint deduplication was added in #35251.

  * The documentation was last updated in #33765.

ACKs for top commit:
  Sjors:
    ACK 2fe34808fa
  optout21:
    ACK 2fe34808fa
  naiyoma:
    ACK 2fe34808fa

Tree-SHA512: 86859d2f81ac337f3b4b6578c6ee0151ffb76b8374dfa58e28e00ce4eb69dc200cd6bd2d0a99f73d0475c3824d6ac1cb9e2542b119ca124dd835132dc95cd023
2026-06-23 14:01:48 +01:00
rkrux
8791c4764c test: use ExtendedPrivateKey in wallet_taproot.py 2026-06-23 15:13:49 +05:30
rkrux
89ceafafb9 test: use ExtendedPrivateKey in wallet_listdescriptors.py 2026-06-23 15:13:48 +05:30
rkrux
bbfffcab58 test: use ExtendedPrivateKey in wallet_send.py 2026-06-23 15:13:48 +05:30
rkrux
2ab6e590f7 test: use ExtendedPrivateKey in wallet_keypool.py 2026-06-23 15:13:48 +05:30
rkrux
9e20118720 test: use ExtendedPrivateKey in wallet_fundrawtransaction.py 2026-06-23 15:13:48 +05:30
rkrux
06af0cddbb test: use ExtendedPrivateKey in wallet_descriptor.py 2026-06-23 15:13:48 +05:30
rkrux
4100fac20e test: use ExtendedPrivateKey in wallet_createwallet.py 2026-06-23 15:13:48 +05:30
rkrux
ff3f6def9a test: use ExtendedPrivateKey in wallet_bumpfee.py 2026-06-23 15:13:47 +05:30
rkrux
003f2a01f6 test: use ExtendedPrivateKey in feature_notifications.py 2026-06-23 15:13:47 +05:30
rkrux
f988e6d6e6 test: use ExtendedPrivateKey in wallet_importdescriptors.py
This avoids hardcoding xprvs and xpubs in the test.

Also use key's parent fingerprint and derivation path while creating descriptors
so that all of it is self-documenting and not dependent on hardcoded values,
making them easy to read and update.

Also use descsum_create function more to avoid hardcoding the descriptor
checksum.
2026-06-23 15:13:42 +05:30
merge-script
6b58eb6d51 Merge bitcoin/bitcoin#35070: validation: prevent FindMostWorkChain from causing UB
d6359937bf validation: check invariants when inserting into m_blocks_unlinked (stratospher)
0852925bd8 test/doc: remove misleading comment and improve tests (stratospher)
ca4a380281 test: add coverage for UB caused by FindMostWorkChain (stratospher)
c787b3b99b validation: avoid duplicates in m_blocks_unlinked (stratospher)

Pull request description:

  This is joint work with @ mzumsande.

  note: this requires a pruned node with deep reorgs to trigger. still it breaks assumptions in the codebase and is good to fix. A similar UB was fixed in https://github.com/bitcoin/bitcoin/pull/34521.

  This PR prevents duplicate insertions into `m_blocks_unlinked` in `FindMostWorkChain`. There are 3 ways to insert into `m_blocks_unlinked`:

  1. `LoadBlockIndex` - not problematic, as each block index is processed only once.
  2. `ReceivedBlockTransactions` - not problematic, as this is usually only called once per block when it is first accepted in `AcceptBlock`. in the rare case it’s triggered again after pruning, the block would have been removed from `m_blocks_unlinked` when it was initially pruned, so duplicates still can’t arise.
  3. `FindMostWorkChain` - problematic when multiple candidate tips share common chains of ancestors, traversals from each tip to the fork point may insert duplicate (`pprev`, `pindex`) entries for blocks whose parents have been pruned.

  When the missing parent is later received and `ReceivedBlockTransactions` processes `m_blocks_unlinked`, the same entry may be processed multiple times. This can result in the block being re-added to `setBlockIndexCandidates` with a modified `nSequenceId`, violating its ordering invariants and leading to undefined behavior. So avoid duplicate insertions into `m_blocks_unlinked` in `FindMostWorkChain`.

  ### how to test:

  use the updated `feature_pruning.py` which adds coverage for this scenario.
  - on master: the test (with the below diff) fails since `nSequenceId` is being modified for an entry in `setBlockIndexCandidates`
  - on this branch: the test (with the below diff) passes

  ```diff --git a/src/validation.cpp b/src/validation.cpp
  --- a/src/validation.cpp
  +++ b/src/validation.cpp
  @@ -3814,6 +3814,12 @@ void ChainstateManager::ReceivedBlockTransactions(const CBlock& block, CBlockInd
                      pindex->nHeight, pindex->m_chain_tx_count, prev_tx_sum(*pindex), CLIENT_NAME, FormatFullVersion(), CLIENT_BUGREPORT);
               }
               pindex->m_chain_tx_count = prev_tx_sum(*pindex);
  +            for (const auto& c : m_chainstates) {
  +                if (c->setBlockIndexCandidates.contains(pindex)) {
  +                    LogInfo("### pindex UB = %s", pindex);
  +                    assert(false);
  +                }
  +            }
               pindex->nSequenceId = nBlockSequenceId++;
               for (const auto& c : m_chainstates) {
                   c->TryAddBlockIndexCandidate(pindex);
  ```

ACKs for top commit:
  sedited:
    Re-ACK d6359937bf
  marcofleon:
    crACK d6359937bf
  stringintech:
    ACK d6359937bf
  mzumsande:
    Sure - Code Review ACK [d635993](d6359937bf)

Tree-SHA512: bb21adc2d92fe1865bbbcebf775a850ca3eccac6fe83d7bca10b78eee4c0abf782e44fa0ddfec9d9a70f42fa40bdc49b68a1d1b4905cdc371ba29117d3120619
2026-06-23 09:25:06 +01:00
Pol Espinasa
517d37ce3e test: tests wallet migration with load_wallet disabled
Co-authored-by: w0xlt <woltx@protonmail.com>
2026-06-22 23:07:18 +02:00
Matthew Zipkin
39e9099da5 logging: deprecate libevent category
Creates logic to deprecate logging categories but still
"support" them so the software doesn't quit with unknown category
on startup. Deprecated categories are always false and attempts
to switch them are logged as warnings.
2026-06-22 05:47:01 -04:00
Matthew Zipkin
21c7542cf8 http: switch servers from libevent to bitcoin 2026-06-22 05:47:00 -04:00
Matthew Zipkin
881d4b6c75 test: cover common HTTP attacks and common malformed requests 2026-06-22 05:46:31 -04:00
Lőrinc
9e6546c517 test: raise reindex mining RPC timeout
`feature_reindex.py` mines a long chain before restarting during reindex.
Bump its local RPC timeout to avoid client timeouts in parallel debug-mode runs.
2026-06-21 19:28:00 +02:00
Ava Chow
1a2523e901 Merge bitcoin/bitcoin#34937: Fix startup failure with RLIM_INFINITY fd limits
735b25519a support: clamp RLIMIT_MEMLOCK to size_t (Sjors Provoost)
8ab4b9fc85 init: clamp fd limits to int (Sjors Provoost)
4afbabdcef Fix startup failure with RLIM_INFINITY fd limits (Sjors Provoost)

Pull request description:

  When setting the fd limit to unlimited, the node fails to start:

  ```sh
  ulimit -n unlimited
  build/bin/bitcoind
  Error: Not enough file descriptors available. -1 available, 160 required.
  ```

  This was caused by `RaiseFileDescriptorLimit()` (introduced in #2568) casting `limitFD.rlim_cur` to `int`, which for `RLIM_INFINITY` overflows to `-1`. Fix it by returning `std::numeric_limits<int>::max()` instead.

  Some platforms implement `RLIM_INFINITY` as the maximum uint64, others as int64 (-1). So simply changing the return type to `uint64_t` wouldn't work.

  Similarly, though unlikely to actually happen:

  ```sh
  ulimit -n 214748364
  build/bin/bitcoind
  Error: Not enough file descriptors available. -2147483648 available, 160 required.
  ```

  The second commit expands the fix by clamping all values above `std::numeric_limits<int>::max()` instead of letting them overflow.

  This PR also expands `test/functional/feature_init.py` to cover these, using `resource.setrlimit`. The check is skipped on environments with a hard limit below infinity (or that don't have the Python [Resource module](https://docs.python.org/3/library/resource.html)).

  macOS by default has a hard limit of infinity, but on e.g. Ubuntu the default hard limit is 524288.

  The third commit applies a similar fix to `PosixLockedPageAllocator::GetLimit()` for 32-bit systems, but without a test.

ACKs for top commit:
  winterrdog:
    Re-ACK 735b25519a
  achow101:
    ACK 735b25519a
  sedited:
    Re-ACK 735b25519a
  pinheadmz:
    ACK 735b25519a

Tree-SHA512: 0ce0292ecd61456bdec6943b06cbb9ecfc5180ee6dce850f8496ef54af22c1fae6ea473085202f5ba6f72e4dc51a29247620c9a0eae31e96658adc77b293129f
2026-06-19 15:57:59 -07:00
Ryan Ofsky
794befd4b0 Merge bitcoin/bitcoin#35384: util: Check write failures before renaming settings.json
0654511e1b util: Check write failures before renaming settings.json (Shrey)

Pull request description:

  This PR Fixes #35373.
  The error message was updated from: "This is probably caused by disk corruption or a crash" to: "This is probably caused by a full disk, disk corruption or a crash"

  The following files were updated:
  1. src/common/settings.cpp -- Updated the main string formatting for the parse failure.
  2. src/test/settings_tests.cpp -- Updated the exact string expectation in the C++ unit test.
  3. test/functional/feature_settings.py -- Updated the expected error message in the Python test suite.

  Configured the Bitcoin Core project natively on Windows using Visual Studio (cmake --preset vs2026-static -DBUILD_GUI=OFF) and it compiled with 100% of the C++ tests passed successfully (347 out of 347).

ACKs for top commit:
  maflcko:
    review ACK 0654511e1b 💧
  winterrdog:
    ACK 0654511e1b
  sedited:
    ACK 0654511e1b
  ryanofsky:
    Code review ACK 0654511e1b with commit message and error message improved since last review

Tree-SHA512: d7b49860f2081a5a9d1d44917b0cf372a77f10cf21773c9b3291871c788a122ec5dde063fdf9e1052cf45b8d2667e15585b952e9f037e84f98fb41546bdd1fa9
2026-06-19 07:38:26 -04:00
rkrux
d2a03d50ac test: add extendedkey.py unit tests by using BIP32 test vectors 2026-06-19 16:09:43 +05:30
rkrux
afdb378082 test: introduce ExtendedPrivateKey and ExtendedPublicKey classes
Using these classes allows the developers to dynamically create
xprvs and xpubs so that they don't need to hardcode such long keys
in the tests that most of the times clutter the tests and make them
difficult to update.

Co-authored-by: w0xlt <94266259+w0xlt@users.noreply.github.com>
2026-06-19 16:09:38 +05:30
Hodlinator
55e3a57f22 qa: Avoid UTXO reuse between test functions 2026-06-18 16:50:44 -07:00
David Gumberg
9c5dd2926a p2p: Ignore CMPCTBLOCK from peer that hasn't sent SENDCMPCT
This commit also changes the default sendcmpct version in the functional
test to `2`, since this is the version that nodes expect, prior to this
commit, nowhere in the functional test framework was the default version
value used:

git grep -P 'msg_sendcmpct\((?![^)]*version\s*=)' HEAD^

`version=2` is a sensible default, since this is the version nodes
currently expect in the SENDCMPCT handshake.
2026-06-18 16:50:44 -07:00