|
7 | 7 |
|
8 | 8 | #include <net.h> |
9 | 9 |
|
| 10 | +#include <net_ibd_peer.h> |
| 11 | + |
10 | 12 | #include <addrdb.h> |
11 | 13 | #include <addrman.h> |
12 | 14 | #include <banman.h> |
|
37 | 39 | #include <util/translation.h> |
38 | 40 | #include <util/vector.h> |
39 | 41 |
|
| 42 | +// Forward declarations for IBD peer selection |
| 43 | +std::chrono::seconds GetNextIBDEpoch(); |
| 44 | +void EvaluateIBDPeers(CConnman& connman); |
| 45 | + |
40 | 46 | #include <algorithm> |
41 | 47 | #include <array> |
42 | 48 | #include <cmath> |
@@ -2560,6 +2566,8 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, std |
2560 | 2566 | auto next_feeler = start + rng.rand_exp_duration(FEELER_INTERVAL); |
2561 | 2567 | auto next_extra_block_relay = start + rng.rand_exp_duration(EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL); |
2562 | 2568 | auto next_extra_network_peer{start + rng.rand_exp_duration(EXTRA_NETWORK_PEER_INTERVAL)}; |
| 2569 | + // Next IBD peer evaluation timestamp |
| 2570 | + auto next_ibd_peer_eval = start + GetNextIBDEpoch(); |
2563 | 2571 | const bool dnsseed = gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED); |
2564 | 2572 | bool add_fixed_seeds = gArgs.GetBoolArg("-fixedseeds", DEFAULT_FIXEDSEEDS); |
2565 | 2573 | const bool use_seednodes{!gArgs.GetArgs("-seednode").empty()}; |
@@ -2593,6 +2601,13 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, std |
2593 | 2601 |
|
2594 | 2602 | PerformReconnections(); |
2595 | 2603 |
|
| 2604 | + // Evaluate IBD peers periodically to find better connections |
| 2605 | + auto now_ibd = GetTime<std::chrono::microseconds>(); |
| 2606 | + if (now_ibd > next_ibd_peer_eval) { |
| 2607 | + EvaluateIBDPeers(*this); |
| 2608 | + next_ibd_peer_eval = now_ibd + GetNextIBDEpoch(); |
| 2609 | + } |
| 2610 | + |
2596 | 2611 | CountingSemaphoreGrant<> grant(*semOutbound); |
2597 | 2612 | if (m_interrupt_net->interrupted()) { |
2598 | 2613 | return; |
@@ -4222,3 +4237,65 @@ std::function<void(const CAddress& addr, |
4222 | 4237 | std::span<const unsigned char> data, |
4223 | 4238 | bool is_incoming)> |
4224 | 4239 | CaptureMessage = CaptureMessageToFile; |
| 4240 | + |
| 4241 | +// IBD Peer Selection Implementation |
| 4242 | +// |
| 4243 | +// During Initial Block Download, we want to connect to the best possible peers |
| 4244 | +// (low latency, high bandwidth) to speed up sync. This function is called |
| 4245 | +// periodically to evaluate our peers and potentially swap to better ones. |
| 4246 | + |
| 4247 | +std::chrono::seconds GetNextIBDEpoch() |
| 4248 | +{ |
| 4249 | + // Configurable epoch length |
| 4250 | + static const auto epoch_length = std::chrono::seconds{gArgs.GetArg("-ibd-peer-epoch", DEFAULT_IBD_PEER_EPOCH_LENGTH.count())}; |
| 4251 | + return epoch_length; |
| 4252 | +} |
| 4253 | + |
| 4254 | +void EvaluateIBDPeers(CConnman& connman) |
| 4255 | +{ |
| 4256 | + // Only run if IBD check callback is available |
| 4257 | + if (!connman.IsInIBD()) return; |
| 4258 | + |
| 4259 | + // Get all full outbound relay peers |
| 4260 | + std::vector<CNode*> outbound_peers; |
| 4261 | + connman.ForEachNode([&outbound_peers](CNode* node) { |
| 4262 | + if (node->IsFullOutboundConn() && node->fSuccessfullyConnected) { |
| 4263 | + outbound_peers.push_back(node); |
| 4264 | + } |
| 4265 | + }); |
| 4266 | + |
| 4267 | + // Need minimum peers to consider swapping |
| 4268 | + if (outbound_peers.size() < IBD_PEER_MIN_PEERS) { |
| 4269 | + return; |
| 4270 | + } |
| 4271 | + |
| 4272 | + // Calculate scores for all peers |
| 4273 | + std::vector<IBDPeerScore> scores; |
| 4274 | + for (const CNode* node : outbound_peers) { |
| 4275 | + auto score = CalculateIBDScore(node); |
| 4276 | + if (score) { |
| 4277 | + scores.push_back(*score); |
| 4278 | + } |
| 4279 | + } |
| 4280 | + |
| 4281 | + if (scores.empty()) return; |
| 4282 | + |
| 4283 | + // Sort by score (highest first) |
| 4284 | + std::sort(scores.begin(), scores.end(), [](const IBDPeerScore& a, const IBDPeerScore& b) { |
| 4285 | + return a.CalculateScore() > b.CalculateScore(); |
| 4286 | + }); |
| 4287 | + |
| 4288 | + // Log scores for debugging |
| 4289 | + for (const auto& score : scores) { |
| 4290 | + LogIBDPeerScore(score); |
| 4291 | + } |
| 4292 | + |
| 4293 | + // If the lowest scoring peer is below threshold, try to find a better one |
| 4294 | + const auto& lowest = scores.back(); |
| 4295 | + if (lowest.CalculateScore() < IBD_PEER_SCORE_THRESHOLD) { |
| 4296 | + // Mark this peer for potential eviction |
| 4297 | + // We'll request a new outbound connection attempt |
| 4298 | + connman.SetTryNewOutboundPeer(true); |
| 4299 | + LogDebug(BCLog::NET, "IBD: Low scoring peer detected, attempting to find better peer\n"); |
| 4300 | + } |
| 4301 | +} |
0 commit comments