| 2305 | } |
| 2306 | |
| 2307 | void PeerManagerImpl::RelayAddress(NodeId originator, |
| 2308 | const CAddress& addr, |
| 2309 | bool fReachable) |
| 2310 | { |
| 2311 | // We choose the same nodes within a given 24h window (if the list of connected |
| 2312 | // nodes does not change) and we don't relay to nodes that already know an |
| 2313 | // address. So within 24h we will likely relay a given address once. This is to |
| 2314 | // prevent a peer from unjustly giving their address better propagation by sending |
| 2315 | // it to us repeatedly. |
| 2316 | |
| 2317 | if (!fReachable && !addr.IsRelayable()) return; |
| 2318 | |
| 2319 | // Relay to a limited number of other nodes |
| 2320 | // Use deterministic randomness to send to the same nodes for 24 hours |
| 2321 | // at a time so the m_addr_knowns of the chosen nodes prevent repeats |
| 2322 | const uint64_t hash_addr{CServiceHash(0, 0)(addr)}; |
| 2323 | const auto current_time{GetTime<std::chrono::seconds>()}; |
| 2324 | // Adding address hash makes exact rotation time different per address, while preserving periodicity. |
| 2325 | const uint64_t time_addr{(static_cast<uint64_t>(count_seconds(current_time)) + hash_addr) / count_seconds(ROTATE_ADDR_RELAY_DEST_INTERVAL)}; |
| 2326 | const CSipHasher hasher{m_connman.GetDeterministicRandomizer(RANDOMIZER_ID_ADDRESS_RELAY) |
| 2327 | .Write(hash_addr) |
| 2328 | .Write(time_addr)}; |
| 2329 | |
| 2330 | // Relay reachable addresses to 2 peers. Unreachable addresses are relayed randomly to 1 or 2 peers. |
| 2331 | unsigned int nRelayNodes = (fReachable || (hasher.Finalize() & 1)) ? 2 : 1; |
| 2332 | |
| 2333 | std::array<std::pair<uint64_t, Peer*>, 2> best{{{0, nullptr}, {0, nullptr}}}; |
| 2334 | assert(nRelayNodes <= best.size()); |
| 2335 | |
| 2336 | LOCK(m_peer_mutex); |
| 2337 | |
| 2338 | for (auto& [id, peer] : m_peer_map) { |
| 2339 | if (peer->m_addr_relay_enabled && id != originator && IsAddrCompatible(*peer, addr)) { |
| 2340 | uint64_t hashKey = CSipHasher(hasher).Write(id).Finalize(); |
| 2341 | for (unsigned int i = 0; i < nRelayNodes; i++) { |
| 2342 | if (hashKey > best[i].first) { |
| 2343 | std::copy(best.begin() + i, best.begin() + nRelayNodes - 1, best.begin() + i + 1); |
| 2344 | best[i] = std::make_pair(hashKey, peer.get()); |
| 2345 | break; |
| 2346 | } |
| 2347 | } |
| 2348 | } |
| 2349 | }; |
| 2350 | |
| 2351 | for (unsigned int i = 0; i < nRelayNodes && best[i].first != 0; i++) { |
| 2352 | PushAddress(*best[i].second, addr); |
| 2353 | } |
| 2354 | } |
| 2355 | |
| 2356 | void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv& inv) |
| 2357 | { |
nothing calls this directly
no test coverage detected