According to [BIP37](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki#Extensions_to_existing_messages), `getdata` commands with a request for filtered blocks via type `MSG_FILTERED_BLOCK` in the `inv` submessage are only responded to if a filter is set:

> The getdata command is extended to allow a new type in the inv submessage. The type field can now be MSG_FILTERED_BLOCK (== 3) rather than MSG_BLOCK. **If no filter has been set on the connection, a request for filtered blocks is ignored.** If a filter has been set, a merkleblock message is returned for the requested block hash.

**Expected behavior**

When no BIP37 filter is set and a we request a filtered block, there should be no response from the node.

**Actual behavior**

When no BIP37 filter is set and a we request a filtered block, we get a `merkleblock` message in reply.

**To reproduce**

The behaviour can reproduced by adding the following lines to the functional test `p2p_filter.py` (introduced recently with PR https://github.com/bitcoin/bitcoin/pull/18334, commit https://github.com/bitcoin/bitcoin/pull/18334/commits/fa156999695ddaeb016d8320bee62f8d96679d55), that has already a callback implemented which requests filtered blocks as reply to `inv` messages:
```
    # add this lines after filtered P2P connection is added to the node, but before filter is set
    filter_node.merkleblock_received = False
    self.nodes[0].generatetoaddress(1, self.node[0].getnewaddress())[0]
    filter_node.sync_with_ping()
    assert not filter_node.merkleblock_received
```
The assertion fails, meaning that a merkleblock was indeed received.

**Possible solution**
Looking at the code in `net_processing.cpp`/`net.h`, it is quite obvious why this happens: the condition to answer to a filtered block request is just whether the (unique) pointer `pfrom->m_tx_relay->pfilter` is set, and this condition is always true. Initially the pointer is set in the constructor of the `struct TxRelay`, pointing to a default-constructed instance of `CBloomFilter`:
https://github.com/bitcoin/bitcoin/blob/d52ba21dfff99173abb927bc964ce7ceb711d789/src/net.h#L812
And after receiving a `filterclear` message it is also reset to an empty instance again:
https://github.com/bitcoin/bitcoin/blob/d52ba21dfff99173abb927bc964ce7ceb711d789/src/net_processing.cpp#L3201
In the following code, the boolean variable `sendMerkleBlock` will thus _always_ be set to true:
https://github.com/bitcoin/bitcoin/blob/d52ba21dfff99173abb927bc964ce7ceb711d789/src/net_processing.cpp#L1500-L1508

A simple solution would be to just set `pfilter` to `nullptr` initially and after receiving a `filterclear` message. The question is if its worth the change, as the described behaviour is IMHO not harmful at all (it just doesn't fit the description in the BIP37 document, which could be adapted?) and connection bloom filters are deprecated anway and [not recommended to be used due to privacy concerns](https://en.bitcoin.it/wiki/BIP37_privacy_problems). It is noteworthy though that possibly other parts in `net_processing.cpp` assume the test on `pfilter` means "a bloom filter has been set", and the fact that this always evaluates to `true` could possibly lead to some unintended behaviour. For example, in the following code part, where a `NodeEvictionCandidate` is created, its member `fBloomFilter` will always be set to true:
https://github.com/bitcoin/bitcoin/blob/d52ba21dfff99173abb927bc964ce7ceb711d789/src/net.cpp#L864-L875
*   nNow + 2 seconds for inbound peers. This is the time at which we'll
     *   consider trying to request the transaction from the peer in
     *   SendMessages(). The delay for inbound peers is to allow outbound peers
     *   a chance to announce before we request from inbound peers, to prevent
     *   an adversary from using inbound connections to blind us to a
     *   transaction (InvBlock).
     *
     *   When we call SendMessages() for a given peer,
     *   we will loop over the transactions in m_tx_process_time, looking
     *   at the transactions whose process_time <= nNow. We'll request each
     *   such transaction that we don't have already and that hasn't been
     *   requested from another peer recently, up until we hit the
     *   MAX_PEER_TX_IN_FLIGHT limit for the peer. Then we'll update
     *   g_already_asked_for for each requested txid, storing the time of the
     *   GETDATA request. We use g_already_asked_for to coordinate transaction
     *   requests amongst our peers.
     *
     *   For transactions that we still need but we have already recently
     *   requested from some other peer, we'll reinsert (process_time, txid)
     *   back into the peer's m_tx_process_time at the point in the future at
     *   which the most recent GETDATA request would time out (ie
     *   GETDATA_TX_INTERVAL + the request time stored in g_already_asked_for).
     *   We add an additional delay for inbound peers, again to prefer
     *   attempting download from outbound peers first.
     *   We also add an extra small random delay up to 2 seconds
     *   to avoid biasing some peers over others. (e.g., due to fixed ordering
     *   of peer processing in ThreadMessageHandler).
     *
     *   When we receive a transaction from a peer, we remove the txid from the
     *   peer's m_tx_in_flight set and from their recently announced set