@@ -2545,6 +2545,31 @@ std::vector<CAddress> CConnman::GetAddresses(Network requestor_network, size_t m
2545
2545
if (m_addr_response_caches.find (requestor_network) == m_addr_response_caches.end () ||
2546
2546
m_addr_response_caches[requestor_network].m_update_addr_response < current_time) {
2547
2547
m_addr_response_caches[requestor_network].m_addrs_response_cache = GetAddresses (max_addresses, max_pct);
2548
+
2549
+ // Choosing a proper cache lifetime is a trade-off between the privacy leak minimization
2550
+ // and the usefulness of ADDR responses to honest users.
2551
+ //
2552
+ // Longer cache lifetime makes it more difficult for an attacker to scrape
2553
+ // enough AddrMan data to maliciously infer something useful.
2554
+ // By the time an attacker scraped enough AddrMan records, most of
2555
+ // the records should be old enough to not leak topology info by
2556
+ // e.g. analyzing real-time changes in timestamps.
2557
+ //
2558
+ // It takes only several hundred requests to scrape everything from an AddrMan containing 100,000 nodes,
2559
+ // so ~24 hours of cache lifetime indeed makes the data less inferable by the time
2560
+ // most of it could be scraped (considering that timestamps are updated via
2561
+ // ADDR self-announcements and when nodes communicate).
2562
+ // We also should be robust to those attacks which may not require scraping *full* victim's AddrMan
2563
+ // (because even several timestamps of the same handful of nodes may leak privacy).
2564
+ //
2565
+ // On the other hand, longer cache lifetime makes ADDR responses
2566
+ // outdated and less useful for an honest requestor, e.g. if most nodes
2567
+ // in the ADDR response are no longer active.
2568
+ //
2569
+ // However, the churn in the network is known to be rather low. Since we consider
2570
+ // nodes to be "terrible" (see IsTerrible()) if the timestamps are older than 30 days,
2571
+ // max. 24 hours of "penalty" due to cache shouldn't make any meaningful difference
2572
+ // in terms of the freshness of the response.
2548
2573
m_addr_response_caches[requestor_network].m_update_addr_response = current_time + std::chrono::hours (21 ) + GetRandMillis (std::chrono::hours (6 ));
2549
2574
}
2550
2575
return m_addr_response_caches[requestor_network].m_addrs_response_cache ;
0 commit comments