chore: prepare v23.1.8 release#7477
Conversation
|
✅ Final review complete — no blockers (commit bcdb34c) |
|
The The job loads |
1270899 to
1c06af7
Compare
…ed masternodes 536f388 fix(qt): keep PoSe score visible when hiding banned masternodes (PastaClaw) Pull request description: # PR description ## Summary - Keep the Masternodes tab PoSe Score column visible when "Hide banned" is checked. - Continue filtering banned masternodes via the existing proxy filter. Closes dashpay#7286. ## Validation - `git diff --check` - Pre-PR review gate: ship - Not run: full build / GUI smoke test; no build directory was available in this worktree. Top commit has no ACKs. Tree-SHA512: ca69dd31322d78ced7d48621ea4dbef8ec65305411abcd245a9b8c7b3059870dfc174caec2ec6d9a05f7940263379e4d5991ad5d1eeb69f5b4894d5aa4751bde
…otx listdiff results 9c74948 chore: removed comment - this code to be removed anyway after deprecated branch removed (Konstantin Akimov) f9a4aeb fix: make non-zero output for platformP2PPort if platform_p2p exist (Konstantin Akimov) 99b0c3d fix: don't include masternode to protx listdiff` if internal migration happened between versions (Konstantin Akimov) Pull request description: ## Issue being fixed or feature implemented There're 2 different versions of protx's internal storages; and they are switched after v24 activation. It seems as when version switched, the incorrect platformP2PPort / platformHTTPPort may be added to diff even if they are not used anymore and it happens only if snapshot is used; for example after node restart. It causes strange result of `protxlistdiff A B` such as: ``` "MASTERNODE": { { "lastPaidHeight": 9204, "platformP2PPort": 0, <---- INVALID it should be correct port here "platformHTTPPort": 0, <----- INVALID it should be correct port here "addresses": { "platform_p2p": [ <VALID> ], "platform_https": [ <VALID> ] ``` It happened on devnet on block on 9216 ## What was done? Added reset of platformP2PPort and platformHTTPPort. Added a workaround to show valid results for nodes that already have corrupted database. ## How Has This Been Tested? Sync node with devnet palona ; restart node -> issue is reproduced. Build a node from this PR, restart node -> issue is not reproduced. ## 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 9c74948 Tree-SHA512: d4f364223f38f70c562fe6e387aa315823a966d1d95a00445c5cfae0b85d4610317cb2a5045daedadc696c56476c976a4836c889e76339d7397253dffe5eaf73
…tibility error for freetype 4a8a5a3 Merge bitcoin#32693: depends: fix cmake compatibility error for freetype (Konstantin Akimov) Pull request description: ## Issue being fixed or feature implemented It fixes freetype dependency build on Kubuntu 26.04 which provide cmake-4 by default. ## What was done? Backport bitcoin#32693 ## How Has This Been Tested? Build succeed ## 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 _(for repository code-owners and collaborators only)_ ACKs for top commit: PastaPastaPasta: utACK 4a8a5a3 Tree-SHA512: b9b796ef3a6e39a1acd58bee1f990d7a5c1b9bcc1b75bc5cb8f9e00ad9cc57cd85c5fd62f585ba7cb57493e55236d8d95069a739acad271cfd01dc6da23065ab
4e5cc4b fix: stabilize par help text in manpages (PastaClaw) Pull request description: # fix: stabilize par help text in manpages ## Issue being fixed or feature implemented Regenerating manpages currently records the local machine's CPU count in the `-par` and `-parbls` help text. That makes otherwise unrelated release manpage regeneration change those entries depending on which machine generated the pages. ## What was done? Updated the `-par` and `-parbls` help text to avoid printing the dynamic lower bound derived from `GetNumCores()`. Runtime behavior is unchanged: negative values still mean "leave that many cores free", `0` still auto-detects, and the existing max/default values remain documented. The checked-in `dashd` and `dash-qt` manpages were updated to match the new stable generated text. ## How Has This Been Tested? Tested on macOS arm64: ```bash git diff --check python3 -m py_compile contrib/devtools/gen-manpages.py rg -n -e '\\fB\\-[0-9]+\\fR to' doc/man/dashd.1 doc/man/dash-qt.1 ``` The grep command returned no matches, confirming the affected generated manpages no longer contain a CPU-count-specific lower bound. Also ran a pre-PR code review gate against the exact worktree diff: ```text Recommendation: ship ``` Note: this worktree did not have configured Dash Core build artifacts and `help2man` is not installed locally, so I did not rerun full manpage generation from rebuilt binaries here. The manpage edits mirror the changed `src/init.cpp` help text. ## Breaking Changes None. ## 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 - [x] 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 4e5cc4b UdjinM6: utACK 4e5cc4b Tree-SHA512: a547caf7f7dce3c2d4dc8295cba75d23da3870b90fd274ee9a3ebbcb2320d8415ef682afe5ce8a9cd56f6b1c979a9c5b7f680032aa2774fd2d61282fbb4007e5
eb1857a ci: update GitHub Actions pins for Node 24 (PastaClaw) Pull request description: # CI action Node 24 pins ## Issue being fixed or feature implemented GitHub Actions now warns that actions targeting Node.js 20 are deprecated and are being forced to run on Node.js 24. Dash Core `develop` already has most of the action updates, but a few workflows still pin older JavaScript action versions. ## What was done? Updated the remaining workflow action pins to Node 24-compatible versions: - `eps1lon/actions-label-merge-conflict@v3.1.0` - `actions/github-script@v8` - `amannn/action-semantic-pull-request@v6` Also replaced the deprecated `actions-ecosystem/action-add-labels@v1` usage in the merge-check workflow with `actions/github-script@v8`, and granted the minimal `issues: write` permission needed for PR labels/comments. ## How Has This Been Tested? - `git diff --check upstream/develop..HEAD` - Parsed all workflow YAML files with Ruby `YAML.load_file` - Searched `.github/workflows` for the deprecated action pins that triggered the warning - Ran the pre-PR code review gate; result: ship ## Breaking Changes None. ## 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 - [ ] I have assigned this pull request to a milestone ACKs for top commit: UdjinM6: utACK eb1857a PastaPastaPasta: utACK eb1857a Tree-SHA512: 706fa8b74bff64c565c7bd5fdad70d5ca1398becbd320c2ea1f61e0c7b74f72f60cfd109a58ad972d56b633c476cf2866df0f2f69e4f25226c0af61bd7ec96b9
actions/upload-artifact@v6 rejects filenames containing ':' (and other NTFS-unsafe characters). The Xcode SDK ships ~9k Perl man pages under usr/share/man with '::' in the name (e.g. APR::Base64.3pm), which breaks the prepared-SDK artifact handoff used by mac depends/src jobs when the depends-sdks cache misses. Strip man pages (and any residual upload-unsafe names) after extract in setup-sdk. Headers/libs/tbd files needed for cross-compiling are kept. This script is checked out from the PR head even when pull_request_target runs develop workflows, so the fix unblocks release PRs without waiting on a default-branch workflow change.
7cb0c29 fix: fall back to serial map when fork is unavailable, drop multiprocess dep (UdjinM6) de1cc2c fix: run of circular-dependencies with python3.15 (Konstantin Akimov) Pull request description: ## Issue being fixed or feature implemented Multiprocess uses dill to pickle the nested handle_module2 closure and dill's Python 3.15 support is broken (co_lnotab was removed from code objects). ## What was done? Moved some functions and variables to global namespace. ## How Has This Been Tested? Run `test/lint/lint-circular-dependencies.py` with python3.15 Review hint: use `git show -w --color-moved=dimmed-zebra` ## Breaking Changes _Please describe any breaking changes your code introduces_ ## 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 _(for repository code-owners and collaborators only)_ ACKs for top commit: UdjinM6: utACK 7cb0c29 Tree-SHA512: cc1aef094f8ed0ffd17e4ef7fdb3bb20af048b8de5c2120b0283fcf7ebb3957f8a8736d97dcd543ef5ac1d3210ed39934fde898d5c47a0ad482d4bf0e263bb91
b5a7ba0 test: drop redundant quorum manager include (PastaClaw) 59fafb0 fix: bound ChainLock seen cache (PastaClaw) Pull request description: ## Issue being fixed or feature implemented Bounds ChainLock seen-CLSIG duplicate tracking so unvalidated or non-current CLSIG inventory cannot grow retained handler state without limit. This improves defensive handling for peer-supplied ChainLock messages while preserving the existing best ChainLock validation and update flow. ## What was done? - Replaced the unbounded `seenChainLocks` map with a bounded `unordered_limitedmap`. - Moved same-height/older ChainLock rejection before inserting into duplicate-tracking state. - Updated cleanup for the bounded cache. - Added focused unit coverage for stale CLSIG retention and cache bounding. ## How Has This Been Tested? Tested locally on macOS in a fresh worktree rebased on current `upstream/develop`: - `make -C src test/test_dash -j$(sysctl -n hw.ncpu)` - `src/test/test_dash --run_test=llmq_chainlock_tests,chainlock_handler_tests` - `git diff --check upstream/develop..HEAD` - `COMMIT_RANGE=upstream/develop..HEAD test/lint/lint-whitespace.py` - Scoped Codex review of `upstream/develop..HEAD`: no significant issues found; recommendation ship. ## Breaking Changes None. ## Checklist: - [x] I have performed a self-review of my own code - [x] 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 - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: kwvg: utACK b5a7ba0 Tree-SHA512: 5626a69dfb1a1fbcbee56b62cc9fa442922a877f2d4ce33c51ade33f0718fe6cfae272e2136fb7e128e790edc8aacbbf694d0daae3a78406a98cb0543127d3ec
439fb7d test: cover undersized DKG contribution intake (pasta) 35d4480 fix: bound DKG contribution blob intake (pasta) Pull request description: ## Issue being fixed or feature implemented The DKG intake hardening on `develop` pre-validates pushed `qcontrib` messages before retaining them. The valid configured envelope is `params.minSize <= actual members <= params.size`; the later DKG session worker still checks the exact `members.size()` once it has session context. Without the lower bound, structurally well-formed but undersized qcontrib payloads can pass the cheap intake check and reach retention before the worker rejects them. ## What was done? Tightened the cheap qcontrib structure check in `NetDKG` so encrypted contribution blob counts must be within the configured quorum bounds: - at least `params.minSize` - at most `params.size` The exact member-count validation remains in the DKG worker. Also added functional coverage for a qcontrib payload that deserializes cleanly but has fewer encrypted contribution blobs than `params.minSize`. ## How Has This Been Tested? Run feature_asset_locks.py multiple times that has been faulty in the first place (by knst). ## Breaking Changes None. ## Checklist: - [x] I have performed a self-review of my own code - [x] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] I have assigned this pull request to a milestone This pull request was created by Codex. ACKs for top commit: knst: tACK 439fb7d UdjinM6: utACK 439fb7d Tree-SHA512: 32de8ac4775cc066de53761de17f7df4c6126214d1cff245e97fc8eeb6222703f26e8bba32d64f8c2b1eae25e79f058766d640658cd801830fe196361e8a4726
af6a0fd feat(serialize): add bounded-vector deserialization primitives (PastaClaw) Pull request description: ## Issue being fixed or feature implemented Network messages often have protocol-specific vector limits below the generic serialization limit. Callers need to enforce those limits before vector allocation and element decoding, without changing the wire format. ## What was done? - Factor the existing batched vector element decoder into a shared internal helper. - Add `UnserializeVectorWithMaxSize` for runtime bounds. - Add `LIMITED_VECTOR` / `LimitedVectorFormatter` for compile-time bounds in `READWRITE` declarations. - Keep serialization byte-for-byte compatible with ordinary vectors; only deserialization is bounded. - Compare CompactSize counts before narrowing or allocating, including counts at and above `MAX_SIZE`. ## Stacked adopters Each consumer remains a separate command-specific PR: - dashpay#7416 — quorum-data response vectors - dashpay#7418 — LLMQ signing message vectors - dashpay#7419 — CoinJoin message vectors - dashpay#7438 — SPORK signature vector Reviewing dashpay#7439 first leaves each child PR with only its protocol-specific policy, punishment, and regression tests. ## How Has This Been Tested? - `src/test/test_dash --run_test=serialize_tests` - Exact and over-limit boundaries, zero limits, custom element formatters, `MAX_SIZE` and `MAX_SIZE + 1` declarations, 64-bit CompactSize counts, wire compatibility, and rejection before element decode are covered. ## Breaking Changes None. Existing vector serialization and deserialization behavior is unchanged. ## Checklist: - [x] I have performed a self-review of my own code - [x] 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 - [ ] I have assigned this pull request to a milestone Top commit has no ACKs. Tree-SHA512: 61e4183a5a2a173254f3105d30969704c2c53dac3ce421f0b3e8e989bc87ec1a94d2757944694db219802403a668d7460943d507ab7948db30b97145d57f26d6
3cb73fd test: drop redundant spork_tests unit suite (PastaClaw) 44a8fe1 test: regression coverage for CSporkMessage signature-size bound (PastaClaw) d2e600f fix: bound CSporkMessage signature vector allocation (PastaClaw) Pull request description: Depends on dashpay#7439. Please review only the two SPORK-specific commits here. ## What changed - bound `CSporkMessage::vchSig` to `CPubKey::COMPACT_SIGNATURE_SIZE` before vector allocation using #7439s `LIMITED_VECTOR` formatter - punish peers that send malformed, truncated, or oversized SPORK messages - add unit coverage for the exact `CompactSize(MAX_SIZE)` trigger and a P2P disconnect regression test ## Why A malformed SPORK message could declare a large signature length in a small payload. Generic byte-vector deserialization would allocate its first 5,000,000-byte chunk before discovering the payload was truncated. The resulting exception was caught by the generic message-processing handler without penalizing the peer, allowing repeated attempts on the same connection. Valid SPORK signatures are 65-byte compact signatures on every network. The testnet distinction changes the signing preimage, not the signature encoding. Shorter well-formed signatures continue through the existing invalid-signature path and are punished there; the formatter prevents oversized declarations from allocating first. The reusable bounded-vector serialization primitives are introduced separately in dashpay#7439. ## Validation - `src/test/test_dash --run_test=spork_tests,serialize_tests` - `test/functional/feature_sporks.py` The exact unit and functional regressions were also run against the vulnerable implementation: the unit test observed the old EOF-after-allocation path, and the malformed P2P peer was not disconnected. ACKs for top commit: PastaPastaPasta: utACK 3cb73fd kwvg: utACK 3cb73fd Tree-SHA512: d547f589c3920baaacb121c618b812314901639c449bd562ea150de3a8743e3fbff10c1c92f2e192de776452d74ad7dc9be02622ddd29d9e5f7e43eacd966fd2
a286e0e fix: bound quorum data response vectors (PastaClaw) Pull request description: Depends on dashpay#7439. Please review only the final command-specific commit here. ## Issue being fixed or feature implemented Quorum-data responses carry verification-vector and encrypted-contribution vectors whose expected sizes are known from the requested quorum. This hardens QDATA processing by checking the serialized vector count before allocating, deserializing, or processing those vectors. This path is MNAuth/request-gated and is intentionally handled separately from unauthenticated public vector intake. ## What was done? - Read QDATA verification vectors with the requested quorum threshold as the maximum. - Read encrypted contributions with the number of valid quorum members as the maximum. - Require exact semantic counts and penalize mismatches before decrypt/aggregate work. - Extend functional coverage for undersized, oversized, and allocation-amplifying CompactSize declarations. The reusable bounded-vector serialization primitives are introduced separately in dashpay#7439. ## How Has This Been Tested? - `test/functional/p2p_quorum_data.py` ## Breaking Changes None. ## Checklist: - [x] I have performed a self-review of my own code - [x] 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 - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only) ACKs for top commit: kwvg: Code near identical to past utACK (see [diff](https://github.com/dashpay/dash/compare/ecf49885bcbb40fd09bd81de95edf54d3996e2fe..a286e0e7eb4fd63eb65f05f5deefd5a2c4c43f55)) --- utACK a286e0e Tree-SHA512: 1d217cff7096f0dbad736e98be91e6b4eac154ae7ca0512cb3200f448b3152485d89f3f13a5d36617d7e4122aac2ed521f79ccd6ca787c0e8fafb200cb3cf118
45ee9af fix: separate CoinJoin entry wire and semantic limits (PastaClaw) d81ff3c fix: bound CoinJoin entry intake (PastaClaw) c72a8f5 fix: bound CoinJoin final signature intake (PastaClaw) Pull request description: Depends on dashpay#7439. Please review only the three CoinJoin-specific commits here. ## Issue being fixed or feature implemented CoinJoin server messages could deserialize or process peer-controlled input/output vectors before enforcing CoinJoin session bounds. This hardens the final-signature and entry intake paths by separating the wire-safety bound from the per-entry semantic bound. ## What was done? - Accept `DSSIGNFINALTX` only during signing and only from an active session participant. - Bound `DSSIGNFINALTX` input deserialization at the largest complete CoinJoin size: currently 20 participants × 9 inputs = 180. - Apply the same 180-element wire-safety cap to both `CCoinJoinEntry` vectors, rejecting larger declarations before vector materialization. - Keep the existing semantic limit of 9 inputs and 9 outputs per entry in `AddEntry()`. - Allow declarations from 10 through 180 to deserialize safely and reach semantic rejection, consuming collateral only when it matches a collateral accepted for the active session. - Remove the special `MAX + 1` input rule, oversized-output flag, and asymmetric input/output deserialization behavior. - Add focused boundary, participant, session-state, collateral, and round-trip tests. The reusable bounded-vector deserialization primitive is introduced separately in dashpay#7439. ## How Has This Been Tested? - `make -C src -j15 test/test_dash` - `./src/test/test_dash --run_test=coinjoin_inouts_tests` (8/8 passed) - `test/lint/lint-whitespace.py` - Focused `LogPrint` format-string lint - Focused `clang-format-diff.py` - `git diff --check` - Independent exact-range Codex review (`9474fc5e2a1..48a1eb95838`): ship, 0 findings ## Breaking Changes None. ## Checklist - [x] I have performed a self-review of my own code - [x] 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 - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: UdjinM6: utACK 45ee9af Tree-SHA512: 8924d894d99ec8420034968cb55dad6ed4970911e01b5cc073b2f71ee79d0246d0aa1936b1d4a99b8f0749f5665097329c4fe65757c5986db25762a5c4ef10b4
…cation 5b6ac38 test: fix getmerkleblocks copyright year (PastaClaw) 862e7b0 test: cover getmerkleblocks oversized bloom-filter prechecks (PastaClaw) 28d2c6c fix(net): bound CBloomFilter and filteradd vectors before allocation (PastaClaw) Pull request description: Prevent peer-declared FILTERADD and CBloomFilter vector lengths from allocating before their command-specific limits are checked. The shared CBloomFilter bound covers FILTERLOAD and governance sync. Each P2P entrypoint catches malformed bounded reads locally and applies the existing 100-point punishment, preventing replay through the outer message-processing catch. The getmerkleblocks RPC keeps its prior complete-oversized, truncated, noncanonical, and above-MAX_SIZE behavior. Adds exact CompactSize(MAX_SIZE) regressions for FILTERADD, FILTERLOAD, and governance sync while retaining valid boundary coverage. Validation: - make -C src dashd dash-cli test/test_dash - test_dash --run_test=bloom_tests (14 cases) - test/functional/p2p_filter.py - test/functional/p2p_govsync_bloom.py - test/lint/lint-python.py - test/lint/lint-whitespace.py - git diff --check - manual getmerkleblocks RPC matrix for complete/truncated boundary and malformed-prefix behavior - independent exact-range review: ship, no significant findings ACKs for top commit: knst: utACK 5b6ac38 Tree-SHA512: 8c433ff069021ccbc2fbaed92764704028a00fddfd9391644e00a3a70c768328a4f479142d8feebfd54a10d8c126ddcf77770f05cb3635a39def89ff320dba2e
… remote OOM 5c10539 perf: avoid O(n) map scan on every recovered sig in pending-queue cap check (pasta) 95e160d fix: bound pending recovered sig queue to prevent remote OOM (pasta) Pull request description: ## Issue Incoming `QSIGREC` (recovered signature) P2P messages are deserialized and appended to the per-node queue `CSigningManager::pendingRecoveredSigs` after only cheap gating checks (quorum exists/active, dedup by full hash). Actual verification is expensive (BLS) and is deferred to a single worker thread that drains only ~32 unique sign-hash sessions per cycle, whereas ingestion is crypto-free and happens on the network threads in parallel across connections. Two problems compound: - **No size bound.** `pendingRecoveredSigs` had no per-node or global cap, and the dedup check keys on the full message hash (which includes the signature), so it does not constrain a peer sending many distinct messages. Ingestion structurally outruns the drain. - **No cleanup on ban/disconnect.** `RemoveBannedNodeStates` only cleans the separate sig-shares subsystem (`CSigSharesManager::nodeStates`); nothing purged `pendingRecoveredSigs` for banned or disconnected peers. Net effect: a peer (or several) can grow the queue faster than it drains, increasing RSS until the node is OOM-killed — a remote, unauthenticated memory-exhaustion DoS. Highest impact against masternodes, which accept many inbound connections and run the LLMQ signing behind ChainLocks / InstantSend. ## Fix - **Bound the queue** in `VerifyAndProcessRecoveredSig` with a per-node cap (`MAX_PENDING_RECSIGS_PER_NODE = 1000`) and a global cap (`MAX_PENDING_RECSIGS_TOTAL = 10000`). Over-cap messages are dropped **silently, without a misbehaviour score** — verification is single-threaded, so an honest peer can legitimately outrun the drain during a burst, and this is queue-depth backpressure rather than a protocol violation (contrast the per-message structural caps for sig-shares, which do ban). - **Purge banned peers' queues** via a new `CSigningManager::RemoveNodesIf(predicate)` (mirroring `CSigSharesManager::RemoveNodesIf`), invoked from `WorkThreadSigning`'s periodic cleanup using `PeerIsBanned`. - **Prune drained (empty) node entries** during collection, so the global-cap scan stays cheap and disconnected nodes' queues are reclaimed once drained without waiting for a ban. With these caps the attacker-controllable pending queue is bounded to roughly **8 MB** worst case (10,000 entries × ~750 bytes resident per entry; the in-memory `CRecoveredSig` is 696 bytes vs. 193 on the wire, dominated by `CBLSLazySignature`). Previously it was unbounded. ## Testing - `make check` targets build clean; full `dashd` builds and links. - `feature_llmq_signing.py` passes — normal recovered-sig relay across masternodes is unaffected by the caps. - `lint-whitespace`, `lint-includes`, `lint-circular-dependencies` clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) ACKs for top commit: UdjinM6: utACK 5c10539 Tree-SHA512: c51f115c26d03a5174b22e311f0a385f776d7b67578735b3bf342b504b3996448e0d34ebe03a9cc28e2cdf52a3edf1088213300ce64b69ec80c90de6d806a19d
bdca48c refactor: use CountedBucketMap for counting total amount of pending sigs (Konstantin Akimov) 355da45 fix: cap sig-share verification batch by share count (PastaClaw) 08d9533 fix: cap amount of unverified batches by 4 (Konstantin Akimov) e2862fe fix: the actual cap enforcement for pending signatures (Konstantin Akimov) 4666ef3 test: add regression tests for CountedBucketMap (Konstantin Akimov) ec15f90 refactor: use dedicated util structure to count internal objects in signing-shares (Konstantin Akimov) Pull request description: ## Issue being fixed or feature implemented Pending incoming LLMQ sig shares are admitted cheaply and verified later by worker threads. Direct and batched share traffic could grow retained pending verification work without per-node/global backpressure. This replaces closed PR dashpay#7413 and keeps the same scope: resource/backpressure hardening for LLMQ signing, with no consensus or user-facing behavior change. ## What was done? - Add per-node and global caps for pending incoming sig shares. - Track pending counts explicitly so cap checks do not require repeated scans. - Gate `QSIGSHARE` and `QBSIGSHARES` pending admission; over-cap shares are dropped without misbehavior scoring. - Clear pending incoming shares when a peer is banned and skip banned node states during collection. - Refuse new pending work for already-banned node states. - Add unit coverage for cap/drop/count cleanup behavior. ## How Has This Been Tested? - `./autogen.sh` - `./configure --without-gui --disable-bench --disable-fuzz-binary` - `make -C src test/test_dash -j$(sysctl -n hw.ncpu)` - `src/test/test_dash --run_test=llmq_utils_tests` - `git diff --check upstream/develop..HEAD` - `COMMIT_RANGE=upstream/develop..HEAD test/lint/lint-whitespace.py` ## Breaking Changes None. ## Checklist: - [x] I have performed a self-review of my own code - [x] 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 - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: kwvg: utACK bdca48c Tree-SHA512: e2403635a608aab5488dbf10b481a778e735a6e5b065eec5a4cc444818f61e89b3a688f82c14aaceae07fd714432d39c013769a54aa66e31bb8abddb3531aaf3
8ff75e0 llmq: cover QBSIGSHARES aggregate sig-share bound with a testable decoder (PastaClaw) e51e304 llmq: bound LLMQ signing vector intake (PastaClaw) c0af156 llmq: bound batched sig-share intake (PastaClaw) Pull request description: Depends on dashpay#7439. Please review only the two command-specific commits here. ## Issue being fixed or feature implemented LLMQ signing P2P messages previously deserialized peer-controlled vectors before enforcing the existing per-message count limits. This hardens the signing message intake path so oversized counts are rejected before vector materialization. This intentionally does not include the QFCOMMITMENT dynamic-bitset fix. ## What was done? - Use the shared runtime-bounded vector reader for signing message batches in `NetSigning::ProcessMessage`. - Bound `CBatchedSigShares::sigShares` declaratively with `LIMITED_VECTOR`. - Retain explicit running-total accounting for QBSIGSHARES, where many individually valid batches could exceed the aggregate cap. - Ban peers on malformed or oversized signing vectors. - Add unit coverage for the exact boundary and oversized batched sig-share vectors. The reusable bounded-vector serialization primitives are introduced separately in dashpay#7439. ## How Has This Been Tested? - `src/test/test_dash --run_test=llmq_utils_tests` - `src/test/test_dash --run_test=serialize_tests` - `test/lint/lint-whitespace.py` - `test/lint/lint-circular-dependencies.py` ## Breaking Changes None. ## Checklist: - [x] I have performed a self-review of my own code - [x] 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 - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only) ACKs for top commit: UdjinM6: utACK 8ff75e0 Tree-SHA512: 873fb78ef55749449c0548828dc8709bf0709637732a000bd009d8bba9ed0270e1582eb0020f852c3a8e8bb6d448d1f7b8c0402e271ac42155081a9d13d25bc8
Narrow exception from Dash dashpay#7387 for the v23.1.8 release history. The full dashpay#7387 merge removes p2p_governance_invs.py after migrating coverage to unit tests. v23.1.x still ships that functional test, so only the prerequisite fixture/coverage subset is included here: - expose RequestedHashCacheSizeForTesting() and governance::RELIABLE_PROPAGATION_TIME for unit observation of ConfirmInventoryRequest / CheckAndRemove - add governance_inv_tests coverage for request-cache expiration and NetGovernance::Schedule periodic cleanup Later dashpay#7414/dashpay#7442 build on these fixtures. p2p_governance_invs.py is retained and updated with dashpay#7442. Co-Authored-By: Claude <noreply@anthropic.com>
…c requests 5ad1ef1 fix: throttle governance vote sync requests (PastaClaw) Pull request description: ## Issue being fixed or feature implemented - Per-object `MNGOVERNANCESYNC` vote requests were not recorded in `NetFulfilledRequestManager`, unlike full governance sync requests. - A peer could repeatedly ask for votes for the same governance object and make the node rescan/build the same vote inventory again. This is a low-cost CPU/lock-work concern, not a crash/OOM primitive. ## What was done? - Add a fulfilled-request key for per-object vote sync requests: `MNGOVERNANCESYNC-votes-<object hash>`. - Return early and score repeat requests from the same peer/address. - Add unit coverage asserting the per-object request is registered as fulfilled. ## How Has This Been Tested? - `git diff --check upstream/develop..HEAD` - `COMMIT_RANGE=upstream/develop..HEAD test/lint/lint-whitespace.py` - Not run locally: `src/test/test_dash --run_test=governance_inv_tests/per_object_vote_sync_is_fulfilled_request_limited` because this fresh worktree has no configured build/test binary. ## Breaking Changes None. ## 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 - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: UdjinM6: utACK 5ad1ef1 Tree-SHA512: 4d72826ddf3a5e1834281fb53a0c7af724ac97eba7a1a0cc73936641015215511c3cc9c409812cc8168be0523d53f2395d6e871f42ab0fcb36ed67404ab63a9e
…the net-layer per-peer request tracker 0c0ec8c test: cover net-layer per-peer governance inv authorization (UdjinM6) 3f5536c fix(net): authorize governance inv responses via the per-peer request tracker (UdjinM6) Pull request description: ## Issue being fixed or feature implemented Governance tracked pending object/vote requests in a global, governance-owned cache (`CGovernanceManager::m_requested_hash_time`). `ConfirmInventoryRequest` recorded a hash when we decided to fetch an inv, and `AcceptMessage` authorized the eventual response (accepting once, then erasing), with entries expiring after `RELIABLE_PROPAGATION_TIME`. That cache was unbounded. ~Bounding it with a global cap (as in dashpay#7425) is only a partial fix: the cap has to be large, and because it is global, a single peer can fill it (a `MNGOVERNANCESYNC`/INV burst) and stall governance-inv intake for everyone until entries expire.~ 18d4725d99cfe527c859621932ed48b436517df4 fixed that. The net layer already tracks pending object requests **per peer** in `CNodeState::ObjectDownloadState` (`m_object_announced` / `m_object_in_flight`), which is bounded per peer by construction (`MAX_PEER_OBJECT_ANNOUNCEMENTS` / `MAX_PEER_OBJECT_IN_FLIGHT`), and governance already touches it on receipt (`PeerEraseObjectRequest`). The two trackers are populated in lockstep — the same `AlreadyHave` call that populated `m_requested_hash_time` also drove `RequestObject`. So the governance-side cache is redundant with state the net layer already keeps, and the net copy cannot be flooded by one peer. This reuses the net-layer tracker as the authorization source and removes the governance-side cache, eliminating the flood surface structurally instead of bounding it. ## What was done? - Add `PeerManager::PeerRequestedObject(nodeid, inv)`: erases **only** the per-peer `m_object_announced` / `m_object_in_flight` for that peer and returns whether the inv was tracked (announced by, or requested from, that peer). It deliberately does **not** touch the global `g_already_asked_for` / `g_erased_object_requests` markers, so an unsolicited push of a known hash from an untracked peer cannot poison request scheduling and suppress a later legitimate fetch. `PeerEraseObjectRequest` / `EraseObjectRequest` keep their existing behavior and callers (tx relay and the other Dash subsystems) unchanged. - Gate `MNGOVERNANCEOBJECT` / `MNGOVERNANCEOBJECTVOTE` acceptance on `PeerRequestedObject` instead of `AcceptMessage`. - Remove `m_requested_hash_time`, `AcceptMessage`, the `ConfirmInventoryRequest` cache write, the `CheckAndRemove` prune, and the obsolete request-cache unit tests. `ConfirmInventoryRequest` keeps only its "do we already have it?" role for `AlreadyHave`. Acceptance becomes per-peer: an object/vote is accepted only if the sending peer announced it or we requested it from that peer. In the inv → getdata gossip model a sender is always a prior announcer, and governance objects/votes are only ever sent as `getdata` responses (never pushed unsolicited), so legitimate flows are unaffected; genuinely unsolicited pushes are now rejected. This is the same INV-tracking requirement the old `AcceptMessage` path already had (`m_requested_hash_time` was only populated on an INV), so no legitimately-served response is newly rejected. Tests covering the modified code: - `src/test/net_tests.cpp` — `peer_requested_object_authorizes_and_erases_per_peer_state`: exercises `PeerRequestedObject` for announced-only and in-flight invs, that it erases the per-peer entry, and the anti-poisoning property (a rejected unsolicited push must not set `g_erased_object_requests` and suppress a later legitimate fetch — driven through the real `SendMessages` getdata scheduler). - `src/test/governance_inv_tests.cpp` — `governance_objects_require_peer_announcement_or_request` and `governance_votes_require_peer_announcement_or_request`: an announcing peer is accepted (and the gate consumes its per-peer tracker entry), an unsolicited peer is rejected without misbehaving, and a second independent announcer's duplicate is accepted idempotently. ## How Has This Been Tested? macOS, `--enable-debug` build. - `make -C src test/test_dash -j"$(sysctl -n hw.ncpu)"` — clean build; each commit builds on its own. - `src/test/test_dash --run_test=net_tests` (19 cases) — pass, no regression from restoring the request-erase functions. - `src/test/test_dash --run_test=governance_inv_tests` (3 cases) — pass. - `src/test/test_dash --run_test=denialofservice_tests` (5 cases) — pass (object-request machinery). - `git diff --check` and `test/lint/lint-whitespace.py` — clean. Follow-up (not in this PR): a functional test driving an end-to-end multi-node governance sync plus the unsolicited-push-does-not-suppress-fetch case. ## Breaking Changes None. No consensus, protocol-message, or serialization change. The only behavioral change is that a governance object/vote pushed by a peer that neither announced it nor was asked for it is now rejected — stricter anti-unsolicited handling on a best-effort, non-consensus gossip path. ## Checklist: - [x] I have performed a self-review of my own code - [x] 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 - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: PastaPastaPasta: utACK 0c0ec8c Tree-SHA512: d93ebf0366e53cdba61cfeb495159e274b9b940d459ae6e4c5f370358d828835fac4d2da3c7765b3c72634980f549eb1bcb7dadcb3e98ebe63219c90b3d634f1
e058152 test: make governance vote fixtures wire-valid (PastaClaw) Pull request description: ## Issue being fixed or feature implemented The governance inventory tests merged in dashpay#7442 construct unsigned synthetic votes and round-trip them through the network parser. Develop now requires governance vote signatures to use a structurally valid 65- or 96-byte encoding, so the fixture is rejected as malformed before the authorization behavior under test is reached. This causes six unit-test failures across CI configurations. ## What was done? Give the synthetic `VOTE_SIGNAL_FUNDING` vote a compact-signature-sized placeholder. The 65-byte encoding matches the real ECDSA voting-key form for funding votes. These tests deliberately use a missing parent object, so vote processing takes the orphan path before cryptographic signature verification; production validation is unchanged. ## How Has This Been Tested? - Built `src/test/test_dash` in an isolated macOS arm64 worktree using the depends toolchain - `./src/test/test_dash --run_test=governance_inv_tests` - `./src/test/test_dash --run_test=governance_vote_wire_tests` - `git diff --check` - Mandatory independent pre-PR review gate: `ship` with no findings ## Breaking Changes None. Test-only change. ## 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 - [ ] I have assigned this pull request to a milestone ACKs for top commit: PastaPastaPasta: utACK e058152 Tree-SHA512: 5caca1e34ce563444ded42f669ff599f7658c6d1dbea1d541588211ac542ee45f3dd768e158899cb23150c5d45ec8dbcbf412a1472f73a3cc3e72a5ac37636e0
…_main while reading blocks bd3446f backport: Merge bitcoin#26326: net: don't lock cs_main while reading blocks (PastaClaw) Pull request description: # backport: Merge bitcoin#26326 ## Upstream backport This PR backports bitcoin#26326: - Upstream PR: bitcoin#26326 - Backported commits: - bitcoin/bitcoin@613a45c (`net: reduce LOCK(cs_main) scope in GETBLOCKTXN`) - bitcoin/bitcoin@75d27fe (`net: reduce LOCK(cs_main) scope in ProcessGetBlockData`) ## Issue being fixed or feature implemented Block-serving paths in `net_processing` were doing disk reads while holding `cs_main`. A peer can request blocks or block transactions repeatedly, so disk I/O should not extend the validation/global chain lock hold time. ## What was done? - Capture the requested block's disk position while holding `cs_main`. - Release `cs_main` before reading the block from disk. - Preserve the upstream `GETBLOCKTXN` invariant that recent blocks cannot be pruned before the post-lock disk read. - Apply the sibling upstream `ProcessGetBlockData` behavior: if the post-lock disk read fails because the block was pruned or cannot be loaded, log the condition, disconnect the peer, and return instead of asserting. - Capture `CanDirectFetch()` and the current tip while holding `cs_main` and use those cached values after the disk read. Dash note: upstream Bitcoin also has a witness-block raw-data fast path in `ProcessGetBlockData`; Dash does not have the corresponding `MSG_WITNESS_BLOCK` path here, so this backport adapts the shared full, filtered, and compact block-serving path. ## Backport prerequisite notes - `intentional_exclusion: bitcoin#27125` — upstream bitcoin#26326's changed lines use the `BlockManager::ReadBlockFromDisk(..., FlatFilePos)` API introduced by bitcoin#27125. Dash does not have that broader blockstorage refactor, but it already has the equivalent local `node::ReadBlockFromDisk(CBlock&, FlatFilePos, Consensus::Params)` helper, which returns the read block hash. This backport intentionally adapts the changed lines to Dash's existing helper and keeps the post-lock hash validation instead of importing bitcoin#27125 as a prerequisite. ## How Has This Been Tested? Tested on macOS arm64. - `git diff --check upstream/develop...HEAD` - `test/lint/lint-whitespace.py` - `./autogen.sh` - `./configure --without-gui --disable-bench --disable-fuzz-binary` - `make -j$(sysctl -n hw.ncpu) src/dashd` ## Breaking Changes None. ## 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 - [ ] I have assigned this pull request to a milestone Top commit has no ACKs. Tree-SHA512: 13e3fed2585e64a45f099a0e0ea482099f399d2133edcde947865a5f2d87a79fa2b328851dbebb7c39c6c4924d8e0d849c9504fd4d41b4c2ff8f2e0d9de2263c
…ate for other peers Narrow exception from Dash dashpay#7237: include only the Bitcoin Core bitcoin#27608 prerequisite required by later compact-block relay hardening (dashpay#7398). The full dashpay#7237 v0.26 batch is intentionally not included on v23.1.x. Co-Authored-By: Claude <noreply@anthropic.com>
…26898, bitcoin#27626, bitcoin#27743, bitcoin#26969, bitcoin#29412, bitcoin#32646, bitcoin#33296) 9d947f3 Merge bitcoin#33296: net: check for empty header before calling FillBlock (pasta) fe1e05d Merge bitcoin#32646: p2p: Add witness mutation check inside FillBlock (pasta) c9b3d19 Merge bitcoin#29412: p2p: Don't process mutated blocks (pasta) 5306dfa Merge bitcoin#26969: net, refactor: net_processing, add ProcessCompactBlockTxns (pasta) 6668c2a Merge bitcoin#27743: Unconditionally return when compact block status == READ_STATUS_FAILED (pasta) cc87ed2 Merge bitcoin#27626: Parallel compact block downloads, take 3 (Claude Code) 622299e Merge bitcoin#26898: fuzz: Add PartiallyDownloadedBlock target (MarcoFalke) Pull request description: ## What Backports a stack of Bitcoin Core compact-block relay hardening PRs, including the fix for a remotely-triggerable crash in compact-block reconstruction. | PR | Title | |----|-------| | bitcoin#26898 | fuzz: Add `PartiallyDownloadedBlock` target (+ `FillBlock` returns `READ_STATUS_INVALID` instead of asserting on a null header) | | bitcoin#27626 | Parallel compact block downloads, take 3 | | bitcoin#27743 | Unconditionally return when compact block status == `READ_STATUS_FAILED` | | bitcoin#26969 | net, refactor: add `ProcessCompactBlockTxns` | | bitcoin#29412 | p2p: Don't process mutated blocks | | bitcoin#32646 | p2p: Add witness mutation check inside `FillBlock` | | bitcoin#33296 | net: check for empty header before calling `FillBlock` | > bitcoin#27608 (the `from_peer` parameter for `RemoveBlockRequest`), which the stack builds on, is already in `develop` via dashpay#7237, so it is not re-included here. ## Why The primary motivation is closing a remotely-triggerable abort. A malicious peer acting as the in-flight compact-block source could send a `cmpctblock` followed by two `blocktxn` messages: the first `blocktxn` fails reconstruction (merkle mismatch) and leaves the now header-less `PartiallyDownloadedBlock` in flight (the `READ_STATUS_FAILED` branch does not call `RemoveBlockRequest`), and the second `blocktxn` re-entered `PartiallyDownloadedBlock::FillBlock`, hitting `assert(!header.IsNull())` → `SIGABRT`. On this branch that crash is eliminated by bitcoin#26898 (`FillBlock` now returns `READ_STATUS_INVALID` on a null header, which the caller handles by discouraging + removing the block request), with bitcoin#33296's explicit guard as belt-and-suspenders. The stack also brings parallel compact-block downloads (fetch the same block from up to `MAX_CMPCTBLOCKS_INFLIGHT_PER_BLOCK` peers) and a defence-in-depth "don't process mutated blocks" check. ## Dash-specific adaptations (non-segwit) Dash is not a segwit chain and has none of the witness-commitment machinery (`GetWitnessCommitmentIndex`, `BlockWitnessMerkleRoot`, `HasWitness`, `m_checked_witness_commitment`, `GetWitnessHash`, `DEPLOYMENT_SEGWIT`). The witness-dependent PRs were slimmed accordingly: - **bitcoin#29412 `IsBlockMutated`** drops the witness-malleation branch entirely; it reduces to the merkle-root check (`CheckMerkleRoot`, with an `m_checked_merkle_root` cache on `CBlock`) plus the CVE-2012-2459 / 64-byte-transaction check (using `::GetSerializeSize(*tx, PROTOCOL_VERSION)` instead of `TX_NO_WITNESS`). The early `BLOCK`-message check is unconditional (no `prev_block`/`DEPLOYMENT_SEGWIT` gating, which upstream only needs for the witness half). - **bitcoin#32646** keeps `FillBlock`'s 2-arg signature (no `segwit_active`); the mutation mock hook becomes `IsBlockMutatedFn`. - **bitcoin#33296** drops the `LookupBlockIndex`/`DEPLOYMENT_SEGWIT` lookup. - `Misbehaving(Peer&, score, msg)` and `ProcessBlock(..., force_processing)` (no `min_pow_checked`) throughout. - Functional tests adapted for the non-witness model: `p2p_compactblocks.py` (the stalling-peer corruption uses a coinbase-content mutation rather than witness data) and a slimmed `p2p_mutated_blocks.py`. ## Testing - Full build, all 7 commits; every changed TU compiles clean. - Unit: full `test_dash` suite passes; `blockencodings_tests` and `validation_tests` specifically exercised. - Functional: `p2p_compactblocks.py` (incl. new `test_multiple_blocktxn_response`), `p2p_mutated_blocks.py` (new), `feature_block.py`, `p2p_invalid_block.py` (v1+v2), `p2p_sendheaders.py`, `p2p_unrequested_blocks.py`, `mining_basic.py` — all pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Top commit has no ACKs. Tree-SHA512: 66e910053e3576559e687986256a51c07fa7a1da9f3abb01091107e7b98d84d11a28f8a48d9ecf409e0779ab61d3cc77d3436df85d3c960c801b98894731799f
dc74e23 fix: move is_mixing atomic from CCoinJoinClientManager to CWallet (Konstantin Akimov) 8d5876f fix: potential deadlock issue. cs_wallet_manager_map should be locked after cs_wallet (Konstantin Akimov) 268bf4d test: make newkeypool mixing test deterministically reproduce lock cycle (PastaClaw) 5511e29 test: cover newkeypool CoinJoin callback behavior (PastaClaw) ef7b1f5 fix: don't auto start mixing for locked wallets (Konstantin Akimov) c7cc8ce refactor: cleanups for CoinJoin client interface (UdjinM6) f8c71cb fix: keep flag `coinjoin` enabled consistently with user's intention over UI or command line (Konstantin Akimov) 4424487 fix: call InitCoinJoin only wallet is added (Konstantin Akimov) 07d5e3e refactor: remove duplicated methods from CJWalletManagerImpl to prefer interface's (Konstantin Akimov) d34a4c1 fix: avoid dangling pointers to CJ clients (Konstantin Akimov) 0cb7919 refactor: remove CoinJoinClientImpl wrapper and return bare pointer to interfaces::CoinJoin::Client (Konstantin Akimov) 69b57ab fix: regression test coinjoin_options_tests by enforcing call of `interfaces::MakeCoinJoinLoader` (Konstantin Akimov) d6f8438 fix: linkage error for non-wallet builds for further changes (Konstantin Akimov) Pull request description: ## Issue being fixed or feature implemented Hold lock during flush operations to prevent TOCTOU race condition. getClient() releases cs_wallet_manager_map before returning the raw pointer. If another thread calls removeWallet() concurrently, the unique_ptr is destroyed while flushWallet() still holds a reference, leading to use-after-free. This is inconsistent with removeWallet() which safely erases under the lock. Discovered here dashpay#7248 (comment) ## What was done? Use `doWithClient(name, [](){...})` instead of `getClient(name)->...` Mutex `cs_wallet_manager_map` should not be ever locked under `cs_wallet`. ## How Has This Been Tested? Run unit & functional tests ## 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: kwvg: utACK dc74e23 PastaPastaPasta: utACK dc74e23 Tree-SHA512: 4030f52aa391c889607d06cdbedc8bbd735ccf628aefd93b37868fb41b0d609cade2229709b8798527cc4d20bc426022767dba776c8a4be5cffe8ec060eb1355
Bump version metadata, refresh manpages, regenerate the example dash.conf with stable -par/-parbls help text (via dashpay#7394), update Flatpak metainfo, and archive current release notes. Co-Authored-By: Claude <noreply@anthropic.com>
1bf7cfc to
bcdb34c
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bcdb34cbf6
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| { | ||
| // Enablement will be re-evaluated when a wallet is added or removed | ||
| CCoinJoinClientOptions::SetEnabled(false); | ||
| CCoinJoinClientOptions::SetEnabled(gArgs.GetBoolArg("-enablecoinjoin", true)); |
There was a problem hiding this comment.
Include util/system before using gArgs
In wallet-enabled builds this translation unit now references gArgs, but none of its includes declare that global (it is declared by util/system.h). Compiling coinjoin/interfaces.cpp therefore fails as soon as the new constructor is built; add the missing include or pass the parsed option in from a header that already exposes ArgsManager.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
This does compile in wallet-enabled builds. I rebuilt dashd and test_dash with this exact source tree; src/coinjoin/libbitcoin_wallet_a-interfaces.o was produced successfully, and the generated .deps/libbitcoin_wallet_a-interfaces.Po explicitly includes util/system.h through the current include graph, so gArgs is declared before use. A direct include could reduce transitive-include reliance, but it is not a P1 build failure and does not justify restarting the release CI/history here.
thepastaclaw
left a comment
There was a problem hiding this comment.
Final validation — Codex + Sonnet
The exact release head was revalidated against source, including the CoinJoin gArgs include chain, governance fulfilled-request behavior, and adjacent governance test commits. No in-scope correctness or review-blocking issue remains; the proposed comments are either speculative maintenance advice or conflict with preserving separately reviewed release-aggregate provenance.
Review provenance
- Codex reviewers:
gpt-5.6-sol— general (completed),gpt-5.6-sol— dash-core-commit-history (completed) - Verifier:
gpt-5.6-sol— final-verifier (fallback) - Sonnet reviewers:
claude-sonnet-5— general (completed),claude-sonnet-5— dash-core-commit-history (completed)
Note: GitHub does not allow PastaClaw to submit an approval or request changes on their own PR, so the canonical verifier result is transported as a COMMENT review.
Release Preparation for v23.1.8
Prepares Dash Core v23.1.8 on the
v23.1.xbranch.Summary
This patch release collects security hardening, P2P and compact-block correctness fixes, CoinJoin reliability corrections, RPC/GUI fixes, and build and CI compatibility updates for the v23.1.x series.
The changes do not alter consensus.
Included Dash backports
CoinJoin and wallet
Security, LLMQ, governance, and serialization
These cover bounded vector deserialization, SPORK/bloom/CoinJoin/quorum message bounds, bounded recovered-signature and signature-share queues, ChainLock cache bounds, governance request authorization and throttling, and associated regression coverage.
Dash #7408 is folded into the release as shipped: cheap QCONTRIB structure checks accept encrypted contribution blob counts in
[params.minSize, params.size]. Exact member-count validation remains in the DKG session worker against the selected member set. An earlier review-only attempt to keep an exact-params.sizeintake check (c38ef02 on the merge-commits lineage) is not present on this history; that regression broke regtest DKG whenever the selected set is smaller than the configured quorum size.P2P and compact blocks
Upstream Bitcoin Core provenance:
ProcessCompactBlockTxnsbitcoin/bitcoin#26969These backports avoid holding
cs_mainduring block reads and harden compact-block download and reconstruction against mutated blocks, malformed headers, failed reconstruction, and parallel-download state corruption.GUI, RPC, build, and CI
-parand-parblshelp text in generated manpages anddash.conf.Commit history
The branch uses one GPG-signed cherry-pick of each relevant source PR merge commit rather than preserving each PR's individual constituent commits. All 26 commits in the release range are GPG-signed.
Two narrow provenance exceptions avoid broadening the release scope:
Release preparation and local adaptations
[minSize, size]).dash.conf, Flatpak metadata, and release notes.actions/upload-artifact@v6cannot represent.protx listdiff.Validation
make check: passedtest/lint/all-lint.py: passedfeature_governance_objects.pyp2p_governance_invs.pyp2p_govsync_bloom.pyfeature_llmq_dkg_intake.pyfeature_sporks.pyp2p_compactblocks.pyp2p_filter.pyp2p_mutated_blocks.pyp2p_quorum_data.pyrpc_coinjoin.pyrpc_getmerkleblocks.pyfeature_asset_locks.py(explicit CI reconciliation for fix: bound DKG contribution blob intake #7408 QCONTRIB range)v23.1.8versions.dash.confmatches the checked-in file.Review
The original 68-commit range was inventoried and mapped to its Dash and Bitcoin Core provenance. A focused security review found no new high- or medium-confidence non-resource-exhaustion vulnerabilities. Release-engineering findings around branch API adaptation, DKG range handling, CoinJoin initialization/UI state, test correctness, and release-note accuracy are folded into their owning source or release-preparation commits.
CI reconciliation (remote head
2c5c01evs this history)Remote CI on merge-commits head
2c5c01ef20cfailed five test jobs (linux64,sqlite,ubsan,tsan,multiprocess) all onfeature_asset_locks.py. Logs show:ActiveDKGSessionHandler::InitNewQuorum ... quorum initialization failedbad-cbtx-assetlocked-amounttest_asset_locksThat head still carried the c38ef02 exact-size QCONTRIB intake check (
blobs.size() == params.size). Valid contributions encrypt one blob per selected member, so counts in[minSize, size)are legitimate and were rejected before DKG could complete under undersized regtest MN sets. The 65c7183 / #7408 range check restores acceptance of those contributions.This final-history branch has the correct range folded into #7408; it never applies c38ef02's exact-size regression. Local re-run of
feature_asset_locks.pyon the final v23.1.8 product tree passed (173 s). Bothfeature_llmq_simplepose.pyvariants also passed on clean runs.Local validation limitations
make check.appstreamcliandhelp2manwere unavailable, so Flatpak metadata received XML validation and manpages were checked against the built binary versions and expected help changes.feature_asset_locks.py), fullmake check, full lint, and complete build were used as the comprehensive local gate.rpc_getmerkleblocks.pyattempt failed locally with RPC port bind contention against leftover functional-testdashdprocesses; it passed on clean retry after those processes were stopped.