Skip to content

net_processing: Avoid reading the block for `MSG_FILTERED_BLOCK` if no filter

Summary

The p2p message MSG_FILTERED_BLOCK is used to retrieve a partial "merkle block" when a txn bloom filter is defined for the peer. As per the spec, if there is no filter defined, nothing is to be returned to the peer. Reference: https://developer.bitcoin.org/reference/p2p_networking.html#merkleblock

So far so good, right?

However, the extant code was reading the whole block into memory regardless (deserializing it, etc), only to check if a filter is defined later on in the function and then doing nothing if that is the case. So reading the block in this case would be useless and waste cycles.

This nit just modifies the code to only really read the block into memory if it's clear we will need it to build the merkle block -- that is, if a filter is defined for the peer.

Implementation Notes

The change involves the following: We need to take the cs_filter lock, check if a filter is defined with the lock held, release the lock, load the block with no lock held, then re-acquire the cs_filter lock and check again if the filter is still defined. While this may seem awkward, this pattern is common in multi-threaded code (the double-check-after-reacquiring-a-lock pattern).

Test Plan

  • Review. There are no behavioral changes, this is a pure code quality/slight performance nit.
  • ninja check && test/functional/test_runner p2p_filter

Merge request reports