Added HEIGHT_V3 message with the following additions:

- latest block's reference
- latest block's online accounts count
- latest blocks transaction count

These are then retained locally in PeerChainTipData (as optional values, which will be null if peer doesn't support HEIGHT_V3 yet).
This commit is contained in:
CalDescent 2022-05-30 14:36:42 +02:00
parent 2478450694
commit 16ba426932
5 changed files with 184 additions and 2 deletions

View File

@ -1197,6 +1197,10 @@ public class Controller extends Thread {
onNetworkHeightV2Message(peer, message);
break;
case HEIGHT_V3:
onNetworkHeightV3Message(peer, message);
break;
case GET_TRANSACTION:
TransactionImporter.getInstance().onNetworkGetTransactionMessage(peer, message);
break;
@ -1537,6 +1541,27 @@ public class Controller extends Thread {
Synchronizer.getInstance().requestSync();
}
private void onNetworkHeightV3Message(Peer peer, Message message) {
HeightV3Message heightV3Message = (HeightV3Message) message;
if (!Settings.getInstance().isLite()) {
// If peer is inbound and we've not updated their height
// then this is probably their initial HEIGHT_V3 message
// so they need a corresponding HEIGHT_V3 message from us
if (!peer.isOutbound() && (peer.getChainTipData() == null || peer.getChainTipData().getLastHeight() == null))
peer.sendMessage(Network.getInstance().buildHeightMessage(peer, getChainTip()));
}
// Update peer chain tip data
PeerChainTipData newChainTipData = new PeerChainTipData(heightV3Message.getHeight(), heightV3Message.getSignature(),
heightV3Message.getReference(), heightV3Message.getTimestamp(), heightV3Message.getMinterPublicKey(),
heightV3Message.getOnlineAccountsCount(), heightV3Message.getTransactionCount());
peer.setChainTipData(newChainTipData);
// Potentially synchronize
Synchronizer.getInstance().requestSync();
}
private void onNetworkGetAccountMessage(Peer peer, Message message) {
GetAccountMessage getAccountMessage = (GetAccountMessage) message;
String address = getAccountMessage.getAddress();

View File

@ -6,19 +6,34 @@ public class PeerChainTipData {
private Integer lastHeight;
/** Latest block signature as reported by peer. */
private byte[] lastBlockSignature;
/** Latest block reference as reported by peer. */
private byte[] lastBlockReference;
/** Latest block timestamp as reported by peer. */
private Long lastBlockTimestamp;
/** Latest block minter public key as reported by peer. */
private byte[] lastBlockMinter;
/** Latest block's online accounts count as reported by peer. */
private Integer lastBlockOnlineAccountsCount;
/** Latest block's transaction count as reported by peer. */
private Integer lastBlockTransactionCount;
public PeerChainTipData(Integer lastHeight, byte[] lastBlockSignature, Long lastBlockTimestamp, byte[] lastBlockMinter) {
public PeerChainTipData(Integer lastHeight, byte[] lastBlockSignature, byte[] lastBlockReference,
Long lastBlockTimestamp, byte[] lastBlockMinter, Integer lastBlockOnlineAccountsCount,
Integer lastBlockTransactionCount) {
this.lastHeight = lastHeight;
this.lastBlockSignature = lastBlockSignature;
this.lastBlockReference = lastBlockReference;
this.lastBlockTimestamp = lastBlockTimestamp;
this.lastBlockMinter = lastBlockMinter;
this.lastBlockOnlineAccountsCount = lastBlockOnlineAccountsCount;
this.lastBlockTransactionCount = lastBlockTransactionCount;
}
public Integer getLastHeight() {
public PeerChainTipData(Integer lastHeight, byte[] lastBlockSignature, Long lastBlockTimestamp, byte[] lastBlockMinter) {
this(lastHeight, lastBlockSignature, null, lastBlockTimestamp, lastBlockMinter, null, null);
}
public Integer getLastHeight() {
return this.lastHeight;
}
@ -26,6 +41,10 @@ public class PeerChainTipData {
return this.lastBlockSignature;
}
public byte[] getLastBlockReference() {
return this.lastBlockReference;
}
public Long getLastBlockTimestamp() {
return this.lastBlockTimestamp;
}
@ -34,4 +53,12 @@ public class PeerChainTipData {
return this.lastBlockMinter;
}
public Integer getLastBlockOnlineAccountsCount() {
return this.lastBlockOnlineAccountsCount;
}
public Integer getLastBlockTransactionCount() {
return this.lastBlockTransactionCount;
}
}

View File

@ -1163,11 +1163,27 @@ public class Network {
}
public Message buildHeightMessage(Peer peer, BlockData blockData) {
final long HEIGHT_V3_PEER_VERSION = 0x0300030003L;
if (peer.getPeersVersion() >= HEIGHT_V3_PEER_VERSION) {
return Network.getInstance().buildHeightV3Message(peer, blockData);
} else {
return Network.getInstance().buildHeightV2Message(peer, blockData);
}
}
private Message buildHeightV2Message(Peer peer, BlockData blockData) {
// HEIGHT_V2 contains way more useful info
return new HeightV2Message(blockData.getHeight(), blockData.getSignature(),
blockData.getTimestamp(), blockData.getMinterPublicKey());
}
private Message buildHeightV3Message(Peer peer, BlockData blockData) {
// HEIGHT_V3 contains even more useful info
return new HeightV3Message(blockData.getHeight(), blockData.getSignature(), blockData.getReference(),
blockData.getTimestamp(), blockData.getMinterPublicKey(), blockData.getOnlineAccountsCount(),
blockData.getTransactionCount());
}
public Message buildNewTransactionMessage(Peer peer, TransactionData transactionData) {
// In V2 we send out transaction signature only and peers can decide whether to request the full transaction
return new TransactionSignaturesMessage(Collections.singletonList(transactionData.getSignature()));

View File

@ -0,0 +1,113 @@
package org.qortal.network.message;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import org.qortal.transform.Transformer;
import org.qortal.transform.block.BlockTransformer;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
public class HeightV3Message extends Message {
private int height;
private byte[] signature;
private byte[] reference;
private long timestamp;
private byte[] minterPublicKey;
private int onlineAccountsCount;
private int transactionCount;
public HeightV3Message(int height, byte[] signature, byte[] reference, long timestamp, byte[] minterPublicKey,
int onlineAccountsCount, int transactionCount) {
super(MessageType.HEIGHT_V3);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try {
bytes.write(Ints.toByteArray(height));
bytes.write(signature);
bytes.write(reference);
bytes.write(Longs.toByteArray(timestamp));
bytes.write(minterPublicKey);
bytes.write(Ints.toByteArray(onlineAccountsCount));
bytes.write(Ints.toByteArray(transactionCount));
} catch (IOException e) {
throw new AssertionError("IOException shouldn't occur with ByteArrayOutputStream");
}
this.dataBytes = bytes.toByteArray();
this.checksumBytes = Message.generateChecksum(this.dataBytes);
}
private HeightV3Message(int id, int height, byte[] signature, byte[] reference, long timestamp, byte[] minterPublicKey,
int onlineAccountsCount, int transactionCount) {
super(id, MessageType.HEIGHT_V3);
this.height = height;
this.signature = signature;
this.reference = reference;
this.timestamp = timestamp;
this.minterPublicKey = minterPublicKey;
this.onlineAccountsCount = onlineAccountsCount;
this.transactionCount = transactionCount;
}
public int getHeight() {
return this.height;
}
public byte[] getSignature() {
return this.signature;
}
public byte[] getReference() {
return this.reference;
}
public long getTimestamp() {
return this.timestamp;
}
public byte[] getMinterPublicKey() {
return this.minterPublicKey;
}
public int getOnlineAccountsCount() {
return this.onlineAccountsCount;
}
public int getTransactionCount() {
return this.transactionCount;
}
public static Message fromByteBuffer(int id, ByteBuffer bytes) {
int height = bytes.getInt();
byte[] signature = new byte[BlockTransformer.BLOCK_SIGNATURE_LENGTH];
bytes.get(signature);
byte[] reference = new byte[BlockTransformer.BLOCK_SIGNATURE_LENGTH];
bytes.get(reference);
long timestamp = bytes.getLong();
byte[] minterPublicKey = new byte[Transformer.PUBLIC_KEY_LENGTH];
bytes.get(minterPublicKey);
int onlineAccountsCount = bytes.getInt();
int transactionCount = bytes.getInt();
return new HeightV3Message(id, height, signature, reference, timestamp, minterPublicKey, onlineAccountsCount,
transactionCount);
}
}

View File

@ -18,6 +18,7 @@ public enum MessageType {
HEIGHT_V2(10, HeightV2Message::fromByteBuffer),
PING(11, PingMessage::fromByteBuffer),
PONG(12, PongMessage::fromByteBuffer),
HEIGHT_V3(13, HeightV3Message::fromByteBuffer),
// Requesting data
PEERS_V2(20, PeersV2Message::fromByteBuffer),