Commit Graph

1715 Commits

Author SHA1 Message Date
MarcoFalke
fa2bd96cc0 test: Map cli CalledProcessError on server error to JSONRPCException
Like authproxy.py, so that tests can work without having to think whether the cli was used or not.
2026-08-06 13:35:48 +02:00
merge-script
17c5e33e9c Merge bitcoin/bitcoin#35216: qa: Improve functional test support on illumos and *BSD
f4a6d079c4 qa: Support `get_bind_addrs` and `feature_bind_extra` on illumos (Hennadii Stepanov)
5e96a8fd5a doc: Add `lsof` to Test Suite Dependencies on NetBSD (Hennadii Stepanov)
5d01aa4772 qa: Ignore `lsof` warnings on NetBSD (Hennadii Stepanov)
70352fda03 qa: Strip prefix length from NetBSD `ifconfig` output (Hennadii Stepanov)
1c1735567e doc: Add `lsof` to Test Suite Dependencies on FreeBSD (Hennadii Stepanov)
4cb7f39c2c qa: Drop OpenBSD from supported platforms in `get_bind_addrs` function (Hennadii Stepanov)
8a982eea85 qa: Add `skip_if_no_lsof_on_nonlinux` helper and use it where needed (Hennadii Stepanov)

Pull request description:

  This PR is a follow-up to #34256. It extends functional test support to illumos-based OSes and fixes several related issues on the *BSDs.

  Changes:
  - Make `lsof` an optional functional test dependency via a new `skip_if_no_lsof` helper, consistent with other optional test deps.
  - Strip the CIDR prefix length from NetBSD `ifconfig` output (no-op on other platforms).
  - Suppress spurious `lsof` warnings on NetBSD.
  - Drop OpenBSD from the platforms supported by `get_bind_addrs`.
  - Document the `lsof` Test Suite Dependency for FreeBSD and NetBSD.
  - Add support for `get_bind_addrs` and `feature_bind_extra` on illumos.

  CI runs: https://github.com/hebasto/bitcoin-core-nightly/pull/280.

  Addresses https://github.com/bitcoin/bitcoin/pull/34256#issuecomment-4361855749.

ACKs for top commit:
  l0rinc:
    Lightly tested code review ACK f4a6d079c4
  sedited:
    utACK f4a6d079c4

Tree-SHA512: 24d943d059f5fa3f5626017eff744836177a41724544355f34b3a31fdf287bd1916bc6e903b598c1c55b61da2ff0f931b4455542d9cff6cf399ef7963096dff4
2026-08-04 17:23:26 +02:00
merge-script
556988790a Merge bitcoin/bitcoin#35592: http: check rpcallowip immediately after accepting connection
55d3cd51a4 doc: add release note describing change for forbidden clients (Matthew Zipkin)
d1ed2a6e25 http: check rpcallowip immediately after accepting connection (Matthew Zipkin)

Pull request description:

  This is a follow-up to #35182 addressing a review comment from that PR: https://github.com/bitcoin/bitcoin/pull/35182#pullrequestreview-4322490068

  This update to HTTPServer checks the IP subnet allowlist as soon as possible (immediately after receiving a connection from a client) before any data is received. This does not entirely protect the server from the "slow loris" attack or [CWE-400](https://cwe.mitre.org/data/definitions/400.html) but does restrict the attack surface to localhost and clients explicitly allowed by the user.

  If a client is not allowed by the list, we disconnect as soon as possible. This is a behavior change from master branch (and previous release with libevent) where `403 Forbidden` was returned (after a potentially large amount request data was written to memory by the server).

  To facilitate existing unit tests, this commit includes a refactor that moves the subnet allow list and relevant methods into the HTTPServer class instead of static file scope. This is needed because otherwise the allow list would be empty when the unit tests run.

  There is still plenty of refactoring to do in order to modernize `HTTPServer` and de-globalize it, but since this specific issue has a resource allocation guard, I wanted to open it quickly on its own.

ACKs for top commit:
  janb84:
    ACK 55d3cd51a4
  winterrdog:
    ACK 55d3cd51a4
  w0xlt:
    ACK 55d3cd51a4
  fjahr:
    Code review ACK 55d3cd51a4

Tree-SHA512: 545911f2e4d2f97ab8bc854e9e57c39eb896428f8c349d34c8e8025a1f6bfb8cfd436f381e36af8b87592c07df3e16210819f3eef7943e23c6626030e615fdf5
2026-08-01 16:43:57 +01:00
Hennadii Stepanov
45f5609f2e qa: Enable interface_gui.py on macOS
This is a follow-up to bitcoin/bitcoin#35551.
2026-07-30 11:38:01 +01:00
Ava Chow
146988ef6c Merge bitcoin/bitcoin#35551: test: add interface_gui.py to test bitcoin-qt startup
aa01721c89 test: add interface_gui.py to test bitcoin-gui startup via RPC (Ryan Ofsky)

Pull request description:

  Adds a functional test that starts bitcoin-qt using QT_QPA_PLATFORM=minimal for headless operation, then verifies it responds to a stop RPC call. This detects startup crashes in the GUI that have no CI coverage today like https://github.com/bitcoin-core/gui/issues/940

  The new test is currently skipped on macos and windows due to different problems on those platforms that may be resolved with future PRs. Fixing the windows issue should also allow the `tool_bitcoin.py` test to be enabled on windows, and fixing the macos issue should allow Qt addressbook and wallet tests to be enabled on macos.

ACKs for top commit:
  achow101:
    ACK aa01721c89
  sedited:
    ACK aa01721c89
  pablomartin4btc:
    ACK aa01721c89
  hebasto:
    ACK aa01721c89.

Tree-SHA512: 84873aed41a856322eca1c391d3ff19b6eb4a0aa253d09ace342e3efe970a330cb11506eb4efe2580b7991132b644c7408feb013c18dbfbfaaf879f88f12e02e
2026-07-29 11:32:46 -07:00
Ava Chow
5311b15727 Merge bitcoin/bitcoin#33014: rpc: Fix internal bug in descriptorprocesspsbt when encountering invalid signatures
7e19ce200b rpc: Fix descriptorprocesspsbt internal bug on invalid signatures (b-l-u-e)

Pull request description:

  Fixes #32849
  descriptorprocesspsbt crashes with an internal bug assertion when given a PSBT whose inputs looked “finalized” that is non-empty final_script_sig / witness but whose signatures did not verify like invalid Schnorr bytes with unusual sighash combinations such as SIGHASH_SINGLE | ANYONECANPAY.

  Completeness was inferred with PSBTInputSigned, which only checks that final fields are present, not that they pass script verification. That let the RPC treat the PSBT as complete and call FinalizeAndExtractPSBT, where a failing invariant surfaced as CHECK_NONFATAL instead of a normal incomplete outcome.

  This PR determines complete the same way as the wallet path: after ProcessPSBT, it recomputes PrecomputedTransactionData and sets complete only if every input passes PSBTInputSignedAndVerified.
  Invalid signatures then yield complete: false and no hex, without going through the finalize path that asserted.

ACKs for top commit:
  achow101:
    ACK 7e19ce200b
  rkrux:
    lgtm re-ACK 7e19ce200b

Tree-SHA512: c534fb5bd3401ee3ac0bc27eaedaaaaf23e5e8510ed9b96a747bb0e41e2bd3d2031b6b08e933e139bb426e97bd05fab6e91397205f4be1db9d17630eea49a8bf
2026-07-22 14:38:42 -07:00
Ava Chow
32eb521002 Merge bitcoin/bitcoin#35215: coins: use SipHash-1-3-UJ for CCoinsMap keys
3bfdcbd7ee coins: reuse cache hasher for txid set (Lőrinc)
2beab94896 coins: use SipHash-1-3-UJ for `CCoinsMap` (Lőrinc)
7ff55cc650 bench: add fixed-width SipHash benchmarks (Lőrinc)
3aea85411f test: add SipHash-1-3-UJ coverage (Pieter Wuille)
a0ccd4ad17 crypto: add fixed-width SipHash-1-3-UJ (Pieter Wuille)
c2d7931b5c crypto: add generic SipHash-1-3-UJ (Pieter Wuille)
25bfca06d6 refactor: simplify adding SipHash-1-3-UJ (Lőrinc)
af50ba8500 test: add shared SipHash vectors (Lőrinc)

Pull request description:

  **Problem:** The in-memory UTXO cache hashes `COutPoint` keys containing a 32-byte txid and a 32-bit output index.
  SipHash-2-4 processes the txid as four independent 64-bit blocks, so its optimized 32-byte and 36-byte paths both take 14 SipRounds.
  This also matters for hash-prefix index work such as [#35531](https://github.com/bitcoin/bitcoin/pull/35531): once a persisted key format chooses a hash function, changing it later requires reindexing.

  **Fix:** Add `SipHasher13UJ`, a custom block-oriented variant combining Pieter Wuille's jumbo-block suggestion with SipHash-1-3, the reduced-round variant discussed in the [SipHash analysis](https://eprint.iacr.org/2012/351.pdf).
  It provides inline `Hash` overloads for the fixed-width inputs used here.
  Use a dedicated `SaltedCoinsCacheHasher` for `CCoinsMap` and `CoinsViewOverlay`'s temporary earlier-txid set, while other outpoint tables remain on SipHash-2-4.
  The salted hash values vary between restarts and are never persisted or sent over the network.

  **Design:** `SipHasher13UJ` accepts normal 64-bit blocks and 256-bit jumbo blocks.
  For hash-table use, cryptographic hash outputs must make up all but a small bounded number of retained jumbo blocks.
  The construction mixes all four limbs around one SipRound, omits byte-oriented padding, and uses an `"unpadded"` finalizer distinct from standard SipHash-1-3.
  The fixed-width paths take four rounds for one `uint256` jumbo block and five when followed by one normal block.
  For outpoints, the 32-bit output index is zero-extended into a normal 64-bit block.

  Retained `CCoinsMap` entries identify real transaction outputs, so their keys contain computed txids.
  Missing-input validation may probe arbitrary claimed prevouts, but `FetchCoin()` immediately erases their temporary entries when the backend lookup fails, so non-hash keys cannot accumulate.
  The assumeutxo loader assumes snapshot txids are valid while loading and verifies the complete snapshot's content hash before activation.
  Every entry in the temporary earlier-txid set is a computed transaction hash, and the set is bounded by the block's transaction count.

  This construction is limited to local hash tables and is not a general-purpose or protocol SipHash replacement.
  Pieter discussed the construction with [SipHash co-author Jean-Philippe Aumasson](https://github.com/bitcoin/bitcoin/pull/35215#issuecomment-4385336928), whose preliminary analysis did not find an easier collision construction and supported SipHash-1-3 for this hash-table use.

  <img width="2100" height="860" alt="siphash_compare_updated" src="https://github.com/user-attachments/assets/cefec6f8-5ec0-450a-a0a2-f946de9ef36d" />

  **Structure:** Shared vectors first cover the existing generic and fixed SipHash-2-4 paths in C++, the generic path in Python, and their randomized equivalence in the fuzzer.
  A behavior-neutral refactor then moves the round, compression, and finalization logic into inline `SipHashState` methods; assembly inspection shows that the fixed-width paths retain their instruction counts, while the generic byte loop retains its prior code generation through a local state copy.
  Three Pieter-authored commits add the generic UJ specification, fixed-width implementation, and shared correctness coverage.
  Benchmarks follow that coverage, then separate commits change `CCoinsMap`'s hasher and reuse it for the temporary earlier-txid set.

  **Tests:** The shared JSON supplies the same byte sequences to the generic C++ and Python SipHash-2-4 implementations, with applicable fixed-width paths checked against the same expected output.
  The SipHash-2-4 rows include the 64 official vectors for inputs from 0 to 63 bytes and cases that vary input chunking.
  The UJ outputs were generated by an independent implementation and are checked using normal blocks, equivalent zero-extended jumbo blocks, and applicable fixed-width `Hash` overloads.
  The integer fuzzer extends these comparisons to arbitrary values and mixed normal/jumbo block encodings.

  [Counting the dbcache buckets](https://gist.github.com/l0rinc/d68f56c3ed89f76f56da6632ef6f2d92) indicates the new outpoint hasher retains the uniform bucket distribution expected by `CCoinsMap`:
  <img width="1200" height="750" alt="ccoinsmap-collisions" src="https://github.com/user-attachments/assets/eeedec81-acdc-4adf-a9c8-bfce089700da" />

  **Benchmarks:** Fixed-width microbenchmarks compare SipHash-2-4 with SipHash-1-3-UJ for 32-byte hashes and inputs containing a 32-byte hash plus a 32-bit index.
  Reported aarch64 measurements and an [independent x86_64 run](https://github.com/bitcoin/bitcoin/pull/35215#issuecomment-4400609637) show the outpoint path is about 2x faster.
  <details><summary>Benchmark runner</summary>

  ```bash
  for COMPILER in gcc clang; do \
    if [ "$COMPILER" = gcc ]; then CC=gcc; CXX=g++; else CC=clang; CXX=clang++; fi; \
    cmake -B "build-bench-$COMPILER" -DCMAKE_BUILD_TYPE=Release -DBUILD_BENCH=ON -DBUILD_TESTS=OFF -DBUILD_GUI=OFF -DENABLE_WALLET=OFF -DCMAKE_C_COMPILER="$CC" -DCMAKE_CXX_COMPILER="$CXX" >/dev/null 2>&1 && \
    cmake --build "build-bench-$COMPILER" --target bench_bitcoin -j"$(nproc)" >/dev/null 2>&1 && \
    echo "" && echo "$(date -I) | SipHash fixed-width microbench | $("$CXX" --version | head -1) | $(hostname) | $(uname -m) | $(lscpu | awk -F: '/Model name/{print $2; exit}' | xargs) | $(nproc) cores | $(free -h | awk '/^Mem:/{print $2}') RAM" && \
    "build-bench-$COMPILER/bin/bench_bitcoin" -filter='SipHash.*32b|SipHash.*36b' -min-time=10000; \
  done
  ```
  </details>

  A two-run GCC `-reindex-chainstate` comparison of the same `CCoinsMap` hot path through height 957,759 with `-dbcache=2000` on a Ryzen 7 3700X/SSD reduced mean wall time from 11,278 s to 10,759 s, a ~5% validation speedup.

ACKs for top commit:
  achow101:
    light ACK 3bfdcbd7ee
  sipa:
    ACK 3bfdcbd7ee (to the extent the code/ideas aren't my own)
  andrewtoth:
    ACK 3bfdcbd7ee
  optout21:
    ACK 3bfdcbd7ee

Tree-SHA512: c3c66051cb1ebdb0cddbc8b8bed2297c524842f92960531de23d9586c5bb950b302c33d06fc15c2320cbbf97273b22ec3f17fd0e7ddcc7df4a8132a47a606277
2026-07-21 15:43:03 -07:00
Lőrinc
af50ba8500 test: add shared SipHash vectors
Lock SipHash-2-4 behavior into shared vectors before refactoring its round and finalization code.
Store inputs as ordered hex byte blocks so `CSipHasher` and the independent Python implementation hash the same byte sequence, with applicable `PresaltedSipHasher` overloads checked against the same vectors.
Add the 64 official SipHash-2-4 vectors alongside block-partition and empty-block cases for the generic path.
Move randomized generic/fixed comparisons to the integer fuzzer.

SipHash-1-3-UJ coverage can add expected outputs for compatible 8- and 32-byte block sequences.
The Python test reads a build-tree copy so functional-test staging behaves consistently when files are symlinked or copied.

Co-authored-by: Pieter Wuille <pieter@wuille.net>
2026-07-17 20:09:58 -07:00
will
6eca11175b lint: remove E731 Ruff ignore
Replace assigned lambdas with local functions so Ruff can enforce E731.
For platform-specific immutable file cleanup, store the command as data
instead of creating conditional callbacks.
2026-07-16 10:29:58 +01: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
Matthew Zipkin
d1ed2a6e25 http: check rpcallowip immediately after accepting connection
Instead of sending 403 Forbidden, disconnect as soon as possible.

To facilitate unit testing, this commit includes a refactor
that moves the subnet allow list and relevant methods
into the HTTPServer class instead of file-scope static scope.
2026-07-08 11:29:26 -04: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
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
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
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
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
Hennadii Stepanov
f4a6d079c4 qa: Support get_bind_addrs and feature_bind_extra on illumos
This extends support for `get_bind_addrs` and `feature_bind_extra` to
illumos-based OSes.
2026-06-29 15:44:41 +01:00
Hennadii Stepanov
5d01aa4772 qa: Ignore lsof warnings on NetBSD
On NetBSD, `lsof` can produce the following warnings:
1. "created device cache file: ..." - usually happens in a CI
environment.
2. "compiled for NetBSD release 10.0; this is 10.1." or similar - when
the `lsof` binary package is installed on a point release.

This change suppresses both warnings printed to stderr and fixes the
affected tests.
2026-06-29 15:44:41 +01:00
Hennadii Stepanov
70352fda03 qa: Strip prefix length from NetBSD ifconfig output
Modern NetBSD `ifconfig` prints interface addresses in CIDR notation
(e.g. `inet 127.0.0.1/8`), unlike the other supported platforms which
print the netmask as a separate field. The trailing prefix length breaks
functional tests that expect a plain IP address.

This change is a no-op on other platforms.
2026-06-29 15:44:41 +01:00
Hennadii Stepanov
4cb7f39c2c qa: Drop OpenBSD from supported platforms in get_bind_addrs function 2026-06-29 15:44:40 +01:00
Hennadii Stepanov
8a982eea85 qa: Add skip_if_no_lsof_on_nonlinux helper and use it where needed
Some functional tests on non-Linux platforms rely on the `lsof` utility.
However, we treat all other functional test dependencies, such as
additional Python modules, as optional, and skip dependent tests if
those are unavailable.

This change makes `lsof` optional as well.
2026-06-29 15:44:34 +01: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
Ryan Ofsky
aa01721c89 test: add interface_gui.py to test bitcoin-gui startup via RPC
Adds a functional test that starts bitcoin-gui (via the bitcoin wrapper
with "gui" subcommand) using QT_QPA_PLATFORM=minimal for headless
operation, then verifies it responds to a stop RPC call. This catches
startup regressions in the GUI that have no CI coverage today.

Extends the test framework to support use_gui=True in TestNode, which
invokes "bitcoin gui" instead of "bitcoin node" and automatically sets
QT_QPA_PLATFORM=minimal. Adds BUILD_GUI to test/config.ini.in and
is_gui_compiled()/skip_if_no_gui() helpers to BitcoinTestFramework.

Co-Authored-By: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 13:39:16 -04: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
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
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
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
Vasil Dimov
9a8ef9b0a3 test: SOCKS5 proxy: expect that connection may be reset during handshake
The client (e.g. `bitcoind`) may open a connection to the proxy and
close it in the middle of the SOCKS5 handshake if it is restarted for
example. Log these as debug messages instead of full blown Python
exception error messages with backtraces.
2026-06-17 08:36:58 +02:00
Vasil Dimov
eb3208364a test: SOCKS5 proxy: expect that connection may be reset when forwarding
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.
2026-06-17 08:36:57 +02:00
rkrux
4dbaa7cc65 test: generalise byte_to_base58 utility function to allow more version types
Passing a version in the byte form is allowed now in addition to the integral
version type. This will be helpful in the next commit.
2026-06-16 20:37:17 +05:30
Sebastian Falbesoner
9fae7e9886 test: doc: remove --perf profiling from functional test framework
This feature was broken for more than a year and no developer apparently
even noticed, so one can conclude that it is largely unused; it seems
thus reasonable to remove it to reduce maintenance burden.
2026-06-13 22:59:23 +02:00
merge-script
142e86a65c Merge bitcoin/bitcoin#35458: qa: Avoid extra tracebacks when exception is raised
472b950b7f qa: Use custom assert_greater_than() over naked assert (Hodlinator)
f42226d526 qa: Silence socket.timeout exception when substituting it for a JSONRPCException (Hodlinator)
659671ac3d qa: Avoid cleanup when exception is raised (Hodlinator)

Pull request description:

  Clean up some cases in which we would trigger multiple tracebacks, which makes it unclear what issue is occuring (https://github.com/bitcoin/bitcoin/issues/31894#issuecomment-4616130031).

  CI log of this occurring: https://github.com/bitcoin/bitcoin/actions/runs/26907239657/job/79375388058?pr=35179

  <details><summary>Relevant log excerpt</summary>

  ```
   test  2026-06-03T19:28:28.119804Z TestFramework.node0 (DEBUG): TestNode.generate() dispatches `generate` call to `generatetoaddress`
   test  2026-06-03T19:28:28.120483Z TestFramework (ERROR): Unexpected exception:
                                     Traceback (most recent call last):
                                       File "/home/runner/work/bitcoin/bitcoin/test/functional/test_framework/authproxy.py", line 165, in _get_response
                                         http_response = self.__conn.getresponse()
                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^
                                       File "/usr/lib/python3.12/http/client.py", line 1448, in getresponse
                                         response.begin()
                                       File "/usr/lib/python3.12/http/client.py", line 336, in begin
                                         version, status, reason = self._read_status()
                                                                   ^^^^^^^^^^^^^^^^^^^
                                       File "/usr/lib/python3.12/http/client.py", line 297, in _read_status
                                         line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
                                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                       File "/usr/lib/python3.12/socket.py", line 707, in readinto
                                         return self._sock.recv_into(b)
                                                ^^^^^^^^^^^^^^^^^^^^^^^
                                     TimeoutError: timed out
                                     During handling of the above exception, another exception occurred:
                                     Traceback (most recent call last):
                                       File "/home/runner/work/bitcoin/bitcoin/ci_build/test/functional/p2p_orphan_handling.py", line 54, in wrapper
                                         func(self)
                                       File "/home/runner/work/bitcoin/bitcoin/ci_build/test/functional/p2p_orphan_handling.py", line 633, in test_maximal_package_protected
                                         testres = node.testmempoolaccept([large_orphan.serialize().hex()])
                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                       File "/home/runner/work/bitcoin/bitcoin/test/functional/test_framework/coverage.py", line 50, in __call__
                                         return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                       File "/home/runner/work/bitcoin/bitcoin/test/functional/test_framework/authproxy.py", line 128, in __call__
                                         response, status = self._request('POST', self.__url.path, postdata.encode('utf-8'))
                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                       File "/home/runner/work/bitcoin/bitcoin/test/functional/test_framework/authproxy.py", line 102, in _request
                                         return self._get_response()
                                                ^^^^^^^^^^^^^^^^^^^^
                                       File "/home/runner/work/bitcoin/bitcoin/test/functional/test_framework/authproxy.py", line 167, in _get_response
                                         raise JSONRPCException({
                                     test_framework.util.JSONRPCException: 'testmempoolaccept' RPC took longer than 30.000000 seconds. Consider using larger timeout for calls that take longer to return. (-344)  [http_status=None]
                                     During handling of the above exception, another exception occurred:
                                     Traceback (most recent call last):
                                       File "/home/runner/work/bitcoin/bitcoin/test/functional/test_framework/test_framework.py", line 143, in main
                                         self.run_test()
                                       File "/home/runner/work/bitcoin/bitcoin/ci_build/test/functional/p2p_orphan_handling.py", line 837, in run_test
                                         self.test_maximal_package_protected()
                                       File "/home/runner/work/bitcoin/bitcoin/ci_build/test/functional/p2p_orphan_handling.py", line 57, in wrapper
                                         self.generate(self.nodes[0], 1)
                                       File "/home/runner/work/bitcoin/bitcoin/test/functional/test_framework/test_framework.py", line 666, in generate
                                         blocks = generator.generate(*args, called_by_framework=True, **kwargs)
                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                       File "/home/runner/work/bitcoin/bitcoin/test/functional/test_framework/test_node.py", line 445, in generate
                                         return self.generatetoaddress(nblocks=nblocks, address=self.get_deterministic_priv_key().address, maxtries=maxtries, **kwargs)
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                       File "/home/runner/work/bitcoin/bitcoin/test/functional/test_framework/test_node.py", line 453, in generatetoaddress
                                         return self.__getattr__('generatetoaddress')(*args, **kwargs)
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                       File "/home/runner/work/bitcoin/bitcoin/test/functional/test_framework/coverage.py", line 50, in __call__
                                         return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                       File "/home/runner/work/bitcoin/bitcoin/test/functional/test_framework/authproxy.py", line 128, in __call__
                                         response, status = self._request('POST', self.__url.path, postdata.encode('utf-8'))
                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                       File "/home/runner/work/bitcoin/bitcoin/test/functional/test_framework/authproxy.py", line 101, in _request
                                         self.__conn.request(method, path, postdata, headers)
                                       File "/usr/lib/python3.12/http/client.py", line 1356, in request
                                         self._send_request(method, url, body, headers, encode_chunked)
                                       File "/usr/lib/python3.12/http/client.py", line 1367, in _send_request
                                         self.putrequest(method, url, **skips)
                                       File "/usr/lib/python3.12/http/client.py", line 1193, in putrequest
                                         raise CannotSendRequest(self.__state)
                                     http.client.CannotSendRequest: Request-sent
   test  2026-06-03T19:28:28.124908Z TestFramework (DEBUG): Closing down network thread
  ```

  </details>

  Fix in authproxy.py can be verified through applying the below diff with/without PR changes and running `./build/test/functional/p2p_orphan_handling.py`:

  ```diff
  --- a/test/functional/test_framework/authproxy.py
  +++ b/test/functional/test_framework/authproxy.py
  @@ -162,6 +162,8 @@ class AuthServiceProxy():
       def _get_response(self):
           req_start_time = time.time()
           try:
  +            if AuthServiceProxy.__id_count > 55:
  +                raise socket.timeout()
               http_response = self.__conn.getresponse()
           except socket.timeout:
               raise JSONRPCException({
  ```

ACKs for top commit:
  maflcko:
    review ACK 472b950b7f 🔼
  polespinasa:
    reACK 472b950b7f

Tree-SHA512: ec1ede0340da9d1338643980e7f2e4646f0aed2e64f339f8b41a447cbbfb4da8158c1cbcb22f2d0cc383c2dd945075602d02b07a47b33b44cc6215f3292c1d46
2026-06-12 10:51:47 +02:00
Anthony Towns
01b8a117d2 test_framework: BIP 434 support 2026-06-04 21:58:56 +10:00
Anthony Towns
6a129983c9 BIP434: FEATURE message support
BIP434 defines FEATURE messages which are sent between VERSION and VERACK
to indicate support for new P2P protocol features. This commit provides
the infrastructure for easily using BIP434 negotiation when implementing
such new P2P protocol features. Note that advertised protocol version
is bumped to 70017, as per BIP434's specification.
2026-06-04 21:58:56 +10:00
merge-script
47da4f9b71 Merge bitcoin/bitcoin#35410: net: use the proxy if overriden when doing v2->v1 reconnections
bf0d257c11 net: un-default the OpenNetworkConnection()'s proxy_override argument (Eugene Siegel)
5a3756d150 test: add a regression test for private broadcast v1 retries (Vasil Dimov)
ab35a028ed test: make reusable filling of a node's addrman (Vasil Dimov)
2333be9cbc test: make reusable starting a standalone P2P listener (Vasil Dimov)
2ffa81fac4 test: make reusable SOCKS5 server starting (Vasil Dimov)
32d072a49f doc: add release notes for #35319 (Vasil Dimov)
d01b461f71 net: ensure no direct private broadcast connections (Vasil Dimov)
fd230f942d net: use the proxy if overriden when doing v2->v1 reconnections (Vasil Dimov)

Pull request description:

  This PR includes https://github.com/bitcoin/bitcoin/pull/35319 and on top of that adds a regression functional test.

  The functional test exercises the relevant code paths without modifying non-test code. To do that it does:

  * Add a bunch of IPv4 addresses to the node's addrman (they will be added without P2P_V2 flag).
  * Get them to report P2P_V2 in their service flags and connect to each one, so that the flags
    in addrman are updated to contain P2P_V2.
  * Get one successful connection to a Tor peer (.onion) so that bitcoind assumes the configured
    Tor proxy works and is indeed a proxy to the Tor network. This will make it open private
    broadcast connections also to IPv4 addresses via that proxy.
  * Start some private broadcast connections.
  * Remember the destination IPv4 address of the first connection and get it to fail the v2
    transport.
  * Wait for a subsequent connection also through the Tor proxy to the same IPv4 and expect
    it to be v1, i.e. the v2->v1 downgrade retry.

  The test fails without the fix - the v1 retry never arrives to the Tor proxy. And passes with the fix. The fix is in the first commit here and in https://github.com/bitcoin/bitcoin/pull/35319, can remove it by `git show fd230f942d | git apply -R`.

ACKs for top commit:
  Crypt-iQ:
    reACK bf0d257c11
  andrewtoth:
    ACK bf0d257c11
  instagibbs:
    ACK bf0d257c11
  sedited:
    utACK bf0d257c11

Tree-SHA512: 11e89be36577199e0312e5e63efeac04e295faaba1cf1c13a30e683d35f473c8dbb419d1897b0333c2e993c10637adecafcf90fe08c812065c793cbc903744c9
2026-06-04 10:38:54 +01:00
Hodlinator
f42226d526 qa: Silence socket.timeout exception when substituting it for a JSONRPCException
This prevents "During handling of the above exception, another exception occurred:" and an extra traceback.
2026-06-04 10:40:03 +02:00
merge-script
a3dc44c085 Merge bitcoin/bitcoin#35385: test: restore JSONRPCException error format
ac09260982 test: restore JSONRPCException error format (rkrux)

Pull request description:

  This is a follow-up to PR #34575.

ACKs for top commit:
  maflcko:
    lgtm ACK ac09260982

Tree-SHA512: 15979f4e2c07993f283640ebfe570e9f8d3842a23a8118042f5b618273e0da8a01bcabe1ec90b6cc49ebf28e9819d1b4f077ac18f62f681a4d4f58ad8e11bdb1
2026-05-29 14:47:29 +01:00
rkrux
ac09260982 test: restore JSONRPCException error format
This is a follow-up to PR 34575.

Copy is done so that checking of error["code"] in test_node.py
while handling this exception doesn't fail.

Co-authored-by: maflcko <6399679+maflcko@users.noreply.github.com>
2026-05-29 17:03:15 +05:30
Vasil Dimov
ab35a028ed test: make reusable filling of a node's addrman
Extract the part of `p2p_private_broadcast.py` that fills a given node's
addrman and put it into `test_framework/test_framework.py`.
2026-05-29 12:52:36 +02:00
Vasil Dimov
2333be9cbc test: make reusable starting a standalone P2P listener
Extract the part of `p2p_private_broadcast.py` that starts
listening on a `P2PConnection` object (or its children classes)
and put it into `test_framework/p2p.py`.
2026-05-29 12:52:35 +02:00
Vasil Dimov
2ffa81fac4 test: make reusable SOCKS5 server starting
Extract the part of `p2p_private_broadcast.py` that configures and
starts the SOCKS5 server into a reusable function and put it into
`test_framework/socks5.py`.

Use bind port 0 to let the OS pick an available port instead of
hackishly assuming that `p2p_port(N)` is available where N is more
than the number of the nodes the test uses.
2026-05-29 12:52:34 +02:00
Ava Chow
d0a54dd8e0 Merge bitcoin/bitcoin#35381: wallet, test: optinrbf deprecation followups
f701cd159a doc: fix typo in release notes of #34917 (rkrux)
7bc39e3d08 wallet, test: add wallet_deprecated_rbf.py for walletrbf deprecated keys & options (rkrux)
2cbbcb5659 wallet, test: remove -deprecatedrpc=bip125 from wallet_send.py (rkrux)
307134bd7e wallet, test: remove -deprecatedrpc=bip125 from wallet_migration.py (rkrux)
3ec550d168 wallet, test: remove -deprecatedrpc=bip125 from wallet_basic.py (rkrux)
a52ea9bff9 wallet, test: remove -walletrbf startup option from wallet_backwards_compatibility.py (rkrux)
42330922dd wallet, test: remove -walletrbf startup option from wallet_backwards_compatibility.py (rkrux)
8cb6e405d8 wallet, test: remove -walletrbf startup option from wallet_listtransactions.py (rkrux)
0ee94b2fef wallet, test: remove -deprecatedrpc=bip125 from wallet_listtransactions.py (rkrux)
5e833e068d wallet, test: -walletrbf startup option from wallet_bumpfee.py (rkrux)
a2a2b1745f wallet, test: remove -walletrbf startup option from rpc_psbt.py (rkrux)
a3fe455a95 wallet: refactor to read -walletrbf only once instead of twice (rkrux)

Pull request description:

  Prerequisite to #35404 and #35405.

  All these changes address the points raised in the review of PR #34917
  here: https://github.com/bitcoin/bitcoin/pull/34917#pullrequestreview-4362148900.

  Essentially updating the existing wallet functional tests without using
  the -deprecatedrpc=bip125 and -walletrbf startup options. Instead,
  these two are added and tested via a singular new
  wallet_deprecated_rbf.py test that can be removed easily later when
  these startup options are completely removed from the wallet post
  deprecation.

ACKs for top commit:
  maflcko:
    review ACK f701cd159a  🌄
  achow101:
    ACK f701cd159a

Tree-SHA512: 700785062b5de8ee3b6c4f50570b769d56c6c4960f2b6e2a2e71be8085c6b51eaeb34fb158fae76f812fe82791aaa0c0277f964f0472cb0784b86caabe6d4ec9
2026-05-28 13:44:17 -07:00
Sjors Provoost
9784818442 mining: add getTransactionsByWitnessID() IPC method 2026-05-28 19:17:24 +02:00
Sjors Provoost
d282ae6883 mining: add getTransactionsByTxID() IPC method 2026-05-28 19:17:23 +02:00
rkrux
42330922dd wallet, test: remove -walletrbf startup option from wallet_backwards_compatibility.py 2026-05-27 17:45:06 +05:30
rkrux
a2a2b1745f wallet, test: remove -walletrbf startup option from rpc_psbt.py
Also, include PSBT_GLOBAL_FALLBACK_LOCKTIME key/value while making the PSBT v2
blank for combinepsbt RPC.
2026-05-27 17:43:44 +05:30
woltx
3962138cc0 test: add IPC submitBlock functional test
Test the new Mining.submitBlock IPC method:
- Invalid block (bad version) returns failure with reason
- Valid block (with a real mempool tx) is accepted and propagates
- Duplicate block returns failure with "duplicate" reason
- Witness commitment without coinbase witness nonce is rejected
  (bad-witness-nonce-size), confirming no auto-fix behavior
- submitBlock then submitSolution: duplicate is accepted (submitSolution
  returns true for already-known blocks)
- submitSolution then submitBlock interaction (duplicate)

Build candidate blocks from BlockTemplate data in the existing coinbase and
submission test, then exercise checkBlock(), submitSolution(), and
submitBlock() against those candidates. submitBlock() uses an isolated IPC
node for cases that would otherwise affect the main submitSolution() and
checkBlock() assertions.
2026-05-26 11:40:02 -07:00
Ryan Ofsky
a4157fc24a Merge bitcoin/bitcoin#33966: refactor: disentangle miner startup defaults from runtime options
1e5d3b4f0d doc: add release note for mining option validation (Sjors Provoost)
0317f52022 ci: enforce iwyu for touched files (Sjors Provoost)
8c58f63578 refactor: have mining files include what they use (Sjors Provoost)
3bb6498fb0 mining: store block create options in NodeContext (Sjors Provoost)
4637cd157d mining: reject invalid block create options (Sjors Provoost)
8daac1d6eb mining: add block create option helpers (Sjors Provoost)
128da7c3ff miner: add block_max_weight to BlockCreateOptions (Sjors Provoost)
fa81e51eae mining: parse block creation args in mining_args (Sjors Provoost)
020166080c mining: use interface for tests, bench and fuzzers (Sjors Provoost)
44082bea47 interfaces: make Mining use const NodeContext (Sjors Provoost)
d4368e059c move-only: add node/mining_types.h (Sjors Provoost)
6aeb1fbea2 test: cover IPC blockmaxweight policy (Sjors Provoost)
63b23ea1e9 test: regression test for waitNext mining policy (Sjors Provoost)
24750f8b31 test: add createNewBlock failure helper (Sjors Provoost)
63ee9cd15b test: misc interface_ipc_mining.py improvements (Sjors Provoost)

Pull request description:

  Although this PR is primarily a refactor, _there are behavior changes_ documented in the release note:
  - the IPC mining interface now rejects out-of-range block template options instead of silently clamping them;
  - startup now rejects `-blockmaxweight` values lower than `-blockreservedweight`, instead of allowing them to be clamped later.

  The interaction between node startup options like `-blockreservedweight` and runtime options, especially those passed via IPC, is confusing.

  They're combined in `BlockAssembler::Options`, which this PR gets rid of in favour of `BlockCreateOptions`.

  `BlockCreateOptions` is used by interface clients. As before, IPC clients have access to a safe / sane subset, whereas RPC and test code can use all fields. The same type is also used to store mining defaults parsed once during node startup in `NodeContext`.

  The maximum block weight setting (`block_max_weight`) is optional. When read from startup options it matches `-blockmaxweight`; when provided by callers it is a runtime override. `Merge()` fills unset fields from startup defaults while preserving caller-provided values.

  This all happens in commits `mining: add block create option helpers` and `mining: store block create options in NodeContext`, and requires some preparation to keep things easy to review.

  We get rid of `BlockAssembler::Options` but this is used in many tests. Since large churn is inevitable, we might as well switch all tests, bench and fuzzers over to the Mining interface. The `mining: use interface for tests, bench and fuzzers` commit does that, dramatically reducing direct use of `BlockAssembler`. Two exceptions are documented in the commit message. Because `test_block_validity` wasn't available via the interface and the block_assemble benchmark needs it, it's moved from `BlockAssembler::Options` to `BlockCreateOptions` (still not exposed via IPC).

  We need access to mining related structs from both the miner and node initialization code. To avoid having to pull in all of `BlockAssembler` for the latter, the `move-only: add node/mining_types.h` commit introduces `node/mining_types.h` and moves `BlockCreateOptions`, `BlockWaitOptions` and `BlockCheckOptions` there from `src/node/types.h`.

  I considered also moving `DEFAULT_BLOCK_MAX_WEIGHT`, `DEFAULT_BLOCK_RESERVED_WEIGHT`, `MINIMUM_BLOCK_RESERVED_WEIGHT` and `DEFAULT_BLOCK_MIN_TX_FEE` there from `policy.h`, since they are distinct from relay policy and not needed by the kernel. But this seems more appropriate for a follow-up and requires additional discussion.

  ---

  I kept variable renaming and other formatting changes to a minimum to ease review with `--color-moved=dimmed-zebra`.

  ## Commit summary

  Tests and test cleanup:
  - `test: misc interface_ipc_mining.py improvements`
  - `test: add assert_create_fails helper`
  - `test: regression test for waitNext mining policy`
  - `test: cover IPC blockmaxweight policy`

  Refactoring test/bench/fuzz callers:
  - `interfaces: make Mining use const NodeContext`
  - `mining: use interface for tests, bench and fuzzers`

  Moving mining interface types:
  - `move-only: add node/mining_types.h`

  Separating startup defaults from runtime options:
  - `mining: parse block creation args in mining_args`: adds `node/mining_args.{h,cpp}` and moves mining option parsing out of `init.cpp`, without storing the parsed values yet.
  - `miner: add block_max_weight to BlockCreateOptions`: moves the runtime maximum block weight setting into `BlockCreateOptions` as an optional value, so it can later be defaulted from startup args when unset.
  - `mining: add block create option helpers`: centralizes block template option defaulting and merging, removes `BlockAssembler::Options`, and preserves behavior except for dropping the `Specified ` prefix from startup option error messages.
  - `mining: reject invalid block create options`: checks typed `BlockCreateOptions` before block template creation, so invalid runtime options are rejected instead of silently clamped. Startup validation also rejects `-blockmaxweight` values lower than `-blockreservedweight`.
  - `mining: store block create options in NodeContext`: stores the startup mining options in `NodeContext` as `BlockCreateOptions`, so startup defaults and runtime overrides can be merged with the same option type.

  Include hygiene, CI and release note:
  - `refactor: have mining files include what they use`
  - `ci: enforce iwyu for touched files`
  - `doc: add release note for mining option validation`

ACKs for top commit:
  w0xlt:
    reACK 1e5d3b4f0d
  sedited:
    ACK 1e5d3b4f0d
  ryanofsky:
    Code review ACK 1e5d3b4f0d. Looks good, thanks for the updates!

Tree-SHA512: 28c715023cb78f02775caa787b243c994bd0f8ce4559afc8db9301e93400ebbc74963626a4afe65ae15bcc16b9192d051a745839f4c804848d50746ea5a224b4
2026-05-26 08:39:03 -04:00