Browse Source

Re-broadcast the arbitrary signatures message if it contains new data, so that the message finds its way to all online peers.

qdn
CalDescent 3 years ago
parent
commit
c9356d0ff5
  1. 27
      src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java
  2. 2
      src/main/java/org/qortal/data/network/PeerData.java
  3. 30
      src/main/java/org/qortal/network/message/ArbitrarySignaturesMessage.java

27
src/main/java/org/qortal/controller/arbitrary/ArbitraryDataManager.java

@ -558,7 +558,8 @@ public class ArbitraryDataManager extends Thread {
}
// We also need to broadcast to the network that we are now hosting files for this transaction
Message newArbitrarySignatureMessage = new ArbitrarySignaturesMessage(Arrays.asList(signature));
// Use a null peer address to indicate our own
Message newArbitrarySignatureMessage = new ArbitrarySignaturesMessage(null, Arrays.asList(signature));
Network.getInstance().broadcast(broadcastPeer -> newArbitrarySignatureMessage);
}
@ -666,9 +667,18 @@ public class ArbitraryDataManager extends Thread {
public void onNetworkArbitrarySignaturesMessage(Peer peer, Message message) {
LOGGER.info("Received arbitrary signature list from peer {}", peer);
ArbitrarySignaturesMessage arbitrarySignaturesMessage = (ArbitrarySignaturesMessage) message;
List<byte[]> signatures = arbitrarySignaturesMessage.getSignatures();
String peerAddress = peer.getPeerData().getAddress().toString();
if (arbitrarySignaturesMessage.getPeerAddress() != null) {
// This message is about a different peer than the one that sent it
peerAddress = arbitrarySignaturesMessage.getPeerAddress();
}
boolean containsNewEntry = false;
try (final Repository repository = RepositoryManager.getRepository()) {
for (byte[] signature : signatures) {
@ -678,13 +688,26 @@ public class ArbitraryDataManager extends Thread {
if (existingEntry == null) {
// We haven't got a record of this mapping yet, so add it
LOGGER.info("Adding arbitrary peer: {} for signature {}", peer.getPeerData().getAddress().toString(), Base58.encode(signature));
LOGGER.info("Adding arbitrary peer: {} for signature {}", peerAddress, Base58.encode(signature));
ArbitraryPeerData arbitraryPeerData = new ArbitraryPeerData(signature, peer);
repository.getArbitraryRepository().save(arbitraryPeerData);
repository.saveChanges();
// Remember that this data is new, so that it can be re-broadcast later
containsNewEntry = true;
}
}
// If at least one signature in this batch was new to us, we should re-broadcast the message to the
// network in case some peers haven't received it yet
if (containsNewEntry) {
LOGGER.info("Rebroadcasting arbitrary signature list for peer {}", peerAddress);
Network.getInstance().broadcast(broadcastPeer -> arbitrarySignaturesMessage);
}
else {
// Don't re-broadcast as otherwise we could get into a loop
}
// If anything needed saving, it would already have called saveChanges() above
repository.discardChanges();
} catch (DataException e) {

2
src/main/java/org/qortal/data/network/PeerData.java

@ -13,6 +13,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
@XmlAccessorType(XmlAccessType.FIELD)
public class PeerData {
public static final int MAX_PEER_ADDRESS_SIZE = 255;
// Properties
// Don't expose this via JAXB - use pretty getter instead

30
src/main/java/org/qortal/network/message/ArbitrarySignaturesMessage.java

@ -1,7 +1,11 @@
package org.qortal.network.message;
import com.google.common.primitives.Ints;
import org.qortal.data.network.PeerData;
import org.qortal.transaction.DeployAtTransaction;
import org.qortal.transform.TransformationException;
import org.qortal.transform.Transformer;
import org.qortal.utils.Serialization;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@ -14,36 +18,44 @@ public class ArbitrarySignaturesMessage extends Message {
private static final int SIGNATURE_LENGTH = Transformer.SIGNATURE_LENGTH;
private String peerAddress;
private List<byte[]> signatures;
public ArbitrarySignaturesMessage(List<byte[]> signatures) {
this(-1, signatures);
public ArbitrarySignaturesMessage(String peerAddress, List<byte[]> signatures) {
this(-1, peerAddress, signatures);
}
private ArbitrarySignaturesMessage(int id, List<byte[]> signatures) {
private ArbitrarySignaturesMessage(int id, String peerAddress, List<byte[]> signatures) {
super(id, MessageType.ARBITRARY_SIGNATURES);
this.peerAddress = peerAddress;
this.signatures = signatures;
}
public String getPeerAddress() {
return this.peerAddress;
}
public List<byte[]> getSignatures() {
return this.signatures;
}
public static Message fromByteBuffer(int id, ByteBuffer bytes) throws UnsupportedEncodingException {
int count = bytes.getInt();
public static Message fromByteBuffer(int id, ByteBuffer bytes) throws UnsupportedEncodingException, TransformationException {
String peerAddress = Serialization.deserializeSizedString(bytes, PeerData.MAX_PEER_ADDRESS_SIZE);
if (bytes.remaining() != count * SIGNATURE_LENGTH)
int signatureCount = bytes.getInt();
if (bytes.remaining() != signatureCount * SIGNATURE_LENGTH)
return null;
List<byte[]> signatures = new ArrayList<>();
for (int i = 0; i < count; ++i) {
for (int i = 0; i < signatureCount; ++i) {
byte[] signature = new byte[SIGNATURE_LENGTH];
bytes.get(signature);
signatures.add(signature);
}
return new ArbitrarySignaturesMessage(id, signatures);
return new ArbitrarySignaturesMessage(id, peerAddress, signatures);
}
@Override
@ -51,6 +63,8 @@ public class ArbitrarySignaturesMessage extends Message {
try {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
Serialization.serializeSizedString(bytes, this.peerAddress);
bytes.write(Ints.toByteArray(this.signatures.size()));
for (byte[] signature : this.signatures)

Loading…
Cancel
Save