Commit Graph

924 Commits

Author SHA1 Message Date
Sjors Provoost
5ed41752c5 refactor: use SignOptions for SignTransaction 2026-04-28 17:43:03 +02:00
Lőrinc
e6430b2773 bench: make setup() use single-iteration epochs
`setup()` in nanobench runs once per epoch, not once per timed call.
If an epoch executes the benchmark body multiple times, `setup()` can silently leave later iterations with different preconditions.

Make `setup()` force `epochIterations(1)` itself: keep rejecting incompatible larger explicit epoch sizes, but allow existing single-iteration callers such as `-sanity-check`.

With `setup()` handling this centrally, remove the redundant `epochIterations(1)` calls from the benchmarks that use it.

Co-authored-by: David Gumberg <davidzgumberg@gmail.com>
2026-04-23 20:54:40 +02:00
Lőrinc
ba0078e3bf bench: fix ephemeral spend inputs
`MempoolCheckEphemeralSpends` wrote every prevout to `tx2.vin[0]` instead of `tx2.vin[i]`.
That left only one child input pointing at the parent transaction, while the remaining inputs kept default prevouts.

Write each prevout to `vin[i]` instead.
Add an assertion that the last child input spends the last parent output.

Co-authored-by: David Gumberg <davidzgumberg@gmail.com>
2026-04-23 20:53:58 +02:00
Lőrinc
b8b7f896e8 bench: drop duplicate balance benchmark
`WalletBalanceMine` duplicated `WalletBalanceClean` exactly.
Remove the duplicate registration so the balance benchmark list stays distinct.
2026-04-23 20:53:57 +02:00
Ava Chow
bb90899955 Merge bitcoin/bitcoin#34435: refactor: use _MiB/_GiB consistently for byte conversions
af0ee28eb6 refactor: use _MiB consistently for Mebibyte conversions (Lőrinc)
b3edd30aa2 util: add _GiB for Gibibyte conversions (Lőrinc)

Pull request description:

  ### Problem
  Byte-size conversions in the codebase currently show up in many equivalent formats (multiplication/division chains, shifts, hex/binary literals), which creates a maintenance burden and makes review error-prone - especially considering the architectural differences of `size_t`.
  Inspired by https://github.com/bitcoin/bitcoin/pull/34305#discussion_r2734720002, it seemed appropriate to unify `Mebibyte` usage across the codebase and add `Gibibyte` support with 32/64 bit `size_t` validation.

  ### Fix
  This PR refactors those call sites to use `""_MiB` (existing) and `""_GiB` (new), and adds the encountered value/pattern replacements to unit tests to make review straightforward, and to ensure the conversions remain valid.
  The literals are overflow-checked when converting to `size_t`, and unit tests cover the 32-bit boundary cases.

  Concretely, it replaces patterns such as:
  * `1024*1024`, `1<<20`, `0x100000`, `1048576`, `/ 1024 / 1024`, `* (1.0 / 1024 / 1024)` → `1_MiB` or `double(1_MiB)`
  * `1024*1024*1024`, `1<<30`, `0x40000000`, `1024_MiB`, `>> 30` → `1_GiB`

  (added unit tests for each replacement category to ease review)

  Additionally, declarations whose initializer reads a `_MiB`/`_GiB` literal are switched to braced initialization so a future oversized value is rejected at compile time through the narrowing check instead of silently truncating.

  ### Note
  In the few places where arithmetic involves signed values, the result is identical to the previous code assuming those quantities never become negative.

ACKs for top commit:
  achow101:
    ACK af0ee28eb6
  janb84:
    ACK af0ee28eb6
  maflcko:
    review ACK af0ee28eb6 🖍
  hodlinator:
    re-ACK af0ee28eb6

Tree-SHA512: 55286ce3f833f88335394a74e9e0b95c7d023e5cdc9ded40accbbbcd870101e4dcc05926865d6bef4c1be1ebd648aa3fdf947ef9575633ccfe56691f145d7a2d
2026-04-22 15:37:59 -07:00
merge-script
1a4371cc3d Merge bitcoin/bitcoin#34882: refactor: Use NodeClock::time_point in more places
fa1015bbcb refactor: Use NodeClock::time_point for m_connected (MarcoFalke)
fa244b984c refactor: Use NodeClock::time_point for m_last_send/recv and m_ping_start (MarcoFalke)
fa2605b204 refactor: Use NodeClock::time_point for CNetMessage::m_time (MarcoFalke)
fa644e625b refactor: Use NodeClock::duration for m_last_ping_time/m_min_ping_time/m_ping_wait (MarcoFalke)
333316f6be doc: Fix typo "eviction criterium" -> "eviction criterion" (MarcoFalke)
fa54fb0129 refactor: gui: Accept up to nanoseconds in formatDurationStr, but clarify they are ignored (MarcoFalke)
fab88884b7 refactor: Avoid manual chrono casts with * or / (MarcoFalke)
facfce37f6 util: Add NodeClock::epoch alias (MarcoFalke)
fa41e072b3 refactor: Use NodeClock alias over deprecated GetTime (MarcoFalke)

Pull request description:

  It is a bit confusing to have some code use the deprecated `GetTime`, which returns a duration and not a time point, and other code to use `NodeClock` time points.

  Fix a few more places to properly use time_point types.

ACKs for top commit:
  stickies-v:
    re-ACK fa1015bbcb
  seduless:
    re-ACK fa1015bbcb
  naiyoma:
    ACK fa1015bbcb
  sedited:
    ACK fa1015bbcb

Tree-SHA512: 7c8df1a9025271b08a40fd0d176bcbbf90920bc4d83a6e1c8cfaad2a894632af2b9a1aca5c3c9ddc3803e559dd168244121fd188ef22f399d60075ff194a9140
2026-04-21 22:46:25 +02:00
Lőrinc
13c8df4d5a refactor: replace DataStream with SpanReader in block deserialization tests
These benchmark inputs are immutable fixture bytes, so `DataStream` adds an unnecessary owned buffer and the setup needed to recreate or preserve its state.

