Commit Graph

48264 Commits

Author SHA1 Message Date
Vasil Dimov
6c08cb7323 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`.

Github-Pull: #35410
Rebased-From: ab35a028ed
2026-06-19 18:47:09 +02:00
Vasil Dimov
70a8687d9d 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`.

Github-Pull: #35410
Rebased-From: 2333be9cbc
2026-06-19 18:47:09 +02:00
Vasil Dimov
ef20249568 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.

Github-Pull: #35410
Rebased-From: 2ffa81fac4
2026-06-19 18:47:08 +02:00
Vasil Dimov
66377c3c84 net: ensure no direct private broadcast connections
Private broadcast connections use either Tor or I2P, which require a
proxy intrinsically or IPv4 or IPv6 which must use a proxy in the
context of private broadcast to avoid leaking the originator's IP
address.

Add a safety check to guard against future mistakes.

Co-authored-by: Andrew Toth <andrewstoth@gmail.com>

Github-Pull: #35410
Rebased-From: d01b461f71
2026-06-19 18:47:08 +02:00
Vasil Dimov
2c7986b3ee net: use the proxy if overriden when doing v2->v1 reconnections
`OpenNetworkConnection()` supports overriding the proxy to use for
connecting. However when v2 connection is attempted and it fails a v1
connection is tried without that proxy.

Store the override proxy in `CNode` and pass it to
`CConnman::m_reconnections` to be used for v1 retries.

Github-Pull: #35410
Rebased-From: fd230f942d
2026-06-19 18:47:08 +02:00
will
70000a560b ci: use Warp cache for Docker layers
Speeds of 1MB/s and 15 minute cached docker image pulls during builds
are not uncommon.

Warp runners provide a local GitHub Actions cache protocol proxy for
Docker layer cache traffic. Point BuildKit's gha cache backend at that
proxy on Warp runners so cached image layers do not have to be fetched
from GitHub's slower cache service.

Add a default for provider so other users (e.g. qa-assets) don't have to
update this unless they use custome runners.

Github-Pull: #35447
Rebased-From: 82901981bf
2026-06-19 18:47:08 +02:00
will
25506ed6d9 ci: Add dynamic cache switching to warp cache
The GHA cache is very slow, taking on the order of minutes to save and
restore from.

Use WarpBuild's cache instead as this is in the same region and much
faster.

WarpBuild cache action does not auto-fallback to GHA if not being run on
Warp. To allow fork runs to fallback to GHA caching, whilst minimising
duplication in the action files, create new "interal" actions which
perform the switching logic, and use these in the (renamed) cache|save
actions.

Without this we would need the `if` logic in our prvious actions, 4
times in each of save and restore.

Plumb the provider through into the action, as a composite action can't
read `env` (`GITHUB_OUTPUT`) from previous steps.

Github-Pull: #35430
Rebased-From: 2ce4ae7d8f
2026-06-19 18:47:08 +02:00
fanquake
39f8e077c8 ci: use ubuntu-latest instead of ubuntu-24.04
To match the usage of -latest for the warp runners.

Github-Pull: #35408
Rebased-From: 5700a61b73
2026-06-19 18:47:08 +02:00
fanquake
1f55b3e463 doc: remove reference to cirrus
Github-Pull: #35408
Rebased-From: 265563bf75
2026-06-19 18:47:08 +02:00
deadmanoz
8f13bb1ea0 crypto: disable ASan instrumentation of SSE4 SHA256 for GCC
The existing Clang-only no_sanitize("address") guard is extended to
also cover GCC.  When GCC compiles this file with -fsanitize=address
in debug builds, the instrumented inline assembly causes a SEGV during
SHA256AutoDetect()'s self-test on CPUs that use the SSE4 code path
(i.e. those without SHA-NI support), regardless of optimization level.

The original Clang code placed the attribute between the function
declarator and the opening brace.  GCC's Attribute Syntax
documentation notes that this position in a function definition
"may, in future, be permitted," so it is not currently supported.
The attribute is moved to the start of the function definition,
which is valid form for both GCC and Clang.

The preprocessor guards are restructured so each compiler branch is
explicit: __clang__ with __has_feature, and __GNUC__ with
__SANITIZE_ADDRESS__.

Github-Pull: #34953
Rebased-From: fedeff7f20
2026-06-19 18:47:08 +02:00
will
6caf6de0a1 ci: switch runners from cirrus to warpbuild
Github-Pull: #35378
Rebased-From: 4bdd46ace3
2026-06-19 18:47:07 +02:00
Andrew Toth
78714f6d4f Disable seek compaction
Seek compaction is causing a cascade effect in the chainstate DB, causing large parts of the database to be rewritten every ~hour.

Every periodic flush writes around 2 MiB. Since this is roughly the `write_buffer_size`, these writes regularly cause the memtable to rotate into a small L0 file. This file has a small seek budget, and with the random UTXO reads done during validation, it can get scheduled for seek compaction quickly.

That seek compaction pushes the small file down to L1. Since most UTXOs are already lower down in L4/L5, many reads that consult this file do not find the key there and continue downward. The bloom filter makes those misses cheap, but LevelDB still decrements the file's seek budget. The file then gets scheduled for another seek compaction, and the same pattern pushes it down through L2 and L3.

The expensive part happens around L3/L4. L4 has many ~32 MiB files holding the bulk of the UTXO set. When LevelDB compacts into L3, it may split the output into many smaller L3 files to limit how much L4 "grandparent" data any one output overlaps. Each of these small L3 files then gets its own small seek budget. Because chainstate keys are hash-random, each small L3 file can still have a broad key range, so many random reads consult it and quickly drain its budget. Once seek-compacted into L4, each tiny L3 file can overlap many L4 files, so compacting a few hundred KiB from L3 can require rewriting hundreds of MiB from L4. Repeating that across many small L3 files can rewrite most of the chainstate.

This is a poor fit for chainstate because UTXO keys are hash-random, the DB is large enough to have many levels, writes are relatively small and periodic, and reads are frequent. The result is that read misses trigger compactions much earlier than size pressure would, and those compactions have very high write amplification.

Disabling seek compaction may leave more files in upper levels for longer, so reads could theoretically consult more files. But Bitcoin Core enables bloom filters for all its LevelDB instances, so these misses are usually cheap in-memory filter checks rather than disk reads.

For the other DBs, the risk is much smaller. They also use bloom filters, and most are smaller and less read-heavy. With fewer levels and less random read pressure, disabling seek compaction should have little effect there.

Co-authored-by: l0rinc <pap.lorinc@gmail.com>

Github-Pull: #35313
Rebased-From: 6bfdb6093bba4710d0f8313ed0113967a8b5176f
2026-06-19 18:46:55 +02:00
willcl-ark
3440027b7d ci: switch to GitHub cache for all runners
Cirrus is winding down and github now offers more than 10GB cache.

Switch to GH cache for all runner-types. Simplify docker build arg
construction, and reduce the number of needed action permissions.

Github-Pull: #35348
Rebased-From: c03107acf5
2026-05-22 13:48:09 +01:00
nervana21
d61687a2ac musig: Reject empty pubkey list in GetMuSig2KeyAggCache
Github-Pull: #35316
Rebased-From: 8ce84321ce
2026-05-22 10:41:23 +01:00
Lőrinc
671e6c2c33 wallet: use outpoint when estimating input size
`CalculateMaximumSignedInputSize()` is passed the outpoint being sized, but that context was not used when estimating the signed input size.
Pass the outpoint through so externally selected inputs are not underestimated.

Co-authored-by: Antoine Poinsot <darosior@protonmail.com>

Github-Pull: #35228
Rebased-From: cd8d3bd937
2026-05-20 15:26:47 +01:00
rkrux
101071722e psbt, test: remove address type restrictions in test
Because the corresponding Taproot fields were added in PSBT in PR 22558, so
these restrictions are no longer necessary.

Github-Pull: #35279
Rebased-From: 81348576cc
2026-05-20 14:00:43 +01:00
merge-script
dbaf0f4fd3 Merge bitcoin/bitcoin#35231: [31.x] Backports
506051cc60 doc: update release notes for v31.x (fanquake)
0449061877 contrib: Fix NameError in signet miner gbt() (Torkel Rogstad)
7a97580997 fuzz: Fix txorphan timeout by limiting block weight (marcofleon)
e379148a7a doc: mention -DWITH_ZMQ=ON in BSD build guides (junbyjun1238)
409b2d8475 wallet: check BDB last page LSN (Lőrinc)
5022e9d411 test: fix P2SH output in coins cache fuzz (Lőrinc)
313a225fef ci: Move --usecli --extended from i386 task to alpine task (MarcoFalke)
64ba4e2a3b depends: Unset `SOURCE_DATE_EPOCH` in `gen_id` script (Hennadii Stepanov)
56190e5c5c ci: add --extended when using --usecli (Pol Espinasa)
9d42e868fe test: fix send_batch_request to pass callables when using --usecli (Pol Espinasa)

Pull request description:

  Backports
  * #34228
  * #34991
  * #35044
  * #35218
  * #35227
  * #35230
  * #35283
  * #35289

ACKs for top commit:
  marcofleon:
    ACK 506051cc60
  willcl-ark:
    ACK 506051cc60

Tree-SHA512: 7c0b5294ccfcd210d78c21218d5e811dfa06c13ea3d5b9e4daffa397f1ea02e463fe53503900f6c330d104f407d07b4f95cb3d33a73c064da5a8acae21c7b3c1
2026-05-19 16:30:28 +01:00
fanquake
506051cc60 doc: update release notes for v31.x 2026-05-15 13:51:47 +01:00
Torkel Rogstad
0449061877 contrib: Fix NameError in signet miner gbt()
The logging.warning call referenced `bci["bestblockhash"]`, a variable
from the calling scope `do_generate()` that is not available inside the
`Generate.gbt()` method. This would crash with a NameError when
getblocktemplate returned a template based on an unexpected previous
block.

Use the `bestblockhash` parameter that was already being passed in and
used correctly in the comparison on the line above.

The bug was introduced in 7b31332370 when the gbt logic was extracted
into its own method — the if-condition was updated but the logging
call was not.

Github-Pull: #35044
Rebased-From: 701bc2dc02
2026-05-15 13:50:38 +01:00
marcofleon
7a97580997 fuzz: Fix txorphan timeout by limiting block weight
Github-Pull: #35289
Rebased-From: 004a7e3cfb
2026-05-14 16:48:52 +01:00
junbyjun1238
e379148a7a doc: mention -DWITH_ZMQ=ON in BSD build guides
The FreeBSD, NetBSD, and OpenBSD build guides state that ZMQ support is compiled in when the package is installed. Since WITH_ZMQ defaults to OFF, update the wording to mention the required CMake option.

Github-Pull: #35283
Rebased-From: ca93ab808c
2026-05-14 12:12:53 +01:00
Lőrinc
409b2d8475 wallet: check BDB last page LSN
The BDB metadata field `last_page` stores the last valid page number, not the number of pages.
The read-only wallet migration parser currently checks reset LSNs with a half-open loop, so it skips the final page and may accept a database whose last page still depends on BDB log files.

Github-Pull: #35227
Rebased-From: e2b0984f99
2026-05-11 11:23:08 +01:00
Lőrinc
5022e9d411 test: fix P2SH output in coins cache fuzz
The `coinscache_sim` fuzz target builds a 23-byte P2SH scriptPubKey manually.
Place `OP_EQUAL` at index 22, after `OP_HASH160`, the 20-byte push opcode, and the 20-byte script hash.
This matches `CScript::IsPayToScriptHash()`, which checks byte 22 for `OP_EQUAL`, see src/script/script.cpp#L229

Github-Pull: #35218
Rebased-From: ac58e6c53c
2026-05-08 15:49:45 +02:00
MarcoFalke
313a225fef ci: Move --usecli --extended from i386 task to alpine task
Github-Pull: #35230
Rebased-From: fad61896e8
2026-05-08 15:49:40 +02:00
Hennadii Stepanov
64ba4e2a3b depends: Unset SOURCE_DATE_EPOCH in gen_id script
Github-Pull: #34228
Rebased-From: 9f7a2293c4
2026-05-08 12:12:47 +02:00
Pol Espinasa
56190e5c5c ci: add --extended when using --usecli
Add the flag --extended to a test (00_setup_env_i686_no_ipc.sh) with the --usecli flag to cover all tests with --usecli.

