3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-01-30 23:02:15 +00:00

Treat client protocol versions higher than the version we prefer equally so we don't zap peers that upgrade early when unimportant (for us) protocol changes roll out.

This commit is contained in:
Mike Hearn 2013-02-21 12:11:37 +01:00
parent 420a29a388
commit 002539f2b8
2 changed files with 11 additions and 5 deletions

View File

@ -1224,7 +1224,7 @@ public class PeerGroup extends AbstractIdleService {
protected Peer selectDownloadPeer(List<Peer> origPeers) { protected Peer selectDownloadPeer(List<Peer> origPeers) {
// Characteristics to select for in order of importance: // Characteristics to select for in order of importance:
// - Chain height is reasonable (majority of nodes) // - Chain height is reasonable (majority of nodes)
// - Highest protocol version (more likely to be maintained, have the features we want) // - High enough protocol version for the features we want (but we'll settle for less)
// - Ping time. // - Ping time.
List<Peer> peers; List<Peer> peers;
synchronized (origPeers) { synchronized (origPeers) {
@ -1238,15 +1238,19 @@ public class PeerGroup extends AbstractIdleService {
for (Peer peer : peers) { for (Peer peer : peers) {
if (peer.getBestHeight() == mostCommonChainHeight) candidates.add(peer); if (peer.getBestHeight() == mostCommonChainHeight) candidates.add(peer);
} }
// Of the candidates, find the highest protocol version. Snapshot their ping times (so they don't change // Of the candidates, find the peers that meet the minimum protocol version we want to target. We could select
// whilst sorting) and then sort to find the lowest. // the highest version we've seen on the assumption that newer versions are always better but we don't want to
int highestVersion = 0; // zap peers if they upgrade early. If we can't find any peers that have our preferred protocol version or
// better then we'll settle for the highest we found instead.
int highestVersion = 0, preferredVersion = 0;
final int PREFERRED_VERSION = FilteredBlock.MIN_PROTOCOL_VERSION;
for (Peer peer : candidates) { for (Peer peer : candidates) {
highestVersion = Math.max(peer.getPeerVersionMessage().clientVersion, highestVersion); highestVersion = Math.max(peer.getPeerVersionMessage().clientVersion, highestVersion);
preferredVersion = Math.min(highestVersion, PREFERRED_VERSION);
} }
List<PeerAndPing> candidates2 = new ArrayList<PeerAndPing>(); List<PeerAndPing> candidates2 = new ArrayList<PeerAndPing>();
for (Peer peer : candidates) { for (Peer peer : candidates) {
if (peer.getPeerVersionMessage().clientVersion == highestVersion) { if (peer.getPeerVersionMessage().clientVersion >= preferredVersion) {
PeerAndPing pap = new PeerAndPing(); PeerAndPing pap = new PeerAndPing();
pap.peer = peer; pap.peer = peer;
pap.pingTime = peer.getPingTime(); pap.pingTime = peer.getPingTime();

View File

@ -375,7 +375,9 @@ public class PeerGroupTest extends TestWithPeerGroup {
public void downloadPeerSelection() throws Exception { public void downloadPeerSelection() throws Exception {
peerGroup.startAndWait(); peerGroup.startAndWait();
VersionMessage versionMessage2 = new VersionMessage(params, 2); VersionMessage versionMessage2 = new VersionMessage(params, 2);
versionMessage2.clientVersion = 60000;
VersionMessage versionMessage3 = new VersionMessage(params, 3); VersionMessage versionMessage3 = new VersionMessage(params, 3);
versionMessage3.clientVersion = 60000;
assertNull(peerGroup.getDownloadPeer()); assertNull(peerGroup.getDownloadPeer());
Peer a = PeerGroup.peerFromChannel(connectPeer(1, versionMessage2)); Peer a = PeerGroup.peerFromChannel(connectPeer(1, versionMessage2));
assertEquals(2, peerGroup.getMostCommonChainHeight()); assertEquals(2, peerGroup.getMostCommonChainHeight());