From ea3fca970c850cecd311c6d7336b52e2f19acb52 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 25 Dec 2012 00:28:49 +0000 Subject: [PATCH] Incorporate protocol version into download peer selection logic. --- .../java/com/google/bitcoin/core/PeerGroup.java | 15 +++++++++++++-- .../com/google/bitcoin/core/PeerGroupTest.java | 8 +++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/google/bitcoin/core/PeerGroup.java b/core/src/main/java/com/google/bitcoin/core/PeerGroup.java index b4a471c5..ec9e11b6 100644 --- a/core/src/main/java/com/google/bitcoin/core/PeerGroup.java +++ b/core/src/main/java/com/google/bitcoin/core/PeerGroup.java @@ -1110,10 +1110,21 @@ public class PeerGroup extends AbstractIdleService { return null; // Make sure we don't select a peer that is behind/synchronizing itself. int mostCommonChainHeight = getMostCommonChainHeight(); + List candidates = new ArrayList(); for (Peer peer : peers) { - if (peer.getBestHeight() == mostCommonChainHeight) return peer; + if (peer.getBestHeight() == mostCommonChainHeight) candidates.add(peer); } - throw new IllegalStateException("Unreachable"); + // Of the candidates, find the highest protocol version. + int highestVersion = 0; + Peer leadingCandidate = null; + for (Peer peer : candidates) { + int v = peer.getPeerVersionMessage().clientVersion; + if (v > highestVersion) { + highestVersion = v; + leadingCandidate = peer; + } + } + return leadingCandidate; } private static class PeerGroupThreadFactory implements ThreadFactory { diff --git a/core/src/test/java/com/google/bitcoin/core/PeerGroupTest.java b/core/src/test/java/com/google/bitcoin/core/PeerGroupTest.java index 0d171c1c..342af25f 100644 --- a/core/src/test/java/com/google/bitcoin/core/PeerGroupTest.java +++ b/core/src/test/java/com/google/bitcoin/core/PeerGroupTest.java @@ -419,8 +419,14 @@ public class PeerGroupTest extends TestWithNetworkConnections { Peer c = PeerGroup.peerFromChannel(connectPeer(3, versionMessage3)); assertEquals(2, peerGroup.getMostCommonChainHeight()); assertEquals(a, peerGroup.getDownloadPeer()); // No change yet. - Peer d = PeerGroup.peerFromChannel(connectPeer(4, versionMessage3)); + PeerGroup.peerFromChannel(connectPeer(4, versionMessage3)); assertEquals(3, peerGroup.getMostCommonChainHeight()); assertEquals(c, peerGroup.getDownloadPeer()); // Switch to first peer advertising new height. + + // New peer with a higher protocol version but same chain height. + VersionMessage versionMessage4 = new VersionMessage(params, 3); + versionMessage4.clientVersion = 100000; + Peer d = PeerGroup.peerFromChannel(connectPeer(5, versionMessage4)); + assertEquals(d, peerGroup.getDownloadPeer()); } }