Optionally include requestTime, requestHops, peerAddress, and isRelayPossible flag in ArbitraryDataFileListMessage

This commit is contained in:
CalDescent 2022-02-18 13:25:20 +00:00
parent 31d34c3946
commit 1a59379162
4 changed files with 106 additions and 10 deletions

View File

@ -472,14 +472,22 @@ public class ArbitraryDataFileListManager {
if (!isBlocked) { if (!isBlocked) {
Peer requestingPeer = request.getB(); Peer requestingPeer = request.getB();
if (requestingPeer != null) { if (requestingPeer != null) {
Long requestTime = arbitraryDataFileListMessage.getRequestTime();
Integer requestHops = arbitraryDataFileListMessage.getRequestHops();
// Add each hash to our local mapping so we know who to ask later // Add each hash to our local mapping so we know who to ask later
Long now = NTP.getTime(); Long now = NTP.getTime();
for (byte[] hash : hashes) { for (byte[] hash : hashes) {
String hash58 = Base58.encode(hash); String hash58 = Base58.encode(hash);
ArbitraryRelayInfo relayMap = new ArbitraryRelayInfo(hash58, signature58, peer, now); ArbitraryRelayInfo relayMap = new ArbitraryRelayInfo(hash58, signature58, peer, now, requestTime, requestHops);
ArbitraryDataFileManager.getInstance().addToRelayMap(relayMap); ArbitraryDataFileManager.getInstance().addToRelayMap(relayMap);
} }
// Bump requestHops if it exists
if (requestHops != null) {
arbitraryDataFileListMessage.setRequestHops(++requestHops);
}
// Forward to requesting peer // Forward to requesting peer
LOGGER.debug("Forwarding file list with {} hashes to requesting peer: {}", hashes.size(), requestingPeer); LOGGER.debug("Forwarding file list with {} hashes to requesting peer: {}", hashes.size(), requestingPeer);
if (!requestingPeer.sendMessage(arbitraryDataFileListMessage)) { if (!requestingPeer.sendMessage(arbitraryDataFileListMessage)) {
@ -582,7 +590,9 @@ public class ArbitraryDataFileListManager {
arbitraryDataFileListRequests.put(message.getId(), newEntry); arbitraryDataFileListRequests.put(message.getId(), newEntry);
} }
ArbitraryDataFileListMessage arbitraryDataFileListMessage = new ArbitraryDataFileListMessage(signature, hashes); String ourAddress = Network.getInstance().getOurExternalIpAddress();
ArbitraryDataFileListMessage arbitraryDataFileListMessage = new ArbitraryDataFileListMessage(signature,
hashes, NTP.getTime(), 0, ourAddress, true);
arbitraryDataFileListMessage.setId(message.getId()); arbitraryDataFileListMessage.setId(message.getId());
if (!peer.sendMessage(arbitraryDataFileListMessage)) { if (!peer.sendMessage(arbitraryDataFileListMessage)) {
LOGGER.debug("Couldn't send list of hashes"); LOGGER.debug("Couldn't send list of hashes");

View File

@ -9,12 +9,16 @@ public class ArbitraryRelayInfo {
private final String signature58; private final String signature58;
private final Peer peer; private final Peer peer;
private final Long timestamp; private final Long timestamp;
private final Long requestTime;
private final Integer requestHops;
public ArbitraryRelayInfo(String hash58, String signature58, Peer peer, Long timestamp) { public ArbitraryRelayInfo(String hash58, String signature58, Peer peer, Long timestamp, Long requestTime, Integer requestHops) {
this.hash58 = hash58; this.hash58 = hash58;
this.signature58 = signature58; this.signature58 = signature58;
this.peer = peer; this.peer = peer;
this.timestamp = timestamp; this.timestamp = timestamp;
this.requestTime = requestTime;
this.requestHops = requestHops;
} }
public boolean isValid() { public boolean isValid() {
@ -38,6 +42,14 @@ public class ArbitraryRelayInfo {
return timestamp; return timestamp;
} }
public Long getRequestTime() {
return this.requestTime;
}
public Integer getRequestHops() {
return this.requestHops;
}
@Override @Override
public String toString() { public String toString() {
return String.format("%s = %s, %s, %d", this.hash58, this.signature58, this.peer, this.timestamp); return String.format("%s = %s, %s, %d", this.hash58, this.signature58, this.peer, this.timestamp);

View File

@ -1195,6 +1195,11 @@ public class Network {
//ArbitraryDataManager.getInstance().broadcastHostedSignatureList(); //ArbitraryDataManager.getInstance().broadcastHostedSignatureList();
} }
public String getOurExternalIpAddress() {
// FUTURE: replace port if UPnP is active, as it will be more accurate
return this.ourExternalIpAddress;
}
// Peer-management calls // Peer-management calls

View File

@ -1,6 +1,8 @@
package org.qortal.network.message; package org.qortal.network.message;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import org.qortal.data.network.PeerData;
import org.qortal.transform.TransformationException; import org.qortal.transform.TransformationException;
import org.qortal.transform.Transformer; import org.qortal.transform.Transformer;
import org.qortal.utils.Serialization; import org.qortal.utils.Serialization;
@ -16,22 +18,38 @@ public class ArbitraryDataFileListMessage extends Message {
private static final int SIGNATURE_LENGTH = Transformer.SIGNATURE_LENGTH; private static final int SIGNATURE_LENGTH = Transformer.SIGNATURE_LENGTH;
private static final int HASH_LENGTH = Transformer.SHA256_LENGTH; private static final int HASH_LENGTH = Transformer.SHA256_LENGTH;
private static final int MAX_PEER_ADDRESS_LENGTH = PeerData.MAX_PEER_ADDRESS_SIZE;
private final byte[] signature; private final byte[] signature;
private final List<byte[]> hashes; private final List<byte[]> hashes;
private final Long requestTime;
private Integer requestHops;
private final String peerAddress;
private final boolean isRelayPossible;
public ArbitraryDataFileListMessage(byte[] signature, List<byte[]> hashes) {
public ArbitraryDataFileListMessage(byte[] signature, List<byte[]> hashes, Long requestTime,
Integer requestHops, String peerAddress, boolean isRelayPossible) {
super(MessageType.ARBITRARY_DATA_FILE_LIST); super(MessageType.ARBITRARY_DATA_FILE_LIST);
this.signature = signature; this.signature = signature;
this.hashes = hashes; this.hashes = hashes;
this.requestTime = requestTime;
this.requestHops = requestHops;
this.peerAddress = peerAddress;
this.isRelayPossible = isRelayPossible;
} }
public ArbitraryDataFileListMessage(int id, byte[] signature, List<byte[]> hashes) { public ArbitraryDataFileListMessage(int id, byte[] signature, List<byte[]> hashes, Long requestTime,
Integer requestHops, String peerAddress, boolean isRelayPossible) {
super(id, MessageType.ARBITRARY_DATA_FILE_LIST); super(id, MessageType.ARBITRARY_DATA_FILE_LIST);
this.signature = signature; this.signature = signature;
this.hashes = hashes; this.hashes = hashes;
this.requestTime = requestTime;
this.requestHops = requestHops;
this.peerAddress = peerAddress;
this.isRelayPossible = isRelayPossible;
} }
public List<byte[]> getHashes() { public List<byte[]> getHashes() {
@ -48,9 +66,6 @@ public class ArbitraryDataFileListMessage extends Message {
int count = bytes.getInt(); int count = bytes.getInt();
if (bytes.remaining() != count * HASH_LENGTH)
return null;
List<byte[]> hashes = new ArrayList<>(); List<byte[]> hashes = new ArrayList<>();
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
@ -59,7 +74,26 @@ public class ArbitraryDataFileListMessage extends Message {
hashes.add(hash); hashes.add(hash);
} }
return new ArbitraryDataFileListMessage(id, signature, hashes); Long requestTime = null;
Integer requestHops = null;
String peerAddress = null;
boolean isRelayPossible = true; // Legacy versions only send this message when relaying is possible
// The remaining fields are optional
if (bytes.hasRemaining()) {
requestTime = bytes.getLong();
requestHops = bytes.getInt();
peerAddress = Serialization.deserializeSizedStringV2(bytes, MAX_PEER_ADDRESS_LENGTH);
isRelayPossible = bytes.getInt() > 0;
}
return new ArbitraryDataFileListMessage(id, signature, hashes, requestTime, requestHops, peerAddress, isRelayPossible);
} }
@Override @Override
@ -75,6 +109,20 @@ public class ArbitraryDataFileListMessage extends Message {
bytes.write(hash); bytes.write(hash);
} }
if (this.requestTime == null) { // Just in case
return bytes.toByteArray();
}
// The remaining fields are optional
bytes.write(Longs.toByteArray(this.requestTime));
bytes.write(Ints.toByteArray(this.requestHops));
Serialization.serializeSizedStringV2(bytes, this.peerAddress);
bytes.write(Ints.toByteArray(this.isRelayPossible ? 1 : 0));
return bytes.toByteArray(); return bytes.toByteArray();
} catch (IOException e) { } catch (IOException e) {
return null; return null;
@ -82,9 +130,30 @@ public class ArbitraryDataFileListMessage extends Message {
} }
public ArbitraryDataFileListMessage cloneWithNewId(int newId) { public ArbitraryDataFileListMessage cloneWithNewId(int newId) {
ArbitraryDataFileListMessage clone = new ArbitraryDataFileListMessage(this.signature, this.hashes); ArbitraryDataFileListMessage clone = new ArbitraryDataFileListMessage(this.signature, this.hashes,
this.requestTime, this.requestHops, this.peerAddress, this.isRelayPossible);
clone.setId(newId); clone.setId(newId);
return clone; return clone;
} }
public Long getRequestTime() {
return this.requestTime;
}
public Integer getRequestHops() {
return this.requestHops;
}
public void setRequestHops(int requestHops) {
this.requestHops = requestHops;
}
public String getPeerAddress() {
return this.peerAddress;
}
public boolean isRelayPossible() {
return this.isRelayPossible;
}
} }