From 501f66ab00187f9133351a4127ea40f7ed3ac468 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sat, 10 Sep 2022 18:31:01 +0100 Subject: [PATCH] BlockTransformer updates necessary for mempow online accounts. Using the feature trigger timestamp here should be much less error prone than a whole new block message version. Once mempow has been live for at least 24 hours, the feature trigger can be removed and the code cleaned up, as all online accounts signatures will use the new format from that time onwards (legacy signatures are trimmed after 24 hours). --- src/main/java/org/qortal/data/block/BlockData.java | 8 ++++++++ .../qortal/transform/block/BlockTransformer.java | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/qortal/data/block/BlockData.java b/src/main/java/org/qortal/data/block/BlockData.java index 61d1a7fb..763bca45 100644 --- a/src/main/java/org/qortal/data/block/BlockData.java +++ b/src/main/java/org/qortal/data/block/BlockData.java @@ -211,6 +211,14 @@ public class BlockData implements Serializable { this.onlineAccountsSignatures = onlineAccountsSignatures; } + public int getOnlineAccountsSignaturesCount() { + if (this.onlineAccountsSignatures != null && this.onlineAccountsSignatures.length > 0) { + // Blocks use a single online accounts signature, so there is no need for this to be dynamic + return 1; + } + return 0; + } + public boolean isTrimmed() { long onlineAccountSignaturesTrimmedTimestamp = NTP.getTime() - BlockChain.getInstance().getOnlineAccountSignaturesMaxLifetime(); long currentTrimmableTimestamp = NTP.getTime() - Settings.getInstance().getAtStatesMaxLifetime(); diff --git a/src/main/java/org/qortal/transform/block/BlockTransformer.java b/src/main/java/org/qortal/transform/block/BlockTransformer.java index 48e79699..9e02a6f5 100644 --- a/src/main/java/org/qortal/transform/block/BlockTransformer.java +++ b/src/main/java/org/qortal/transform/block/BlockTransformer.java @@ -235,7 +235,7 @@ public class BlockTransformer extends Transformer { // Online accounts timestamp is only present if there are also signatures onlineAccountsTimestamp = byteBuffer.getLong(); - final int signaturesByteLength = onlineAccountsSignaturesCount * Transformer.SIGNATURE_LENGTH; + final int signaturesByteLength = getOnlineAccountSignaturesLength(onlineAccountsSignaturesCount, onlineAccountsCount, timestamp); if (signaturesByteLength > BlockChain.getInstance().getMaxBlockSize()) throw new TransformationException("Byte data too long for online accounts signatures"); @@ -371,7 +371,7 @@ public class BlockTransformer extends Transformer { if (onlineAccountsSignatures != null && onlineAccountsSignatures.length > 0) { // Note: we write the number of signatures, not the number of bytes - bytes.write(Ints.toByteArray(onlineAccountsSignatures.length / Transformer.SIGNATURE_LENGTH)); + bytes.write(Ints.toByteArray(blockData.getOnlineAccountsSignaturesCount())); // We only write online accounts timestamp if we have signatures bytes.write(Longs.toByteArray(blockData.getOnlineAccountsTimestamp())); @@ -511,6 +511,16 @@ public class BlockTransformer extends Transformer { return nonces; } + public static int getOnlineAccountSignaturesLength(int onlineAccountsSignaturesCount, int onlineAccountCount, long blockTimestamp) { + if (blockTimestamp >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp()) { + // Once mempow is active, we expect the online account signatures to be appended with the nonce values + return (onlineAccountsSignaturesCount * Transformer.SIGNATURE_LENGTH) + (onlineAccountCount * INT_LENGTH); + } + else { + // Before mempow, only the online account signatures were included (which will likely be a single signature) + return onlineAccountsSignaturesCount * Transformer.SIGNATURE_LENGTH; + } + } public static byte[] extract(byte[] input, int pos, int length) { byte[] output = new byte[length];