ThreadOpenConnections skips candidate addresses that fail HasAllDesirableServiceFlags before attempting a connection (net.cpp, in the addrman try loop). That filter has no functional test coverage today, and cannot have any: addpeeraddress hardcodes NODE_NETWORK | NODE_WITNESS, so every address a test can place into addrman already carries the desirable flags. There is no way to put an address there that the filter should skip.
peerman_tests covers GetDesirableServiceFlags itself, but not the selection path that consumes it.
Two commits:
test: allow addpeeraddress to set service flagsadds an optionalservicesargument, defaulting to the value that is currently hardcoded, so existing callers are unaffected. Covered inrpc_net.py: default flags are recorded, explicit flags round-trip throughgetrawaddrman, and an address lacking desirable flags can be placed.test: cover outbound service flag filtering in ThreadOpenConnectionsuses it. Two otherwise identical nodes differ only in the service flags of the addresses in their addrman. The node holding only addresses without desirable flags makes no connection attempt; the node holding usable ones does. Both run with an unreachable proxy, so no attempt can succeed — what is observed is whether one is made at all.
The new test sets disable_autoconnect = False, since the behaviour under test is the node's own addrman-driven outbound connection logic.
Tested on macOS/arm64. p2p_outbound_service_flags.py passes on three consecutive runs; rpc_net.py (both transports), p2p_dns_seeds.py, p2p_seednode.py, p2p_addr_relay.py and feature_asmap.py also pass.