The shared P2P message thread currently waits for block processing to finish before it can process messages from other peers.
This PR moves block processing to a dedicated worker after the initial checks, following the approach of #18963 and #16324:
- Initial checks still run on the P2P message thread and decide whether a block should enter the processing queue.
- A single worker processes queued blocks one at a time, in the order they are added to the queue.
- Each peer can have only one block queued or being processed at a time. The node handles the processing result and any required peer penalties before processing that peer’s next incoming message.
- Tracking block requests and reconstructing blocks from compact-block transaction responses no longer require
cs_main, the chain lock. - When
cs_mainis busy,SendMessages()defers work such as requesting headers, blocks or transactions and announcing new blocks or transactions. This allows the P2P message thread to move on to other peers.
A controlled 10,000-block IBD benchmark showed these response-time improvements, measured as the median of four per-run medians:
| Probe | Download connections | Baseline → This branch | Reduction |
|---|---|---|---|
| PING/PONG | 1 | 41.8 → 0.77 ms | 98% |
| Block serving | 1 | 39.0 → 26.5 ms | 32% |
| Block serving | 4 | 107.0 → 58.5 ms | 45% |
With four download connections, the median time to download and validate the 10,000 tested blocks during IBD fell by approximately 5%, from 473.6 s to 450.3 s.
The comparison used matching Clang 18 Release builds of baseline 4519933391dd and this branch, mainnet blocks 910,489 - 920,488, one local source node, and -assumevalid=0 -blocksonly=1. Each setup ran four times per build. PINGs ran at 10/s; the block probe requested the same previously validated block after warmup, at most once per second, timing receipt of the full block.
These results apply to this controlled IBD workload; they do not establish gains for other services, hardware, or network conditions. Performance outside IBD was not measured.
Tests and test infrastructure account for approximately 67% of the diff. Production code and build integration account for 1,132 changed lines (883 additions and 249 deletions).
I’m opening this PR as a draft primarily to gather feedback on the overall approach.