Skip to content

Conversation

@PastaPastaPasta
Copy link
Member

Issue being fixed or feature implemented

See commits; release v23.0.1

What was done?

see commits

How Has This Been Tested?

Breaking Changes

Checklist:

Go over all the following points, and put an x in all the boxes that apply.

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation
  • I have assigned this pull request to a milestone (for repository code-owners and collaborators only)

35dc258 chore: trivial cleanup (UdjinM6)
96de036 fix: HD chain encryption check ordering issue (UdjinM6)

Pull request description:

  ## Issue being fixed or feature implemented
  Previously, LoadHDChain() would fail if CRYPTED_HDCHAIN records were
  read before MASTER_KEY records during wallet loading, because the
  check `m_storage.HasEncryptionKeys() != chain.IsCrypted()` would
  incorrectly fail when mapMasterKeys was still empty.

  This PR fixes the issue by:
  - Adding an optional fSkipEncryptionCheck parameter to LoadHDChain()
  - Skipping the encryption check during wallet loading in ReadKeyValue()
  - Adding comprehensive validation in LoadWallet() after all records
    are loaded to ensure HD chain encryption consistency

  ## What was done?

  ## How Has This Been Tested?
  run tests

  ## Breaking Changes
  n/a

  ## Checklist:
  - [ ] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [ ] I have added or updated relevant unit/integration/functional/e2e tests
  - [ ] I have made corresponding changes to the documentation
  - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  PastaPastaPasta:
    utACK 35dc258

Tree-SHA512: f986209cb03a87559ddf417a7b0f833303968918086f125170b372d0856f5dd22d41ff3577e788ed100133d6862ca532228c857c4e862f526e53609b0324568e
@PastaPastaPasta PastaPastaPasta added this to the 23.0.1 milestone Dec 1, 2025
@github-actions
Copy link

github-actions bot commented Dec 1, 2025

✅ No Merge Conflicts Detected

This PR currently has no conflicts with other open PRs.

kwvg and others added 10 commits December 1, 2025 10:46
04b647f doc: update `dependencies.md` (Kittywhiskers Van Gogh)
5046964 depends: add patches included with Qt 5.15.19 (Kittywhiskers Van Gogh)
0286d78 depends: Qt 5.15.18 (Kittywhiskers Van Gogh)

