From 58579295081ae0368c48c3e1790f7039b96da483 Mon Sep 17 00:00:00 2001 From: CalDescent Date: Fri, 1 Apr 2022 18:39:34 +0100 Subject: [PATCH] Correction to commit #eb876e1 Block serialization is in fact affected by the online accounts serialization, as we have to calculate the expected length ahead of time. --- src/main/java/org/qortal/block/Block.java | 29 +++++++++++++++---- .../transform/block/BlockTransformer.java | 2 +- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/qortal/block/Block.java b/src/main/java/org/qortal/block/Block.java index 3a53d61c..5a900575 100644 --- a/src/main/java/org/qortal/block/Block.java +++ b/src/main/java/org/qortal/block/Block.java @@ -977,11 +977,7 @@ public class Block { return ValidationResult.ONLINE_ACCOUNT_SIGNATURES_MISSING; // Verify the online account signatures length - int expectedLength; - if (this.blockData.getTimestamp() >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp()) - expectedLength = onlineRewardShares.size() * (Transformer.SIGNATURE_LENGTH + Transformer.REDUCED_SIGNATURE_LENGTH + Transformer.INT_LENGTH + (OnlineAccountsManager.MAX_NONCE_COUNT * Transformer.INT_LENGTH)); - else - expectedLength = onlineRewardShares.size() * Transformer.SIGNATURE_LENGTH; + int expectedLength = Block.getExpectedOnlineAccountsSignaturesLength(onlineRewardShares.size(), this.blockData.getTimestamp()); if (this.blockData.getOnlineAccountsSignatures().length != expectedLength) return ValidationResult.ONLINE_ACCOUNT_SIGNATURES_MALFORMED; @@ -2064,6 +2060,29 @@ public class Block { return null; } + /** + * Expected length of serialized online accounts + * @param onlineRewardSharesCount the number of reward shares in the serialized data + * @param timestamp the block's timestamp, used for versioning / serialization differences + * @return the number of bytes to expect + */ + public static int getExpectedOnlineAccountsSignaturesLength(int onlineRewardSharesCount, long timestamp) { + int expectedLength; + + if (timestamp >= BlockChain.getInstance().getOnlineAccountsMemoryPoWTimestamp()) { + // byte array contains signatures, reduced signatures, and nonces + expectedLength = onlineRewardSharesCount * + (Transformer.SIGNATURE_LENGTH + Transformer.REDUCED_SIGNATURE_LENGTH + Transformer.INT_LENGTH + + (OnlineAccountsManager.MAX_NONCE_COUNT * Transformer.INT_LENGTH)); + } + else { + // byte array contains signatures only + expectedLength = onlineRewardSharesCount * Transformer.SIGNATURE_LENGTH; + } + + return expectedLength; + } + private void logDebugInfo() { try { // Avoid calculations if possible. We have to check against INFO here, since Level.isMoreSpecificThan() confusingly uses <= rather than just < diff --git a/src/main/java/org/qortal/transform/block/BlockTransformer.java b/src/main/java/org/qortal/transform/block/BlockTransformer.java index 4621491b..12a0124f 100644 --- a/src/main/java/org/qortal/transform/block/BlockTransformer.java +++ b/src/main/java/org/qortal/transform/block/BlockTransformer.java @@ -217,7 +217,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 = Block.getExpectedOnlineAccountsSignaturesLength(onlineAccountsSignaturesCount, timestamp); if (signaturesByteLength > BlockChain.getInstance().getMaxBlockSize()) throw new TransformationException("Byte data too long for online accounts signatures");