Github-Pull: #34991
Rebased-From: a49bc1e24e
2026-05-07 11:42:24 +02:00
Pol Espinasa
9d42e868fe test: fix send_batch_request to pass callables when using --usecli
send_batch_request() was building raw dicts without a "jsonrpc" version, which made Core to treat them as version 1.0 requests.
This worked in normal mode, but failed with --usecli because TestNodeCLI.batch() expects callables, not dicts.

This commit fixes it by using get_request() which is defined in both AuthServiceProxy and TestNodeCLIAttr.
The assert is changed because by using get_reques() AuthServiceProxy treats it as "jsonrpc" version 2.0 requests, which don't return "error" keys.

Github-Pull: #34991
Rebased-From: 5603ae0ffa
2026-05-07 11:42:24 +02:00
merge-script
24bfb2c8be Merge bitcoin/bitcoin#35210: [31.x] validation: correct lifetime of precomputed tx data
0cedd6abf2 validation: correct lifetime of precomputed tx data (Antoine Poinsot)

Pull request description:

  This backports #35209 to the version 31 branch.

ACKs for top commit:
  fanquake:
    ACK 0cedd6abf2

Tree-SHA512: 12e3b73c5e2e5b49d9abd9d3dcf9aee98f98fcaa1d9f05ae8fe4e7d19bef5a22dad0eafd51acf9720b215c4d166dae2931a45528ac362e5cdb953c690febea96
2026-05-07 11:41:38 +02:00
Ava Chow
42800d93a4 Merge bitcoin/bitcoin#35046: [31.x] Backports
6bb2b07587 doc: update release notes for v31.x (fanquake)
1bb9c40bb8 ci: unconfine seccomp for i686 no IPC (Lőrinc)
2eafae9dc1 multi_index: fix compilation failure with boost >= 1.91 (Cory Fields)
ab19213660 test: Remove unused, confusing and brittle connect_nodes.wait_for_connect (MarcoFalke)
bb536df042 test: Fix all races after a socket is closed gracefully (MarcoFalke)
402f347fd5 test: Stricter checks in rpc_setban.py (MarcoFalke)
332d2a2ef2 test: Add is_connected_to helper (MarcoFalke)
e1545b56b9 test: Add clean shutdown to Socks5Server (optout)
20480f5eb9 test: Add missing self.options.timeout_factor scale in tool_bitcoin_chainstate.py (MarcoFalke)
27e5a3020a net_processing: don't modify addrman for private broadcast connections (Vasil Dimov)

Pull request description:

  Backports:
  * #34425
  * #34863
  * #35032
  * #35080
  * #35175
  * #35202

ACKs for top commit:
  achow101:
    ACK 6bb2b07587

Tree-SHA512: ea6827e7a1643f96e27ab5f26621f9d4c137df2cb03938d96f7bee82d11f66a61757c609a604653469a4699b3417a1659395d039bbf4348988c2ea4a34a26418
2026-05-06 03:47:37 -07:00
fanquake
6bb2b07587 doc: update release notes for v31.x 2026-05-05 15:14:45 +02:00
Lőrinc
1bb9c40bb8 ci: unconfine seccomp for i686 no IPC
Docker 29.4.2 blocks `socketcall(2)` in the default seccomp profile:
https://docs.docker.com/engine/release-notes/29/#2942
https://github.com/moby/profiles/releases/tag/seccomp%2Fv0.2.2
https://github.com/moby/moby/pull/52501

That affects the `i686, no IPC` job because it runs 32-bit Linux test binaries inside Docker.

Add Docker's documented `--security-opt seccomp=unconfined` workaround to this job's `CI_CONTAINER_CAP` - the hook `ci/test/02_run_container.py` already appends to `docker run`.

This restores socket availability for the 32-bit test binaries throughout the job:
https://docs.docker.com/engine/security/seccomp/#run-without-the-default-seccomp-profile

Github-Pull: #35202
Rebased-From: 11c9ef92a8
2026-05-05 15:14:26 +02:00
Antoine Poinsot
0cedd6abf2 validation: correct lifetime of precomputed tx data
This makes sure `txsdata` always outlives the Script check queue (since local
objects are destructed in reverse order of construction).

