backport: Merge bitcoin/bitcoin#26326: net: don't lock cs_main while reading blocks - #7350
Conversation
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughThis PR adds a compile-time check that Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Peer
participant NetProcessing
participant Chainstate
participant Disk
Peer->>NetProcessing: request block data
NetProcessing->>Chainstate: get tip, block position, direct-fetch state
NetProcessing->>Disk: ReadBlockFromDisk(block_pos)
Disk-->>NetProcessing: block data
NetProcessing->>NetProcessing: compare returned hash to requested hash
NetProcessing-->>Peer: serve block response or disconnect
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
✅ No Merge Conflicts DetectedThis PR currently has no conflicts with other open PRs. |
6440dea to
97af883
Compare
|
✅ Review complete (commit bd3446f) |
thepastaclaw
left a comment
There was a problem hiding this comment.
Code Review
Targeted change narrows the cs_main hold window in GETBLOCKTXN by capturing the block file position under the lock and performing the disk read outside it, with a hash check that fails closed on stale/pruned/mismatched reads. Both agents concur the change is correct; only a minor log-granularity nitpick remains.
💬 1 nitpick(s)
|
Is this not code we inherited from bitcoin? it is rare we want to accept a "fix" in their code. |
|
Good question. I checked this against upstream Bitcoin: the change is actually bringing this path back in line with the current inherited Bitcoin pattern, not inventing a Dash-only behavior. Bitcoin master already copies the recent block position under So I agree with the general rule — we should be cautious about “fixing” inherited Bitcoin code — but in this case the safer path is to follow the upstream Bitcoin fix rather than keep Dash on the older wider-lock version. |
Hmm; it seems then, that there may be a backport that we should backport instead of doing this adhoc? |
|
Yep — I traced it more precisely and there is an exact upstream Bitcoin commit for this:
That commit adds the same So I agree with your process concern: this should be treated as a Bitcoin backport, not as an ad-hoc Dash-only fix. If you prefer, I can close this PR and re-run it through the normal backport flow; otherwise I can update the PR metadata/commit message to explicitly cite the upstream commit. |
|
This pull request has conflicts, please rebase. |
97af883 to
c6ccbc6
Compare
|
This pull request has conflicts, please rebase. |
|
Rebased this onto current |
thepastaclaw
left a comment
There was a problem hiding this comment.
Code Review
Cumulative review at c6ccbc6246: the GETBLOCKTXN lock-scope reduction is correct — FlatFilePos is captured under cs_main, disk I/O runs lock-free, and the post-read hash check fails closed on stale/mismatched reads. No new in-scope defects in the latest delta. Carrying forward the prior nitpick about the log message conflating read failure with hash mismatch (already tracked in an unresolved inline thread).
💬 1 nitpick(s)
Note: GitHub does not allow me to submit APPROVE on my own PR, so this is posted as a COMMENT while preserving the verified non-blocking findings.
| if (!hash || *hash != req.blockhash) { | ||
| LogPrint(BCLog::NET, "Peer %d sent us a getblocktxn for a block we could not read\n", pfrom.GetId()); | ||
| return; |
There was a problem hiding this comment.
💬 Nitpick: Log line conflates disk read failure with hash mismatch
After cs_main is released, two operationally distinct failures share one log line: ReadBlockFromDisk returning std::nullopt (OpenBlockFile failure, deserialization error, PoW header check failure — typically pruning or corruption) and a successful read whose *hash != req.blockhash (the FlatFilePos captured under cs_main no longer points at the requested block, e.g. a race with reorg/prune/reindex in the very window this PR introduces). Splitting these into two messages would make the new lock-scope reduction easier to diagnose if it surfaces in the wild. Purely diagnostic quality; behavior is correct. Existing unresolved thread: #7350 (comment).
source: ['claude', 'codex']
|
Claw; please update this to actually be a backport, if it should so be instead of an adhoc change that doesn't accomplish / get shown in history as a backport |
c6ccbc6 to
037d040
Compare
|
Updated. I amended the PR head so the commit history now records this as a partial backport of bitcoin#26326, specifically bitcoin/bitcoin@613a45c ( |
thepastaclaw
left a comment
There was a problem hiding this comment.
Code Review
Cumulative review at 037d040ace. Source tree is unchanged from c6ccbc62; the push only rewrote commit metadata into proper Dash partial-backport form. The GETBLOCKTXN lock-scope reduction is correct: FlatFilePos captured under cs_main, disk read runs lock-free, post-read hash check fails closed on mismatch/missing/pruned. Only carried-forward finding is a low-confidence log-diagnostic nitpick about line 4496 conflating two distinct failure modes.
💬 1 nitpick(s)
Carried-forward findings already raised (1)
These findings were not re-posted as new inline comments because an existing review thread already covers them.
- [NITPICK] (deduped existing open thread)
src/net_processing.cpp:4495-4497: Log message conflates I/O failure with hash mismatch — Two operationally distinct failures share one log message:ReadBlockFromDiskreturningstd::nullopt(OpenBlockFile failure, deserialization error, PoW header check failure — typically pruning/corruption) and a successful read whose*hash != req.blockhash(the FlatFilePos captured under cs_m...
Note: GitHub does not allow me to approve my own PR, so this is posted as a COMMENT while preserving the verified nonblocking finding.
|
@PastaPastaPasta @UdjinM6 this is ready for human Core review. The PR history/title/body now identify it as a partial backport of bitcoin#26326, the branch is mergeable against |
…blocks 613a45c net: reduce LOCK(cs_main) scope in GETBLOCKTXN (Andrew Toth) 75d27fe net: reduce LOCK(cs_main) scope in ProcessGetBlockData (Andrew Toth) Pull request description: Inspired by bitcoin#11913 and bitcoin#26308. cs_main doesn't need to be locked while reading blocks. This removes the locks in net_processing. Dash notes: This backports bitcoin#26326. The upstream witness-block raw-data fast path is not present in Dash, so the ProcessGetBlockData adaptation applies to Dash's existing full, filtered, and compact block serving path.
037d040 to
bd3446f
Compare
|
Updated this into a full backport of bitcoin#26326 instead of the prior partial GETBLOCKTXN-only form. The branch now includes both upstream commits: 613a45c (GETBLOCKTXN) and 75d27fe (ProcessGetBlockData). GETBLOCKTXN now preserves the upstream assert invariant; the log/disconnect behavior is only in the sibling ProcessGetBlockData commit where upstream intentionally made that behavior change. Validation: |
|
@coderabbitai review |
✅ Action performedReview finished.
|
thepastaclaw
left a comment
There was a problem hiding this comment.
Code Review
Source: reviewer lanes attempted: opus general/commit-history/backport-reviewer all failed with extra-usage limit (resets Jul 10, 8am America/Chicago); gpt-5.5 general, gpt-5.5 dash-core-commit-history, and gpt-5.5 backport-reviewer completed. Verifier: gpt-5.5 after opus verifier failed with the same usage limit.
Prior reconciliation: the prior 037d040a nitpick about GETBLOCKTXN logging is FIXED at bd3446f6; the shared log branch was removed and the current path asserts hash && *hash == req.blockhash after the captured-position read.
Carried-forward prior findings: none.
New findings in latest delta: one backport-prerequisite finding was reported by the backport reviewer and promoted by the deterministic policy gate. The verifier otherwise found no general correctness or commit-history issues.
Note: posted as a COMMENT review because GitHub does not allow me to submit REQUEST_CHANGES on my own PR; the verified blocking finding is preserved below.
🔴 1 blocking
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `src/net_processing.cpp`:
- [BLOCKING] src/net_processing.cpp:2745-2747: Missing prerequisite: bitcoin#27125
Upstream bitcoin#26326's starting state already had bitcoin#27125's BlockManager disk-read methods, and the upstream changed lines call `m_chainman.m_blockman.ReadBlockFromDisk(*pblockRead, block_pos)` in ProcessGetBlockData and GETBLOCKTXN. Dash's starting state does not have that API; it still exposes namespace-level `node::ReadBlockFromDisk(CBlock&, FlatFilePos, Consensus::Params)` and this backport adapts the changed lines to that older helper. The missing upstream API was introduced by f0bb1021f0 in merge c2f2abd0a4 (`Merge bitcoin/bitcoin#27125: refactor, kernel: Decouple ArgsManager from blockstorage`), which is not an ancestor of this Dash head. This is a soft prerequisite gap: Dash has an equivalent local helper that returns the read block hash, so the conflict resolution looks correct and should preserve the intended post-lock disk-read validation, but the upstream dependency chain is incomplete relative to the modified section.
---
**Policy gate (backport-prereq-restore):** For full upstream backport PRs, a missing prerequisite is blocking unless the finding is explicitly allowlisted (e.g. `intentional_exclusion: true` or a matching entry in `policy_overrides`). The agent's original evidence above is the basis for this block; either backport the prerequisite or annotate the intentional exclusion in the PR description.
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
Follow-up on my self-review note at #7350 (review): Handled by documenting the prerequisite decision in the PR body under "Backport prerequisite notes":
The reason is that upstream bitcoin#26326 uses the BlockManager No branch/code change needed for this follow-up; current CI is green. |
|
CI triage note for the old linux64_ubsan-test failure in run 28288653526: the red test was feature_asset_locks.py timing out while waiting for quorum list propagation in test_v24_fork / mine_quorum_2_nodes. The failing PR head c6ccbc6246 changed only src/net_processing.cpp, so the failure was unrelated to this PR's GETBLOCKTXN/block-serving backport. I added this occurrence to the existing flaky-test issue #7310. The later final PR head bd3446f passed linux64_ubsan-test, and the PR is now merged, so no branch change is needed. |
…_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
…_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
…_main while reading blocks Backport of dashpay#7350 (upstream merge f2ae9f0, cherry-picked with -m1). v23.1.x adaptations, both restoring the exact shape of the original bitcoin#26326 commits (75d27fe, 613a45c) for this branch's older APIs: (1) ReadBlockFromDisk(FlatFilePos) here returns bool, not develop's std::optional<uint256> hash (which came from a later backport not in scope) - the read-failure paths test the bool like the bitcoin originals and drop the hash-equality assert. (2) SendBlockTransactions on this branch takes no Peer& parameter - the new GETBLOCKTXN call site omits *peer. All other hunks unchanged from upstream. (cherry picked from commit f2ae9f0362f269bf00885d1b0e4a30fa46a6f66a)
24920a0 chore: prepare v23.1.8 release (pasta) 2194248 Merge #7348: fix: penalize oversized notfound messages (pasta) f5c72c3 Merge #7347: fix: punish invalid dstx messages (pasta) 550caf7 Merge #7465: fix(qt): handle pixel-sized fonts when scaling widgets (pasta) e203710 Merge #7419: fix(net): bound CoinJoin message vector intake (pasta) 5f5b960 Merge #7418: fix(net): bound signing message vector intake (Pasta) 7cc2cca Merge #7450: test: make governance vote fixtures wire-valid (Pasta) f011c80 Merge #7440: fix(net): bound governance vote signature deserialization (Pasta) 4b4d96a Merge #7442: fix(net): authorize governance inv responses via the net-layer per-peer request tracker (Pasta) f855b13 Merge #7444: fix(net): bound bloom message vectors before allocation (Pasta) 5b5c6fb Merge #7415: fix: bound pending sig share queue (Pasta) 9bbe808 Merge #7416: fix(net): bound quorum data response vectors (Pasta) da42f50 Merge #7424: fix: bound ChainLock seen cache (Pasta) 5b310df Merge #7438: fix: bound SPORK signature deserialization (Pasta) e118d0c Merge #7259: fix: dangling point to cj client (Pasta) 9921621 Merge #7439: refactor: add bounded vector deserialization (Pasta) 89bdf7c Merge #7414: fix(net): throttle per-object governance vote sync requests (Pasta) 44c396d Merge #7402: fix: bound pending recovered sig queue to prevent remote OOM (Pasta) 05cfe27 Merge #7351: fix: limit signing share sessions per peer (pasta) 3ef3a5b Merge #7408: fix: bound DKG contribution blob intake (pasta) 0ea6532 Merge #7387: test: migrate governance inv cache coverage to unit tests (Pasta) 8ffdf7f Merge #7398: backport: compact block relay hardening (bitcoin#26898, bitcoin#27626, bitcoin#27743, bitcoin#26969, bitcoin#29412, bitcoin#32646, bitcoin#33296) (Pasta) 2915142 backport: bitcoin#27608 - p2p: Avoid prematurely clearing download state for other peers (PastaClaw) 90b5473 Merge #7396: fix: run of circular-dependencies with python3.15 (Pasta) b003cdc Merge #7395: ci: update GitHub Actions pins for Node 24 (pasta) 97c3dd1 Merge #7394: fix: stabilize par help text in manpages (pasta) 8f8616b Merge #7372: backport: bitcoin#32693: depends: fix cmake compatibility error for freetype (pasta) 48f72be Merge #7360: fix: empty platformP2PPort deprecated field in protx listdiff results (pasta) a8cccff Merge #7298: fix(qt): keep PoSe score visible when hiding banned masternodes (pasta) Pull request description: Release PR for Dash Core v23.1.8, a patch release on top of v23.1.7. Fast-forwards from `v23.1.x` (currently at `chore: prepare v23.1.7 release`), 29 commits, no merge commits, no conflicts. ## Contents Backports of PRs already reviewed and merged on `develop`: `#7259` `#7347` `#7348` `#7351` `#7298` `#7360` `#7372` `#7387` `#7394` `#7395` `#7396` `#7398` `#7402` `#7408` `#7414` `#7415` `#7416` `#7418` `#7419` `#7424` `#7438` `#7439` `#7440` `#7442` `#7444` `#7450` `#7465` Plus `backport: bitcoin#27608`, a single commit taken from Dash #7237 because #7398's compact-block hardening depends on it. The rest of that v0.26 batch is intentionally not included on v23.1.x. The commit is byte-identical to its reviewed counterpart inside #7237. And release preparation: version bump, regenerated man pages, release notes, archived 23.1.7 notes. ## Note for reviewers: this branch was rebuilt An earlier revision of this PR was discarded and the branch rebuilt from scratch. Review comments on the previous revision point at commits that no longer exist, though the feedback itself was carried over (see below). The reason: several commits titled `Merge #NNNN` in the earlier revision contained substantial code that exists nowhere upstream — apparently written from a description of each PR rather than ported from its diff. For example, `feature_llmq_simplepose.py` is byte-identical between v23.1.7 and `develop`, yet the earlier `Merge #7408` rewrote 66 lines of it; `test/functional/p2p_governance_invs.py` does not exist on `develop` at all, yet had grown from 62 to 148 lines. That mislabeling matters because a commit titled `Merge #NNNN` invites less scrutiny, not more. It also had consequences: the earlier revision was **missing #7440 entirely**, and contained eleven consecutive commits that did not compile (code written against newer upstream APIs this branch does not have — `Misbehaving(Peer&)`, and `PeerIsBanned` used five commits before it was declared). Every commit on this branch has now been diffed against its upstream merge commit. Where a backport differs, it is because v23.1.x predates an upstream refactor and the change had to be applied to the pre-refactor file — for example #7418 and #7438 patch `signing_shares.cpp` / `spork.cpp` where upstream patches `net_signing.cpp` / `net_processing.cpp`. ## Dropped from this branch - **#7350** (`net: don't lock cs_main while reading blocks`) — dropped on review feedback. It is a 110-line lock-structure refactor of `ProcessGetBlockData` with no measured benefit, and it would add avoidable churn to the eventual master→develop merge-back. Nothing on this branch depends on it: #7398's compact-block work precedes it, and the remaining 14 commits replay with zero conflicts once it is removed. Thanks @knst. ## Added after the initial review pass - **#7351** (`fix: limit signing share sessions per peer`) — cherry-picked as a single commit and placed before #7402, matching upstream's merge order. The include block additionally carries `<ranges>`: upstream's diff adds only `<algorithm>` because develop already had it, whereas v23.1.x did not and the backported `GetSessionCount()` / `GetAnnouncementSessionCount()` use `std::ranges::count_if`. - **#7465** (`fix(qt): handle pixel-sized fonts when scaling widgets`) — cherry-picked from the five upstream commits. `optiontests.cpp` additionally includes `qt/guiutil_font.h`, because `fontsLoaded()` and `updateFonts()` are declared there on v23.1.x while develop declares them in `qt/guiutil.h`, which is all the upstream test includes. Two further backports were added later and applied without any adaptation -- their diffs are byte-for-byte identical to upstream: - **#7347** (`fix: punish invalid dstx messages`) - **#7348** (`fix: penalize oversized notfound messages`) ## Adaptations worth flagging - **#7360** — upstream gates `platformP2PPort` / `platformHTTPPort` in `protx listdiff` behind `IsServiceDeprecatedRPCEnabled()`. On 23.x those deprecated fields are deliberately not enforced through gating (see `bbcd9d543e6`), so shipping the gate as-is would silently drop two fields that v23.1.7 always returned. Changed to `if (true)` with a comment, per review feedback, keeping the block aligned with `develop`. The substantive fix from #7360 — reading the live port from `netInfo` instead of the always-zero scalar — is retained. - **#7415** — the pending-map caps (`MAX_PENDING_SIG_SHARES_PER_NODE`, `MAX_PENDING_SIG_SHARES_TOTAL`) are backported. The additional bound upstream places on batches awaiting verification is not, because it guards a condition that does not exist here: upstream's dispatcher pushes one task per batch inside an inner loop, whereas v23.1.x pushes a single looping worker per 10 ms tick. There is no unbounded task queue to bound. - **Man pages** — regenerated without the `lock` debug category, which only exists under `DEBUG_LOCKCONTENTION` and so is absent from release binaries. Thanks @UdjinM6 for catching this. ## Known CI failure macOS jobs are expected to fail. `actions/upload-artifact@v6` rejects filenames containing `:`, and the Xcode SDK ships Perl man pages with `::` in the name. A release-branch-only workaround existed on the earlier revision but was dropped as it corresponds to no upstream PR. This is accepted for this release. ## Testing - Every commit through #7465 compiles individually (verified for 27 of the 29; the three additions below were verified at the tip) — verified individually, not just at the tip. - Full build clean; no new warnings. - Unit tests pass. - Functional tests pass: `feature_llmq_signing` (both variants), `feature_llmq_chainlocks`, `feature_llmq_dkgerrors`, `feature_llmq_is_cl_conflicts`, `p2p_instantsend`, `feature_dip3_deterministicmns` (both wallet types), `rpc_coinjoin`. - Qt unit tests pass (32 cases, run under the `cocoa` platform plugin so the pixel-sized font regression from #7465 actually executes rather than self-skipping). - Lint: one pre-existing `lint-cppcheck-dash` failure, identical on v23.1.7, in files this branch does not touch. Top commit has no ACKs. Tree-SHA512: 0fa469c9a33820aa85fbb8b90c5877409d09490f746f1300b05ceda470a600765f900bec42e5aad5d90a2d46b44e28c20e44dc4a8fe719553a072298069eaec4
backport: Merge bitcoin#26326
Upstream backport
This PR backports bitcoin#26326:
net: reduce LOCK(cs_main) scope in GETBLOCKTXN)net: reduce LOCK(cs_main) scope in ProcessGetBlockData)Issue being fixed or feature implemented
Block-serving paths in
net_processingwere doing disk reads while holdingcs_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?
cs_main.cs_mainbefore reading the block from disk.GETBLOCKTXNinvariant that recent blocks cannot be pruned before the post-lock disk read.ProcessGetBlockDatabehavior: 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.CanDirectFetch()and the current tip while holdingcs_mainand 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 correspondingMSG_WITNESS_BLOCKpath here, so this backport adapts the shared full, filtered, and compact block-serving path.Backport prerequisite notes
intentional_exclusion: bitcoin/bitcoin#27125— upstream net: don't lock cs_main while reading blocks in net processing bitcoin/bitcoin#26326's changed lines use theBlockManager::ReadBlockFromDisk(..., FlatFilePos)API introduced by refactor, kernel: Decouple ArgsManager from blockstorage bitcoin/bitcoin#27125. Dash does not have that broader blockstorage refactor, but it already has the equivalent localnode::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 refactor, kernel: Decouple ArgsManager from blockstorage bitcoin/bitcoin#27125 as a prerequisite.How Has This Been Tested?
Tested on macOS arm64.
git diff --check upstream/develop...HEADtest/lint/lint-whitespace.py./autogen.sh./configure --without-gui --disable-bench --disable-fuzz-binarymake -j$(sysctl -n hw.ncpu) src/dashdBreaking Changes
None.
Checklist