Commit Graph

29568 Commits

Author SHA1 Message Date
Hennadii Stepanov
41bf8f2d5e Merge bitcoin-core/gui#877: Add a menu action to restore then migrate a legacy wallet
14371fd1fc gui: Add a menu item to restore then migrate a wallet file (Ava Chow)
f11a7d248c gui: Add restore_and_migrate function to restore then migrate a wallet (Ava Chow)
16ab6dfc10 gui: Move actual migration part of migrate() to its own function (Ava Chow)
4ec2d18a07 wallet, interfaces, gui: Expose load_after_restore parameter (Ava Chow)

Pull request description:

  Some users will have a backup of their legacy wallet. These cannot be restored since the "Restore Wallet" action expects to be able to load the wallet after restoring, and this fails for legacy wallets now that they are deleted. Furthermore, the "Migrate Wallet" action only allows users to migrate wallets that are in the wallets directory, so such backups cannot be migrated from the GUI.

  This PR resolves this issue by adding a menu item in the "Migrate Wallet" menu which allows users to select their backup file so that it will first be restored but not loaded, and then migrated.

  Depends on https://github.com/bitcoin/bitcoin/pull/32620

ACKs for top commit:
  hebasto:
    ACK 14371fd1fc.

Tree-SHA512: 2b09c012f4c70d0cb283305bf3d1a18ae5a2bfb80977c91544ac1fbc29d6360df49438cfdc8f66661ddb42ddab728c8ef1f9e0d7031877fbd846f9cea957398e
2025-12-15 15:42:40 +00:00
merge-script
2210feb446 Merge bitcoin/bitcoin#34051: log: Remove brittle and confusing LogPrintLevel
fa8a5d215c log: Remove brittle and confusing LogPrintLevel (MarcoFalke)
fac24bbec8 test: Clarify logging_SeverityLevels test (MarcoFalke)
f273167661 ipc: separate log statements per level (stickies-v)
94c51ae540 libevent: separate log statements per level (stickies-v)

Pull request description:

  `LogPrintLevel` has many issues:

  * It encourages to log several levels in one source location. This is problematic, because all levels (even warnings and errors) will be rate limited equally for the same location.
  * Its warning and error logs are specially formatted compared to all other warning and error logs in the codebase, making them harder to spot (both in the debug log and in the code).
  * It is verbose to type and read.
  * It is confusing, because the majority of code uses the `Log$LEVEL(...)` macros. Having less ways to achieve the same makes the code more consistent and easier to review.

  Fix all issues by removing it

ACKs for top commit:
  stickies-v:
    re-ACK fa8a5d215c
  ajtowns:
    ACK fa8a5d215c
  pablomartin4btc:
    re-ACK fa8a5d215c

Tree-SHA512: 9fbb04962d9c26e566338694a7725b3c0e88ef733322d890bcc6aeddb45266c754e7c885c69bbfebd1588cc09912c6784cfc00e69882f1271a8c87d201490478
2025-12-14 12:30:48 +00:00
MarcoFalke
fa8a5d215c log: Remove brittle and confusing LogPrintLevel 2025-12-13 13:43:24 +01:00
MarcoFalke
fac24bbec8 test: Clarify logging_SeverityLevels test
The test was a bit confusing, because it just referred to the "global
log level" without explicitly specifying what it is. The level is set
though the LogSetup constructor. However, it is easier to follow unit
tests, if they are self-contained. So just set the level to Debug
explicitly here.

Also, add a new debug_3 log, to further document the intended behavior
of the unit test.

Also, replace the LogPrintLevel with the shorter and exact replacements
LogTrace and LogDebug.
2025-12-13 12:50:12 +01:00
stickies-v
f273167661 ipc: separate log statements per level
Avoids ratelimiting unconditional log statements when debug logging
is enabled. Introduces slight behaviour change by removing
the category from unconditional logs, making them more uniform
with the other unconditional logs in the codebase.

Also, in a slight behavior change, prefix the info-level (and higher)
messages with "ipc:".
2025-12-13 12:49:39 +01:00
stickies-v
94c51ae540 libevent: separate log statements per level
Avoids ratelimiting unconditional log statements when debug logging
is enabled. Introduces slight behaviour change by removing
the category from unconditional logs, making them more uniform
with the other unconditional logs in the codebase.

Also, in a slight behavior change, prefix the info-level (and higher)
messages with "libevent:".
2025-12-13 12:48:27 +01:00
marcofleon
a70a14a3f4 refactor: Separate out logic for building a tree-shaped dependency graph 2025-12-12 16:09:53 +01:00
marcofleon
ce29d7d626 fuzz: Fix variable in clusterlin_postlinearize_tree check
The test intends to verify that running `PostLinearize` a
second time on a tree-structured graph doesn't change the
result. But `PostLinearize` was being called on the original
variable, not the copy. So the check was comparing the
unmodified copy against itself, which is useless.

Fix by post-linearizing the correct variable.
2025-12-12 15:04:10 +00:00
marcofleon
876e2849b4 fuzz: Fix incorrect loop bounds in clusterlin_postlinearize_tree
The dependency graphs generated by this test can have holes
(unused indices) in them. This means some of the transactions
were skipped when using `depgraph_gen.TxCount()` as the upper
bound of the loop. Switch to using `depgraph.Positions()` to
correctly handle sparse graphs.
2025-12-12 15:02:26 +00:00
merge-script
938d7aacab Merge bitcoin/bitcoin#33657: rest: allow reading partial block data from storage
07135290c1 rest: allow reading partial block data from storage (Roman Zeyde)
4e2af1c065 blockstorage: allow reading partial block data from storage (Roman Zeyde)
f2fd1aa21c blockstorage: return an error code from `ReadRawBlock()` (Roman Zeyde)

Pull request description:

  It allows fetching specific transactions using an external index, following https://github.com/bitcoin/bitcoin/pull/32541#issuecomment-3267485313.

  Currently, electrs and other indexers map between an address/scripthash to the list of the relevant transactions.

  However, in order to fetch those transactions from bitcoind, electrs relies on reading the whole block and post-filtering for a specific transaction[^1]. Other indexers use a `txindex` to fetch a transaction using its txid [^2][^3][^4].

  The above approach has significant storage and CPU overhead, since the `txid` is a pseudo-random 32-byte value. Also, mainnet `txindex` takes ~60GB today.

  This PR is adding support for using the transaction's position within its block to be able to fetch it directly using [REST API](https://github.com/bitcoin/bitcoin/blob/master/doc/REST-interface.md), using the following HTTP request:

  ```
  GET /rest/blockpart/BLOCKHASH.bin?offset=OFFSET&size=SIZE
  ```

  - The offsets' index can be encoded much more efficiently ([~1.3GB today](https://github.com/romanz/bindex-rs/pull/66#issuecomment-3508476436)).

  - Address history query performance can be tested on mainnet using [1BitcoinEaterAddressDontSendf59kuE](https://mempool.space/address/1BitcoinEaterAddressDontSendf59kuE) - assuming warm OS block cache, [it takes <1s to fetch 5200 txs, i.e. <0.2ms per tx](https://github.com/romanz/bindex-rs/pull/66#issuecomment-3508476436) with [bindex](https://github.com/romanz/bindex-rs).

  - Only binary and hex response formats are supported.

  [^1]: https://github.com/romanz/electrs/blob/master/doc/schema.md
  [^2]: https://github.com/Blockstream/electrs/blob/new-index/doc/schema.md#txstore
  [^3]: https://github.com/spesmilo/electrumx/blob/master/docs/HOWTO.rst#prerequisites
  [^4]: https://github.com/cculianu/Fulcrum/blob/master/README.md#requirements

ACKs for top commit:
  maflcko:
    review ACK 07135290c1 🏪
  l0rinc:
    ACK 07135290c1
  hodlinator:
    re-ACK 07135290c1

Tree-SHA512: bcce7bf4b9a3e5e920ab5a83e656f50d5d7840cdde6b7147d329cf578f8a2db555fc1aa5334e8ee64d5630d25839ece77a2cf421c6c3ac1fa379bb453163bd4f
2025-12-12 13:22:00 +00:00
merge-script
597b8be223 Merge bitcoin/bitcoin#34025: net: Waste less time in socket handling
5f5c1ea019 net: Cache -capturemessages setting (Anthony Towns)
cea443e246 net: Pass time to InactivityChecks fuctions (Anthony Towns)

Pull request description:

  Cuts out some wasted time in net socket handling. First, only calculates the current time once every 50ms, rather than once for each peer, which given we only care about second-level precision seems more than adequate. Second, caches the value of the `-capturemessages` setting in `CConnman` rather than re-evaluating it every time we invoke `PushMessaage`.

ACKs for top commit:
  maflcko:
    review ACK 5f5c1ea019 🏣
  vasild:
    ACK 5f5c1ea019
  sedited:
    ACK 5f5c1ea019
  mzumsande:
    ACK 5f5c1ea019

Tree-SHA512: 0194143a3a4481c6355ac9eab27ce6ae4bed5db1d483ba5d06288dd92f195ccb9f0f055a9eb9d7e16e9bbf72f145eca1ff17c6700ee9aa42730103a8f047b32c
2025-12-12 10:49:59 +00:00
Ava Chow
14371fd1fc gui: Add a menu item to restore then migrate a wallet file
Some users will have backups of a legacy wallet which cannot be restored
due to being a legacy wallet, and therefore cannot be migrated from the
GUI. This menu item allows such users to restore and migrate their
wallets in a single action.
2025-12-11 12:11:15 -08:00
Ava Chow
f11a7d248c gui: Add restore_and_migrate function to restore then migrate a wallet
restore_and_migrate first restores a wallet file to the wallets
directory in the expected layout, then it performs legacy to descriptor
wallet migration on the restored wallet.
2025-12-11 12:11:15 -08:00
Ava Chow
16ab6dfc10 gui: Move actual migration part of migrate() to its own function
We will need to use the same migration code in a later commit, so first
move it to a separate function.
2025-12-11 12:04:27 -08:00
Ava Chow
4ec2d18a07 wallet, interfaces, gui: Expose load_after_restore parameter
RestoreWallet has a load_after_restore parameter, expose this to callers
using it through the wallet interface as well.
2025-12-11 12:04:27 -08:00
Ava Chow
d155fc12a0 Merge bitcoin/bitcoin#32414: validation: periodically flush dbcache during reindex-chainstate
c1e554d3e5 refactor: consolidate 3 separate locks into one block (Andrew Toth)
41479ed1d2 test: add test for periodic flush inside ActivateBestChain (Andrew Toth)
84820561dc validation: periodically flush dbcache during reindex-chainstate (Andrew Toth)

Pull request description:

  After #30611 we periodically do a non-erasing flush of the dbcache to disk roughly every hour during IBD.
  The intention was to also do this periodic flush during reindex-chainstate, so we would not risk losing progress during a system failure when reindexing with a high dbcache value.

  It was discovered that reindex-chainstate does not perform a PERIODIC flush until it has already reached the tip. Since reindexing to tip usually happens within 24 hours, this behaviour was unnoticed with the previous periodic flush interval. Note that reindex-chainstate still does IF_NEEDED flushes during `ConnectBlock`, so this also would not be noticed when running with a lower dbcache value.

  This patch moves the PERIODIC flush from after the outer loop in `ActivateBestChain` to inside the outer loop after we release `cs_main`. This will periodically flush during IBD, reindex-chainstate, and steady state.

ACKs for top commit:
  l0rinc:
    ACK c1e554d3e5
  achow101:
    ACK c1e554d3e5
  sipa:
    utACK c1e554d3e5

Tree-SHA512: c447ad03e16c9978b8ed2c285b38e1b4c56e7778ab93b6f64435116f47b8931017f5f56ab53eb61656693146aaced776f666af573a41ab28e8f2b6d8657fa756
2025-12-11 11:56:01 -08:00
Roman Zeyde
07135290c1 rest: allow reading partial block data from storage
It will allow fetching specific transactions using an external index,
following https://github.com/bitcoin/bitcoin/pull/32541#issuecomment-3267485313.

Co-authored-by: Hodlinator <172445034+hodlinator@users.noreply.github.com>
Co-authored-by: Lőrinc <pap.lorinc@gmail.com>
2025-12-11 19:02:56 +01:00
Roman Zeyde
4e2af1c065 blockstorage: allow reading partial block data from storage
It will allow fetching specific transactions using an external index,
following https://github.com/bitcoin/bitcoin/pull/32541#issuecomment-3267485313.

No logging takes place in case of an invalid offset/size (to avoid spamming the log),
by using a new `ReadRawError::BadPartRange` error variant.

Co-authored-by: Hodlinator <172445034+hodlinator@users.noreply.github.com>
Co-authored-by: Lőrinc <pap.lorinc@gmail.com>
2025-12-11 18:54:55 +01:00
Roman Zeyde
f2fd1aa21c blockstorage: return an error code from ReadRawBlock()
It will enable different error handling flows for different error types.

Also, `ReadRawBlockBench` performance has decreased due to no longer reusing a vector
with an unchanging capacity - mirroring our production code behavior.

Co-authored-by: Hodlinator <172445034+hodlinator@users.noreply.github.com>
Co-authored-by: Lőrinc <pap.lorinc@gmail.com>
2025-12-11 18:54:55 +01:00
merge-script
5be20c380d Merge bitcoin/bitcoin#34033: scripted-diff: Unify error and warning log formatting
fa89f60e31 scripted-diff: LogPrintLevel(*,BCLog::Level::*,*) -> LogError()/LogWarning() (MarcoFalke)
fa6c7a1954 scripted-diff: LogPrintLevel(*,BCLog::Level::Debug,*) -> LogDebug() (MarcoFalke)

Pull request description:

  Errors and warnings should normally not happen. However, if they do happen, it is easier to spot them, if they are all logged in the same format via `LogError` or `LogWarning`.

  So do that with a scripted-diff.

  This is a minimal behavior change and unifies the log output from:

      [net:error] Something bad happened
      [net:warning] Something problematic happened

  to either

      [error] Something bad happened
      [warning] Something problematic happened

  or, when `-loglevelalways=1` is enabled:

      [all:error] Something bad happened
      [all:warning] Something problematic happened

  Such a behavior change is desired, because all warning and error logs are written in the same style in the source code and they are logged in the same format for log consumers.

  Removing the category should be harmless, because warning and error messages should be descriptive and unique anyway.

ACKs for top commit:
  ajtowns:
    ACK fa89f60e31
  stickies-v:
    ACK fa89f60e31
  rkrux:
    lgtm code review ACK fa89f60e31

Tree-SHA512: dafa47ab561609a79005faf008fe188dd714f6e07bb2dfbe4db49290d6636b12eb7ac4a18ed32bcc5526641a9f258dbc37c08e10c223ec068b97976590ff0b52
2025-12-11 09:00:18 -08:00
Ava Chow
b26762bdcb Merge bitcoin/bitcoin#33805: merkle: migrate path arg to reference and drop unused args
24ed820d4f merkle: remove unused `mutated` arg from `BlockWitnessMerkleRoot` (Lőrinc)
63d640fa6a merkle: remove unused `proot` and `pmutated` args from `MerkleComputation` (Lőrinc)
be270551df merkle: migrate `path` arg of `MerkleComputation` to a reference (Lőrinc)

Pull request description:

  ### Summary
  Simplifies merkle tree computation by removing dead code found through coverage analysis (following up on #33768 and #33786).

  ### History

  #### BlockWitnessMerkleRoot
  Original `MerkleComputation` was added in ee60e5625b (diff-706988c23877f8a557484053887f932b2cafb3b5998b50497ce7ff8118ac85a3R131) where it was called for either `&hash, mutated` or `position, &ret` args.
  In 1f0e7ca09c (diff-706988c23877f8a557484053887f932b2cafb3b5998b50497ce7ff8118ac85a3L135-L165) the first usage was inlined in `ComputeMerkleRoot`, leaving the `proot` and , `pmutated` values unused in `MerkleComputation`.
  Later in 4defdfab94 the method was moved to test and in 63d6ad7c89 (diff-706988c23877f8a557484053887f932b2cafb3b5998b50497ce7ff8118ac85a3R87-R95) was restored to the code, though with unused parameters again.

  #### BlockWitnessMerkleRoot
  `BlockWitnessMerkleRoot` was introduced in 8b49040854 where it was already called with `NULL` 8b49040854 (diff-34d21af3c614ea3cee120df276c9c4ae95053830d7f1d3deaf009a4625409ad2R3509) or an unused dummy 8b49040854 (diff-34d21af3c614ea3cee120df276c9c4ae95053830d7f1d3deaf009a4625409ad2R3598-R3599) for the `mutated` parameter.

  ### Fixes

  #### BlockWitnessMerkleRoot
  - Converts `path` parameter from pointer to reference (always non-null at call site)
  - Removes `proot` and `pmutated` parameters (always `nullptr` at call site)

  #### BlockWitnessMerkleRoot
  - Removes unused `mutated` output parameter (always passed as `nullptr`)

  The change is a refactor that shouldn't introduce *any* behavioral change, only remove dead code, leftovers from previous refactors.

  ### Coverage proof
  https://maflcko.github.io/b-c-cov/total.coverage/src/consensus/merkle.cpp.gcov.html

ACKs for top commit:
  optout21:
    utACK 24ed820d4f
  Sjors:
    utACK 24ed820d4f
  achow101:
    ACK 24ed820d4f
  sedited:
    ACK 24ed820d4f
  hodlinator:
    ACK 24ed820d4f

Tree-SHA512: 6960411304631bc381a3db7a682f6b6ba51bd58936ca85aa237c69a9109265b736b22ec4d891875bddfcbe8517bd3f014c44a4b387942eee4b01029c91ec93e1
2025-12-10 15:28:50 -08:00
Ava Chow
0f6d8a347a Merge bitcoin/bitcoin#30442: precalculate SipHash constant salt XORs
6eb5ba5691 refactor: extract shared `SipHash` state into `SipHashState` (Lőrinc)
118d22ddb4 optimization: cache `PresaltedSipHasher` in `CBlockHeaderAndShortTxIDs` (Lőrinc)
9ca52a4cbe optimization: migrate `SipHashUint256` to `PresaltedSipHasher` (Lőrinc)
ec11b9fede optimization: introduce `PresaltedSipHasher` for repeated hashing (Lőrinc)
20330548cf refactor: extract `SipHash` C0-C3 constants to class scope (Lőrinc)
9f9eb7fbc0 test: rename k1/k2 to k0/k1 in `SipHash` consistency tests (Lőrinc)

Pull request description:

  This change is part of [[IBD] - Tracking PR for speeding up Initial Block Download](https://github.com/bitcoin/bitcoin/pull/32043)

  ### Summary

  The in-memory representation of the UTXO set uses (salted) [SipHash](https://github.com/bitcoin/bitcoin/blob/master/src/coins.h#L226) to avoid key collision attacks.

  Hashing `uint256` keys is performed frequently throughout the codebase. Previously, specialized optimizations existed as standalone functions (`SipHashUint256` and `SipHashUint256Extra`), but the constant salting operations (C0-C3 XOR with keys) were recomputed on every call.

  This PR introduces `PresaltedSipHasher`, a class that caches the initial SipHash state (v0-v3 after XORing constants with keys), eliminating redundant constant computations when hashing multiple values with the same keys. The optimization is applied uniformly across:
  - All `Salted*Hasher` classes (`SaltedUint256Hasher`, `SaltedTxidHasher`, `SaltedWtxidHasher`, `SaltedOutpointHasher`)
  - `CBlockHeaderAndShortTxIDs` for compact block short ID computation

  ### Details

  The change replaces the standalone `SipHashUint256` and `SipHashUint256Extra` functions with `PresaltedSipHasher` class methods that cache the constant-salted state. This is particularly beneficial for hash map operations where the same salt is used repeatedly (as suggested by Sipa in https://github.com/bitcoin/bitcoin/pull/30442#issuecomment-2628994530).

  `CSipHasher` behavior remains unchanged; only the specialized `uint256` paths and callers now reuse the cached state instead of recomputing it.

  ### Measurements

  Benchmarks were run using local `SaltedOutpointHasherBench_*` microbenchmarks (not included in this PR) that exercise `SaltedOutpointHasher` in realistic `std::unordered_set` scenarios.

  <details>
  <summary>Benchmarks</summary>

  ```C++
  diff --git a/src/bench/crypto_hash.cpp b/src/bench/crypto_hash.cpp
  --- a/src/bench/crypto_hash.cpp(revision 9b1a7c3e8d)
  +++ b/src/bench/crypto_hash.cpp(revision e1b4f056b3097e7e34b0eda31f57826d81c9d810)
  @@ -2,7 +2,6 @@
   // Distributed under the MIT software license, see the accompanying
   // file COPYING or http://www.opensource.org/licenses/mit-license.php.

  -
   #include <bench/bench.h>
   #include <crypto/muhash.h>
   #include <crypto/ripemd160.h>
  @@ -12,9 +11,11 @@
   #include <crypto/sha512.h>
   #include <crypto/siphash.h>
   #include <random.h>
  -#include <span.h>
   #include <tinyformat.h>
   #include <uint256.h>
  +#include <primitives/transaction.h>
  +#include <util/hasher.h>
  +#include <unordered_set>

   #include <cstdint>
   #include <vector>
  @@ -205,6 +206,98 @@
       });
   }

  +static void SaltedOutpointHasherBench_hash(benchmark::Bench& bench)
  +{
  +    FastRandomContext rng{/*fDeterministic=*/true};
  +    constexpr size_t size{1000};
  +
  +    std::vector<COutPoint> outpoints(size);
  +    for (auto& outpoint : outpoints) {
  +        outpoint = {Txid::FromUint256(rng.rand256()), rng.rand32()};
  +    }
  +
  +    const SaltedOutpointHasher hasher;
  +    bench.batch(size).run([&] {
  +        size_t result{0};
  +        for (const auto& outpoint : outpoints) {
  +            result ^= hasher(outpoint);
  +        }
  +        ankerl::nanobench::doNotOptimizeAway(result);
  +    });
  +}
  +
  +static void SaltedOutpointHasherBench_match(benchmark::Bench& bench)
  +{
  +    FastRandomContext rng{/*fDeterministic=*/true};
  +    constexpr size_t size{1000};
  +
  +    std::unordered_set<COutPoint, SaltedOutpointHasher> values;
  +    std::vector<COutPoint> value_vector;
  +    values.reserve(size);
  +    value_vector.reserve(size);
  +
  +    for (size_t i{0}; i < size; ++i) {
  +        COutPoint outpoint{Txid::FromUint256(rng.rand256()), rng.rand32()};
  +        values.emplace(outpoint);
  +        value_vector.push_back(outpoint);
  +        assert(values.contains(outpoint));
  +    }
  +
  +    bench.batch(size).run([&] {
  +        bool result{true};
  +        for (const auto& outpoint : value_vector) {
  +            result ^= values.contains(outpoint);
  +        }
  +        ankerl::nanobench::doNotOptimizeAway(result);
  +    });
  +}
  +
  +static void SaltedOutpointHasherBench_mismatch(benchmark::Bench& bench)
  +{
  +    FastRandomContext rng{/*fDeterministic=*/true};
  +    constexpr size_t size{1000};
  +
  +    std::unordered_set<COutPoint, SaltedOutpointHasher> values;
  +    std::vector<COutPoint> missing_value_vector;
  +    values.reserve(size);
  +    missing_value_vector.reserve(size);
  +
  +    for (size_t i{0}; i < size; ++i) {
  +        values.emplace(Txid::FromUint256(rng.rand256()), rng.rand32());
  +        COutPoint missing_outpoint{Txid::FromUint256(rng.rand256()), rng.rand32()};
  +        missing_value_vector.push_back(missing_outpoint);
  +        assert(!values.contains(missing_outpoint));
  +    }
  +
  +    bench.batch(size).run([&] {
  +        bool result{false};
  +        for (const auto& outpoint : missing_value_vector) {
  +            result ^= values.contains(outpoint);
  +        }
  +        ankerl::nanobench::doNotOptimizeAway(result);
  +    });
  +}
  +
  +static void SaltedOutpointHasherBench_create_set(benchmark::Bench& bench)
  +{
  +    FastRandomContext rng{/*fDeterministic=*/true};
  +    constexpr size_t size{1000};
  +
  +    std::vector<COutPoint> outpoints(size);
  +    for (auto& outpoint : outpoints) {
  +        outpoint = {Txid::FromUint256(rng.rand256()), rng.rand32()};
  +    }
  +
  +    bench.batch(size).run([&] {
  +        std::unordered_set<COutPoint, SaltedOutpointHasher> set;
  +        set.reserve(size);
  +        for (const auto& outpoint : outpoints) {
  +            set.emplace(outpoint);
  +        }
  +        ankerl::nanobench::doNotOptimizeAway(set.size());
  +    });
  +}
  +
   static void MuHash(benchmark::Bench& bench)
   {
       MuHash3072 acc;
  @@ -276,6 +369,10 @@
   BENCHMARK(SHA256_32b_AVX2, benchmark::PriorityLevel::HIGH);
   BENCHMARK(SHA256_32b_SHANI, benchmark::PriorityLevel::HIGH);
   BENCHMARK(SipHash_32b, benchmark::PriorityLevel::HIGH);
  +BENCHMARK(SaltedOutpointHasherBench_hash, benchmark::PriorityLevel::HIGH);
  +BENCHMARK(SaltedOutpointHasherBench_match, benchmark::PriorityLevel::HIGH);
  +BENCHMARK(SaltedOutpointHasherBench_mismatch, benchmark::PriorityLevel::HIGH);
  +BENCHMARK(SaltedOutpointHasherBench_create_set, benchmark::PriorityLevel::HIGH);
   BENCHMARK(SHA256D64_1024_STANDARD, benchmark::PriorityLevel::HIGH);
   BENCHMARK(SHA256D64_1024_SSE4, benchmark::PriorityLevel::HIGH);
   BENCHMARK(SHA256D64_1024_AVX2, benchmark::PriorityLevel::HIGH);

  ```

  </details>

  > cmake -B build -DBUILD_BENCH=ON -DCMAKE_BUILD_TYPE=Release && cmake --build build -j$(nproc) && build/bin/bench_bitcoin -filter='SaltedOutpointHasherBench' -min-time=10000

  > Before:

  |               ns/op |                op/s |    err% |     total | benchmark
  |--------------------:|--------------------:|--------:|----------:|:----------
  |               58.60 |       17,065,922.04 |    0.3% |     11.02 | `SaltedOutpointHasherBench_create_set`
  |               11.97 |       83,576,684.83 |    0.1% |     11.01 | `SaltedOutpointHasherBench_hash`
  |               14.50 |       68,985,850.12 |    0.3% |     10.96 | `SaltedOutpointHasherBench_match`
  |               13.90 |       71,942,033.47 |    0.4% |     11.03 | `SaltedOutpointHasherBench_mismatch`

  > After:

  |               ns/op |                op/s |    err% |     total | benchmark
  |--------------------:|--------------------:|--------:|----------:|:----------
  |               57.27 |       17,462,299.19 |    0.1% |     11.02 | `SaltedOutpointHasherBench_create_set`
  |               11.24 |       88,997,888.48 |    0.3% |     11.04 | `SaltedOutpointHasherBench_hash`
  |               13.91 |       71,902,014.20 |    0.2% |     11.01 | `SaltedOutpointHasherBench_match`
  |               13.29 |       75,230,390.31 |    0.1% |     11.00 | `SaltedOutpointHasherBench_mismatch`

  compared to master:
  ```python
  create_set - 17,462,299.19 / 17,065,922.04 - 2.3% faster
  hash       - 88,997,888.48 / 83,576,684.83 - 6.4% faster
  match      - 71,902,014.20 / 68,985,850.12 - 4.2% faster
  mismatch   - 75,230,390.31 / 71,942,033.47 - 4.5% faster
  ```

  > C++ compiler .......................... GNU 13.3.0

  > Before:

  |               ns/op |                op/s |    err% |          ins/op |          cyc/op |    IPC |         bra/op |   miss% |     total | benchmark
  |--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
  |              136.76 |        7,312,133.16 |    0.0% |        1,086.67 |          491.12 |  2.213 |         119.54 |    1.1% |     11.01 | `SaltedOutpointHasherBench_create_set`
  |               23.82 |       41,978,882.62 |    0.0% |          252.01 |           85.57 |  2.945 |           4.00 |    0.0% |     11.00 | `SaltedOutpointHasherBench_hash`
  |               60.42 |       16,549,695.42 |    0.1% |          460.51 |          217.04 |  2.122 |          21.00 |    1.4% |     10.99 | `SaltedOutpointHasherBench_match`
  |               78.66 |       12,713,595.35 |    0.1% |          555.59 |          282.52 |  1.967 |          20.19 |    2.2% |     10.74 | `SaltedOutpointHasherBench_mismatch`

  > After:

  |               ns/op |                op/s |    err% |          ins/op |          cyc/op |    IPC |         bra/op |   miss% |     total | benchmark
  |--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
  |              135.38 |        7,386,349.49 |    0.0% |        1,078.19 |          486.16 |  2.218 |         119.56 |    1.1% |     11.00 | `SaltedOutpointHasherBench_create_set`
  |               23.67 |       42,254,558.08 |    0.0% |          247.01 |           85.01 |  2.906 |           4.00 |    0.0% |     11.00 | `SaltedOutpointHasherBench_hash`
  |               58.95 |       16,962,220.14 |    0.1% |          446.55 |          211.74 |  2.109 |          20.86 |    1.4% |     11.01 | `SaltedOutpointHasherBench_match`
  |               76.98 |       12,991,047.69 |    0.1% |          548.93 |          276.50 |  1.985 |          20.25 |    2.3% |     10.72 | `SaltedOutpointHasherBench_mismatch`

  ```python
  compared to master:
  create_set -  7,386,349.49 / 7,312,133.16  - 1.0% faster
  hash       - 42,254,558.08 / 41,978,882.62 - 0.6% faster
  match      - 16,962,220.14 / 16,549,695.42 - 2.4% faster
  mismatch   - 12,991,047.69 / 12,713,595.35 - 2.1% faster
  ```

ACKs for top commit:
  achow101:
    ACK 6eb5ba5691
  vasild:
    ACK 6eb5ba5691
  sipa:
    ACK 6eb5ba5691

Tree-SHA512: 9688b87e1d79f8af9efc18a8487922c5f1735487a9c5b78029dd46abc1d94f05d499cd1036bd615849aa7d6b17d11653c968086050dd7d04300403ebd0e81210
2025-12-10 15:22:34 -08:00
Ava Chow
c2975f26d6 Merge bitcoin/bitcoin#33602: [IBD] coins: reduce lookups in dbcache layer propagation
0ac969cddf validation: don't reallocate cache for short-lived CCoinsViewCache (Lőrinc)
c8f5e446dc coins: reduce lookups in dbcache layer propagation (Lőrinc)

Pull request description:

  This change is part of [[IBD] - Tracking PR for speeding up Initial Block Download](https://github.com/bitcoin/bitcoin/pull/32043)

  ### Summary

  Previously, when the parent coins cache had no entry and the child did, `BatchWrite` performed a find followed by `try_emplace`, which resulted in multiple `SipHash` computations and bucket traversals on the common insert path.
  On a different path, these caches were recreated needlessly for every block connection.

  ### Fix for double fetch

  This change uses a single leading `try_emplace` and branches on the returned `inserted` flag. In the `FRESH && SPENT` case (not used in production, only exercised by tests), we erase the just-inserted placeholder (which is constant time with no rehash anyway). Semantics are unchanged for all valid parent/child state combinations.

  This change is a minimal version of [bitcoin/bitcoin@`723c49b` (#32128)](723c49b63b) and draws simplification ideas [bitcoin/bitcoin@`ae76ec7` (#30673)](ae76ec7bcf) and https://github.com/bitcoin/bitcoin/pull/30326.

  ### Fix for temporary cache recreation

  Related to parent cache propagation, the second commit makes it possible to avoid destructuring-recreating-destructuring of these short-live parent caches created for each new block.
  A few temporary `CCoinsViewCache`'s are destructed right after the `Flush()`, therefore it is not necessary to call `ReallocateCache` to recreate them right before they're killed anyway.

  This change was based on a subset of https://github.com/bitcoin/bitcoin/pull/28945, the original authors and relevant commenters were added as coauthors to this version.

  -----

  Reindex-chainstate indicates ~1% speedup.
  <details>
  <summary>Details</summary>

  ```python
  COMMITS="647cdb4f7e8041affed887e2325ee03a91078bb1 0b0c3293ffd75afb27dadc0b28426b40132a8c6b"; \
  STOP=909090; DBCACHE=4500; \
  CC=gcc; CXX=g++; \
  BASE_DIR="/mnt/my_storage"; DATA_DIR="$BASE_DIR/BitcoinData"; LOG_DIR="$BASE_DIR/logs"; \
  (echo ""; for c in $COMMITS; do git fetch -q origin $c && git log -1 --pretty='%h %s' $c || exit 1; done; echo "") && \
  hyperfine \
    --sort command \
    --runs 2 \
    --export-json "$BASE_DIR/rdx-$(sed -E 's/(\w{8})\w+ ?/\1-/g;s/-$//'<<<"$COMMITS")-$STOP-$DBCACHE-$CC.json" \
    --parameter-list COMMIT ${COMMITS// /,} \
    --prepare "killall bitcoind 2>/dev/null; rm -f $DATA_DIR/debug.log; git checkout {COMMIT}; git clean -fxd; git reset --hard && \
      cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DENABLE_IPC=OFF && ninja -C build bitcoind && \
      ./build/bin/bitcoind -datadir=$DATA_DIR -stopatheight=$STOP -dbcache=1000 -printtoconsole=0; sleep 20" \
    --cleanup "cp $DATA_DIR/debug.log $LOG_DIR/debug-{COMMIT}-$(date +%s).log" \
    "COMPILER=$CC ./build/bin/bitcoind -datadir=$DATA_DIR -stopatheight=$STOP -dbcache=$DBCACHE -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0"

  647cdb4f7e Merge bitcoin/bitcoin#33311: net: Quiet down logging when router doesn't support natpmp/pcp
  0b0c3293ff validation: don't reallocate cache for short-lived CCoinsViewCache

  Benchmark 1: COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=909090 -dbcache=4500 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 (COMMIT = 647cdb4f7e)
    Time (mean ± σ):     16233.508 s ±  9.501 s    [User: 19064.578 s, System: 951.672 s]
    Range (min … max):   16226.790 s … 16240.226 s    2 runs

  Benchmark 2: COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=909090 -dbcache=4500 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 (COMMIT = 0b0c3293ffd75afb27dadc0b28426b40132a8c6b)
    Time (mean ± σ):     16039.626 s ± 17.284 s    [User: 18870.130 s, System: 950.722 s]
    Range (min … max):   16027.405 s … 16051.848 s    2 runs

  Relative speed comparison
          1.01 ±  0.00  COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=909090 -dbcache=4500 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 (COMMIT = 647cdb4f7e)
          1.00          COMPILER=gcc ./build/bin/bitcoind -datadir=/mnt/my_storage/BitcoinData -stopatheight=909090 -dbcache=4500 -reindex-chainstate -blocksonly -connect=0 -printtoconsole=0 (COMMIT = 0b0c3293ffd75afb27dadc0b28426b40132a8c6b)
  ```

  </details>

ACKs for top commit:
  optout21:
    utACK 0ac969cddf
  achow101:
    ACK 0ac969cddf
  andrewtoth:
    utACK 0ac969cddf
  sedited:
    ACK 0ac969cddf

Tree-SHA512: 9fcc3f1a8314368576a4fba96ca72665527eaa3a97964ab5b39491757f3527147d134f79a5c3456f76c1330c7ef862989d23f764236c5e2563be89a81c1cee47
2025-12-10 15:02:25 -08:00
merge-script
56ce78d5f6 Merge bitcoin/bitcoin#34031: net: Remove "tor" as a network specification
e7ac5a133c doc: add release note for 34031 (fanquake)
c4c70a256e netbase: Remove "tor" as a network specification (Carl Dong)

Pull request description:

  "tor" as a network specification was deprecated in 60dc8e4208 in favor of "onion"
  and this commit removes it and updates the relevant test.

  Previously #16029. This has been warning as being deprecated since `v0.17.0`.

  This PR only removes the already deprecated usage of tor as a network specification, the use of tor throughout the codebase, is not deprecated.

ACKs for top commit:
  davidgumberg:
    crACK e7ac5a133c
  laanwj:
    Code review ACK e7ac5a133c
  janb84:
    ACK e7ac5a133c
  stickies-v:
    ACK e7ac5a133c

Tree-SHA512: f211dec151c21728b4cd2b1716ee68907871beaa85d8c89e2bc17576e701d03c03e5455593de94970d787aa3264fab60d8c6debeeff908e00d8feb48804692e9
2025-12-10 11:51:01 +00:00
Anthony Towns
5f5c1ea019 net: Cache -capturemessages setting 2025-12-10 06:51:47 +10:00
merge-script
cca113f5b0 Merge bitcoin/bitcoin#34008: log: don't rate-limit "new peer" with -debug=net
d4d184eda9 log: don't rate-limit "new peer" with -debug=net (0xb10c)

Pull request description:

  Previously, when `debug=net` is enabled, we log "New [..] peer connected" for new inbound peers with `LogInfo`. However, `LogInfo` will get rate-limited since https://github.com/bitcoin/bitcoin/pull/32604. When we specifically turn on `debug=net`, we don't want these log messages to be rate-limited.

  To fix this, use `LogDebug(BCLog::NET, ...)` for potentially high-rate inbound connections. Otherwise use `LogInfo`. This means we don't rate-limit the messages for inbound peers when `debug=net` is turned on but will rate-limit if we created outbound at a high rate as these are logged via `LogInfo`.

  The new log messages look similar to:
  ```
  2025-12-08T00:00:00Z [net] New inbound peer connected: transport=v2 version=70016 blocks=0 peer=1
  2025-12-08T00:00:00Z New outbound-full-relay peer connected: transport=v2 version=70016 blocks=281738 peer=5
  ```

  --

  I ran into this message getting rate-limited on one of my monitoring nodes with `-logsourcelocations=1`: With logsourcelocations, one of these lines is about 338 chars (or 338 bytes) long. We rate-limit after more than 1048576 bytes per hour, which results in about 3100 in- and outbound connections per hour. With evicted and instantly reconnecting connections from an entity like LinkingLion, this can be reached fairly quickly.

ACKs for top commit:
  stickies-v:
    utACK d4d184eda9
  Crypt-iQ:
    tACK d4d184eda9
  maflcko:
    review ACK d4d184eda9 🚲
  rkrux:
    lgtm code review ACK d4d184eda9
  glozow:
    lgtm ACK d4d184eda9

Tree-SHA512: 14dbf693fa44a74c9822590e7a08167d2deeb1bc6f4b8aeb00c1b035c0df7101087d5c80a3c0d637879d5c52f88b30f0cb4c0577cff6f647d2eb3300f49d8ea3
2025-12-09 11:16:12 -08:00
merge-script
2c44c41984 Merge bitcoin/bitcoin#33553: validation: Improve warnings in case of chain corruption
4b47113698 validation: Reword CheckForkWarningConditions and call it also during IBD and at startup (Martin Zumsande)
2f51951d03 p2p: Add warning message when receiving headers for blocks cached as invalid (Martin Zumsande)

Pull request description:

  In case of corruption that leads to a block being marked as invalid that is seen as valid by the rest of the network, the user currently doesn't receive good error messages, but will often be stuck in an endless headers-sync loop with no explanation (#26391).

  This PR improves warnings in two ways:
  - When we receive a header that is already saved in our disk, but invalid, add a warning. This will happen repeatedly during the headerssync loop (see https://github.com/bitcoin/bitcoin/issues/26391#issuecomment-1291765534 on how to trigger it artificially).
  - Removes the IBD check from `CheckForkWarningConditions` and adds a call to the function during init (`LoadChainTip()`). The existing check was added in 55ed3f1475 a long time ago when we had more sophisticated fork detection that could lead to false positives during IBD, but that  logic was removed in fa62304c97 so that I don't see a reason to suppress the warning anymore.

  Fixes #26391 (We'll still do the endless looping, trying to find a peer with a headers that we can use, but will now repeatedly log warnings while doing so).

ACKs for top commit:
  glozow:
    ACK `git range-diff 6d2c8ea9dbd77c71051935b5ab59224487509559...4b4711369880369729893ba7baef11ba2a36cf4b`
  theStack:
    re-ACK 4b47113698
  sedited:
    ACK 4b47113698

Tree-SHA512: 78bc53606374636d616ee10fdce0324adcc9bcee2806a7e13c9471e4c02ef00925ce6daef303bc153b7fcf5a8528fb4263c875b71d2e965f7c4332304bc4d922
2025-12-09 08:25:17 -08:00
Lőrinc
6eb5ba5691 refactor: extract shared SipHash state into SipHashState
Split the repeated `SipHash` v[0..3] initialization into a small `SipHashState` helper that is used by both `CSipHasher` and `PresaltedSipHasher`.

Added explanatory comments to clarify behavior, documenting the equivalence of `PresaltedSipHasher` `operator()` overloads to `CSipHasher` usage.

Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
2025-12-09 17:17:47 +01:00
Lőrinc
118d22ddb4 optimization: cache PresaltedSipHasher in CBlockHeaderAndShortTxIDs
Replaces separate `shorttxidk0`/`shorttxidk1` members with a cached `PresaltedSipHasher`, so `GetShortID()` reuses the precomputed `SipHash` state instead of rebuilding it on every call.

`CBlockHeaderAndShortTxIDs` was never intended to be used before `FillShortTxIDSelector()` runs; doing so already relied on indeterminate salt values.
The new `Assert(m_hasher)` just makes this invariant explicit and fails fast if the object is used in an uninitialized state.
2025-12-09 17:16:17 +01:00
Lőrinc
9ca52a4cbe optimization: migrate SipHashUint256 to PresaltedSipHasher
Replaces standalone `SipHashUint256` with an `operator()` overload in `PresaltedSipHasher`.
Updates all hasher classes (`SaltedUint256Hasher`, `SaltedTxidHasher`, `SaltedWtxidHasher`) to use `PresaltedSipHasher` internally, enabling the same constant-state caching optimization while keeping behavior unchanged.

Benchmark was also adjusted to cache the salting part.
2025-12-09 17:16:15 +01:00
Lőrinc
ec11b9fede optimization: introduce PresaltedSipHasher for repeated hashing
Replaces the `SipHashUint256Extra` function with the `PresaltedSipHasher` class that caches the constant-salted state (v[0-3] after XORing with keys).
This avoids redundant XOR operations when hashing multiple values with the same keys, benefiting use cases like `SaltedOutpointHasher`.

This essentially brings the precalculations in the `CSipHasher` constructor to the `uint256`-specialized SipHash implementation.

> cmake -B build -DBUILD_BENCH=ON -DCMAKE_BUILD_TYPE=Release && cmake --build build -j$(nproc) && build/src/bench/bench_bitcoin -filter='SaltedOutpointHasherBench.*' -min-time=10000

> C++ compiler .......................... AppleClang 16.0.0.16000026

|               ns/op |                op/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|               57.27 |       17,462,299.19 |    0.1% |     11.02 | `SaltedOutpointHasherBench_create_set`
|               11.24 |       88,997,888.48 |    0.3% |     11.04 | `SaltedOutpointHasherBench_hash`
|               13.91 |       71,902,014.20 |    0.2% |     11.01 | `SaltedOutpointHasherBench_match`
|               13.29 |       75,230,390.31 |    0.1% |     11.00 | `SaltedOutpointHasherBench_mismatch`

compared to master:
create_set - 17,462,299.19/17,065,922.04 - 2.3% faster
hash       - 88,997,888.48/83,576,684.83 - 6.4% faster
match      - 71,902,014.20/68,985,850.12 - 4.2% faster
mismatch   - 75,230,390.31/71,942,033.47 - 4.5% faster

> C++ compiler .......................... GNU 13.3.0

|               ns/op |                op/s |    err% |          ins/op |          cyc/op |    IPC |         bra/op |   miss% |     total | benchmark
|--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
|              135.38 |        7,386,349.49 |    0.0% |        1,078.19 |          486.16 |  2.218 |         119.56 |    1.1% |     11.00 | `SaltedOutpointHasherBench_create_set`
|               23.67 |       42,254,558.08 |    0.0% |          247.01 |           85.01 |  2.906 |           4.00 |    0.0% |     11.00 | `SaltedOutpointHasherBench_hash`
|               58.95 |       16,962,220.14 |    0.1% |          446.55 |          211.74 |  2.109 |          20.86 |    1.4% |     11.01 | `SaltedOutpointHasherBench_match`
|               76.98 |       12,991,047.69 |    0.1% |          548.93 |          276.50 |  1.985 |          20.25 |    2.3% |     10.72 | `SaltedOutpointHasherBench_mismatch`

compared to master:
create_set -  7,386,349.49/7,312,133.16  - 1% faster
hash       - 42,254,558.08/41,978,882.62 - 0.6% faster
match      - 16,962,220.14/16,549,695.42 - 2.4% faster
mismatch   - 12,991,047.69/12,713,595.35 - 2% faster

Co-authored-by: sipa <pieter@wuille.net>
2025-12-09 17:13:44 +01:00
Lőrinc
20330548cf refactor: extract SipHash C0-C3 constants to class scope
Moves the `SipHash` initialization constants (C0-C3) from magic numbers to named static constexpr members of `CSipHasher`.
2025-12-09 17:03:18 +01:00
Lőrinc
9f9eb7fbc0 test: rename k1/k2 to k0/k1 in SipHash consistency tests
Aligns test variable naming with the `k0`/`k1` convention used consistently throughout the codebase for `SipHash` keys.
Also splits the single-param `SipHash` test from the one with extra, for clarity.
2025-12-09 17:03:18 +01:00
merge-script
29ed608dc7 Merge bitcoin/bitcoin#33961: script: Add a separate ScriptError for empty pubkeys encountered in Tapscript
9d5021a05b script: add SCRIPT_ERR_TAPSCRIPT_EMPTY_PUBKEY (billymcbip)

Pull request description:

  We currently have two callsites for `SCRIPT_ERR_PUBKEYTYPE`:
  - A pre-tapscript policy error behind the `SCRIPT_VERIFY_STRICTENC` flag: 4de26b111f/src/script/interpreter.cpp (L220)
  - A [consensus error](https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki?plain=1#L93) in Tapscript: 4de26b111f/src/script/interpreter.cpp (L368)

  It would be good for readability and testability to have separate errors for both cases, as they are quite distinct (policy vs. consensus, format vs. emptiness).

  **This PR adds `SCRIPT_ERR_TAPSCRIPT_EMPTY_PUBKEY` for the consensus error path.**

  This change would make our error handling more consistent. We have more granular errors for other pubkey error paths already: `SCRIPT_ERR_WITNESS_PUBKEYTYPE`,  `SCRIPT_ERR_DISCOURAGE_UPGRADABLE_PUBKEYTYPE`. We also have separate errors for MINIMAL_IF: `SCRIPT_ERR_MINIMALIF` for the policy error pre-tapscript, and `SCRIPT_ERR_TAPSCRIPT_MINIMALIF` for the consensus error post-tapscript.

  Tests:

  Added a test case to `script_tests` and ran `build/bin/test_bitcoin --run_test=script_tests --log_level=success`.
  ```
  test/script_tests.cpp:144: info: check '[["aa","#SCRIPT# 0 CHECKSIG","#CONTROLBLOCK#",0.00000001],"","0x51 0x20 #TAPROOTOUTPUT#","P2SH,WITNESS,TAPROOT","TAPSCRIPT_EMPTY_PUBKEY","TAPSCRIPT: OP_CHECKSIG with empty pubkey must fail"] (with flags 165d5d)' has passed
  ...
  ```

  Ran `DIR_UNIT_TEST_DATA="$(pwd)/../qa-assets/unit_test_data" build/bin/test_bitcoin --run_test=script_assets_tests --log_level=success`.

  Updated `feature_taproot.py` and ran `build/test/functional/feature_taproot.py`.

  Looking forward to your feedback.

ACKs for top commit:
  sedited:
    ACK 9d5021a05b
  darosior:
    utACK 9d5021a05b
  sipa:
    ACK 9d5021a05b

Tree-SHA512: bc0b7f64454313fe392ffb2d23aa4eca3deadc5ea1d10b3fba0b3ab4cb0575a5ddcb002dc27b4fa7aa3c180840a83d1b3e5c89351009ce7ffe684d58e1980ace
2025-12-09 08:01:49 -08:00
merge-script
dbc8928069 Merge bitcoin/bitcoin#33993: init: point out -stopatheight may be imprecise
ff06e2468a init: point out -stopatheight may be imprecise (brunoerg)

Pull request description:

  `-stopatheight` is used to stop running bitcoind after reaching a given height. However, this feature is imprecise since some blocks can still be processed during the shutdown.

  There are some previous discussions around it in https://github.com/bitcoin/bitcoin/pull/13713, https://github.com/bitcoin/bitcoin/pull/13490 and https://github.com/bitcoin/bitcoin/issues/13477. However, I'm not sure if it will get fixed since it's undesirable to burden the validation code further with this and we can bypass this behavior by using `invalidateblock` to wind back. Anyway, since at this moment its behavior is imprecise I think worth mentioning it in documentation.

ACKs for top commit:
  rkrux:
    re-ACK ff06e2468a
  stickies-v:
    ACK ff06e2468a
  pablomartin4btc:
    ACK ff06e2468a
  jaonoctus:
    re-ACK ff06e2468a

Tree-SHA512: 222d5e89021d5f9a7ce0edca44c4ce20b13f71832413dccea78ad40a01f2a615a061f8cf446d7290ed911023922adbc6fa22f0c88cff306dcd8b4ae14194e9b8
2025-12-09 07:39:46 -08:00
0xb10c
d4d184eda9 log: don't rate-limit "new peer" with -debug=net
Previously, when `debug=net` is enabled, we log "New [..] peer connected"
for new inbound peers with `LogInfo`. However, `LogInfo` will get
rate-limited since https://github.com/bitcoin/bitcoin/pull/32604.
When we specifically turn on `debug=net`, we don't want these log
messages to be rate-limited.

To fix this, use `LogDebug(BCLog::NET, ...)` for potentially high-
rate inbound connections. Otherwise use `LogInfo`. This means we
don't rate-limit the messages for inbound peers when `debug=net`
is turned on but will rate-limit if we created outbound at a high
rate as these are logged via `LogInfo`.

--

I ran into this message getting rate-limited on one of my monitoring
nodes with `-logsourcelocations=1`: With logsourcelocations, one of
these lines is about 338 chars (or 338 bytes) long. We rate-limit
after more than 1048576 bytes per hour, which results in about
3100 in- and outbound connections per hour. With evicted and
instantly reconnecting connections from an entity like LinkingLion,
this can be reached fairly quickly.

Co-Authored-By: Eugene Siegel <elzeigel@gmail.com>
Co-Authored-By: Anthony Towns <aj@erisian.com.au>
2025-12-09 13:05:16 +01:00
Carl Dong
c4c70a256e netbase: Remove "tor" as a network specification
"tor" as a network specification was deprecated in 60dc8e4208 in favor
of "onion" and this commit removes it and updates the relevant test.

Co-authored-by: Mara van der Laan <126646+laanwj@users.noreply.github.com>
2025-12-09 10:12:32 +00:00
MarcoFalke
fa89f60e31 scripted-diff: LogPrintLevel(*,BCLog::Level::*,*) -> LogError()/LogWarning()
This is a minimal behavior change and changes log output from:

  [net:error] Something bad happened
  [net:warning] Something problematic happened

to either

  [error] Something bad happened
  [warning] Something problematic happened

or, when -loglevelalways=1 is enabled:

  [all:error] Something bad happened
  [all:warning] Something problematic happened

Such a behavior change is desired, because all warning and error logs
are written in the same style in the source code and they are logged in
the same format for log consumers.

-BEGIN VERIFY SCRIPT-

 sed --regexp-extended --in-place \
   's/LogPrintLevel\((BCLog::[^,]*), BCLog::Level::(Error|Warning), */Log\2(/g' \
   $( git grep -l LogPrintLevel ':(exclude)src/test/logging_tests.cpp' )

-END VERIFY SCRIPT-
2025-12-09 10:44:33 +01:00
MarcoFalke
fa6c7a1954 scripted-diff: LogPrintLevel(*,BCLog::Level::Debug,*) -> LogDebug()
This refactor does not change behavior.

-BEGIN VERIFY SCRIPT-

 sed --regexp-extended --in-place \
   's/LogPrintLevel\((BCLog::[^,]*), BCLog::Level::Debug,/LogDebug(\1,/g' \
   $( git grep -l LogPrintLevel ':(exclude)src/test/logging_tests.cpp' )

-END VERIFY SCRIPT-
2025-12-09 10:44:29 +01:00
Ryan Ofsky
d5c8199b79 Merge bitcoin/bitcoin#34006: Add util::Expected (std::expected)
faa23738fc refactor: Enable clang-tidy bugprone-unused-return-value (MarcoFalke)
fa114be27b Add util::Expected (std::expected) (MarcoFalke)

Pull request description:

  Some low-level code could benefit from being able to use `std::expected` from C++23:

  * Currently, some code is using `std::optional<E>` to denote an optional error. This is fine, but a bit confusing, because `std::optional` is normally used for values, not errors. Using `std::expected<void, E>` is clearer.
  * Currently, some code is using `std::variant<V, E>` to denote either a value or an error. This is fine, but a bit verbose, because `std::variant` requires a visitor or get_if/holds_alternative instead of a simple call of the `operator bool` for `std::expected`.

  In theory, `util::Result` could be taught to behave similar to `std::expected` (see https://github.com/bitcoin/bitcoin/pull/34005). However, it is unclear if this is the right approach:

  * `util::Result` is mostly meant for higher level code, where errors come with translated error messages.
  * `std::expected` is mostly meant for lower level code, where errors could be an enum, or any other type.
  * https://github.com/bitcoin/bitcoin/pull/25665 aims to minimize the memory footprint of the error by wrapping it in a unique_ptr internally. `std::expected` requires the value and error to be "nested within it" (https://cplusplus.github.io/LWG/issue4141). So from a memory-layout perspective, the two are not compatible.
  * `std::expected` also comes with `std::unexpected`, which also does not map cleanly to `util::Result`.

  So just add a minimal drop-in port of `std::expected`.

ACKs for top commit:
  romanz:
    tACK faa23738fc
  sedited:
    Re-ACK faa23738fc
  hodlinator:
    ACK faa23738fc
  rkrux:
    light Code Review ACK faa23738fc
  ryanofsky:
    Code review ACK faa23738fc, only adding `value_or` implementation and `CheckedReturnTypes` clang-tidy commit since last review.
  stickies-v:
    ACK faa23738fc

Tree-SHA512: fdbd0f6bf439738ffe6a68da5522f1051537f8df9c308eb90bef6bd2e06931d79f1c5da22d5500765e9cb1d801d5be39e11e10d47c9659fec1a8c8804cb7c872
2025-12-08 20:11:51 -05:00
merge-script
77248e8496 Merge bitcoin/bitcoin#33771: refactor: C++20 operators
48840bfc2d refactor: Prefer `<=>` over multiple relational operators (Daniel Pfeifer)
5a0f49bd26 refactor: Remove all `operator!=` definitions (Daniel Pfeifer)

Pull request description:

  Remove all `operator!=` definitions and provide `operator<=>` as a replacement where all relational comparison operators were defined before.

  The compiler is able to deduce missing comparison operators from `operator!=` and `operator<=>`. The compiler provided operators have the following advantages:

  1. less code
  2. guaranteed consistency

  Refactoring that changes the implementation, or replaces it with `= default` is left for a separate PR.

ACKs for top commit:
  optout21:
    utACK 48840bfc2d
  Chand-ra:
    tACK [`48840bf`](48840bfc2d). Built the PR and ran unit tests; everything passes.
  maflcko:
    review ACK 48840bfc2d 🌖
  stickies-v:
    utACK 48840bfc2d. Pretty straightforward cleanup taking advantage of C++20 improvements, nice.
  janb84:
    ACK 48840bfc2d
  sipa:
    ACK 48840bfc2d

Tree-SHA512: 7fedc4abc451c7ad611e3a960ff939a35580667222009cb30ca546e564dc9161e3e8d4d1d7d44c538d961cc8f7adba6e6dbcebcd1be370bf33aef294d06f236b
2025-12-08 16:46:03 +00:00
Anthony Towns
cea443e246 net: Pass time to InactivityChecks fuctions
We run InactivityChecks() for each node everytime poll()/select() every
50ms or so. Rather than calculating the current time once for each node,
just calculate it once and reuse it.
2025-12-07 00:36:24 +10:00
merge-script
89dc82295e Merge bitcoin/bitcoin#29641: scripted-diff: Use LogInfo over LogPrintf
fa4395dffd refactor: Remove unused LogPrintf (MarcoFalke)
fa05181d90 scripted-diff: LogPrintf -> LogInfo (MarcoFalke)

Pull request description:

  `LogPrintf` has many issues:

  * It does not mention the log severity (info).
  * It is a deprecated alias for `LogInfo`, according to the dev notes.
  * It wastes review cycles, because reviewers sometimes point out that it is deprecated.
  * It makes the code inconsistent, when both versions of the alias are used.

  Fix all issues by removing the deprecated alias.

ACKs for top commit:
  ajtowns:
    ACK fa4395dffd
  stickies-v:
    ACK fa4395dffd
  rkrux:
    lgtm ACK fa4395dffd

Tree-SHA512: de95d56df27b9ee33548cc7ee7595e2d253474094473089ee67787ddb171384383c683142672c3e2c1984e19eee629b2c469dc85713640a73391610581edbdbe
2025-12-06 13:47:44 +00:00
MarcoFalke
faa23738fc refactor: Enable clang-tidy bugprone-unused-return-value
This requires some small refactors to silence false-positive warnings.

Also, expand the bugprone-unused-return-value.CheckedReturnTypes option
to include util::Result, and util::Expected.
2025-12-06 13:06:28 +01:00
MarcoFalke
fa114be27b Add util::Expected (std::expected) 2025-12-06 13:06:21 +01:00
Chandra Pratap
57b888ce0e fuzz: Add a test case for ParseByteUnits()
`ParseByteUnits()` is the only parsing function in `strencodings.cpp`
lacking a fuzz test. Add a test case to check the function against
arbitrary strings and randomized default_multiplier's.
2025-12-05 15:23:54 +00:00
merge-script
b8e66b901d Merge bitcoin/bitcoin#33858: test: add unit test coverage for the empty leaves path in MerkleComputation
ffcae82a68 test: exercise TransactionMerklePath with empty block; targets the MerkleComputation empty-leaves path that was only reached by fuzz tests (frankomosh)

Pull request description:

  As noted in [#32243 (comment)](https://github.com/bitcoin/bitcoin/pull/32243#issuecomment-2988854482), the early return inside `MerkleComputation` when `leaves.size() == 0` was only exercised by fuzz tests.

  The existing `merkle_test_empty_block` calls `BlockMerkleRoot`, which uses `ComputeMerkleRoot`, but does not exercise the `TransactionMerklePath` → `ComputeMerklePath` → `MerkleComputation` code path.

  Coverage before adding test:
  <img width="2459" height="66" alt="before" src="https://github.com/user-attachments/assets/ca94015a-d7c2-4281-ac60-13b22f177b67" />

  Coverage after adding test:
  <img width="2459" height="66" alt="after" src="https://github.com/user-attachments/assets/b1d4e1bb-af72-46ab-8898-f18db39dd2fb" />

ACKs for top commit:
  kevkevinpal:
    ACK [ffcae82](ffcae82a68)
  maflcko:
    lgtm ACK ffcae82a68
  brunoerg:
    code review ACK ffcae82a68
  sedited:
    ACK ffcae82a68

Tree-SHA512: d2499d91269c4f4f9a86011f7ad13f675834662a5bd37b0e7cbe887a7d9acf4170e53f0bdc528011fc82866b9c1dec34f4e7e9cd64cc3100591c1580a4df5d00
2025-12-05 13:05:07 +00:00
merge-script
0c9ab0f8f8 Merge bitcoin/bitcoin#33956: net: fix use-after-free with v2->v1 reconnection logic
167df7a98c net: fix use-after-free with v2->v1 reconnection logic (Eugene Siegel)

Pull request description:

  `CConnman::Stop()` resets `semOutbound`, yet `m_reconnections` is not cleared in `Stop`. Each `ReconnectionInfo` contains a `grant` member that points to the memory that `semOutbound` pointed to and `~CConnman` will attempt to access the grant field (memory that was already freed) when destroying `m_reconnections`. Fix this by calling `m_reconnections.clear()` in `CConnman::Stop()` and add appropriate annotations.

  I was able to reproduce the original issue https://github.com/bitcoin/bitcoin/issues/33615 with the following diff by randomly stopping my node while it was attempting to reconnect (and verified that this patch fixes the issue, at least in my ~40-50 runs):
  <details>
  <summary> diff </summary>

  ```diff
  diff --git a/src/net.cpp b/src/net.cpp
  index ef1c63044a..9c1d161d8b 100644
  --- a/src/net.cpp
  +++ b/src/net.cpp
  @@ -1918,8 +1918,8 @@ void CConnman::DisconnectNodes()
       {
           LOCK(m_nodes_mutex);

  -        const bool network_active{fNetworkActive};
  -        if (!network_active) {
  +//        const bool network_active{fNetworkActive};
  +//        if (!network_active) {
               // Disconnect any connected nodes
               for (CNode* pnode : m_nodes) {
                   if (!pnode->fDisconnect) {
  @@ -1927,7 +1927,7 @@ void CConnman::DisconnectNodes()
                       pnode->fDisconnect = true;
                   }
               }
  -        }
  +//        }

           // Disconnect unused nodes
           std::vector<CNode*> nodes_copy = m_nodes;
  @@ -1941,7 +1941,7 @@ void CConnman::DisconnectNodes()
                   // Add to reconnection list if appropriate. We don't reconnect right here, because
                   // the creation of a connection is a blocking operation (up to several seconds),
                   // and we don't want to hold up the socket handler thread for that long.
  -                if (network_active && pnode->m_transport->ShouldReconnectV1()) {
  +                if (true) {
                       reconnections_to_add.push_back({
                           .addr_connect = pnode->addr,
                           .grant = std::move(pnode->grantOutbound),
  ```
  </details>

  I'm curious to see if others can reproduce as well.

ACKs for top commit:
  dergoegge:
    Code review ACK 167df7a98c
  darosior:
    utACK 167df7a98c
  mzumsande:
    ACK 167df7a98c

Tree-SHA512: 33fdfb110a7cdae182b5cd5400eea8a271308a62dd56491e0aef8865eff24a9ea908be74e4e2e2ee00ac1cb698e46f270f56dffffe34cf2cfd79e9b1079d6531
2025-12-05 10:23:45 +00:00
MarcoFalke
fa4395dffd refactor: Remove unused LogPrintf 2025-12-04 19:53:06 +01:00
MarcoFalke
fa05181d90 scripted-diff: LogPrintf -> LogInfo
This refactor does not change behavior.

-BEGIN VERIFY SCRIPT-

 sed --in-place 's/\<LogPrintf\>/LogInfo/g' \
   $( git grep -l '\<LogPrintf\>' -- ./contrib/ ./src/ ./test/ ':(exclude)src/logging.h' )

-END VERIFY SCRIPT-
2025-12-04 19:52:49 +01:00