This is the root cause for a security vulnerability reported by Cory Fields in
2024 that could be exploited by crafting an invalid block to cause nodes to
read freed memory. The vulnerability was covertly fixed in commit
`492e1f09943fcb6145c21d470299305a19e17d8b`.

See security advisory for CVE-2024-52911 for more details.

Github-Pull: #35209
Rebased-From: 1ed799fb21
2026-05-05 08:16:02 -04:00
Cory Fields
2eafae9dc1 multi_index: fix compilation failure with boost >= 1.91
This effectively reverts a3cb309e7c from PR #30194.

That PR reduced the multi_index type signatures as recommended upstream, but
this is no longer supported as of boost 1.91 because it is no longer necessary.
1.91 drops support for the pre-c++11 work-arounds that bloated the type
signatures to begin with.

The upstream `BOOST_MULTI_INDEX_ENABLE_MPL_SUPPORT` define is meant to provide
compatibility with removed features, but it does not work for this case. Using
`indexed_by` directly when defining the `multi_index` (as opposed to inheriting
from it) works with all versions, and avoids the use of the back-compat define.

This is a slight regression when building against boost < 1.91 because the
bloated type signatures are reintroduced in that case, but it's not significant
enough to go to the trouble of introducing version detection and ifdefs.

Github-Pull: #35175
Rebased-From: 0bc9d354df
2026-04-29 19:51:43 +01:00
MarcoFalke
ab19213660 test: Remove unused, confusing and brittle connect_nodes.wait_for_connect
The option is unused since the last removals in:
* 4c40a923f0, and
* 81bf3ebff7

It was brittle and lead to intermittent test issues. Generally, it is
also confusing, because if a test wanted to connect nodes without
checking their connection, it can use `addnode`, like the rpc_setban.py
test.

So fix all issues by removing it.

Github-Pull: #34425
Rebased-From: fae807ed25
2026-04-21 11:24:06 +01:00
MarcoFalke
bb536df042 test: Fix all races after a socket is closed gracefully
This waits for any disconnect (e.g. from a restart of one of the nodes)
to fully happen before the next connect.

Can be reviewed with the git option:

--color-moved=dimmed-zebra

Github-Pull: #34425
Rebased-From: fab2772647
2026-04-21 11:24:03 +01:00
MarcoFalke
402f347fd5 test: Stricter checks in rpc_setban.py
Make the checks stricter and easier to follow:
* Fix a typo.
* After the first ban from node 1 wait until node 0 "sees" the ban.
* Move the restart_node out of the debug log context, to avoid bloat.
* Removed the timeout from the outer/lower exit stack to check "dropped
  (banned)\n" on node 1, because the inner/top exit stack waits longer.
* The inner/top exit stack checks for the both disconnections peer=2 and
  possibly peer=3 (for v2->v1 retry).
* And finally, add a redundant assert to confirm once more that node 0
  is has "seen" the ban.

Github-Pull: #34425
Rebased-From: fa21edddb2
2026-04-21 11:24:00 +01:00
MarcoFalke
332d2a2ef2 test: Add is_connected_to helper
Needed in the next commit.

Co-Authored-By: David Gumberg <davidzgumberg@gmail.com>

Github-Pull: #34425
Rebased-From: faa404e119
2026-04-21 11:23:56 +01:00
optout
e1545b56b9 test: Add clean shutdown to Socks5Server
The `Socks5Server` utility handles multiple incoming connections,
which are handled in separate background threads.
The `stop()` method unblocks and waits for the main background thread
cleanly, but it doesn't attempt to wait for any handler threads.
This change stores handler threads and connections, and attempts
to shut them down before `stop()` returns.

Co-authored-by: vasild <vd@FreeBSD.org>
Co-authored-by: w0xlt <94266259+w0xlt@users.noreply.github.com>

Github-Pull: #34863
Rebased-From: 6ac49373aa
2026-04-21 11:07:37 +01:00
MarcoFalke
20480f5eb9 test: Add missing self.options.timeout_factor scale in tool_bitcoin_chainstate.py
Apply the timeout factor inside the add_block function.

Also, force named args for the two expected strings.

Also, add trailing comma for style.

Github-Pull: #35080
Rebased-From: fa02eb87df
2026-04-16 09:10:24 +01:00
Vasil Dimov
27e5a3020a net_processing: don't modify addrman for private broadcast connections
It is best if the internal addrman database is not modified with
information coming from private broadcast connections because that
information can potentially later be sent via other connections.

