diff --git a/src/ripple/app/ledger/LedgerMaster.cpp b/src/ripple/app/ledger/LedgerMaster.cpp index 3bb24ae87..70d3c6616 100644 --- a/src/ripple/app/ledger/LedgerMaster.cpp +++ b/src/ripple/app/ledger/LedgerMaster.cpp @@ -596,16 +596,23 @@ public: return; } + // Select target Peer based on highest score. + // The score is randomized but biased in favor of Peers with low latency. Peer::ptr target; - int count = 0; - - Overlay::PeerSequence peerList = getApp().overlay ().getActivePeers (); - for (auto const& peer : peerList) { - if (peer->hasRange (missingIndex, missingIndex + 1)) + int maxScore = 0; + Overlay::PeerSequence peerList = getApp().overlay ().getActivePeers (); + for (auto const& peer : peerList) { - if ((count++ == 0) || ((rand() % count) == 0)) - target = peer; + if (peer->hasRange (missingIndex, missingIndex + 1)) + { + int score = peer->getScore (true); + if (! target || (score > maxScore)) + { + target = peer; + maxScore = score; + } + } } } diff --git a/src/ripple/overlay/Peer.h b/src/ripple/overlay/Peer.h index e97045a4a..d650f5f79 100644 --- a/src/ripple/overlay/Peer.h +++ b/src/ripple/overlay/Peer.h @@ -81,6 +81,10 @@ public: bool isHighLatency() const = 0; + virtual + int + getScore (bool) const = 0; + virtual RippleAddress const& getNodePublic() const = 0; diff --git a/src/ripple/overlay/impl/PeerImp.cpp b/src/ripple/overlay/impl/PeerImp.cpp index dcb0a6cec..09050e85f 100644 --- a/src/ripple/overlay/impl/PeerImp.cpp +++ b/src/ripple/overlay/impl/PeerImp.cpp @@ -2171,7 +2171,7 @@ PeerImp::peerTXData (Job&, uint256 const& hash, } int -PeerImp::getScore (bool haveItem) +PeerImp::getScore (bool haveItem) const { // Random component of score, used to break ties and avoid // overloading the "best" peer diff --git a/src/ripple/overlay/impl/PeerImp.h b/src/ripple/overlay/impl/PeerImp.h index 618e3b426..85ca2040f 100644 --- a/src/ripple/overlay/impl/PeerImp.h +++ b/src/ripple/overlay/impl/PeerImp.h @@ -305,7 +305,7 @@ public: // Called to determine our priority for querying int - getScore (bool haveItem); + getScore (bool haveItem) const override; bool isHighLatency() const override;