diff --git a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileManager.java b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileManager.java index 4f77f299..f8c9298e 100644 --- a/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileManager.java +++ b/src/main/java/org/qortal/controller/arbitrary/ArbitraryDataFileManager.java @@ -293,6 +293,10 @@ public class ArbitraryDataFileManager extends Thread { } } + private void removeDirectConnectionInfo(ArbitraryDirectConnectionInfo connectionInfo) { + this.directConnectionInfo.remove(connectionInfo); + } + public boolean fetchDataFilesFromPeersForSignature(byte[] signature) { String signature58 = Base58.encode(signature); @@ -305,9 +309,19 @@ public class ArbitraryDataFileManager extends Thread { LOGGER.debug("Attempting a direct peer connection for signature {}...", signature58); - // Peers found, so pick a random one and request data from it - int index = new SecureRandom().nextInt(connectionInfoList.size()); - ArbitraryDirectConnectionInfo directConnectionInfo = connectionInfoList.get(index); + // Peers found, so pick one with the highest number of chunks + Comparator highestChunkCountFirstComparator = + 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); diff --git a/src/main/java/org/qortal/data/arbitrary/ArbitraryDirectConnectionInfo.java b/src/main/java/org/qortal/data/arbitrary/ArbitraryDirectConnectionInfo.java index ae9c0969..163726b4 100644 --- a/src/main/java/org/qortal/data/arbitrary/ArbitraryDirectConnectionInfo.java +++ b/src/main/java/org/qortal/data/arbitrary/ArbitraryDirectConnectionInfo.java @@ -1,6 +1,8 @@ package org.qortal.data.arbitrary; +import java.util.Arrays; import java.util.List; +import java.util.Objects; public class ArbitraryDirectConnectionInfo { @@ -31,4 +33,27 @@ public class ArbitraryDirectConnectionInfo { public long getTimestamp() { return this.timestamp; } + + public int getHashCount() { + if (this.hashes == null) { + return 0; + } + return this.hashes.size(); + } + + @Override + public boolean equals(Object other) { + if (other == this) + return true; + + if (!(other instanceof ArbitraryDirectConnectionInfo)) + return false; + + ArbitraryDirectConnectionInfo otherDirectConnectionInfo = (ArbitraryDirectConnectionInfo) other; + + return Arrays.equals(this.signature, otherDirectConnectionInfo.getSignature()) + && Objects.equals(this.peerAddress, otherDirectConnectionInfo.getPeerAddress()) + && Objects.equals(this.hashes, otherDirectConnectionInfo.getHashes()) + && Objects.equals(this.timestamp, otherDirectConnectionInfo.getTimestamp()); + } }