Co-authored-by: Greg Sanders <gsanders87@gmail.com>
Co-authored-by: Lőrinc <pap.lorinc@gmail.com>

Github-Pull: #35032
Rebased-From: 1ed1a12402
2026-04-16 09:10:22 +01:00
Ava Chow
6574cb4086 Merge bitcoin/bitcoin#35042: [31.x] Finalize 31.0
e9f1466155 doc: 31.0 release notes (Ava Chow)
6a25f3e3d4 doc: update manpages for v31.0 (Ava Chow)
bd40a32411 build: Bump to 31.0 (Ava Chow)

Pull request description:

  Final steps for 31.0, assuming rc4 has no major issues.

ACKs for top commit:
  hebasto:
    ACK e9f1466155.
  janb84:
    ACK e9f1466155

Tree-SHA512: 1d712ee30f28df62c3c5cee8c2369c55b31a015b8184dbbc2a6fcfd887519c79970b257f8325b8d8bb61610c8dc92b64439de24cc35e31761fb737059c99a107
v31.0
2026-04-15 13:55:24 -07:00
Ava Chow
e9f1466155 doc: 31.0 release notes 2026-04-14 09:22:57 -07:00
Ava Chow
6a25f3e3d4 doc: update manpages for v31.0 2026-04-09 11:38:53 -07:00
Ava Chow
bd40a32411 build: Bump to 31.0 2026-04-09 11:36:14 -07:00
merge-script
c96d9c28b3 Merge bitcoin/bitcoin#35034: [31.x] Fix guix build and rc4
4a5fdb0d88 doc: update manpages for v31.0rc4 (Ava Chow)
7d56e1017d build: bump version to v31.0rc4 (Ava Chow)
2937d4ba41 guix: Restore download and build-system-cmake modules (Ava Chow)

Pull request description:

  Restoring missing guix modules required for guix building to work, and bump to rc4.

ACKs for top commit:
  davidgumberg:
    ACK 4a5fdb0d88
  hebasto:
    ACK 4a5fdb0d88, the Guix manifest has been processed for `x86_64-w64-mingw32` without errors on my machine.

Tree-SHA512: e7bbf17fc761b926fedea076b85a103e146c22d6dbad645ab087472daa78d8728dcfacf49103bb979652144da74e94e7e5878e05c9ef04b101ce96b234689ddb
v31.0rc4
2026-04-09 07:21:41 +08:00
Ava Chow
4a5fdb0d88 doc: update manpages for v31.0rc4 2026-04-08 11:59:09 -07:00
Ava Chow
7d56e1017d build: bump version to v31.0rc4 2026-04-08 11:54:46 -07:00
Ava Chow
2937d4ba41 guix: Restore download and build-system-cmake modules
The time-machine commit in 31.x still requires these modules for the
build to work.
2026-04-08 11:52:56 -07:00
merge-script
cc14d7ad3e Merge bitcoin/bitcoin#35028: [31.x] Backports + rc3
c168baec80 doc: update manual pages for v31.0rc3 (fanquake)
275843f2a6 build: bump version to v31.0rc3 (fanquake)
afa8ba04e0 test: remove macOS REDUCE_EXPORTS exception workaround (Alfonso Roman Zubeldia)
1bc22a38a8 Squashed 'src/ipc/libmultiprocess/' changes from 70f632bda8..3edbe8f67c (fanquake)

Pull request description:

  Backports:
  * #35014

  Also contains a libmultiprocess subtree pull.
  Also bumps to `rc3` + regens manpages.

ACKs for top commit:
  Sjors:
    utACK c168baec80
  hebasto:
    ACK c168baec80.
  marcofleon:
    ACK c168baec80

Tree-SHA512: 88aaef85a6ce6018fe5233d5a4a46d75c57914af9ff41158b85533ddf5e42df45ed7f6cbfdbffe2c4d2db6853af1ff4473440ab5ecc62c9cadf070f5cdcab883
v31.0rc3
2026-04-08 20:04:06 +08:00
fanquake
c168baec80 doc: update manual pages for v31.0rc3 2026-04-08 11:31:14 +08:00