Use `SpanReader` for block deserialization in `checkblock` instead.
This keeps `DeserializeBlockTest` focused on deserialization work, while `CheckBlockTest` still uses untimed setup only to rebuild a fresh uncached `CBlock` for the timed `CheckBlock()` call.

Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
2026-04-21 12:27:20 +02:00
Lőrinc
2529f25555 refactor: use SpanReader in PrevectorDeserialize
`PrevectorDeserialize` only needs a reusable read-only view over fixed serialized bytes.
Keeping a mutable `DataStream` around just to call `Rewind()` is unnecessary.

Rebuild a fresh `SpanReader` for each benchmark run and remove `DataStream::Rewind()`, whose remaining use was this benchmark-only reset path.
The benchmark can now serialize exactly the 1000 entries it deserializes, so drop the stale extra element that used to avoid full consumption.

Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
2026-04-21 12:27:20 +02:00
Lőrinc
b8eb6c2081 refactor: use SpanReader in TestBlockAndIndex
`TestBlockAndIndex` still deserialized its fixed block fixture through `DataStream` and appended a dummy byte to avoid compaction after full consumption.

Use `SpanReader` for that fixture instead.
This removes the leftover dummy-byte workaround and reads the immutable fixture through a read-only view.
2026-04-21 12:25:44 +02:00
Lőrinc
af0ee28eb6 refactor: use _MiB consistently for Mebibyte conversions
Replace hard-coded MiB byte conversions (e.g. `1024*1024`, `1<<20`, `1048576`) with the existing `_MiB` literal to improve readability and avoid repeating constants.
In the few spots where arithmetic involves signed values, the result is identical to the previous code assuming those quantities never turn negative.

Also switch to brace init on every declaration assigned from `_MiB`/`_GiB` literals so a future oversized value (e.g. `unsigned int x{4096_MiB}`) becomes a compile error through the C++11 narrowing check instead of silently truncating.

Extend unit tests to cover the 32-bit `size_t` overflow boundary and to assert equivalence for integer and floating-point conversions.

Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
Co-authored-by: w0xlt <94266259+w0xlt@users.noreply.github.com>
2026-04-20 11:15:41 +02:00
merge-script
963ea38c0c Merge bitcoin/bitcoin#35038: bench: add script verification benchmark for P2TR script-path spends
fbffe8a64a bench: improve `VerifyNestedIfScript` benchmark precision (make stack clearing untimed) (David Gumberg)
616ee6fe74 bench: add script verification benchmark for P2TR script-path spends (Sebastian Falbesoner)

