When selecting peers to relay an address to, only pick addrv2-capable ones if the address cannot be represented in addr(v1).
Without this I expect that propagation of torv3 addresses over the cleartext network will be very hard for a while.
When selecting peers to relay an address to, only pick addrv2-capable ones if the address cannot be represented in addr(v1).
Without this I expect that propagation of torv3 addresses over the cleartext network will be very hard for a while.
Assuming backport to 0.21.1
Concept ACK
1442 | @@ -1443,8 +1443,8 @@ static void RelayAddress(const CNode& originator, 1443 | std::array<std::pair<uint64_t, CNode*>,2> best{{{0, nullptr}, {0, nullptr}}}; 1444 | assert(nRelayNodes <= best.size()); 1445 | 1446 | - auto sortfunc = [&best, &hasher, nRelayNodes, &originator](CNode* pnode) { 1447 | - if (pnode->RelayAddrsWithConn() && pnode != &originator) { 1448 | + auto sortfunc = [&best, &hasher, nRelayNodes, &originator, &addr](CNode* pnode) { 1449 | + if (pnode->RelayAddrsWithConn() && pnode != &originator && (addr.IsAddrV1Compatible() || pnode->m_wants_addrv2)) {
Does it make sense to add a new method CNode::SupportsAddress(const CAddress&) and do here: pnode->SupportsAddress(addr) and in CNode::PushAddress() instead of the variable addr_format_supported?
That makes sense, but if m_wants_addrv2 is going to move to net_processing's data structures (where it IMO belongs) it's perhaps wasteful to push more into net now?
EDIT: oh, i see, that logic already exists in net. Yeah, fixing.
Done.
ACK 0048b841a2c4b854607a6de8c02a808152510457
Excellent!
I got a bit confused by the description, getting the impression that we would try to relay torv3 addresses to non-addrv2 peers and I said to myself "huh, but we already avoid that in PushAddress() with m_wants_addrv2 || _addr.IsAddrV1Compatible()!?".
1185 | {
1186 | // Whether the peer supports the address in `_addr`. For example,
1187 | // nodes that do not implement BIP155 cannot receive Tor v3 addresses
1188 | // because they require ADDRv2 (BIP155) encoding.
1189 | - const bool addr_format_supported = m_wants_addrv2 || _addr.IsAddrV1Compatible();
1190 | + const bool addr_format_supported = IsAddrCompatible(_addr);
perhaps hoist the documentation too (rewritten slightly here)
+ /**
+ * Whether the peer supports the address. For example, a peer that does not
+ * implement BIP155 cannot receive Tor v3 addresses because it requires
+ * ADDRv2 (BIP155) encoding.
+ */
bool IsAddrCompatible(const CAddress& addr) const
{
return m_wants_addrv2 || addr.IsAddrV1Compatible();
@@ -1183,9 +1188,6 @@ public:
void PushAddress(const CAddress& _addr, FastRandomContext &insecure_rand)
{
- // Whether the peer supports the address in `_addr`. For example,
- // nodes that do not implement BIP155 cannot receive Tor v3 addresses
- // because they require ADDRv2 (BIP155) encoding.
const bool addr_format_supported = IsAddrCompatible(_addr);
Good idea, done.
This seems like a good idea.
Initial code review ACK a29892429388a10e1cab9a69c3013a537410a20d
Building and testing.
ACK 794ae71701f3766a86fd61044368d36004d5687f
1190 | {
1191 | - // Whether the peer supports the address in `_addr`. For example,
1192 | - // nodes that do not implement BIP155 cannot receive Tor v3 addresses
1193 | - // because they require ADDRv2 (BIP155) encoding.
1194 | - const bool addr_format_supported = m_wants_addrv2 || _addr.IsAddrV1Compatible();
1195 | + const bool addr_format_supported = IsAddrCompatible(_addr);
nit: I think the variable name is as readable as the function call and it is used in just one place, so it may as well be ditched:
-if (_addr.IsValid() && !m_addr_known->contains(_addr.GetKey()) && addr_format_supported) {
+if (_addr.IsValid() && !m_addr_known->contains(_addr.GetKey()) && IsAddrCompatible(_addr)) {
Done.
ACK 794ae71701f3766a86fd61044368d36004d5687f
ACK 37fe80e6267094f6051ccf9bec0c7f1a6b9e15da
ACK 37fe80e6267094f6051ccf9bec0c7f1a6b9e15da