forked from Qortal/qortal
Re-broadcast the arbitrary signatures message if it contains new data, so that the message finds its way to all online peers.
This commit is contained in:
parent
6b5d938a40
commit
c9356d0ff5
@ -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
|
// 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);
|
Network.getInstance().broadcast(broadcastPeer -> newArbitrarySignatureMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,9 +667,18 @@ public class ArbitraryDataManager extends Thread {
|
|||||||
|
|
||||||
public void onNetworkArbitrarySignaturesMessage(Peer peer, Message message) {
|
public void onNetworkArbitrarySignaturesMessage(Peer peer, Message message) {
|
||||||
LOGGER.info("Received arbitrary signature list from peer {}", peer);
|
LOGGER.info("Received arbitrary signature list from peer {}", peer);
|
||||||
|
|
||||||
ArbitrarySignaturesMessage arbitrarySignaturesMessage = (ArbitrarySignaturesMessage) message;
|
ArbitrarySignaturesMessage arbitrarySignaturesMessage = (ArbitrarySignaturesMessage) message;
|
||||||
List<byte[]> signatures = arbitrarySignaturesMessage.getSignatures();
|
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()) {
|
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||||
for (byte[] signature : signatures) {
|
for (byte[] signature : signatures) {
|
||||||
|
|
||||||
@ -678,13 +688,26 @@ public class ArbitraryDataManager extends Thread {
|
|||||||
|
|
||||||
if (existingEntry == null) {
|
if (existingEntry == null) {
|
||||||
// We haven't got a record of this mapping yet, so add it
|
// 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);
|
ArbitraryPeerData arbitraryPeerData = new ArbitraryPeerData(signature, peer);
|
||||||
repository.getArbitraryRepository().save(arbitraryPeerData);
|
repository.getArbitraryRepository().save(arbitraryPeerData);
|
||||||
repository.saveChanges();
|
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
|
// If anything needed saving, it would already have called saveChanges() above
|
||||||
repository.discardChanges();
|
repository.discardChanges();
|
||||||
} catch (DataException e) {
|
} catch (DataException e) {
|
||||||
|
@ -13,6 +13,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
@XmlAccessorType(XmlAccessType.FIELD)
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
public class PeerData {
|
public class PeerData {
|
||||||
|
|
||||||
|
public static final int MAX_PEER_ADDRESS_SIZE = 255;
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
|
|
||||||
// Don't expose this via JAXB - use pretty getter instead
|
// Don't expose this via JAXB - use pretty getter instead
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package org.qortal.network.message;
|
package org.qortal.network.message;
|
||||||
|
|
||||||
import com.google.common.primitives.Ints;
|
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.transform.Transformer;
|
||||||
|
import org.qortal.utils.Serialization;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -14,36 +18,44 @@ public class ArbitrarySignaturesMessage extends Message {
|
|||||||
|
|
||||||
private static final int SIGNATURE_LENGTH = Transformer.SIGNATURE_LENGTH;
|
private static final int SIGNATURE_LENGTH = Transformer.SIGNATURE_LENGTH;
|
||||||
|
|
||||||
|
private String peerAddress;
|
||||||
private List<byte[]> signatures;
|
private List<byte[]> signatures;
|
||||||
|
|
||||||
public ArbitrarySignaturesMessage(List<byte[]> signatures) {
|
public ArbitrarySignaturesMessage(String peerAddress, List<byte[]> signatures) {
|
||||||
this(-1, 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);
|
super(id, MessageType.ARBITRARY_SIGNATURES);
|
||||||
|
|
||||||
|
this.peerAddress = peerAddress;
|
||||||
this.signatures = signatures;
|
this.signatures = signatures;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPeerAddress() {
|
||||||
|
return this.peerAddress;
|
||||||
|
}
|
||||||
|
|
||||||
public List<byte[]> getSignatures() {
|
public List<byte[]> getSignatures() {
|
||||||
return this.signatures;
|
return this.signatures;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Message fromByteBuffer(int id, ByteBuffer bytes) throws UnsupportedEncodingException {
|
public static Message fromByteBuffer(int id, ByteBuffer bytes) throws UnsupportedEncodingException, TransformationException {
|
||||||
int count = bytes.getInt();
|
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;
|
return null;
|
||||||
|
|
||||||
List<byte[]> signatures = new ArrayList<>();
|
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];
|
byte[] signature = new byte[SIGNATURE_LENGTH];
|
||||||
bytes.get(signature);
|
bytes.get(signature);
|
||||||
signatures.add(signature);
|
signatures.add(signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ArbitrarySignaturesMessage(id, signatures);
|
return new ArbitrarySignaturesMessage(id, peerAddress, signatures);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -51,6 +63,8 @@ public class ArbitrarySignaturesMessage extends Message {
|
|||||||
try {
|
try {
|
||||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
Serialization.serializeSizedString(bytes, this.peerAddress);
|
||||||
|
|
||||||
bytes.write(Ints.toByteArray(this.signatures.size()));
|
bytes.write(Ints.toByteArray(this.signatures.size()));
|
||||||
|
|
||||||
for (byte[] signature : this.signatures)
|
for (byte[] signature : this.signatures)
|
||||||
|
Loading…
Reference in New Issue
Block a user