Pull request description:

  Similarly as #34472 already did for key-path spends, this PR adds a benchmark for P2TR script-path spends. So far we don't have a benchmark on master yet that exercises the verification of taproot commitments ([`VerifyTaprootCommitment`](141fbe4d53/src/script/interpreter.cpp (L1903))).

  Note that the tapscript leaf intentionally includes a single OP_CHECKSIG as it likely reflects the real world best. Spending tapscript leafs without any signature checks don't make much sense (they could be trivially tampered with and thus stolen by miners), and doing more than one signature check seems the exception rather than the rule.

  The primary motivation for this PR is to evaluate how potential secp256k1 changes in pubkey tweaking (e.g. [#1843](https://github.com/bitcoin-core/secp256k1/pull/1843)) may impact script verification performance.

ACKs for top commit:
  davidgumberg:
    reACK fbffe8a
  l0rinc:
    ACK fbffe8a64a
  sedited:
    ACK fbffe8a64a

Tree-SHA512: 6fa1f2c336d6332b4f2d22173279ee29ad3ec5e5431109913a6978fef32e22a34d3247729ac9092bfdbbcd8f9dfcad8da50bc4ede2cb7efc1f93d6a744ddf41b
2026-04-19 12:01:33 +02:00
merge-script
2f9aa400d9 Merge bitcoin/bitcoin#33032: wallet, test: Replace MockableDatabase with in-memory SQLiteDatabase
037ea2c714 walletdb: Remove m_mock from SQLiteDatabase (Ava Chow)
59484e2fdb wallet: Make Mockable{Database,Batch} subclasses of SQLite classes (Ava Chow)
b69f989dc5 wallet, bench: Use TestingSetup in CoinSelection benchmark (Ava Chow)
e7d67c9fd9 test: Make duplicating MockableDatabases use cursor and batch (Ava Chow)
964eafb71c bench, wallet: Make WalletMigration's setup WalletBatch scoped (Ava Chow)

Pull request description:

  `MockableDatabase` was introduced for the tests to avoid tying non-database tests to a particular database type. However, since the only database type now is sqlite, and because the mockable behavior is no longer used by the tests, we can replace usage of the `MockabeDatabase` with a SQLite database that lives only in memory.

  This is particularly useful for future work that has the wallet make use of SQLite's capabilities more, which are less conducive to having a separate mock database implementation.

ACKs for top commit:
  brunoerg:
    code review ACK 037ea2c714
  sedited:
    Re-ACK 037ea2c714
  furszy:
    Code review ACK 037ea2c714

Tree-SHA512: 0a99c27ef4e590966b3af929bf3acf99666861905aabf150fe5660ea07c881a49935a4e7dcd676dcd5e70616898d89d872b6e156ae9c600de1361c1b2469b64d
2026-04-19 10:54:39 +02:00
David Gumberg
fbffe8a64a bench: improve VerifyNestedIfScript benchmark precision (make stack clearing untimed)
on `master`:

|               ns/op |                op/s |    err% |          ins/op |          cyc/op |    IPC |         bra/op |   miss% |     total | benchmark
|--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
|           19,890.59 |           50,275.02 |    1.3% |      673,992.65 |       85,238.74 |  7.907 |     143,404.89 |    0.0% |      0.01 | `VerifyNestedIfScript`

vs this commit:

|           ns/script |            script/s |    err% |      ins/script |      cyc/script |    IPC |     bra/script |   miss% |     total | benchmark
|--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
|           12,089.00 |           82,719.83 |    0.4% |      375,703.00 |       51,987.00 |  7.227 |      69,249.00 |    0.2% |      0.00 | `VerifyNestedIfScript`

Co-authored-by: Lőrinc <pap.lorinc@gmail.com>
2026-04-14 13:33:22 +02:00
Sebastian Falbesoner
616ee6fe74 bench: add script verification benchmark for P2TR script-path spends
To reflect the likely most common real-world scenario, a single
OP_CHECKSIG is contained in the Tapscript leaf.

While touching this benchmark, also set the operation unit to "script"
and do some minor refactorings to deduplicate code and improve readability.

Co-authored-by: David Gumberg <davidzgumberg@gmail.com>
Co-authored-by: Lőrinc <pap.lorinc@gmail.com>
2026-04-14 13:31:08 +02:00
Ryan Ofsky
976985eccd Merge bitcoin/bitcoin#34124: validation: make CCoinsView a pure virtual interface
8783cc8056 refactor: inline `CCoinsViewBacked` implementation (Lőrinc)
86296f276d coins: make `CCoinsView` methods pure virtual (Lőrinc)
b637566c8d coins: add explicit `CoinsViewEmpty` noop backend (Lőrinc)
90c635c01c fuzz: keep backend assertions aligned to active backend (Lőrinc)
a9f92e3497 refactor: normalize CCoinsView whitespace and signatures (Lőrinc)
38a99f3344 scripted-diff: normalize `CCoinsView` naming (Lőrinc)
06172ef0d5 refactor: rename `hashBlock` to `m_block_hash` to avoid shadowing (Lőrinc)

Pull request description:

  ### Problem
  `CCoinsView` is the coins view interface, but historically it also provided built-in no-op behavior:

  * It provided default no-op implementations (returning `std::nullopt`, `uint256()`, `false`, or `nullptr`) instead of being pure virtual.
  * Callers could instantiate a bare `CCoinsView` and get silent no-op behavior.
  * Mixing the interface definition with a built-in dummy implementation blurred the abstraction boundary.

  ### Context
  This is part of the ongoing coins caching cleanup in #34280.

  ### Fix
  This PR separates the interface from no-op behavior and makes `CCoinsView` pure virtual in incremental steps:
  * Add `CoinsViewEmpty` as an explicit no-op coins view for tests, benchmarks, and temporary backends.
  * Replace direct bare-`CCoinsView` test and dummy instantiations with `CoinsViewEmpty`.
  * Make all `CCoinsView` methods pure virtual (`PeekCoin`, `GetCoin`, `HaveCoin`, `GetBestBlock`, `GetHeadBlocks`, `BatchWrite`, `Cursor`, `EstimateSize`).
  * Remove the legacy default implementations from `coins.cpp`.
  * Update fuzz and dummy backends to use `CoinsViewEmpty` explicitly.

ACKs for top commit:
  w0xlt:
    reACK 8783cc8056
  ryanofsky:
    Code review ACK 8783cc8056. Just updated comments and variable name since last review. The fuzz test code is much clearer now IMO
  andrewtoth-exo:
    ACK 8783cc8056
  ajtowns:
    ACK 8783cc8056

Tree-SHA512: cfc831578aa309788c1b5dafbfecca3de388cc4215534c3f3df24f90d7770ed37b1fd7aa134df91d611d0a1ca75929accb98d5ed7df7b52851c259e04f08e4a3
2026-04-13 08:40:36 -04:00
MarcoFalke
fa1015bbcb refactor: Use NodeClock::time_point for m_connected
Also, increase the precision to the native one, over prescribing second
precision.
2026-04-13 09:49:13 +02:00
Ava Chow
58dccd27e1 Merge bitcoin/bitcoin#34858: test: Use NodeClockContext in more tests
faad08e59c test: Use NodeClockContext in more tests (MarcoFalke)
fa8fe0941e fuzz: Use NodeClockContext (MarcoFalke)
fa9f434df8 test: Allow time_point in boost checks (MarcoFalke)

Pull request description:

  Currently mocktime is written to a global, which may leak between sub-tests (albeit some tests try to reset the mocktime on a best-effort basis). Also, when advancing it, one has to keep a counter variable around.

  Fix both issues by using the recently added `NodeClockContext`, which resets the mocktime once it goes out of scope. Also, it has a method to advance the mocktime by a delta.

ACKs for top commit:
  achow101:
    ACK faad08e59c
  seduless:
    Tested ACK faad08e59c
  frankomosh:
    Tested ACK faad08e59c. Ran all relevant tests, all clean. Also verified that the default-constructor call sites in orphanage_tests and addrman_tests behave identically to the explicit `{Now<NodeSeconds>()}` form.
  ryanofsky:
    Code review ACK faad08e59c but had a question about dropping +1 in one test below.

Tree-SHA512: bd56931970eed02bfcf3f3593ef64a61a8a1d8cc8adf190d6903b35df0fd7e6d865678c7d5bd23ce53d074cb2cf53a0a19212fdeb593b047dac5561859bc86b0
2026-04-09 14:33:30 -07:00
Lőrinc
b637566c8d coins: add explicit CoinsViewEmpty noop backend
Introduce `CoinsViewEmpty` as an explicit no-op `CCoinsView` implementation, and define its singleton accessor out of line in `coins.cpp` to avoid `-Wunique-object-duplication` in shared-library builds.`
Use it at call sites that intentionally want a no-op backend instead of constructing anonymous placeholder views.

`CCoinsViewTest` and `CoinsViewBottom` now inherit defaults from `CoinsViewEmpty` (e.g. the unused `EstimateSize()`, which now returns 0).

Co-authored-by: Ryan Ofsky <ryan@ofsky.org>
2026-04-08 22:36:13 +02:00
Ava Chow
b730dc3301 Merge bitcoin/bitcoin#34208: bench: add fluent API for untimed setup steps in nanobench
8825051e08 refactor: improve benchmark setup and execution for various tests (Lőrinc)
83b8528ddb bench: add fluent API for untimed setup steps in `nanobench` (Lőrinc)

Pull request description:

  ### Context
  As described in https://github.com/martinus/nanobench/issues/130, we have a few benchmarks where we have to reset the state between runs; otherwise, the repetitions will do something different than the first iteration.

  ### Upstream
  I have opened a PR to `nanobench` to introduce an untimed setup phase, see: https://github.com/martinus/nanobench/pull/136

  ### Tests

  Tests were only added upstream. It would be a bit awkward to wire them into `nanobench.h` outside the benchmarking setup:
  58350cfe59 (diff-88160f647ce57661afe7d755fa70a5fa342a2b79d72d3511596878e69ed5cdc3)

  ### Fix
  I have moved the changes here as well and applied them to a few simple benchmarks as a demonstration.
  We can revert the ones that are controversial and add others in follow-ups. This PR is mostly meant to add the `setup` feature.

  ### Benchmarks
  Most benchmarks show a modest "speedup"; others a "slowdown" - but it's only the effect of the setup that's not measured anymore - and a `run` phase that does the same operation in each epoch iteration (wallet benchmark changes were reverted for simplicity):
  <img width="1496" height="882" alt="image" src="https://github.com/user-attachments/assets/34c14565-f3df-41e5-9a86-95b2ca21703a" />

ACKs for top commit:
  achow101:
    ACK 8825051e08
  janb84:
    re ACK 8825051e08
  sedited:
    ACK 8825051e08

Tree-SHA512: b3e385abcfca013a21b3785b0b837c2b61e302d71a098dadcd8d2f0cb42f6bbf4a222299771443f095962d1b24e696d5684f2b8efdb6f63f2f939699961cdf0d
2026-04-06 13:55:13 -07:00
Ava Chow
b69f989dc5 wallet, bench: Use TestingSetup in CoinSelection benchmark 2026-04-02 11:18:26 -07:00
Ava Chow
964eafb71c bench, wallet: Make WalletMigration's setup WalletBatch scoped
WalletBatch needs to be in a scope so that it is destroyed before the
database is closed during migration.
2026-04-02 11:18:26 -07:00
Hennadii Stepanov
8b49e2dd4e ci, iwyu: Fix warnings in src/util and treat them as errors 2026-03-30 16:39:42 +01:00
merge-script
954374d405 Merge bitcoin/bitcoin#34926: test: Replace DEBUG_LOG_OUT with -printtoconsole=1
261d229455 test: Replace DEBUG_LOG_OUT with -printtoconsole=1 (Hodlinator)

Pull request description:

  `-printtoconsole=1` has the same functionality but works in more cases than `DEBUG_LOG_OUT`, so remove the latter (`-printtoconsole` is already used when fuzzing). This means we can drop `G_TEST_LOG_FUN`.

  ---
  Behavior can be verified through
  ```shell
  ctest --test-dir build --debug
  ```
  and checking for:
  ```
  142: Test command: /home/hodlinator/bc/2/build/bin/test_bitcoin "--run_test=coinselector_tests" "--catch_system_error=no" "--log_level=test_suite" "--" "-printtoconsole=1"
  ...
  142: 2026-03-26T13:40:02.169392Z [test] [../src/kernel/context.cpp:20] [operator()] Using the 'sse4(1way);sse41(4way);avx2(8way)' SHA256 implementation
  ```

  ---
  Inspired by: https://github.com/bitcoin/bitcoin/pull/34918#discussion_r2994780532

ACKs for top commit:
  nkatha23:
    ACK 261d229
  maflcko:
    review ACK 261d229455 📬
  kevkevinpal:
    crACK [261d229](261d229455)
  janb84:
    cr ACK 261d229455

Tree-SHA512: f4c793b4a00730ade113241baeaaef08ae0333df15ada5929dd46aacd1ac875733e58aa341fac8fb5875eb5ebca735d40c664bf0ef62132094e0c993da5b20e5
2026-03-28 14:44:16 +08:00
Hodlinator
261d229455 test: Replace DEBUG_LOG_OUT with -printtoconsole=1 2026-03-26 14:41:57 +01:00
David Gumberg
a7e4a59d6d qa: Remove all instances of remove_all except test cleanup
Adds a lint check for `remove_all()`

`fs::remove_all()`/`std::filesystem::remove_all()` is extremely
dangerous, all user-facing instances of it have been removed, and it
also deserves to be removed from the places in our test code where it is
being used unnecessarily.
2026-03-24 16:03:02 -07:00
merge-script
667e081a2a Merge bitcoin/bitcoin#34598: bench: use larger payload in HexStrBench
353c660be5 bench: use deterministic `HexStr` payload (Lőrinc)

Pull request description:

  ### Context
  Split out of https://github.com/bitcoin/bitcoin/pull/32554
  Inspired by https://github.com/bitcoin/bitcoin/pull/32457#discussion_r2081323234

  ### Problem
  `HexStrBench` uses the bytes from the embedded block fixture as a random source of bytes to measure `HexStr` performance against.
  This coupling makes block benchmark migrations in #32554 slightly more work than necessary.

  ### Fix
  We can use deterministic pseudo-random bytes instead so this benchmark keeps stable input without fixture coupling.
  Use `MAX_BLOCK_WEIGHT` so the benchmark stays in the same size range and keeps measured work above harness overhead.
  This changes the benchmark baseline because input size moves from about 1 MB to 4 MB.

ACKs for top commit:
  maflcko:
    lgtm ACK 353c660be5
  sedited:
    ACK 353c660be5
  hodlinator:
    ACK 353c660be5

Tree-SHA512: 5144b9b71761c581ff13c8f1163efed5e97f247f3c760dd7e513209c84d50f13253aa0d2ab3a431aaa51c204fea51bece41ac128b3d0e3a9ef02d1be11d6a6db
2026-03-24 16:35:25 +01:00
MarcoFalke
faad08e59c test: Use NodeClockContext in more tests 2026-03-20 10:33:23 +01:00
Ava Chow
bc1c540920 Merge bitcoin/bitcoin#29060: Policy: Report debug message why inputs are non standard
d8f4e7caf0 doc: add release notes (ismaelsadeeq)
248c175e3d test: ensure `ValidateInputsStandardness` optionally returns debug string (ismaelsadeeq)
d2716e9e5b policy: update `AreInputsStandard` to return error string (ismaelsadeeq)

Pull request description:

  This PR is another attempt at  #13525.

  Transactions that fail `PreChecks` Validation due to non-standard inputs now  returns invalid validation state`TxValidationResult::TX_INPUTS_NOT_STANDARD` along with a debug error message.

  Previously, the debug error message for non-standard inputs do not specify why the inputs were considered non-standard.
  Instead, the same error string, `bad-txns-nonstandard-inputs`, used for all types of non-standard input scriptSigs.

  This PR updates the `AreInputsStandard`  to include the reason why inputs are non-standard in the debug message.
  This improves the `Precheck` debug message to be more descriptive.

  Furthermore, I have addressed all remaining comments from #13525 in this PR.

ACKs for top commit:
  instagibbs:
    ACK d8f4e7caf0
  achow101:
    ACK d8f4e7caf0
  sedited:
    Re-ACK d8f4e7caf0

Tree-SHA512: 19b1a73c68584522f863b9ee2c8d3a735348667f3628dc51e36be3ba59158509509fcc1ffc5683555112c09c8b14da3ad140bb879eac629b6f60b8313cfd8b91
2026-03-19 15:43:18 -07:00
Ava Chow
3ca3e519b6 Merge bitcoin/bitcoin#34684: refactor: Enable -Wswitch in exhaustive switch'es, Enable -Wcovered-switch-default
fa4ec13b44 build: Enable -Wcovered-switch-default (MarcoFalke)
fa2670bd4b refactor: Enable -Wswitch in exhaustive switch (MarcoFalke)

Pull request description:

  The compiler flag `-Wswitch` is enabled. However, it can not fire when a `default:` case exists. Fix that by removing the default case where a switch is already handling all cases exhaustively.

  Also, enable `-Wcovered-switch-default` to catch those cases at compile time in the future.

  Also, apply the comment according to the dev notes.

  Can be reviewed via `--ignore-all-space`

ACKs for top commit:
  stickies-v:
    re-ACK fa4ec13b44, no changes except for addressing silent merge conflict from d339884f1d
  l0rinc:
    ACK fa4ec13b44
  achow101:
    ACK fa4ec13b44
  sedited:
    ACK fa4ec13b44

Tree-SHA512: 8dd9e71a8cd338255f43448a59a1a4d40a9fc16e19a707cc10fb71442d4df9f82a0e5fae77868ef49cd0ea27fdd972687572c1a50b6aba7e08c6ce87576afc6a
2026-03-19 14:15:38 -07:00
Ava Chow
abaadc3d5b Merge bitcoin/bitcoin#31774: crypto: Use secure_allocator for AES256_ctx
af0da2fce2 crypto: Use `secure_allocator` for `AES256CBC*::iv` (David Gumberg)
d53852be31 crypto: Use `secure_allocator` for `AES256_ctx` (David Gumberg)
8c6fedaa81 build: `lockedpool.cpp` kernel -> crypto (David Gumberg)
51ac1abf6f bench: Add wallet encryption benchmark (David Gumberg)
9a15872516 wallet: Make encryption derivation clock mockable (David Gumberg)
ae5485fa0d refactor: Generalize derivation target calculation (David Gumberg)

Pull request description:

  Fixes #31744

  Reuse `secure_allocator` for `AES256_ctx` in the aes 256 encrypters and decrypters and the `iv` of `AES256CBC` encrypters and decrypters. These classes are relevant to `CCrypter`, used for encrypting wallets, and my understanding is that if an attacker knows some or all of the contents of these data structures (`AES256_ctx` & `iv`) they might be able to decrypt a user's wallet.

   Presently the `secure_allocator` tries to protect sensitive data with `mlock()` on POSIX systems and `VirtualLock()` on Windows to prevent memory being paged to disk, and by zero'ing out memory contents on deallocation with `memory_cleanse()` which is similar to `OPENSSL_cleanse()` by scaring compilers away from optimizing `memset` calls on non-Windows systems, and using `SecureZeroMemory()` on Windows.

ACKs for top commit:
  achow101:
    ACK af0da2fce2
  furszy:
    utACK af0da2fce2
  theStack:
    re-ACK af0da2fce2

Tree-SHA512: 49067934fd2f2b285fc7b1a7c853fd2d4475431b3a811ae511f61074dc71a99a0826c3ab40ab4a5dfc84b2b9914a90c920d2484b38ac19502e3bd6170ad27622
2026-03-13 13:34:35 -07:00
MarcoFalke
fa2670bd4b refactor: Enable -Wswitch in exhaustive switch
Also, apply the comment according to the dev notes.

Also, modify the dev notes to give a lambda-wrapped example.

Can be reviewed via --ignore-all-space

Co-authored-by: Lőrinc <pap.lorinc@gmail.com>
2026-03-13 09:02:09 +01:00
merge-script
9df4f9d100 Merge bitcoin/bitcoin#34472: bench: add script verification benchmark for P2TR key path spends
d339884f1d bench: add script verification benchmark for P2TR key path spends (Sebastian Falbesoner)
dd93362a1d bench: simplify script verification benchmark, generalize signing (Sebastian Falbesoner)

Pull request description:

  We currently benchmark Schnorr signature verification only in the context of block validation ([`ConectBlock*`](8bb77f348e/src/bench/connectblock.cpp (L107)) benchmarks), but not individually for single inputs [1]. This PR adds a script verification benchmark for P2TR key path spends accordingly, by generalizing the already existing one for P2WPKH spends.

  This should make it easier to quantify potential performance improvements like e.g. https://github.com/bitcoin-core/secp256k1/pull/1777, which allows to plug in our HW-optimized SHA256 functions to be used in libsecp256k1 (see the linked example commit f68bef06d9). IIRC from last CoreDev, the main speedup from this is expected for ECDSA signing though (as this involves quite a lot of hashing), but it still makes sense to have verification benchmarks available for both signature types as well.

  (An alternative way could be to add benchmarks for the signing/verifying member functions `CKey::Sign{,Schnorr}`, `CPubKey::Verify` and `XOnlyPubKey::VerifySchnorr` directly, if we prefer that.)

  [1] this claim can be practically verified by putting an `assert(false);` into `XOnlyPubKey::VerifySchnorr`: the three benchmarks crashing are `ConnectBlockAllSchnorr`, `ConnectBlockMixedEcdsaSchnorr` and `SignTransactionSchnorr` (as signing includes verification)

ACKs for top commit:
  furszy:
    ACK d339884f1d
  sedited:
    Re-ACK d339884f1d
  w0xlt:
    ACK d339884f1d

Tree-SHA512: efd20444984bdf1dab4d3d876fdbe2a3a838d7cebc0e31e26683009b81afe4dab8611e2c28c87e46fe8b7e305895c93e461b7934a5aaf293f72b19488b9cec60
2026-03-11 10:11:02 +01:00
David Gumberg
51ac1abf6f bench: Add wallet encryption benchmark 2026-03-10 19:09:21 -07:00
merge-script
3a222507fd Merge bitcoin/bitcoin#34037: wallet, doc: clarify the coin selection filters that enforce cluster count
a067ca3410 [doc] coin selection filters by max cluster count, not descendant (glozow)
f7be5fb8fc [refactor] rename variable to clarify it is unused and cluster count (glozow)

Pull request description:

  Followup to #33629.

  Fix misleading docs and variable names. Namely, `getTransactionAncestry` returns the cluster count, not max descendant count of ancestor set (not worth reimplementing as it is merely a heuristic). No behavior changes - I don’t think much needs to be changed for the first release containing cluster mempool.

  Current `CoinEligibilityFilter`s enforce a maximum ancestor count (summed across all outputs, potentially overestimating) and max descendant count across ancestors of the output.

  Since #33629, these filters have started using cluster count instead of max desc count across ancestors. The change isn’t dangerous, as the cluster count bounds descendant count as well. Currently, the wallet is essentially enforcing a mixture of both limits - this is good while we are transitioning. Note that the cluster count enforced is 25, not 64, since it's grabbing the node's descendant count limit. While it is not an apples-to-apples comparison, a cluster count limit of 25 helps us avoid busting legacy descendant limits (which will be common on the network for a while).

  Potential things for the future, out of scope for this PR:
  - When we get rid of the ancestor/descendant config options, `getPackageLimits` can probably be replaced with hard-coded values.
  - Change the `OutputGroup`s to track the actual cluster count that results from spending these outputs and merging their clusters.
  - Loosen from 25 after that policy is no longer common.
  - Clean up `getPackageLimits`.

ACKs for top commit:
  achow101:
    ACK a067ca3410
  ismaelsadeeq:
    reACK a067ca3410
  rkrux:
    crACK a067ca3410

Tree-SHA512: d7cacd5bf668d42e26e8b83e42a42c280929c3bfd554c3db1de605e5939f8b36c14ecfd2839abeb4eec352363df1891b3420a693c250916391ab10a5ce26396b
2026-03-09 10:11:08 +00:00
Lőrinc
8825051e08 refactor: improve benchmark setup and execution for various tests
Note that `make_hard_case` already clears the UTXO pool in `coin_selection.cpp`.

./build/bin/bench_bitcoin -filter='^(BnBExhaustion|AddrManAddThenGood|DeserializeBlockTest|DeserializeAndCheckBlockTest|CheckBlockTest|LoadExternalBlockFile|FindByte|WalletCreatePlain|WalletCreateEncrypted|WalletLoadingDescriptors)$'

|               ns/op |                op/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|       15,088,500.00 |               66.28 |    0.2% |      0.17 | `AddrManAddThenGood`
|          179,208.00 |            5,580.11 |    2.0% |      0.00 | `BnBExhaustion`

|            ns/block |             block/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|          318,166.00 |            3,143.01 |    3.5% |      0.00 | `CheckBlockTest`
|          886,750.00 |            1,127.71 |    0.8% |      0.01 | `DeserializeBlockTest`

|               ns/op |                op/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|               42.00 |       23,809,523.81 |    2.4% |      0.00 | `FindByte`
|        5,473,208.00 |              182.71 |    0.4% |      0.06 | `LoadExternalBlockFile`
|      584,168,041.00 |                1.71 |    0.3% |      6.43 | `WalletCreateEncrypted`
|      168,040,458.00 |                5.95 |    1.1% |      1.85 | `WalletCreatePlain`
|      155,446,625.00 |                6.43 |    0.7% |      0.78 | `WalletLoadingDescriptors`

|               ns/op |                op/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|       14,894,917.00 |               67.14 |    0.3% |      0.16 | `AddrManAddThenGood`
|          177,667.00 |            5,628.51 |    1.3% |      0.00 | `BnBExhaustion`

|            ns/block |             block/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|          313,791.00 |            3,186.83 |    3.8% |      0.00 | `CheckBlockTest`
|          888,208.00 |            1,125.86 |    0.7% |      0.01 | `DeserializeBlockTest`

|               ns/op |                op/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|               41.00 |       24,390,243.90 |    2.4% |      0.00 | `FindByte`
|        5,445,208.00 |              183.65 |    1.0% |      0.06 | `LoadExternalBlockFile`
|      581,800,500.00 |                1.72 |    0.4% |      6.40 | `WalletCreateEncrypted`
|      166,035,583.00 |                6.02 |    0.5% |      1.82 | `WalletCreatePlain`
|      153,574,792.00 |                6.51 |    0.1% |      0.77 | `WalletLoadingDescriptors`
2026-03-08 12:02:18 +00:00
Lőrinc
83b8528ddb bench: add fluent API for untimed setup steps in nanobench
Some benchmarks need per-epoch state reset so every measured run does the same work.
Add `Bench::setup(...).run(...)` for untimed per-epoch setup.
The existing `run()` now delegates to `runImpl()` with an empty setup lambda, keeping the old API unchanged.

This vendors the upstream change from `martinus/nanobench`.
The upstream PR also adds tests that verify setup is excluded from timing and runs once before each epoch's iterations.
Those tests are not copied here because wiring them into `src/bench/nanobench.h` outside the benchmarking setup would be awkward.

The `Default is 1ms, so we are mostly relying ...` comment update matches current upstream `nanobench` master.

-------

Running a few benchmarks (which will be migrated in the next commit to use the new setup method) several times to showcase the spread:

./build/bin/bench_bitcoin -filter='^(BnBExhaustion|AddrManAddThenGood|DeserializeBlockTest|DeserializeAndCheckBlockTest|CheckBlockTest|LoadExternalBlockFile|FindByte|WalletCreatePlain|WalletCreateEncrypted|WalletLoadingDescriptors)$'

|               ns/op |                op/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|       26,400,542.00 |               37.88 |    0.4% |      0.29 | `AddrManAddThenGood`
|          189,075.00 |            5,288.91 |    0.4% |      0.01 | `BnBExhaustion`

|            ns/block |             block/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|        1,237,000.00 |              808.41 |    2.4% |      0.01 | `DeserializeAndCheckBlockTest`
|          893,333.00 |            1,119.40 |    0.6% |      0.01 | `DeserializeBlockTest`

|               ns/op |                op/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|               31.62 |       31,622,370.70 |    0.2% |      0.01 | `FindByte`
|        5,506,875.00 |              181.59 |    1.4% |      0.06 | `LoadExternalBlockFile`
|      593,480,333.00 |                1.68 |    0.4% |      6.53 | `WalletCreateEncrypted`
|      174,305,167.00 |                5.74 |    0.7% |      1.93 | `WalletCreatePlain`
|      160,833,875.00 |                6.22 |    0.2% |      0.80 | `WalletLoadingDescriptors`

|               ns/op |                op/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|       26,005,125.00 |               38.45 |    1.3% |      0.29 | `AddrManAddThenGood`
|          181,909.67 |            5,497.23 |    0.1% |      0.01 | `BnBExhaustion`

|            ns/block |             block/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|        1,223,000.00 |              817.66 |    2.8% |      0.01 | `DeserializeAndCheckBlockTest`
|          892,917.00 |            1,119.92 |    0.7% |      0.01 | `DeserializeBlockTest`

|               ns/op |                op/s |    err% |     total | benchmark
|--------------------:|--------------------:|--------:|----------:|:----------
|               31.58 |       31,660,608.70 |    0.5% |      0.01 | `FindByte`
|        5,612,750.00 |              178.17 |    1.1% |      0.06 | `LoadExternalBlockFile`
|      594,012,250.00 |                1.68 |    0.2% |      6.53 | `WalletCreateEncrypted`
|      174,668,334.00 |                5.73 |    0.8% |      1.92 | `WalletCreatePlain`
|      158,494,375.00 |                6.31 |    0.3% |      0.79 | `WalletLoadingDescriptors`
2026-03-08 12:02:17 +00:00
MarcoFalke
fa79098ce2 test: Fix shutdown vptr race in BlockFilterIndexSync bench 2026-03-04 20:39:06 +01:00
ismaelsadeeq
d2716e9e5b policy: update AreInputsStandard to return error string
This commit renames AreInputsStandard to ValidateInputsStandardness.

ValidateInputsStandardness now returns valid TxValidationState if all inputs
(scriptSigs) use only standard transaction forms else returns invalid
TxValidationState which states why an input is not standard.
2026-03-02 22:19:28 +00:00
Pieter Wuille
ecc9a84f85 clusterlin: use 'cost' terminology instead of 'iters' (refactor) 2026-02-24 10:08:47 -05:00
Lőrinc
353c660be5 bench: use deterministic HexStr payload
`HexStrBench` uses the bytes from the embedded block fixture as a random source of bytes to measure `HexStr` performance against.
This coupling makes block benchmark migrations slightly more work than necessary.

We can use deterministic pseudo-random bytes instead so this benchmark keeps stable input without fixture coupling.
Use `MAX_BLOCK_WEIGHT` so the benchmark stays in the same size range and keeps measured work above harness overhead.
This changes the benchmark baseline because input size moves from about 1 MB to 4 MB.

Co-authored-by: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>
Co-authored-by: Hodlinator <172445034+hodlinator@users.noreply.github.com>
2026-02-16 14:02:18 +01:00
glozow
a067ca3410 [doc] coin selection filters by max cluster count, not descendant
Avoid confusion by clarifying the docs and renaming the variables that
now hold cluster count rather than descendant count. No behavior change.
2026-02-11 11:09:42 -08:00
Pieter Wuille
fba004a3df txgraph: pass fallback_order to TxGraph (preparation)
This adds an std::function<strong_ordering(Ref&,Ref&)> argument to the
MakeTxGraph function, which can be used by the caller (e.g., mempool
code) to provide a fallback order to TxGraph.

This is just preparation; TxGraph does not yet use this fallback order
for anything.
2026-02-09 15:55:58 -05:00
Pieter Wuille
39d0052cbf clusterlin: make optimal linearizations deterministic (feature)
This allows passing in a fallback order comparator to Linearize(), which
is used as final tiebreak when deciding the order of chunks and
transactions within a chunk, rather than a random tiebreak.

The order of transactions within a chunk becomes:
1. Topology (parents before children)
2. Individual transaction feerate (high to low)
3. Weight (small to large)
4. Fallback (low to high fallback order)

The order of chunks within a cluster becomes:
1. Topology (chunks after their dependencies)
2. Feerate (high to low)
3. Weight (small to large)
4. Max-fallback (chunk with lowest maximum-fallback-tx first)

For now, txgraph passes a naive comparator to Linearize(), which makes
the cluster order deterministic when treating the input transactions as
identified by the DepGraphIndex. However, since DepGraphIndexes are the
result of possibly-randomized operations inside txgraph, this doesn't
actually make txgraph's per-cluster ordering deterministic. That will be
changed in a later commit, by using a txid-based fallback instead.
2026-02-09 15:55:58 -05:00
Pieter Wuille
3ddafceb9a txgraph: initialize Ref in AddTransaction (preparation)
Instead of returning a TxGraph::Ref from TxGraph::AddTransaction(),
pass in a TxGraph::Ref& which is updated to refer to the new transaction
in that graph.

This cleans up the usage somewhat, avoiding the need for dummy Refs in
CTxMemPoolEntry constructor calls, but the motivation is that a future
commit will allow a callback to passed to MakeTxGraph to define a
fallback order on the transaction objects. This does not work when a
Ref is created separately from the CTxMemPoolEntry it ends up living in,
as passing the newly-created Ref to the callback would be UB before it's
emplaced in its final CTxMemPoolEntry.
2026-02-09 15:55:55 -05:00
Sebastian Falbesoner
d339884f1d bench: add script verification benchmark for P2TR key path spends 2026-02-09 13:54:56 +01:00
Ava Chow
3b39a8aeb4 Merge bitcoin/bitcoin#34483: refactor: Use SpanReader over DataStream
fa0677d131 refactor: Use SpanReader over DataStream (MarcoFalke)
fad3eb3956 refactor: Use SpanReader over DataStream (MarcoFalke)
fa06e26764 refactor: [qt] Use SpanReader to avoid two vector copies (MarcoFalke)
fabd4d2e2e refactor: Avoid UB in SpanReader::ignore (MarcoFalke)
fa20bc2ec2 refactor: Use empty() over eof() in the streams interface (MarcoFalke)
fa879db735 test: Read debug log for self-checking comment (MarcoFalke)

Pull request description:

  This changes all places, where possible, to use SpanReader over DataStream. This makes the code easier to read and reason about, because `SpanReader` can never write data. Also, the code should be minimally faster, because it avoids a full redundant copy of the whole vector of bytes.

ACKs for top commit:
  stickies-v:
    re-ACK fa0677d131
  achow101:
    ACK fa0677d131
  janb84:
    re ACK fa0677d131
  sipa:
    crACK fa0677d131

Tree-SHA512: 1d9f43fc6e71d481cf7b8f8457f479745ee331734649e9e2c2ab00ce5d317112796c77afc328612ed004e65ac5c16fc92279d760cfb012cfddce9098c4af810f
2026-02-06 18:00:18 -08:00
MarcoFalke
fa0677d131 refactor: Use SpanReader over DataStream
This refactor does not change behavior. However, it avoids a vector
copy, which can lead to a minimal speed-up of 1%-5%, depending on the
call-site. This is mostly relevant for the fuzz tests and utils that
read large blobs of data (like a full block).
2026-02-06 07:56:57 +01:00
Ava Chow
4ae00e9a71 Merge bitcoin/bitcoin#32636: Split CWallet::Create() into CreateNew and LoadExisting
db2effaca4 scripted-diff: refactor: CWallet::Create() -> CreateNew() (David Gumberg)
27e021ebc0 wallet: Correctly log stats for encrypted messages. (David Gumberg)
d8bec61be2 wallet: remove loading logic from CWallet::Create (David Gumberg)
f35acc893f refactor: wallet: Factor out `WriteVersion()` from `PopulateWalletFromDB()` (David Gumberg)
e12ff8aca0 test: wallet: Split create and load (David Gumberg)
70dbc79b09 wallet: Use CWallet::LoadExisting() for loading existing wallets. (David Gumberg)
ae66e01164 wallet: Create separate function for wallet load (David Gumberg)
bc69070416 refactor: Wallet stats logging in its own function (David Gumberg)
a9d64cd49c wallet: Remove redundant birth time update (David Gumberg)
b4a49cc727 wallet: Move argument parsing to before DB load (David Gumberg)
b15a94a618 refactor: Split out wallet argument loading (David Gumberg)
a02c4a82d8 refactor: Move -walletbroadcast setting init (David Gumberg)
411caf7281 wallet: refactor: PopulateWalletFromDB use switch statement. (David Gumberg)
a48e23f566 refactor: wallet: move error handling to PopulateWalletFromDB() (David Gumberg)
0972785fd7 wallet: Delete unnecessary PopulateWalletFromDB() calls (David Gumberg)
f0a046094e scripted-diff: refactor: CWallet::LoadWallet->PopulateWalletFromDB (David Gumberg)

Pull request description:

  This PR is mostly a refactor which splits out logic used for creating wallets and for loading wallets, both of which are presently contained in `CWallet::Create()` into `CWallet::CreateNew()` and `CWallet::LoadExisting()`

  The real win of this PR is that `CWallet::Create()` uses a very bad heuristic for trying to guess whether or not it is supposed to be creating a new wallet or loading an existing wallet:

  370c592612/src/wallet/wallet.cpp (L2882-L2885)

  This heuristic assumes that wallets with no `ScriptPubKeyMans` are being created, which sounds reasonable, but as demonstrated in #32112 and #32111, this can happen when the user tries to load a wallet file that is corrupted, both issues are fixed by this PR and any other misbehavior for wallet files which succeeded the broken heuristic's sniff test for new wallets.

  It was already the case that every caller of `CWallet::Create()` knows whether it is creating a wallet or loading one, so we can avoid replacing this bad heuristic with another one, and just shift the burden to the caller.

ACKs for top commit:
  achow101:
    ACK db2effaca4
  polespinasa:
    approach ACK db2effaca4
  w0xlt:
    reACK db2effaca4
  murchandamus:
    ACK db2effaca4
  rkrux:
    ACK db2effaca4

Tree-SHA512: c28d60e0a3001058da3fd2bdbe0726c7ebe742a4b900a1dee2e5132eccc22e49619cb747a99b4032b000eafd4aa2fdd4ec244c32be2012aba809fdc94b5f6ecd
2026-02-04 11:06:36 -08:00
Sebastian Falbesoner
dd93362a1d bench: simplify script verification benchmark, generalize signing
Simplify the benchmark with the following changes:
- Set the deterministic private key using uint256::ONE,
  put it in a `FlatSigningProvider` instance for easier signing
- Use `GetScriptForDestination` for creating the output script
- Use `SignTransaction` to sign, instead of doing it manually
  (also removes the need to caclulate the public key hash manually)
- Pass standard script verification flags instead of combining them manually

These steps, in particular the generalized signing, prepare the
benchmarking extension for a different script type (P2TR key-path) in
the next commit.
2026-02-03 15:12:49 +01:00
Ava Chow
47c9297172 Merge bitcoin/bitcoin#32420: mining, ipc: omit dummy extraNonce from coinbase
d511adb664 [miner] omit dummy extraNonce via IPC (Sjors Provoost)
bf3b5d6d06 test: clarify getCoinbaseRawTx() comparison (Sjors Provoost)
78df9003d6 [doc] Update comments on dummy extraNonces in tests (Anthony Towns)

Pull request description:

  This PR changes the Mining IPC interface to stop including a dummy `extraNonce` in the coinbase `scriptSig` by default, exposing only the consensus-required BIP34 height. This simplifies downstream mining software (including Stratum v2), avoids forcing clients to strip or ignore data we generate, and reduces the risk of incompatibilities if future soft forks add required commitments to the `scriptSig`.

  Existing behavior is preserved for RPCs, tests, regtest, and internal mining by explicitly opting in to the dummy `extraNonce` where needed (e.g. to satisfy `bad-cb-length` at low heights), so consensus rules and test coverage are unchanged. The remainder of the PR consists of small comment fixes, naming clarifications, and test cleanups to make the intent and behavior clearer.

ACKs for top commit:
  achow101:
    ACK d511adb664
  ryanofsky:
    Code review ACK d511adb664. Just rebased since last review and make suggested tweaks. I'd really like to see this PR merged for the cleanups and sanity it brings to this code. Needs another reviewer though.
  sedited:
    ACK d511adb664

Tree-SHA512: d41fa813eb6b5626f4f475d8abc506b29090f4a2d218f2d6824db58b5ebe2ed7c584a903b44de18ccec142bb79c257b0aba6d6da073f56175aec88df96aaaaba
2026-02-02 15:21:16 -08:00