Problem: Serving blocks to legacy nodes currently decodes and reserializes them just to remove witnesses. MSG_WITNESS_BLOCK already avoids this work by serving the stored bytes directly. Faster witnessless IBD, as proposed in #36476, also needs peers to serve these blocks efficiently.
Fix: Read disk-backed, non-Signet MSG_BLOCK replies into an owned byte buffer, check the header's proof of work and expected hash, and strip witness ranges from that buffer in place.
Extract a shared helper so decoding transactions and skipping their bytes follow the same encoding rules. Signet keeps ReadBlock for its solution check. Header checks now precede transaction parsing, so records corrupted in both places can log a different error.
Performance:
Time to read a block from disk and build its non-witness message:
| Block | Before | After | Speedup |
|---|---|---|---|
block413567 |
1.31 ms | 0.147 ms | 8.9x |
| Same block with synthetic witnesses | 3.47 ms | 0.374 ms | 9.3x |
The synthetic fixture adds a 512-byte witness item and an empty item to every input.
Related work: This extends the raw witness-block serving added in #13151. The #13011 discussion and the closed #13098 identify unnecessary transaction hashing when serving historical blocks. The implementation also builds on the bulk block reads introduced in #31551.