3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-15 19:55:51 +00:00

PeerGroup: simplify how the download peer is selected to avoid pointless thrashing at startup. This change will probably reduce load on the network as well.

This commit is contained in:
Mike Hearn 2015-02-16 17:45:48 +01:00
parent 7d98075efe
commit 887bc63ce2

View File

@ -17,44 +17,30 @@
package org.bitcoinj.core; package org.bitcoinj.core;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.*;
import com.google.common.base.*; import com.google.common.base.*;
import com.google.common.collect.ImmutableList; import com.google.common.collect.*;
import com.google.common.collect.ImmutableSet; import com.google.common.net.*;
import com.google.common.collect.Lists; import com.google.common.primitives.*;
import com.google.common.collect.Maps;
import com.google.common.net.InetAddresses;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.common.util.concurrent.*; import com.google.common.util.concurrent.*;
import com.subgraph.orchid.TorClient; import com.subgraph.orchid.*;
import net.jcip.annotations.GuardedBy; import net.jcip.annotations.*;
import org.bitcoinj.crypto.DRMWorkaround; import org.bitcoinj.crypto.*;
import org.bitcoinj.net.BlockingClientManager; import org.bitcoinj.net.*;
import org.bitcoinj.net.ClientConnectionManager; import org.bitcoinj.net.discovery.*;
import org.bitcoinj.net.FilterMerger; import org.bitcoinj.script.*;
import org.bitcoinj.net.NioClientManager; import org.bitcoinj.utils.*;
import org.bitcoinj.net.discovery.PeerDiscovery;
import org.bitcoinj.net.discovery.PeerDiscoveryException;
import org.bitcoinj.net.discovery.TorDiscovery;
import org.bitcoinj.script.Script;
import org.bitcoinj.utils.DaemonThreadFactory;
import org.bitcoinj.utils.ExponentialBackoff;
import org.bitcoinj.utils.ListenerRegistration;
import org.bitcoinj.utils.Threading; import org.bitcoinj.utils.Threading;
import org.slf4j.Logger; import org.slf4j.*;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable; import javax.annotation.*;
import java.io.IOException; import java.io.*;
import java.net.*; import java.net.*;
import java.util.*; import java.util.*;
import java.util.concurrent.*; import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.*;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.*;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
/** /**
* <p>Runs a set of connections to the P2P network, brings up connections to replace disconnected nodes and manages * <p>Runs a set of connections to the P2P network, brings up connections to replace disconnected nodes and manages
@ -1281,10 +1267,9 @@ public class PeerGroup implements TransactionBroadcaster {
// TODO: The peer should calculate the fast catchup time from the added wallets here. // TODO: The peer should calculate the fast catchup time from the added wallets here.
for (Wallet wallet : wallets) for (Wallet wallet : wallets)
peer.addWallet(wallet); peer.addWallet(wallet);
// Re-evaluate download peers. if (downloadPeer == null) {
Peer newDownloadPeer = selectDownloadPeer(peers); // Kick off chain download if we aren't already doing it.
if (downloadPeer != newDownloadPeer) { setDownloadPeer(selectDownloadPeer(peers));
setDownloadPeer(newDownloadPeer);
boolean shouldDownloadChain = downloadListener != null && chain != null; boolean shouldDownloadChain = downloadListener != null && chain != null;
if (shouldDownloadChain) { if (shouldDownloadChain) {
startBlockChainDownloadFromPeer(downloadPeer); startBlockChainDownloadFromPeer(downloadPeer);
@ -1781,7 +1766,7 @@ public class PeerGroup implements TransactionBroadcaster {
// 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)
// - High enough protocol version for the features we want (but we'll settle for less) // - High enough protocol version for the features we want (but we'll settle for less)
// - Ping time. // - Randomly, to try and spread the load.
if (peers.isEmpty()) if (peers.isEmpty())
return null; return null;
// Make sure we don't select a peer that is behind/synchronizing itself. // Make sure we don't select a peer that is behind/synchronizing itself.
@ -1801,23 +1786,14 @@ public class PeerGroup implements TransactionBroadcaster {
highestVersion = Math.max(peer.getPeerVersionMessage().clientVersion, highestVersion); highestVersion = Math.max(peer.getPeerVersionMessage().clientVersion, highestVersion);
preferredVersion = Math.min(highestVersion, PREFERRED_VERSION); preferredVersion = Math.min(highestVersion, PREFERRED_VERSION);
} }
List<PeerAndPing> candidates2 = new ArrayList<PeerAndPing>(); ArrayList<Peer> candidates2 = new ArrayList<Peer>(candidates.size());
for (Peer peer : candidates) { for (Peer peer : candidates) {
if (peer.getPeerVersionMessage().clientVersion >= preferredVersion) { if (peer.getPeerVersionMessage().clientVersion >= preferredVersion) {
PeerAndPing pap = new PeerAndPing(); candidates2.add(peer);
pap.peer = peer;
pap.pingTime = peer.getPingTime();
candidates2.add(pap);
} }
} }
// Sort by ping time. int index = (int) (Math.random() * candidates2.size());
Collections.sort(candidates2, new Comparator<PeerAndPing>() { return candidates2.get(index);
@Override
public int compare(PeerAndPing peerAndPing, PeerAndPing peerAndPing2) {
return Longs.compare(peerAndPing.pingTime, peerAndPing2.pingTime);
}
});
return candidates2.get(0).peer;
} }
/** /**