forked from Qortal/qortal
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.
This commit is contained in:
parent
76b8ba91dd
commit
c185d79672
@ -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) {
|
||||||
// Peers found, so pick one with the highest number of chunks
|
if (isStopping) {
|
||||||
Comparator<ArbitraryDirectConnectionInfo> highestChunkCountFirstComparator =
|
return false;
|
||||||
Comparator.comparingInt(ArbitraryDirectConnectionInfo::getHashCount).reversed();
|
|
||||||
ArbitraryDirectConnectionInfo directConnectionInfo = connectionInfoList.stream()
|
|
||||||
.sorted(highestChunkCountFirstComparator).findFirst().orElse(null);
|
|
||||||
|
|
||||||
if (directConnectionInfo == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove from the list so that a different peer is tried next time
|
|
||||||
removeDirectConnectionInfo(directConnectionInfo);
|
|
||||||
|
|
||||||
String peerAddressString = directConnectionInfo.getPeerAddress();
|
|
||||||
boolean success = Network.getInstance().requestDataFromPeer(peerAddressString, signature);
|
|
||||||
|
|
||||||
// Parse the peer address to find the host and port
|
|
||||||
String host = null;
|
|
||||||
int port = -1;
|
|
||||||
String[] parts = peerAddressString.split(":");
|
|
||||||
if (parts.length > 1) {
|
|
||||||
host = parts[0];
|
|
||||||
port = Integer.parseInt(parts[1]);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Use default listen port
|
|
||||||
port = Settings.getInstance().getDefaultListenPort();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
if (port != defaultPort) {
|
|
||||||
String newPeerAddressString = String.format("%s:%d", host, defaultPort);
|
|
||||||
success = Network.getInstance().requestDataFromPeer(newPeerAddressString, signature);
|
|
||||||
}
|
}
|
||||||
}
|
Thread.sleep(500L);
|
||||||
}
|
|
||||||
|
|
||||||
// If _still_ unsuccessful, try matching the peer's IP address with some known peers, and then connect
|
// Firstly fetch peers that claim to be hosting files for this signature
|
||||||
// to each of those in turn until one succeeds.
|
List<ArbitraryDirectConnectionInfo> connectionInfoList = getDirectConnectionInfoForSignature(signature);
|
||||||
if (!success) {
|
if (connectionInfoList == null || connectionInfoList.isEmpty()) {
|
||||||
if (host != null) {
|
LOGGER.debug("No remaining direct connection peers found for signature {}", signature58);
|
||||||
final String finalHost = host;
|
return false;
|
||||||
List<PeerData> knownPeers = Network.getInstance().getAllKnownPeers().stream()
|
}
|
||||||
.filter(knownPeerData -> knownPeerData.getAddress().getHost().equals(finalHost))
|
|
||||||
.collect(Collectors.toList());
|
LOGGER.debug("Attempting a direct peer connection for signature {}...", signature58);
|
||||||
// Loop through each match and attempt a connection
|
|
||||||
for (PeerData matchingPeer : knownPeers) {
|
// Peers found, so pick one with the highest number of chunks
|
||||||
String matchingPeerAddress = matchingPeer.getAddress().toString();
|
Comparator<ArbitraryDirectConnectionInfo> highestChunkCountFirstComparator =
|
||||||
success = Network.getInstance().requestDataFromPeer(matchingPeerAddress, signature);
|
Comparator.comparingInt(ArbitraryDirectConnectionInfo::getHashCount).reversed();
|
||||||
if (success) {
|
ArbitraryDirectConnectionInfo directConnectionInfo = connectionInfoList.stream()
|
||||||
// Successfully connected, so stop making connections
|
.sorted(highestChunkCountFirstComparator).findFirst().orElse(null);
|
||||||
break;
|
|
||||||
|
if (directConnectionInfo == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove from the list so that a different peer is tried next time
|
||||||
|
removeDirectConnectionInfo(directConnectionInfo);
|
||||||
|
|
||||||
|
String peerAddressString = directConnectionInfo.getPeerAddress();
|
||||||
|
|
||||||
|
// Parse the peer address to find the host and port
|
||||||
|
String host = null;
|
||||||
|
int port = -1;
|
||||||
|
String[] parts = peerAddressString.split(":");
|
||||||
|
if (parts.length > 1) {
|
||||||
|
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);
|
||||||
|
|
||||||
|
int defaultPort = Settings.getInstance().getDefaultListenPort();
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
if (port != defaultPort) {
|
||||||
|
String newPeerAddressString = String.format("%s:%d", host, defaultPort);
|
||||||
|
success = Network.getInstance().requestDataFromPeer(newPeerAddressString, signature);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (success) {
|
// If _still_ unsuccessful, try matching the peer's IP address with some known peers, and then connect
|
||||||
// We were able to connect with a peer, so track the request
|
// to each of those in turn until one succeeds.
|
||||||
ArbitraryDataFileListManager.getInstance().addToSignatureRequests(signature58, false, true);
|
if (!success) {
|
||||||
|
if (host != null) {
|
||||||
|
final String finalHost = host;
|
||||||
|
List<PeerData> knownPeers = Network.getInstance().getAllKnownPeers().stream()
|
||||||
|
.filter(knownPeerData -> knownPeerData.getAddress().getHost().equals(finalHost))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
// Loop through each match and attempt a connection
|
||||||
|
for (PeerData matchingPeer : knownPeers) {
|
||||||
|
String matchingPeerAddress = matchingPeer.getAddress().toString();
|
||||||
|
int matchingPeerPort = matchingPeer.getAddress().getPort();
|
||||||
|
// Make sure that it's not a port we've already tried
|
||||||
|
if (matchingPeerPort != port && matchingPeerPort != defaultPort) {
|
||||||
|
success = Network.getInstance().requestDataFromPeer(matchingPeerAddress, signature);
|
||||||
|
if (success) {
|
||||||
|
// Successfully connected, so stop making connections
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
// We were able to connect with a peer, so track the request
|
||||||
|
ArbitraryDataFileListManager.getInstance().addToSignatureRequests(signature58, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user