Pull request description:

  ## Motivation

  Bitcoin switched to Qt 6.x in [bitcoin#30997](bitcoin#30997), upgrading from Qt 5.15.16 to Qt 6.7.3. This transition was enabled by, alongside a series of changes to GUI code, migrating the build system to CMake (see [bitcoin#30454](bitcoin#30454)). While efforts have been undertaken to bridge the gap between the pre-transition Autotools infrastructure and our infrastructure, migration is complicated by two factors:

  * The need for significant OOO backports to bridge the gap
  * Our divergence from upstream's GUI implementation that will require manual assessment to follow best Qt 6 practices

  This means that the timeline to migration is medium-term at best but in the meanwhile, the latest OSS version of Qt is 5.15.18 ([source](https://lists.qt-project.org/pipermail/announce/2025-October/000592.html)) and between 5.15.16 and 5.15.19 (the as-of-this-writing, still proprietary release of Qt, [source](https://www.qt.io/blog/commercial-lts-qt-5.15.19-released)), mitigations for vulnerabilities have been included ([source](https://wiki.qt.io/List_of_known_vulnerabilities_in_Qt_products)).

  While Qt 5.15.19 OSS is not available, critical patches shipped with them are. This pull request updates our Qt depends to the latest available OSS release (v5.15.18) and includes the patches included in the 5.15.19 release.

  ## Additional Information

  * Guidance on patch application has been taken from the `qt@5` Homebrew formula ([source](https://github.com/Homebrew/homebrew-core/blob/013dad6a9c390da76aacba8249afa47d4c807a85/Formula/q/qt@5.rb)).

  * The patches themselves have been sourced from Qt ([source](https://download.qt.io/archive/qt/5.15/)) and modified to fit the build's directory structure, it should remain identical otherwise.

  *`clang_18_libpng.patch` has been dropped as it is already included in v5.15.18

  ## Breaking Changes

  None expected.

  ## Checklist

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)**
  - [x] I have added or updated relevant unit/integration/functional/e2e tests **(note: N/A)**
  - [x] I have made corresponding changes to the documentation
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  PastaPastaPasta:
    utACK 04b647f
  UdjinM6:
    light ACK 04b647f

Tree-SHA512: 02e497e32561fcd91c4a08cf389a522cec14b8fc98cd3b5c4bc108d829dc32009c8ade52651e4f56d0d43b9cbad2d2cff9a6ec95e1bfc5a4b2167c0a8d47e791
…Diffs()` when `nVersion` is present

65c33ea fix: correct BLS scheme setting in `MigrateLegacyDiffs()` when `nVersion` is present (UdjinM6)

Pull request description:

  ## Issue being fixed or feature implemented
  BLS public key legacy scheme is only being set when `nVersion` field is missing and needed to be auto-filled, instead of being set whenever a `pubKeyOperator` field is present.

  ## What was done?
  Moved the `SetLegacy()` call outside the `nVersion` check.

  ## How Has This Been Tested?
  Migrate on mainnet at block 2367886

  ## Breaking Changes
  n/a

  ## Checklist:
  - [ ] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [ ] I have added or updated relevant unit/integration/functional/e2e tests
  - [ ] I have made corresponding changes to the documentation
  - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  kwvg:
    utACK 65c33ea

Tree-SHA512: e68bc9ae9dc8fa0c780b64225ea1b9be10c1a097dd10cbc5d7d91a6e84ac0ffb75c37dd2b7bd60e7e93f25b8c395e74054b9e2360f3ea549b9e293fd2308e15e
…instant send database

42b3341 perf: remove duplicated check of same key in the instant send database (Konstantin Akimov)

Pull request description:

  ## Issue being fixed or feature implemented

  Previous implementation checked both Deterministic and Non-deterministic instant send locks; though once non-determinstic has been removed, implementation has been updated and now the same key is checked twice.

  ## What was done?
  This PR removes duplicated check

  ## How Has This Been Tested?
  See CI

  ## Breaking Changes
  N/A

  ## Checklist:
  - [x] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [ ] I have added or updated relevant unit/integration/functional/e2e tests
  - [ ] I have made corresponding changes to the documentation
  - [x] I have assigned this pull request to a milestone

ACKs for top commit:
  PastaPastaPasta:
    utACK [42b3341](dashpay@42b3341)
  kwvg:
    utACK 42b3341
  UdjinM6:
    utACK 42b3341

Tree-SHA512: f0213e7ad8f4d380561538d194a9fc9ed1b1ed4580f1848aa14d7958b817ac716e09bb4b83f611a86b2f1b8d920fb65f87721b35bee8f7e84b97193eae459adb
f8be956 refactor: rename second BuildNewListFromBlock variant to RebuildListFromBlock (UdjinM6)
f3ee1d7 refactor: move verification progress log out of VerifySnapshotPair (UdjinM6)
f482f01 fix: drop redundant thread safety annotations (UdjinM6)
6df3a7c docs: add release notes for evodb verify/repair RPCs (UdjinM6)
7decd15 docs: add comprehensive evodb verify/repair documentation (UdjinM6)
17b556a feat: add evodb verify and repair RPC commands (UdjinM6)
5379fce refactor: add CDeterministicMNList::IsEqual method (UdjinM6)
496ed89 refactor: add BuildNewListFromBlock overload accepting explicit prevList (UdjinM6)

Pull request description:

  ## Issue being fixed or feature implemented
  dashpay#6961 should fix the issue for new nodes migrating to v23. This PR aims to provide tools for nodes that updated before the fix implemented in dashpay#6961.

  ## What was done?

  Preparatory Refactoring (2 commits)

  1. BuildNewListFromBlock overload - Added method overload that accepts explicit prevList parameter instead of loading from database.
  Needed for repair to rebuild from trusted snapshots.
  2. CDeterministicMNList::IsEqual - Added equality comparison method to verify recalculated diffs produce correct results.

  Main Feature (1 commit)

  3. evodb verify and repair RPCs - Core implementation:
    - Two new hidden RPC commands for diagnosing/repairing corrupted evodb diffs
    - evodb verify - Read-only verification between snapshots (every 576 blocks)
    - evodb repair - Recalculates corrupted diffs from blockchain data
    - Fail-fast on critical errors, efficient 16MB batched writes, cache clearing

  Documentation (2 commits)

  4. Comprehensive docs - Full technical documentation in doc/evodb-verify-repair.md
  5. Release notes - Short user-facing notes in doc/release-notes-6969.md

  Key Points

  - Purpose: Repair corrupted evodb diffs without full reindex (when possible)
  - Use cases: After crashes, disk corruption, or suspected database issues
  - Limitations: Can't repair missing snapshots (needs reindex), requires unpruned blocks
  - Performance: I/O intensive, logs progress every 100 snapshot pairs
  - Safety: Verifies repairs before committing, clears caches, clear error messages

  ## How Has This Been Tested?
  1. Sync on testnet/mainet with v22.1.3 (save evodb from datadir for repeated experiments) and stop the node
  2. Start v23 (with `--noconnect` to avoid altering blocks and chainstate), wait for migration to finish and stop the node
  3. Start a node with this patch and run:
     1. `evodb verify`, should see a bunch of errors in `verificationErrors`
     2. `evodb repair`, should see same errors in `verificationErrors` and none in `repairErrors` (can specify start/stop params from errors in `verificationErrors` to speed things up a bit, `verificationErrors` should look accordingly)
     3. `evodb verify` or `evodb repair` again, should see no errors now

  ## Breaking Changes
  n/a

  ## Checklist:
  - [ ] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [ ] I have added or updated relevant unit/integration/functional/e2e tests
  - [ ] I have made corresponding changes to the documentation
  - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  PastaPastaPasta:
    utACK f8be956

Tree-SHA512: 0cddb7f9fb3ae5519ae8cdb868aafbaeace35ca9f5fa7319d7ddbee3466e7765a21a8bae402983e3fc8f0a2ffab32c8bc60149af65bc2522143ca939b081c605
f961e04 fix: initialize BLS in benchmarking setup (pasta)

Pull request description:

  ## Issue being fixed or feature implemented
  Crashes like below happen when BLS bench's are ran w/o BLS_DKG bench's
  ```
  > $ ./src/bench/bench_dash --filter="BLS_.*"                                                                     [±ci/run-bench ●]

  |               ns/op |                op/s |    err% |     total | benchmark
  |--------------------:|--------------------:|--------:|----------:|:----------
  |           70,625.77 |           14,159.14 |    0.5% |      0.08 | `BLS_PubKeyAggregate_Batch_100`
  |          143,101.94 |            6,988.03 |    0.6% |      0.17 | `BLS_PubKeyAggregate_Batch_200`
  |           16,714.92 |           59,826.77 |    1.4% |      0.02 | `BLS_PubKeyAggregate_Batch_25`
  |            2,733.86 |          365,783.71 |    0.9% |      0.01 | `BLS_PubKeyAggregate_Batch_5`
  |           34,708.34 |           28,811.52 |    0.7% |      0.04 | `BLS_PubKeyAggregate_Batch_50`
  |           77,659.39 |           12,876.74 |    0.5% |      0.09 | `BLS_PubKeyAggregate_Iterative_100`
  |          155,927.75 |            6,413.23 |    0.8% |      0.19 | `BLS_PubKeyAggregate_Iterative_200`
  |           18,291.67 |           54,669.70 |    1.3% |      0.02 | `BLS_PubKeyAggregate_Iterative_25`
  |            2,830.29 |          353,320.46 |    0.5% |      0.01 | `BLS_PubKeyAggregate_Iterative_5`
  |           37,932.04 |           26,362.94 |    0.9% |      0.05 | `BLS_PubKeyAggregate_Iterative_50`
  |              777.73 |        1,285,787.58 |    1.5% |      0.01 | `BLS_PubKeyAggregate_Normal`
  |              390.42 |        2,561,315.62 |    1.2% |      0.01 | `BLS_SecKeyAggregate_Normal`
  |          516,138.10 |            1,937.47 |    0.3% |      0.62 | `BLS_Sign_Normal`
  |            1,463.50 |          683,294.10 |    0.8% |      0.01 | `BLS_SignatureAggregate_Normal`
  expected valid but it is invalid
  Assertion failure:
    assertion: false
    file: bls.cpp, line: 301
    function: operator()
     0#: (0x103732300) stacktraces.cpp:640   - __assert_rtn
     1#: (0x102AB46CC) basic_ostream.h       - BLS_Verify_Batched(ankerl::nanobench::Bench&)::$_0::operator()() const
     2#: (0x102AB46CC) nanobench.h:1221      - ankerl::nanobench::Bench& ankerl::nanobench::Bench::run<BLS_Verify_Batched(ankerl::nanobench::Bench&)::$_0>(BLS_Verify_Batched(ankerl::nanobench::Bench&)::$_0&&)
     3#: (0x102AAFBE4) vector:1933           - std::__1::vector<bool, std::__1::allocator<bool>>::__destroy_vector::operator()[abi:ne190102]()
     4#: (0x102AAFBE4) vector:1942           - std::__1::vector<bool, std::__1::allocator<bool>>::~vector[abi:ne190102]()
     5#: (0x102AAFBE4) vector:1942           - std::__1::vector<bool, std::__1::allocator<bool>>::~vector[abi:ne190102]()
     6#: (0x102AAFBE4) bls.cpp:305           - BLS_Verify_Batched(ankerl::nanobench::Bench&)
     7#: (0x102A9605C) function.h            - std::__1::__function::__value_func<void (ankerl::nanobench::Bench&)>::operator()[abi:ne190102](ankerl::nanobench::Bench&) const
     8#: (0x102A9605C) function.h:989        - std::__1::function<void (ankerl::nanobench::Bench&)>::operator()(ankerl::nanobench::Bench&) const
     9#: (0x102A9605C) bench.cpp:120         - benchmark::BenchRunner::RunAll(benchmark::Args const&)
    10#: (0x102AA8EE4) string:1881           - std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::__is_long[abi:ne190102]() const
    11#: (0x102AA8EE4) string:1212           - std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::~basic_string()
    12#: (0x102AA8EE4) string:1210           - std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>::~basic_string()
    13#: (0x102AA8EE4) bench.h:54            - benchmark::Args::~Args()
    14#: (0x102AA8EE4) bench.h:54            - benchmark::Args::~Args()
    15#: (0x102AA8EE4) bench_bitcoin.cpp:137 - main
    16#: (0x1919C0274) <unknown-file>        - ???
  Assertion failed: (false), function operator(), file bls.cpp, line 301.
  [1]    20836 abort      ./src/bench/bench_dash --filter="BLS_.*"
  ```

  ## What was done?
  Don't assume scheme

  ## How Has This Been Tested?
  Bench ran

  ## Breaking Changes

  ## Checklist:
    _Go over all the following points, and put an `x` in all the boxes that apply._
  - [ ] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [ ] I have added or updated relevant unit/integration/functional/e2e tests
  - [ ] I have made corresponding changes to the documentation
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    ACK f961e04

Tree-SHA512: b71017742a6217d0aaac01113e0878e5adf4b0d33f97631784110cabab11cc09696505309089e5fc7eec1803d373a9e753b275268e14b418dd97787d47fd3ba4
…epair operations

084bb62 chore: clang-format (UdjinM6)
ce506bc perf: reduce cs_main lock scope in evodb verify/repair operations (UdjinM6)

Pull request description:

  ## Issue being fixed or feature implemented
  Previously, evodb_verify_or_repair_impl held cs_main for the entire operation, which could take minutes when verifying/repairing large block ranges. This caused significant lock contention and blocked other operations requiring cs_main.

  This commit reduces the cs_main lock scope to only the initial setup phase where we resolve block indexes from the active chain. The actual verification and repair work (applying diffs, rebuilding lists from blocks, verifying snapshots) now runs without holding cs_main.

  ## What was done?
  Changes:
  - Wrap block index resolution in a scoped cs_main lock
  - Remove AssertLockHeld(cs_main) from helper functions:
    * RecalculateAndRepairDiffs
    * CollectSnapshotBlocks
    * VerifySnapshotPair
    * RepairSnapshotPair
    * RebuildListFromBlock (CSpecialTxProcessor)
  - Update function signatures to remove EXCLUSIVE_LOCKS_REQUIRED(cs_main)

  ## How Has This Been Tested?
  Run evodb verify/repair on a mainnet node and monitor logs - it keeps processing other stuff while rpc command is still running.

  ## Breaking Changes
  This is safe because:
  - CBlockIndex pointers remain valid after lock release (never deleted)
  - Block parent relationships (pprev, GetAncestor) are immutable
  - ReadBlockFromDisk takes cs_main internally when accessing nFile/nDataPos
  - Helper functions only process already-loaded block data and snapshots
  - ChainLocks prevent deep reorgs in Dash anyway

  ## Checklist:
  - [ ] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [ ] I have added or updated relevant unit/integration/functional/e2e tests
  - [ ] I have made corresponding changes to the documentation
  - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  kwvg:
    utACK 084bb62
  knst:
    utACK 084bb62

Tree-SHA512: aa0db93133767cc6de897d2989c35f00d1cd0506c51463a86cb76cbbe51ea8be5372efb9dbc16791992d8128bc26812e075d13c30c396f97f22198e9611e75dc
… at node startup

2e5fdd8 feat: verify and repair evodb diffs automatically at node startup (UdjinM6)

Pull request description:

  ## Issue being fixed or feature implemented
  Automatically verify and repair deterministic masternode list diffs in evodb during node startup. Helps detect and fix database corruption without manual intervention.

  ## What was done?
  - Add `DB_LIST_REPAIRED` marker to track when repair is complete
  - Skip repair during reindex (fresh rebuild)
  - Add `-forceevodbrepair` flag to force re-verification
  - Shutdown gracefully on critical errors with user instructions
  - Run in background thread with minimal `cs_main` locking

  ## How Has This Been Tested?
  Run a node, check logs

  ## Breaking Changes
  n/a

  ## Checklist:
  - [ ] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [ ] I have added or updated relevant unit/integration/functional/e2e tests
  - [ ] I have made corresponding changes to the documentation
  - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  PastaPastaPasta:
    utACK 2e5fdd8
  kwvg:
    utACK 2e5fdd8

---

nit suggestions to be considered only if other reviews request changes, else disregard

Tree-SHA512: 6f78e90057bd3e2f8cc7948ce8c6cd14ac0f33395b2c552d89f2abda50159ebfe1f957a2dcf59bc712a495bf12a7f796ab9f3902f90035add70475bffe37def2
3cce090 fix: include QDebug directly (pasta)

Pull request description:

  ## Issue being fixed or feature implemented
  QT packages shipped with Debian 13 currently doesn't build, due to missing QDebug include.

  ## What was done?
  directly include

  ## How Has This Been Tested?
  Builds on Debian 13 w/ system packages

  ## Breaking Changes

  ## Checklist:
    _Go over all the following points, and put an `x` in all the boxes that apply._
  - [ ] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [ ] I have added or updated relevant unit/integration/functional/e2e tests
  - [ ] I have made corresponding changes to the documentation
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  knst:
    utACK 3cce090
  kwvg:
    utACK 3cce090
  UdjinM6:
    utACK 3cce090

Tree-SHA512: 4a0e2d7e4cdc7d1d805d6e2e002be6f029af807b69ea15a2199fa884a1afab12524570f1b2ef3615dbf4cd9ea59f2d22e98110450d7335f8694f335b8d5014c8
… size based on output flag

b220dec fix: update BuildTestVectors call to adjust batch size based on output flag (pasta)

Pull request description:

  ## Issue being fixed or feature implemented
  see dashpay#7011

  ## What was done?

  ## How Has This Been Tested?
  runs locally; but I didn't reproduce the failure, likely due to different compilation flags. Even with undefined sanitizer, I couldn't reproduce.

  ## Breaking Changes

  ## Checklist:
    _Go over all the following points, and put an `x` in all the boxes that apply._
  - [ ] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [ ] I have added or updated relevant unit/integration/functional/e2e tests
  - [ ] I have made corresponding changes to the documentation
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    utACK b220dec

Tree-SHA512: 5cfb630c576abf7f019348fd4acd878ab44485bd0b658521660259ed1ea0570b46eafbbd783bc58f2b707d549f6daf74e1c8f16a636b597d1c3e9aab386f5722
@PastaPastaPasta PastaPastaPasta force-pushed the chore/v23.0.1-backports branch 2 times, most recently from 302ec78 to 626ffe0 Compare December 1, 2025 16:50
@PastaPastaPasta
Copy link
Member Author

Note: CI failure is fake failure

@UdjinM6
Copy link

UdjinM6 commented Dec 1, 2025

Note: CI failure is fake failure

yeah, needs #6986 to fix it (or can be ignored)

@PastaPastaPasta PastaPastaPasta force-pushed the chore/v23.0.1-backports branch from 626ffe0 to 4e9eeca Compare December 1, 2025 18:07
UdjinM6
UdjinM6 previously approved these changes Dec 1, 2025
Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 4e9eeca7c5832786c5465fa158ebf6cc640a1d8b

@UdjinM6 UdjinM6 requested a review from thephez December 1, 2025 18:19
kwvg
kwvg previously approved these changes Dec 1, 2025
Copy link
Collaborator

@kwvg kwvg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 4e9eeca7c5832786c5465fa158ebf6cc640a1d8b

@UdjinM6 UdjinM6 dismissed their stale review December 1, 2025 23:19

Should drop doc/release-notes-6969.md

@PastaPastaPasta PastaPastaPasta force-pushed the chore/v23.0.1-backports branch from 4e9eeca to 04d88bf Compare December 2, 2025 00:24
@UdjinM6
Copy link

UdjinM6 commented Dec 2, 2025

@coderabbitai pls review

@coderabbitai
Copy link

coderabbitai bot commented Dec 2, 2025

@UdjinM6, I'll review the changes in this backport and release PR for v23.0.1. I'll focus on identifying any genuine issues like bugs, undefined behavior, crashes, compilation errors, or linter failures while being mindful that this is a backport PR where changes should generally match upstream sources.


🧠 Learnings used
Learnt from: knst
Repo: dashpay/dash PR: 6916
File: src/univalue/include/univalue.h:81-88
Timestamp: 2025-10-25T07:08:51.918Z
Learning: For backport PRs from bitcoin/bitcoin, bitcoin-core/gui, etc., backported changes should match the original upstream PRs even if they appear strange, modify vendored code, or seem to violate coding guidelines. Still flag genuine issues like bugs, undefined behavior, crashes, compilation errors, or linter failures.
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link

coderabbitai bot commented Dec 2, 2025

Walkthrough

This pull request updates Dash Core from v23.0.0 to v23.0.1, incorporating a Qt library upgrade from 5.15.14 to 5.15.18 with three CVE security patches (CVE-2025-4211, CVE-2025-5455, CVE-2025-30348). The core functional changes introduce a new EvoDB repair and verification system allowing deterministic masternode list diffs to be recalculated and repaired via RPC commands (evodb_verify/evodb_repair), and enhance HD chain loading with optional encryption consistency checks. Supporting infrastructure includes chain helper utilities, new public APIs in CDeterministicMNManager and CSpecialTxProcessor for snapshot verification, and HD chain post-load validation in the wallet layer. Build version, consensus parameters, and documentation are updated accordingly.

Sequence Diagram(s)

sequenceDiagram
    participant RPC as RPC Layer<br/>(evodb_verify/repair)
    participant Manager as CDeterministicMNManager<br/>(RecalculateAndRepairDiffs)
    participant Collector as Snapshot<br/>Collection
    participant Verifier as Snapshot<br/>Verification
    participant Repairer as Snapshot<br/>Repair
    participant Writer as Diff<br/>Persistence
    participant Cache as Cache<br/>Invalidation

    RPC->>Manager: RecalculateAndRepairDiffs(start, stop, repair=true/false)
    activate Manager
    
    Manager->>Collector: CollectSnapshotBlocks(start, stop)
    activate Collector
    Collector-->>Manager: vector<CBlockIndex>
    deactivate Collector
    
    loop For each snapshot block pair
        Manager->>Verifier: VerifySnapshotPair(from, to, list_from, list_to)
        activate Verifier
        Verifier-->>Manager: verification result
        deactivate Verifier
        
        alt repair=true
            Manager->>Repairer: RepairSnapshotPair(from, to, lists, build_func)
            activate Repairer
            Repairer-->>Manager: recalculated diffs
            deactivate Repairer
            
            Manager->>Writer: WriteRepairedDiffs(diffs)
            activate Writer
            Writer->>Cache: Clear caches
            Writer-->>Manager: completion marker
            deactivate Writer
        end
    end
    
    Manager-->>RPC: RecalcDiffsResult{diffsRecalculated, snapshotsVerified, errors}
    deactivate Manager
    
    RPC-->>RPC: Format JSON response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas requiring extra attention:

  • src/evo/deterministicmns.cpp & .h: New public repair API with RecalcDiffsResult struct, RecalculateAndRepairDiffs orchestration, and helper methods for snapshot verification/repair. Complex state management and multi-step workflow requiring verification of correctness.
  • src/evo/specialtxman.cpp & .h: New RebuildListFromBlock method that accepts explicit prevList parameter and assertion-based validation; potential impact on MN list reconstruction logic during repair.
  • src/rpc/evo.cpp: New evodb_verify and evodb_repair RPC commands with complex error handling, result aggregation, and parameter validation across block ranges.
  • src/wallet/walletdb.cpp & scriptpubkeyman.cpp: HD chain loading refactored with optional encryption checks and post-load validation; encryption state consistency now enforced after full wallet load, affecting wallet corruption detection logic.
  • depends/patches/qt/CVE-2025-*.patch: Three security patches to Qt library; memory_resource.patch contains conditional compilation logic changes affecting macOS/iOS compatibility; XML DOM encoding and charset handling patches warrant security review.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.81% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main purpose: backporting changes and final updates for v23.0.1 release to the v23.0.x branch.
Description check ✅ Passed The description references commits and indicates this is a release PR for v23.0.1, which aligns with the changeset containing version bumps, dependency updates, and documentation changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (6)
src/evo/specialtxman.h (1)

82-86: Add cs_main lock annotation to RebuildListFromBlock for consistency

RebuildListFromBlock performs the same kind of deterministic MN list updates as BuildNewListFromBlock, but unlike BuildNewListFromBlock it lacks an EXCLUSIVE_LOCKS_REQUIRED annotation. To keep the thread-safety annotations consistent and help static analysis catch misuse, it should also declare that it expects cs_main to be held.

You can adjust the declaration like this:

-    bool RebuildListFromBlock(const CBlock& block, gsl::not_null<const CBlockIndex*> pindexPrev,
-                              const CDeterministicMNList& prevList, const CCoinsViewCache& view, bool debugLogs,
-                              BlockValidationState& state, CDeterministicMNList& mnListRet);
+    bool RebuildListFromBlock(const CBlock& block, gsl::not_null<const CBlockIndex*> pindexPrev,
+                              const CDeterministicMNList& prevList, const CCoinsViewCache& view, bool debugLogs,
+                              BlockValidationState& state, CDeterministicMNList& mnListRet)
+        EXCLUSIVE_LOCKS_REQUIRED(::cs_main);

And mirror the same annotation on the definition in src/evo/specialtxman.cpp.

src/evo/specialtxman.cpp (3)

173-180: Refactoring BuildNewListFromBlock to delegate to RebuildListFromBlock is sound

BuildNewListFromBlock now simply fetches the previous list from m_dmnman and forwards all work to RebuildListFromBlock, which is exactly what external callers (like EvoDB repair code) need. This keeps the consensus logic in one place and avoids code duplication while preserving the existing requirement to hold cs_main at the call site.


182-203: RebuildListFromBlock API and prevList sanity check look correct

The new RebuildListFromBlock takes an explicit prevList, asserts that it’s either default-constructed or matches pindexPrev->GetBlockHash(), and then rebuilds the next list exactly as before. This makes the “prev list must align with pindexPrev” contract explicit for both in-core processing and EvoDB repair callbacks without altering list construction behavior.


249-261: Collateral check guard avoids false positives in non-tip contexts

Wrapping the ProRegTx collateral recheck in

if (!view.GetBestBlock().IsNull()) {
    // existing collateral validation...
}

ensures this additional “paranoia” check only runs when the UTXO view is anchored at a known best block, avoiding spurious bad-protx-collateral failures in contexts where view doesn’t represent the current tip (e.g., offline EvoDB repair). Consensus-critical collateral validation still happens in CheckProRegTx, so this guard doesn’t weaken security.

src/rpc/evo.cpp (1)

1801-1880: evodb_verify / evodb_repair RPCs are well-structured and integrate cleanly

The two new RPCs thinly wrap evodb_verify_or_repair_impl, expose sensible optional startBlock/stopBlock parameters, and return detailed structured results (counts plus error arrays) without altering node state in verify mode. Registering them under "hidden" in RegisterEvoRPCCommands keeps them discoverable for advanced operators without cluttering the public surface.

src/evo/deterministicmns.h (1)

441-479: IsEqual implementation correctly ignores non-deterministic fields.

Per the learnings, internalId and nTotalRegisteredCount are non-deterministic and can differ between nodes depending on sync history. This implementation correctly:

  • Compares only consensus-critical fields (blockHash, nHeight, mnUniquePropertyMap)
  • Ignores nTotalRegisteredCount as documented
  • Uses SerializeHash for pdmnState comparison to avoid enumerating all state fields

One minor style inconsistency: the code uses dmn_rhs->get()->proTxHash while dmn uses dmn->proTxHash. Both work correctly, but for consistency could use (*dmn_rhs)->proTxHash.

-            if (dmn->proTxHash != dmn_rhs->get()->proTxHash ||
-                dmn->collateralOutpoint != dmn_rhs->get()->collateralOutpoint ||
-                dmn->nOperatorReward != dmn_rhs->get()->nOperatorReward ||
-                dmn->nType != dmn_rhs->get()->nType ||
-                // Use SerializeHash for pdmnState to avoid enumerating all state fields
-                SerializeHash(*dmn->pdmnState) != SerializeHash(*dmn_rhs->get()->pdmnState)) {
+            if (dmn->proTxHash != (*dmn_rhs)->proTxHash ||
+                dmn->collateralOutpoint != (*dmn_rhs)->collateralOutpoint ||
+                dmn->nOperatorReward != (*dmn_rhs)->nOperatorReward ||
+                dmn->nType != (*dmn_rhs)->nType ||
+                // Use SerializeHash for pdmnState to avoid enumerating all state fields
+                SerializeHash(*dmn->pdmnState) != SerializeHash(*(*dmn_rhs)->pdmnState)) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b380d48 and 04d88bf8e4558b8795152862f584e1db461ca319.

📒 Files selected for processing (32)
  • configure.ac (1 hunks)
  • depends/packages/qt.mk (3 hunks)
  • depends/patches/qt/CVE-2025-30348-qtbase-5.15.patch (1 hunks)
  • depends/patches/qt/CVE-2025-4211-qtbase-5.15.patch (1 hunks)
  • depends/patches/qt/CVE-2025-5455-qtbase-5.15.patch (1 hunks)
  • depends/patches/qt/clang_18_libpng.patch (0 hunks)
  • depends/patches/qt/fix-macos-linker.patch (0 hunks)
  • depends/patches/qt/memory_resource.patch (0 hunks)
  • depends/patches/qt/zlib-timebits64.patch (0 hunks)
  • doc/dependencies.md (1 hunks)
  • doc/evodb-verify-repair.md (1 hunks)
  • doc/man/dash-cli.1 (3 hunks)
  • doc/man/dash-qt.1 (6 hunks)
  • doc/man/dash-tx.1 (2 hunks)
  • doc/man/dash-wallet.1 (2 hunks)
  • doc/man/dashd.1 (5 hunks)
  • doc/release-notes.md (4 hunks)
  • doc/release-notes/dash/release-notes-23.0.0.md (1 hunks)
  • src/bench/bench_bitcoin.cpp (2 hunks)
  • src/bench/bls.cpp (2 hunks)
  • src/chainparams.cpp (2 hunks)
  • src/evo/deterministicmns.cpp (3 hunks)
  • src/evo/deterministicmns.h (3 hunks)
  • src/evo/specialtxman.cpp (2 hunks)
  • src/evo/specialtxman.h (1 hunks)
  • src/init.cpp (3 hunks)
  • src/instantsend/db.cpp (1 hunks)
  • src/qt/bitcoin.cpp (1 hunks)
  • src/rpc/evo.cpp (2 hunks)
  • src/wallet/scriptpubkeyman.cpp (1 hunks)
  • src/wallet/scriptpubkeyman.h (1 hunks)
  • src/wallet/walletdb.cpp (2 hunks)
💤 Files with no reviewable changes (4)
  • depends/patches/qt/zlib-timebits64.patch
  • depends/patches/qt/fix-macos-linker.patch
  • depends/patches/qt/memory_resource.patch
  • depends/patches/qt/clang_18_libpng.patch
🧰 Additional context used
📓 Path-based instructions (9)
{guix-build*,releases,**/guix-build*,releases/**,.github/**,depends/**,ci/**,contrib/**,doc/**}

📄 CodeRabbit inference engine (CLAUDE.md)

Do not make changes to build system files (guix-build*), release artifacts, or avoid changes to .github, depends, ci, contrib, and doc directories unless specifically prompted

Files:

  • doc/dependencies.md
  • doc/evodb-verify-repair.md
  • doc/man/dash-cli.1
  • doc/man/dash-qt.1
  • doc/man/dash-wallet.1
  • depends/patches/qt/CVE-2025-30348-qtbase-5.15.patch
  • doc/release-notes.md
  • doc/release-notes/dash/release-notes-23.0.0.md
  • depends/patches/qt/CVE-2025-5455-qtbase-5.15.patch
  • depends/patches/qt/CVE-2025-4211-qtbase-5.15.patch
  • doc/man/dash-tx.1
  • depends/packages/qt.mk
  • doc/man/dashd.1
src/**/*.{cpp,h,hpp,cc}

📄 CodeRabbit inference engine (CLAUDE.md)

Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1

Files:

  • src/wallet/scriptpubkeyman.h
  • src/evo/specialtxman.h
  • src/bench/bench_bitcoin.cpp
  • src/rpc/evo.cpp
  • src/chainparams.cpp
  • src/bench/bls.cpp
  • src/evo/deterministicmns.h
  • src/wallet/scriptpubkeyman.cpp
  • src/wallet/walletdb.cpp
  • src/init.cpp
  • src/qt/bitcoin.cpp
  • src/evo/deterministicmns.cpp
  • src/instantsend/db.cpp
  • src/evo/specialtxman.cpp
src/wallet/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

Wallet implementation must use Berkeley DB and SQLite

Files:

  • src/wallet/scriptpubkeyman.h
  • src/wallet/scriptpubkeyman.cpp
  • src/wallet/walletdb.cpp
src/{masternode,evo}/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

Masternode lists must use immutable data structures (Immer library) for thread safety

Files:

  • src/evo/specialtxman.h
  • src/evo/deterministicmns.h
  • src/evo/deterministicmns.cpp
  • src/evo/specialtxman.cpp
src/{masternode,evo,llmq,governance,coinjoin}/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Dash-specific database implementations: CFlatDB for persistent storage (MasternodeMetaStore, GovernanceStore, SporkStore, NetFulfilledRequestStore) and CDBWrapper extensions for Evolution/DKG/InstantSend/Quorum/RecoveredSigs data

Files:

  • src/evo/specialtxman.h
  • src/evo/deterministicmns.h
  • src/evo/deterministicmns.cpp
  • src/evo/specialtxman.cpp
src/evo/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

Special transactions use payload serialization routines defined in src/evo/specialtx.h and must include appropriate special transaction types (ProRegTx, ProUpServTx, ProUpRegTx, ProUpRevTx)

Files:

  • src/evo/specialtxman.h
  • src/evo/deterministicmns.h
  • src/evo/deterministicmns.cpp
  • src/evo/specialtxman.cpp
src/{masternode,llmq,evo,coinjoin,governance}/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

Use unordered_lru_cache for efficient caching with LRU eviction in Dash-specific data structures

Files:

  • src/evo/specialtxman.h
  • src/evo/deterministicmns.h
  • src/evo/deterministicmns.cpp
  • src/evo/specialtxman.cpp
src/bench/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

Performance benchmarks in src/bench/ must use the nanobench library

Files:

  • src/bench/bench_bitcoin.cpp
  • src/bench/bls.cpp
src/qt/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

GUI implementation in src/qt/ must use Qt 5

Files:

  • src/qt/bitcoin.cpp
🧠 Learnings (25)
📓 Common learnings
Learnt from: knst
Repo: dashpay/dash PR: 6916
File: src/univalue/include/univalue.h:81-88
Timestamp: 2025-10-25T07:08:51.918Z
Learning: For backport PRs from bitcoin/bitcoin, bitcoin-core/gui, etc., backported changes should match the original upstream PRs even if they appear strange, modify vendored code, or seem to violate coding guidelines. Still flag genuine issues like bugs, undefined behavior, crashes, compilation errors, or linter failures.
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.
Learnt from: knst
Repo: dashpay/dash PR: 6883
File: src/rpc/rawtransaction.cpp:1088-1125
Timestamp: 2025-10-13T12:37:12.357Z
Learning: In backport pull requests (especially from Bitcoin Core), treat "moved" or refactored code as out-of-scope for content-level review. Focus validation on verifying that code is moved correctly: no fields added, no fields removed, no fields reordered, and no unexpected changes beyond whitespace adjustments. Pre-existing issues in the upstream code should be preserved to maintain fidelity to the original implementation.
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6786
File: ci/test/04_install.sh:99-101
Timestamp: 2025-08-01T07:46:37.840Z
Learning: In backport PRs like #6786, UdjinM6 prefers to defer non-critical fixes (such as shell command expansion issues) to separate commits/PRs to maintain focus on the primary backport objectives, consistent with the project's pattern of avoiding scope creep.
Learnt from: knst
Repo: dashpay/dash PR: 6871
File: contrib/guix/libexec/build.sh:358-360
Timestamp: 2025-10-05T20:38:28.457Z
Learning: In the Dash repository, when backporting code from Bitcoin Core, typos and minor issues in comments should be kept as-is to reduce merge conflicts in future backports, even if they remain unfixed in Bitcoin Core's master branch.
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo,llmq,governance,coinjoin}/**/*.{cpp,h} : Use Dash-specific database implementations: CFlatDB for persistent storage (MasternodeMetaStore, GovernanceStore, SporkStore, NetFulfilledRequestStore) and CDBWrapper extensions for Evolution/DKG/InstantSend/Quorum/RecoveredSigs data
📚 Learning: 2025-08-11T17:16:36.654Z
Learnt from: PastaPastaPasta
Repo: dashpay/dash PR: 6804
File: src/qt/proposalwizard.cpp:40-42
Timestamp: 2025-08-11T17:16:36.654Z
Learning: In the Dash repository, when a PR adds new files that are not from Bitcoin backports, these files must be added to the list in test/util/data/non-backported.txt. This applies to newly created files like qt/proposalwizard.{h,cpp} and forms/proposalwizard.ui. Limited exemptions may exist for subtrees and similar cases.

Applied to files:

  • doc/dependencies.md
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/qt/**/*.{cpp,h} : GUI implementation in src/qt/ must use Qt 5

Applied to files:

  • doc/dependencies.md
  • src/qt/bitcoin.cpp
  • depends/packages/qt.mk
📚 Learning: 2025-08-08T07:01:47.332Z
Learnt from: knst
Repo: dashpay/dash PR: 6805
File: src/wallet/rpc/wallet.cpp:357-357
Timestamp: 2025-08-08T07:01:47.332Z
Learning: In src/wallet/rpc/wallet.cpp, the upgradetohd RPC now returns a UniValue string message (RPCResult::Type::STR) instead of a boolean, including guidance about mnemonic backup and null-character passphrase handling; functional tests have been updated to assert returned strings in several cases.

Applied to files:

  • src/wallet/scriptpubkeyman.h
  • src/rpc/evo.cpp
  • src/wallet/scriptpubkeyman.cpp
  • src/wallet/walletdb.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,txmempool}/**/*.{cpp,h} : Block validation and mempool handling must use extensions to Bitcoin Core mechanisms for special transaction validation and enhanced transaction relay

Applied to files:

  • src/evo/specialtxman.h
  • src/bench/bench_bitcoin.cpp
  • src/evo/deterministicmns.h
  • src/init.cpp
  • src/qt/bitcoin.cpp
  • src/evo/specialtxman.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/evo/evodb/**/*.{cpp,h} : Evolution Database (CEvoDb) must handle masternode snapshots, quorum state, governance objects with efficient differential updates for masternode lists

Applied to files:

  • src/evo/specialtxman.h
  • doc/evodb-verify-repair.md
  • src/rpc/evo.cpp
  • src/evo/deterministicmns.h
  • src/init.cpp
  • src/evo/deterministicmns.cpp
  • src/evo/specialtxman.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/evo/**/*.{cpp,h} : Special transactions use payload serialization routines defined in src/evo/specialtx.h and must include appropriate special transaction types (ProRegTx, ProUpServTx, ProUpRegTx, ProUpRevTx)

Applied to files:

  • src/evo/specialtxman.h
  • src/init.cpp
  • src/evo/specialtxman.cpp
📚 Learning: 2025-11-13T20:02:55.480Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6969
File: src/evo/deterministicmns.h:441-479
Timestamp: 2025-11-13T20:02:55.480Z
Learning: In `src/evo/deterministicmns.h`, the `internalId` field in `CDeterministicMN` and the `mnInternalIdMap` in `CDeterministicMNList` are non-deterministic and used only for internal bookkeeping and efficient lookups. Different nodes can assign different internalIds to the same masternode depending on their sync history. Methods like `IsEqual()` intentionally ignore internalId mappings and only compare consensus-critical deterministic fields (proTxHash, collateral, state, etc.).

Applied to files:

  • src/evo/specialtxman.h
  • src/evo/deterministicmns.h
  • src/evo/deterministicmns.cpp
  • src/evo/specialtxman.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo,llmq,governance,coinjoin}/**/*.{cpp,h} : Use Dash-specific database implementations: CFlatDB for persistent storage (MasternodeMetaStore, GovernanceStore, SporkStore, NetFulfilledRequestStore) and CDBWrapper extensions for Evolution/DKG/InstantSend/Quorum/RecoveredSigs data

Applied to files:

  • doc/evodb-verify-repair.md
  • src/evo/deterministicmns.h
  • doc/release-notes.md
  • doc/release-notes/dash/release-notes-23.0.0.md
  • src/wallet/walletdb.cpp
  • src/init.cpp
  • src/evo/deterministicmns.cpp
  • src/instantsend/db.cpp
📚 Learning: 2025-10-05T20:38:28.457Z
Learnt from: knst
Repo: dashpay/dash PR: 6871
File: contrib/guix/libexec/build.sh:358-360
Timestamp: 2025-10-05T20:38:28.457Z
Learning: In the Dash repository, when backporting code from Bitcoin Core, typos and minor issues in comments should be kept as-is to reduce merge conflicts in future backports, even if they remain unfixed in Bitcoin Core's master branch.

Applied to files:

  • doc/man/dash-qt.1
  • doc/release-notes.md
  • doc/release-notes/dash/release-notes-23.0.0.md
  • doc/man/dashd.1
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq}/**/*.{cpp,h} : BLS integration must be used for cryptographic foundation of advanced masternode features

Applied to files:

  • src/bench/bench_bitcoin.cpp
  • src/bench/bls.cpp
  • src/evo/deterministicmns.h
  • src/init.cpp
📚 Learning: 2025-07-23T09:30:34.631Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.h:5-6
Timestamp: 2025-07-23T09:30:34.631Z
Learning: Dash Core uses BITCOIN_ prefix for header guards as the standard convention, inherited from Bitcoin Core. Only a few BLS-specific files in src/bls/ use DASH_ prefix. The vast majority of files (385+) use BITCOIN_ prefix.

Applied to files:

  • src/bench/bench_bitcoin.cpp
  • doc/man/dashd.1
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/bench/**/*.{cpp,h} : Performance benchmarks in src/bench/ must use the nanobench library

Applied to files:

  • src/bench/bench_bitcoin.cpp
📚 Learning: 2025-11-04T18:23:28.175Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6933
File: src/governance/classes.cpp:147-154
Timestamp: 2025-11-04T18:23:28.175Z
Learning: In src/governance/classes.cpp, CSuperblock::GetPaymentsLimit intentionally uses synthetic difficulty constants (nBits = 1 for mainnet, powLimit for networks with min difficulty) and simple height-based V20 activation checks instead of actual chain block data. This is by design because superblocks themselves are "synthetic" governance payment blocks, not regular mined blocks.

Applied to files:

  • src/chainparams.cpp
📚 Learning: 2025-06-06T11:53:09.094Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6665
File: src/evo/providertx.h:82-82
Timestamp: 2025-06-06T11:53:09.094Z
Learning: In ProTx serialization code (SERIALIZE_METHODS), version checks should use hardcoded maximum flags (/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true) rather than deployment-based flags. This is because serialization code should be able to deserialize any structurally valid ProTx up to the maximum version the code knows how to handle, regardless of current consensus validity. Validation code, not serialization code, is responsible for checking whether a ProTx version is consensus-valid based on deployment status.

Applied to files:

  • src/chainparams.cpp
📚 Learning: 2025-01-07T18:50:44.838Z
Learnt from: knst
Repo: dashpay/dash PR: 6511
File: src/evo/deterministicmns.cpp:1369-1373
Timestamp: 2025-01-07T18:50:44.838Z
Learning: The functions `MigrateDBIfNeeded` and `MigrateDBIfNeeded2` in `src/evo/deterministicmns.cpp` are temporary and will be removed in a future version. Refactoring suggestions for these functions should be avoided.

Applied to files:

  • src/evo/deterministicmns.h
  • src/evo/deterministicmns.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo}/**/*.{cpp,h} : Masternode lists must use immutable data structures (Immer library) for thread safety

Applied to files:

  • src/evo/deterministicmns.h
  • src/init.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/node/chainstate.{cpp,h} : Chainstate initialization must be separated into dedicated src/node/chainstate.* files

Applied to files:

  • src/evo/deterministicmns.h
  • src/wallet/walletdb.cpp
  • src/init.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,consensus,net_processing}/**/*.{cpp,h} : ValidationInterface callbacks must be used for event-driven architecture to coordinate subsystems during block/transaction processing

Applied to files:

  • src/evo/deterministicmns.h
  • src/init.cpp
  • src/evo/specialtxman.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/wallet/**/*.{cpp,h} : Wallet implementation must use Berkeley DB and SQLite

Applied to files:

  • src/wallet/walletdb.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/coinjoin/**/*.{cpp,h} : CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs

Applied to files:

  • src/init.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/llmq/**/*.{cpp,h} : InstantSend implementation must provide distributed key generation for secure transaction locking with quorum consensus

Applied to files:

  • src/instantsend/db.cpp
📚 Learning: 2025-10-21T11:09:34.688Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6849
File: src/governance/governance.cpp:1339-1343
Timestamp: 2025-10-21T11:09:34.688Z
Learning: In the Dash Core codebase, `CacheMap` (defined in src/cachemap.h) is internally thread-safe and uses its own `mutable CCriticalSection cs` to protect access to its members. Methods like `GetSize()`, `Insert()`, `Get()`, `HasKey()`, etc., can be called without holding external locks.

Applied to files:

  • src/instantsend/db.cpp
📚 Learning: 2025-08-19T14:57:31.801Z
Learnt from: knst
Repo: dashpay/dash PR: 6692
File: src/llmq/blockprocessor.cpp:217-224
Timestamp: 2025-08-19T14:57:31.801Z
Learning: In PR #6692, knst acknowledged a null pointer dereference issue in ProcessBlock() method where LookupBlockIndex may return nullptr but is passed to gsl::not_null, and created follow-up PR #6789 to address it, consistent with avoiding scope creep in performance-focused PRs.

Applied to files:

  • src/evo/specialtxman.cpp
📚 Learning: 2025-07-09T15:02:26.899Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6729
File: src/evo/deterministicmns.cpp:1313-1316
Timestamp: 2025-07-09T15:02:26.899Z
Learning: In Dash's masternode transaction validation, `IsVersionChangeValid()` is only called by transaction types that update existing masternode entries (like `ProUpServTx`, `ProUpRegTx`, `ProUpRevTx`), not by `ProRegTx` which creates new entries. This means validation logic in `IsVersionChangeValid()` only applies to the subset of transaction types that actually call it, not all masternode transaction types.

Applied to files:

  • src/evo/specialtxman.cpp
🧬 Code graph analysis (5)
src/wallet/scriptpubkeyman.h (1)
src/wallet/scriptpubkeyman.cpp (2)
  • LoadHDChain (430-438)
  • LoadHDChain (430-430)
src/evo/specialtxman.h (1)
src/evo/specialtxman.cpp (2)
  • RebuildListFromBlock (182-508)
  • RebuildListFromBlock (182-185)
src/rpc/evo.cpp (1)
src/rpc/server_util.cpp (4)
  • EnsureAnyNodeContext (28-45)
  • EnsureAnyNodeContext (28-28)
  • EnsureChainman (87-93)
  • EnsureChainman (87-87)
src/evo/deterministicmns.cpp (1)
src/evo/deterministicmns.h (2)
  • CDeterministicMNList (133-194)
  • nHeight (148-181)
src/evo/specialtxman.cpp (1)
src/evo/deterministicmns.h (2)
  • CDeterministicMNList (133-194)
  • nHeight (148-181)
🪛 LanguageTool
doc/evodb-verify-repair.md

[style] ~84-~84: Consider placing the discourse marker ‘first’ at the beginning of the sentence for more clarity.
Context: ...ed ... ] } ``` Description: This command first runs verification on all snapshot pairs...

(SENT_START_FIRST_PREMIUM)

doc/release-notes.md

[grammar] ~3-~3: Ensure spelling is correct
Context: ...patch version release, bringing various bugfixes, performance improvements, and new tool...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~44-~44: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...bugdirectly in Qt code (dash#7009). - FixedBuildTestVectors` call to adjust batch...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

doc/release-notes/dash/release-notes-23.0.0.md

[grammar] ~3-~3: Ensure spelling is correct
Context: ...release, bringing new features, various bugfixes and other improvements. This release is...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[style] ~4-~4: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...e is mandatory for all masternodes. This release is optional but recommended for...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)


[style] ~202-~202: Consider using “formerly” to strengthen your wording.
Context: ...e now validated at startup. Values that previously worked and were considered valid can no...

(PREVIOUSLY_FORMERLY)


[style] ~230-~230: Consider using a different verb for a more formal wording.
Context: ...) ### Mobile CoinJoin Compatibility - Fixed an issue where CoinJoin funds mixed in ...

(FIX_RESOLVE)

🪛 markdownlint-cli2 (0.18.1)
doc/dependencies.md

36-36: Link text should be descriptive

(MD059, descriptive-link-text)

doc/evodb-verify-repair.md

3-3: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)


8-8: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


57-57: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

doc/release-notes.md

28-28: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


31-31: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


37-37: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


46-46: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


51-51: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)

🔇 Additional comments (38)
src/wallet/scriptpubkeyman.h (1)

407-407: LGTM: Backward-compatible API extension.

The new optional parameter with default value false ensures existing callers retain the original encryption-check behavior, while allowing the wallet loading path to defer validation until all records are loaded.

src/wallet/scriptpubkeyman.cpp (1)

430-438: LGTM: Clean conditional encryption check implementation.

The logic correctly short-circuits when skip_encryption_check is true, allowing the wallet loading code to defer encryption-state validation until all records (including master keys) are loaded. The lock acquisition and assignment to m_hd_chain remain unchanged.

src/wallet/walletdb.cpp (2)

575-579: LGTM: Appropriate deferral of encryption check during loading.

The comment clearly explains the rationale for skipping the encryption check during initial load. Using /*skip_encryption_check=*/true with the named parameter comment improves readability. The error message update from "SetHDChain failed" to "LoadHDChain failed" correctly matches the function being called.


879-894: LGTM: Robust post-load encryption consistency validation.

The post-load validation correctly:

  1. Uses GetLegacyScriptPubKeyMan() (non-creating variant) since we're only checking existing state.
  2. Only validates when an HD chain exists (appropriate guard).
  3. Compares wallet encryption state (HasEncryptionKeys()) with HD chain encryption state (IsCrypted()).
  4. Returns DBErrors::CORRUPT for mismatches, which is the correct severity for data integrity issues.
  5. Provides a descriptive error message logging both states for debugging.

The placement after cursor close and before applying active ScriptPubKeyMans ensures all records are loaded before validation.

src/bench/bench_bitcoin.cpp (2)

7-7: BLS header inclusion is appropriate and scoped to the benchmark binary

Including <bls/bls.h> here cleanly provides BLSInit() and bls::bls_legacy_scheme for the benchmark main without affecting other translation units. Looks good.


68-69: BLS initialization and legacy‑scheme toggle look correct

Initializing BLS once at startup and explicitly disabling the legacy scheme before running any benchmarks is straightforward and low‑risk; it aligns with how the rest of the BLS benchmarks are structured.

src/bench/bls.cpp (1)

258-258: Adaptive invalid-case counts maintain correctness while reducing non-output cost

Tying both count and invalidCount to bench.output() keeps the original 1000/10 mix in output mode while shrinking to 1/1 in non-output mode. invalidCount never exceeds count, so BuildTestVectors remains safe, and invalid-path coverage is preserved.

Also applies to: 314-314

src/qt/bitcoin.cpp (1)

52-52: LGTM! QDebug include added for debugging support.

Standard Qt header addition to enable debug logging capabilities. No functional changes to runtime behavior.

doc/man/dash-tx.1 (1)

2-2: LGTM! Release version metadata updated to v23.0.1.

Documentation correctly reflects the December 2025 v23.0.1 release. Changes are consistent with the version bump in configure.ac.

Also applies to: 4-4, 12-12, 122-122

doc/man/dash-cli.1 (1)

2-2: LGTM! Version metadata updated consistently.

Release documentation updated to reflect v23.0.1 (December 2025), matching the broader release updates across all man pages.

Also applies to: 4-4, 18-18, 165-165

depends/patches/qt/CVE-2025-5455-qtbase-5.15.patch (1)

1-20: LGTM! CVE-2025-5455 security patch applied.

This patch improves charset handling in qDecodeDataUrl by replacing index-based iteration with a more robust QLatin1String approach. The fix properly handles edge cases in data URL parsing.

Based on learnings, backported security patches should match upstream implementations. The logic correctly:

  1. Copies the remainder after "charset" prefix
  2. Trims leading spaces using mid(1) in a loop
  3. Checks for '=' at the start of the trimmed string
doc/man/dash-wallet.1 (1)

2-2: LGTM! Release documentation updated.

Version metadata correctly updated to v23.0.1 (December 2025), consistent with the release version bump.

Also applies to: 4-4, 6-6, 10-10, 112-112

configure.ac (1)

5-5: LGTM! Patch version bumped to 1 for v23.0.1 release.

Build version incremented from 0 to 1, correctly reflecting the v23.0.1 patch release. This change aligns with all documentation and man page updates throughout the PR.

src/instantsend/db.cpp (1)

268-287: LGTM! Redundant database read removed.

The refactored logic correctly sets ret = nullptr when the read fails or the hash doesn't match, eliminating an unnecessary second database read operation. The streamlined flow:

  1. Attempt to read InstantSendLock from database
  2. If read fails OR serialized hash doesn't match, set result to nullptr
  3. Cache the result (which may be nullptr) and return

This change improves efficiency and clarifies the "not found" signal path.

doc/man/dashd.1 (1)

2-2: LGTM! Release documentation and parameters updated.

Documentation correctly updated for v23.0.1 (December 2025) release, including:

  • Version metadata updated consistently
  • Default assumevalid block hashes refreshed for mainnet and testnet
  • Thread count parameter ranges adjusted (negative range now -14 instead of -24)
  • Debug category listings refined

All changes are documentation-only with no functional code impact.

Also applies to: 4-4, 9-9, 26-28, 126-127, 131-132, 871-875, 1140-1140

doc/release-notes/dash/release-notes-23.0.0.md (1)

1-323: Release notes content looks consistent with v23.0.0 changes

The document accurately reflects the EvoDB migration, block filter index v2, extended address support, RPC/network/wallet/GUI changes, and links to the correct compare range. I don’t see any broken links or misleading statements that would warrant changes in this backport context; existing minor typos can stay as-is to avoid churn.

doc/man/dash-qt.1 (1)

2-10: Man page updates look internally consistent

The bump to v23.0.1, updated assumevalid hashes, adjusted thread ranges for -par/-parbls, and the new default for -font-weight-normal all line up with the corresponding parameters in src/chainparams.cpp and the rest of the PR. The removal of the lock debug category from the list is also consistent with it being a debug-only category. No changes needed.

Also applies to: 24-31, 128-134, 1160-1161, 1182-1191

src/chainparams.cpp (1)

221-225: Consensus chain work / assumevalid bumps look fine

The new nMinimumChainWork and defaultAssumeValid values for mainnet (height 2381436) and testnet (height 1374139) are consistent with the updated documentation/man pages and follow the established pattern of periodically advancing these checkpoints. Leaving chainTxData anchored to slightly earlier blocks is acceptable and does not affect consensus.

Also applies to: 420-424

doc/evodb-verify-repair.md (1)

1-160: EvoDB verify/repair documentation aligns with the implemented workflow

The doc clearly explains the semantics, parameters, return structures, error handling, and operational caveats (pruning, CRITICAL errors, locking) for evodb verify and evodb repair. It matches the high-level behavior described elsewhere in the PR and should be sufficient for operators to use the new RPCs safely. No changes needed.

doc/dependencies.md (1)

36-36: Qt dependency row matches the intended bump; verify build scripts are in sync

The GUI dependency table now correctly reflects Qt 5.15.18 with a reference to the Dash PR that performs the bump and adds CVE patches. Please ensure that depends/packages/qt.mk and any CI/build scripts are using the same version string.

depends/patches/qt/CVE-2025-4211-qtbase-5.15.patch (1)

41-61: Windows GetTempPath2W integration is correct and follows recommended pattern

The patch properly implements the Microsoft-recommended pattern for runtime API detection. The typedef signature DWORD (WINAPI *)(DWORD, LPWSTR) correctly matches both GetTempPath2W and the fallback GetTempPathW. Using GetModuleHandleW on the known system DLL kernel32.dll followed by GetProcAddress is the standard approach; the static lambda ensures one-time initialization. The fallback to GetTempPathW ensures compatibility with systems predating Windows 11 / Server 2022 (though GetTempPath2W is available via backports on some older builds). GetTempPath2W provides security benefits for SYSTEM account processes while maintaining identical behavior for regular callers, making this a sound upgrade path.

depends/patches/qt/CVE-2025-30348-qtbase-5.15.patch (1)

46-154: encodeText rewrite looks consistent with upstream and preserves semantics

The new buffered encodeText implementation (via appendToOutput and the switch over UTF‑16 code units) keeps the escaping rules for <, ", &, >, AVN/EOL, and codec canEncode behavior while avoiding the previous quadratic QString::replace pattern. No correctness or UB issues are apparent, and this matches the intended upstream Qt fix for QTBUG‑127549.

src/init.cpp (2)

84-88: Evo helper includes are correctly introduced

Adding evo/chainhelper.h and evo/specialtxman.h here is appropriate given the new EvoDB repair flow later in this file and keeps init-time wiring in one place.


724-724: New -forceevodbrepair argument is wired appropriately

The -forceevodbrepair debug/testing flag is registered consistently with other debug options and matches its later usage (GetBoolArg("-forceevodbrepair", false)) during startup repair.

src/rpc/evo.cpp (1)

2040-2051: RPC command registration correctly wires in EvoDB helpers

Adding

{"hidden", &evodb_verify},
{"hidden", &evodb_repair},

to RegisterEvoRPCCommands is consistent with existing patterns for advanced/diagnostic RPCs and ensures the new EvoDB maintenance endpoints are available wherever Evo RPCs are registered.

depends/packages/qt.mk (2)

26-28: CVE patches correctly added to patch list and applied in preprocess step.

The three CVE patches are properly declared in the patches list and applied in sequence during preprocessing (lines 258-260).


2-6: The file depends/packages/qt.mk is a build system file covered by the coding guidelines restriction: "Do not make changes to build system files unless specifically prompted." Verify that modifications to this file were explicitly requested before proceeding.

src/evo/deterministicmns.h (3)

37-38: Forward declarations appropriately added.

These forward declarations enable the new repair workflow API without requiring full header inclusion.


724-749: Repair workflow API is well-designed.

The RecalcDiffsResult struct provides clear aggregation of results and errors. The BuildListFromBlockFunc callback type allows flexibility in how MN lists are constructed during repair. The [[nodiscard]] attributes appropriately ensure callers handle return values.


758-769: Private helper method declarations properly organized.

Helper methods for the repair workflow are correctly placed in the private section. The method signatures clearly indicate their purpose and follow existing patterns in the class.

src/evo/deterministicmns.cpp (8)

28-35: Required include and database key constant added.

The <functional> header is needed for std::function used in BuildListFromBlockFunc. The DB_LIST_REPAIRED constant follows the naming convention of existing database keys.


1487-1498: Legacy pubKeyOperator handling correctly sets scheme based on version.

The migration properly detects when pubKeyOperator needs the legacy flag set based on nVersion. This ensures correct BLS signature verification after migration.


1576-1683: RecalculateAndRepairDiffs implementation is well-structured.

The implementation:

  • Properly clamps start height to DIP0003 activation
  • Validates snapshot availability before proceeding
  • Logs progress periodically to avoid spam
  • Accumulates errors for caller review
  • Correctly handles the case where the initial DIP0003 snapshot may not exist in DB

1699-1747: CollectSnapshotBlocks correctly identifies snapshot boundaries.

The implementation properly handles:

  • Walking backwards to find the nearest snapshot block (divisible by DISK_SNAPSHOT_PERIOD)
  • Special case for DIP0003 activation height as the initial snapshot
  • Calculation of next snapshot height accounting for DIP0003 irregularity

1749-1791: VerifySnapshotPair correctly validates diff application.

The method:

  • Sequentially applies stored diffs from the database
  • Sets diff.nHeight before calling ApplyDiff (required by the method)
  • Uses the new IsEqual method for comparison
  • Properly catches exceptions and accumulates errors

1793-1865: RepairSnapshotPair correctly rebuilds diffs from blockchain data.

Key design decisions are well-documented:

  • Uses a dummy CCoinsView because blocks were already validated when connected; UTXO lookups aren't needed for special transaction extraction
  • Verifies that recalculated diffs produce the expected target snapshot before returning
  • Returns empty vector on any failure with descriptive error messages

The temp_diffs.reserve() optimization is a nice touch for reducing allocations.


1867-1913: WriteRepairedDiffs correctly handles batched database writes and cache invalidation.

The implementation:

  • Uses AssertLockNotHeld(cs) to ensure database writes don't hold the manager lock
  • Batches writes with a 16MB threshold (consistent with MigrateLegacyDiffs)
  • Correctly clears both mnListDiffsCache and mnListsCache after writes to force fresh reads
  • Takes LOCK(cs) only briefly for cache clearing, maintaining good concurrency

1685-1697: CompleteRepair uses assert(false) on commit failure.

The assert(false) on line 1695 will crash the node if the database commit fails. While this is a critical operation where failure could indicate data corruption, consider if a more graceful error handling approach might be appropriate (e.g., throwing an exception that the caller can handle, or returning an error code).

@UdjinM6
Copy link

UdjinM6 commented Dec 2, 2025

Note: CI failure is fake failure

yeah, needs #6986 to fix it (or can be ignored)

Thinking about it again and maybe we should actually backport it cause otherwise CI in master will look broken.

…k size just 64kb instead 16Mb

def5d0a chore: fix indentation (UdjinM6)
7a93394 test: inline node_p2p_port to dynamically_prepare_masternode instead passing args (Konstantin Akimov)
37c6855 fix: priority -fastprune over -tinyblock (Konstantin Akimov)
375bf9d test: new commandline argument -tinyblk to use blk size just 64kb instead 1Mb (Konstantin Akimov)
99f8abf test: avoid copy-paste when update dip3 params in dash.conf (Konstantin Akimov)
2972e84 test: removed duplicated code from dynamically_initialize_datadir with dash.conf preparation (Konstantin Akimov)
521d92f tests: unify dash.conf for dynamically added masternodes and statically added (Konstantin Akimov)

Pull request description:

  ## Issue being fixed or feature implemented
  Even trivial functional tests that have only genesis blocks without any funds still creates 2 files 17 Mbs in total: 16Mb files for blk00000.dat and 1Mb for rev00000.dat for each node:
  ```
  $ test/functional/rpc_help.py --nocleanup
  <succeed>
  $ find /tmp/dash_func_test_5coohz_8 -ls | grep -E '/rev|blk'
     436679   1024 -rw-------   1 knst     knst      1048576 Nov 17 02:08 /tmp/dash_func_test_5coohz_8/node0/regtest/blocks/rev00000.dat
     436673  16384 -rw-------   1 knst     knst     16777216 Nov 17 02:08 /tmp/dash_func_test_5coohz_8/node0/regtest/blocks/blk00000.dat
  ```

  It doesn't look like a lot for a single test, but we have 300 functional tests, in average ~3 nodes -> more than 10Gb of mostly zeroes written on disk for each CI run. Files are not sparse and indeed takes IO and disk space.

  ## What was done?
  Introduced a new command line argument `-tinyblk` which reduce allocated space for empty blk files to 64kb only.
  It works similar as `-fastprune` but doesn't affect pruning settings; only block size.

  Also minor refactoring for functional tests to avoid copy-past code when writting dash.conf for case of statically and dynamically added new nodes; duplicated code is unified.

  ## How Has This Been Tested?
  CI succeed for this PR: https://github.com/dashpay/dash/actions/runs/19412323566/job/55536154684?pr=6986

  While `develop` fails: https://github.com/dashpay/dash/actions/runs/19392476511
  ```
  Unhandled exception. System.IO.IOException: No space left on device : '/home/runner/actions-runner/cached/_diag/Worker_20251116-201117-utc.log'
  ```

  Local run:
  ```
    1602527     64 -rw-------   1 knst     knst        65536 Nov 17 04:12 /tmp/dash_func_test_bw8hmeiz/node0/regtest/blocks/blk00000.dat
    1602533     64 -rw-------   1 knst     knst        65536 Nov 17 04:12 /tmp/dash_func_test_bw8hmeiz/node0/regtest/blocks/rev00000.dat
  ```

  64kb only.
  Some other tests that have more blocks and transactions in blocks have increased data file correctly as expected, for example:
  ```
    1505724    320 -rw-------   1 knst     knst       327680 Nov 17 04:05 ./feature_llmq_simplepose_268/node0/regtest/blocks/blk00000.dat
  ```

  Local run with 30 parallel jobs (-j30) become ~10seconds faster (195s -> 180+); for 20 jobs - no difference as IO is no more limiting factor.

  ## Breaking Changes
  N/A

  ## Checklist:
  - [x] I have performed a self-review of my own code
  - [ ] I have commented my code, particularly in hard-to-understand areas
  - [x] I have added or updated relevant unit/integration/functional/e2e tests
  - [ ] I have made corresponding changes to the documentation
  - [x] I have assigned this pull request to a milestone

ACKs for top commit:
  UdjinM6:
    light ACK def5d0a
  kwvg:
    utACK def5d0a

Tree-SHA512: 6b0bcfdfb07e711a939dacc5c068527647bf1e65c10d8cfe9231facab6072d7a080376d38906708225b8851930bace0b20d1741a3da3daf346e292d237a72387
Copy link
Collaborator

@thephez thephez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestions for heading formatting in release notes

kwvg
kwvg previously approved these changes Dec 2, 2025
Copy link
Collaborator

@kwvg kwvg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 8705c8bd3e1fa4bbd6a1b255147bea45f940a153

Copy link
Collaborator

@thephez thephez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Release notes LGTM 👍 2159fef7d6acf6102908ea3991e2858bcf9ea7ec

Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 2159fef7d6acf6102908ea3991e2858bcf9ea7ec

@PastaPastaPasta PastaPastaPasta force-pushed the chore/v23.0.1-backports branch from 2159fef to 736bb26 Compare December 2, 2025 15:29
Copy link
Collaborator

@kwvg kwvg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 736bb26

@PastaPastaPasta PastaPastaPasta merged commit cd2f5c4 into dashpay:v23.0.x Dec 2, 2025
28 of 30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants