Browse Source

Loop through all available direct peer connections and try each one in turn.

Also added some extra conditionals to avoid repeated attempts with the same port.
name-fixes
CalDescent 3 years ago
parent
commit
c185d79672
  1. 144
      src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileManager.java

144
src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileManager.java

@ -317,80 +317,102 @@ public class ArbitraryDataFileManager extends Thread {
public boolean fetchDataFilesFromPeersForSignature(byte[] signature) { public boolean fetchDataFilesFromPeersForSignature(byte[] signature) {
String signature58 = Base58.encode(signature); String signature58 = Base58.encode(signature);
// Firstly fetch peers that claim to be hosting files for this signature boolean success = false;
List<ArbitraryDirectConnectionInfo> connectionInfoList = getDirectConnectionInfoForSignature(signature);
if (connectionInfoList == null || connectionInfoList.isEmpty()) {
LOGGER.debug("No direct connection peers found for signature {}", signature58);
return false;
}
LOGGER.debug("Attempting a direct peer connection for signature {}...", signature58); try {
while (!success) {
if (isStopping) {
return false;
}
Thread.sleep(500L);
// Peers found, so pick one with the highest number of chunks // Firstly fetch peers that claim to be hosting files for this signature
Comparator<ArbitraryDirectConnectionInfo> highestChunkCountFirstComparator = List<ArbitraryDirectConnectionInfo> connectionInfoList = getDirectConnectionInfoForSignature(signature);
Comparator.comparingInt(ArbitraryDirectConnectionInfo::getHashCount).reversed(); if (connectionInfoList == null || connectionInfoList.isEmpty()) {
ArbitraryDirectConnectionInfo directConnectionInfo = connectionInfoList.stream() LOGGER.debug("No remaining direct connection peers found for signature {}", signature58);
.sorted(highestChunkCountFirstComparator).findFirst().orElse(null); return false;
}
if (directConnectionInfo == null) { LOGGER.debug("Attempting a direct peer connection for signature {}...", signature58);
return false;
}
// Remove from the list so that a different peer is tried next time // Peers found, so pick one with the highest number of chunks
removeDirectConnectionInfo(directConnectionInfo); Comparator<ArbitraryDirectConnectionInfo> highestChunkCountFirstComparator =
Comparator.comparingInt(ArbitraryDirectConnectionInfo::getHashCount).reversed();
ArbitraryDirectConnectionInfo directConnectionInfo = connectionInfoList.stream()
.sorted(highestChunkCountFirstComparator).findFirst().orElse(null);
String peerAddressString = directConnectionInfo.getPeerAddress(); if (directConnectionInfo == null) {
boolean success = Network.getInstance().requestDataFromPeer(peerAddressString, signature); return false;
}
// Parse the peer address to find the host and port // Remove from the list so that a different peer is tried next time
String host = null; removeDirectConnectionInfo(directConnectionInfo);
int port = -1;
String[] parts = peerAddressString.split(":"); String peerAddressString = directConnectionInfo.getPeerAddress();
if (parts.length > 1) {
host = parts[0]; // Parse the peer address to find the host and port
port = Integer.parseInt(parts[1]); String host = null;
} int port = -1;
else { String[] parts = peerAddressString.split(":");
// Use default listen port if (parts.length > 1) {
port = Settings.getInstance().getDefaultListenPort(); host = parts[0];
} port = Integer.parseInt(parts[1]);
} else {
// Assume no port included
host = peerAddressString;
// Use default listen port
port = Settings.getInstance().getDefaultListenPort();
}
String peerAddressStringWithPort = String.format("%s:%d", host, port);
success = Network.getInstance().requestDataFromPeer(peerAddressStringWithPort, signature);
// If unsuccessful, and using a non-standard port, try a second connection with the default listen port,
// since almost all nodes use that. This is a workaround to account for any ephemeral ports that may
// have made it into the dataset.
if (!success) {
if (host != null && port > 0) {
int defaultPort = Settings.getInstance().getDefaultListenPort(); int defaultPort = Settings.getInstance().getDefaultListenPort();
if (port != defaultPort) {
String newPeerAddressString = String.format("%s:%d", host, defaultPort); // If unsuccessful, and using a non-standard port, try a second connection with the default listen port,
success = Network.getInstance().requestDataFromPeer(newPeerAddressString, signature); // since almost all nodes use that. This is a workaround to account for any ephemeral ports that may
// have made it into the dataset.
if (!success) {
if (host != null && port > 0) {
if (port != defaultPort) {
String newPeerAddressString = String.format("%s:%d", host, defaultPort);
success = Network.getInstance().requestDataFromPeer(newPeerAddressString, signature);
}
}
} }
}
}
// If _still_ unsuccessful, try matching the peer's IP address with some known peers, and then connect // If _still_ unsuccessful, try matching the peer's IP address with some known peers, and then connect
// to each of those in turn until one succeeds. // to each of those in turn until one succeeds.
if (!success) { if (!success) {
if (host != null) { if (host != null) {
final String finalHost = host; final String finalHost = host;
List<PeerData> knownPeers = Network.getInstance().getAllKnownPeers().stream() List<PeerData> knownPeers = Network.getInstance().getAllKnownPeers().stream()
.filter(knownPeerData -> knownPeerData.getAddress().getHost().equals(finalHost)) .filter(knownPeerData -> knownPeerData.getAddress().getHost().equals(finalHost))
.collect(Collectors.toList()); .collect(Collectors.toList());
// Loop through each match and attempt a connection // Loop through each match and attempt a connection
for (PeerData matchingPeer : knownPeers) { for (PeerData matchingPeer : knownPeers) {
String matchingPeerAddress = matchingPeer.getAddress().toString(); String matchingPeerAddress = matchingPeer.getAddress().toString();
success = Network.getInstance().requestDataFromPeer(matchingPeerAddress, signature); int matchingPeerPort = matchingPeer.getAddress().getPort();
if (success) { // Make sure that it's not a port we've already tried
// Successfully connected, so stop making connections if (matchingPeerPort != port && matchingPeerPort != defaultPort) {
break; success = Network.getInstance().requestDataFromPeer(matchingPeerAddress, signature);
if (success) {
// Successfully connected, so stop making connections
break;
}
}
}
} }
} }
}
}
if (success) { if (success) {
// We were able to connect with a peer, so track the request // We were able to connect with a peer, so track the request
ArbitraryDataFileListManager.getInstance().addToSignatureRequests(signature58, false, true); ArbitraryDataFileListManager.getInstance().addToSignatureRequests(signature58, false, true);
}
}
} catch (InterruptedException e) {
// Do nothing
} }
return success; return success;

Loading…
Cancel
Save