forked from Qortal/qortal
Direct peer connections now send a file list request to the peer, rather than individually requesting every chunk for a transaction.
This commit is contained in:
parent
40a8cdc71f
commit
33731b969a
@ -304,6 +304,60 @@ public class ArbitraryDataFileListManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean fetchArbitraryDataFileList(Peer peer, byte[] signature) {
|
||||||
|
String signature58 = Base58.encode(signature);
|
||||||
|
|
||||||
|
// Require an NTP sync
|
||||||
|
Long now = NTP.getTime();
|
||||||
|
if (now == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.debug(String.format("Sending data file list request for signature %s to peer %s...", signature58, peer));
|
||||||
|
|
||||||
|
// Build request
|
||||||
|
// Use a time in the past, so that the recipient peer doesn't try and relay it
|
||||||
|
long timestamp = now - 60000L;
|
||||||
|
Message getArbitraryDataFileListMessage = new GetArbitraryDataFileListMessage(signature, timestamp, 0);
|
||||||
|
|
||||||
|
// Save our request into requests map
|
||||||
|
Triple<String, Peer, Long> requestEntry = new Triple<>(signature58, null, NTP.getTime());
|
||||||
|
|
||||||
|
// Assign random ID to this message
|
||||||
|
int id;
|
||||||
|
do {
|
||||||
|
id = new Random().nextInt(Integer.MAX_VALUE - 1) + 1;
|
||||||
|
|
||||||
|
// Put queue into map (keyed by message ID) so we can poll for a response
|
||||||
|
// If putIfAbsent() doesn't return null, then this ID is already taken
|
||||||
|
} while (arbitraryDataFileListRequests.put(id, requestEntry) != null);
|
||||||
|
getArbitraryDataFileListMessage.setId(id);
|
||||||
|
|
||||||
|
// Send the request
|
||||||
|
peer.sendMessage(getArbitraryDataFileListMessage);
|
||||||
|
|
||||||
|
// Poll to see if data has arrived
|
||||||
|
final long singleWait = 100;
|
||||||
|
long totalWait = 0;
|
||||||
|
while (totalWait < ArbitraryDataManager.ARBITRARY_REQUEST_TIMEOUT) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(singleWait);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
requestEntry = arbitraryDataFileListRequests.get(id);
|
||||||
|
if (requestEntry == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (requestEntry.getA() == null)
|
||||||
|
break;
|
||||||
|
|
||||||
|
totalWait += singleWait;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public void deleteFileListRequestsForSignature(byte[] signature) {
|
public void deleteFileListRequestsForSignature(byte[] signature) {
|
||||||
String signature58 = Base58.encode(signature);
|
String signature58 = Base58.encode(signature);
|
||||||
for (Iterator<Map.Entry<Integer, Triple<String, Peer, Long>>> it = arbitraryDataFileListRequests.entrySet().iterator(); it.hasNext();) {
|
for (Iterator<Map.Entry<Integer, Triple<String, Peer, Long>>> it = arbitraryDataFileListRequests.entrySet().iterator(); it.hasNext();) {
|
||||||
|
@ -69,22 +69,6 @@ public class ArbitraryDataFileManager {
|
|||||||
|
|
||||||
// Fetch data files by hash
|
// Fetch data files by hash
|
||||||
|
|
||||||
public boolean fetchAllArbitraryDataFiles(Repository repository, Peer peer, byte[] signature) {
|
|
||||||
try {
|
|
||||||
TransactionData transactionData = repository.getTransactionRepository().fromSignature(signature);
|
|
||||||
if (!(transactionData instanceof ArbitraryTransactionData))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ArbitraryTransactionData arbitraryTransactionData = (ArbitraryTransactionData) transactionData;
|
|
||||||
|
|
||||||
// We use null to represent all hashes associated with this transaction
|
|
||||||
return this.fetchArbitraryDataFiles(repository, peer, signature, arbitraryTransactionData, null);
|
|
||||||
|
|
||||||
} catch (DataException e) {}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean fetchArbitraryDataFiles(Repository repository,
|
public boolean fetchArbitraryDataFiles(Repository repository,
|
||||||
Peer peer,
|
Peer peer,
|
||||||
byte[] signature,
|
byte[] signature,
|
||||||
@ -95,23 +79,6 @@ public class ArbitraryDataFileManager {
|
|||||||
ArbitraryDataFile arbitraryDataFile = ArbitraryDataFile.fromHash(arbitraryTransactionData.getData(), signature);
|
ArbitraryDataFile arbitraryDataFile = ArbitraryDataFile.fromHash(arbitraryTransactionData.getData(), signature);
|
||||||
byte[] metadataHash = arbitraryTransactionData.getMetadataHash();
|
byte[] metadataHash = arbitraryTransactionData.getMetadataHash();
|
||||||
arbitraryDataFile.setMetadataHash(metadataHash);
|
arbitraryDataFile.setMetadataHash(metadataHash);
|
||||||
|
|
||||||
// If hashes are null, we will treat this to mean all data hashes associated with this file
|
|
||||||
if (hashes == null) {
|
|
||||||
if (metadataHash == null) {
|
|
||||||
// This transaction has no metadata/chunks, so use the main file hash
|
|
||||||
hashes = Arrays.asList(arbitraryDataFile.getHash());
|
|
||||||
}
|
|
||||||
else if (!arbitraryDataFile.getMetadataFile().exists()) {
|
|
||||||
// We don't have the metadata file yet, so request it
|
|
||||||
hashes = Arrays.asList(arbitraryDataFile.getMetadataFile().getHash());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Add the chunk hashes
|
|
||||||
hashes = arbitraryDataFile.getChunkHashes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean receivedAtLeastOneFile = false;
|
boolean receivedAtLeastOneFile = false;
|
||||||
|
|
||||||
// Now fetch actual data from this peer
|
// Now fetch actual data from this peer
|
||||||
|
@ -6,7 +6,7 @@ import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
|
|||||||
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
|
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
|
||||||
import org.qortal.block.BlockChain;
|
import org.qortal.block.BlockChain;
|
||||||
import org.qortal.controller.Controller;
|
import org.qortal.controller.Controller;
|
||||||
import org.qortal.controller.arbitrary.ArbitraryDataFileManager;
|
import org.qortal.controller.arbitrary.ArbitraryDataFileListManager;
|
||||||
import org.qortal.controller.arbitrary.ArbitraryDataManager;
|
import org.qortal.controller.arbitrary.ArbitraryDataManager;
|
||||||
import org.qortal.crypto.Crypto;
|
import org.qortal.crypto.Crypto;
|
||||||
import org.qortal.data.block.BlockData;
|
import org.qortal.data.block.BlockData;
|
||||||
@ -307,12 +307,7 @@ public class Network {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
return ArbitraryDataFileListManager.getInstance().fetchArbitraryDataFileList(connectedPeer, signature);
|
||||||
return ArbitraryDataFileManager.getInstance().fetchAllArbitraryDataFiles(repository, connectedPeer, signature);
|
|
||||||
} catch (DataException e) {
|
|
||||||
LOGGER.info("Unable to fetch arbitrary data files");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user