MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / RelayAddress

Method RelayAddress

src/net_processing.cpp:2307–2354  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2305}
2306
2307void 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
2356void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv& inv)
2357{

Callers

nothing calls this directly

Calls 10

CServiceHashClass · 0.85
count_secondsFunction · 0.85
IsAddrCompatibleFunction · 0.85
CSipHasherClass · 0.85
WriteMethod · 0.45
FinalizeMethod · 0.45
sizeMethod · 0.45
beginMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected