From abab2d1cde209e6a052c10b69fc9bb9a30af50dd Mon Sep 17 00:00:00 2001 From: CalDescent Date: Fri, 8 Oct 2021 12:22:21 +0100 Subject: [PATCH] Fixed issue preventing blocks from being served from the archive. Now prefixing the byte buffer with the block height to mimic a cached block message. --- .../qortal/api/resource/BlocksResource.java | 2 +- .../org/qortal/controller/Controller.java | 2 +- .../qortal/repository/BlockArchiveReader.java | 25 ++++++++++++++----- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/qortal/api/resource/BlocksResource.java b/src/main/java/org/qortal/api/resource/BlocksResource.java index b9ffe03c..b8163c7d 100644 --- a/src/main/java/org/qortal/api/resource/BlocksResource.java +++ b/src/main/java/org/qortal/api/resource/BlocksResource.java @@ -140,7 +140,7 @@ public class BlocksResource { } // Not found, so try the block archive - byte[] bytes = BlockArchiveReader.getInstance().fetchSerializedBlockBytesForSignature(signature, repository); + byte[] bytes = BlockArchiveReader.getInstance().fetchSerializedBlockBytesForSignature(signature, false, repository); if (bytes != null) { return Base58.encode(bytes); } diff --git a/src/main/java/org/qortal/controller/Controller.java b/src/main/java/org/qortal/controller/Controller.java index 1434b24f..c8943ded 100644 --- a/src/main/java/org/qortal/controller/Controller.java +++ b/src/main/java/org/qortal/controller/Controller.java @@ -1393,7 +1393,7 @@ public class Controller extends Thread { // If we have no block data, we should check the archive in case it's there if (blockData == null) { if (Settings.getInstance().isArchiveEnabled()) { - byte[] bytes = BlockArchiveReader.getInstance().fetchSerializedBlockBytesForSignature(signature, repository); + byte[] bytes = BlockArchiveReader.getInstance().fetchSerializedBlockBytesForSignature(signature, true, repository); if (bytes != null) { CachedBlockMessage blockMessage = new CachedBlockMessage(bytes); blockMessage.setId(message.getId()); diff --git a/src/main/java/org/qortal/repository/BlockArchiveReader.java b/src/main/java/org/qortal/repository/BlockArchiveReader.java index c173b6f2..2621bade 100644 --- a/src/main/java/org/qortal/repository/BlockArchiveReader.java +++ b/src/main/java/org/qortal/repository/BlockArchiveReader.java @@ -1,5 +1,6 @@ package org.qortal.repository; +import com.google.common.primitives.Ints; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.qortal.data.at.ATStateData; @@ -13,10 +14,7 @@ import org.qortal.utils.Triple; import static org.qortal.transform.Transformer.INT_LENGTH; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.RandomAccessFile; +import java.io.*; import java.nio.ByteBuffer; import java.nio.file.Path; import java.nio.file.Paths; @@ -167,7 +165,7 @@ public class BlockArchiveReader { return null; } - public byte[] fetchSerializedBlockBytesForSignature(byte[] signature, Repository repository) { + public byte[] fetchSerializedBlockBytesForSignature(byte[] signature, boolean includeHeightPrefix, Repository repository) { if (this.fileListCache.isEmpty()) { this.fetchFileList(); @@ -175,7 +173,22 @@ public class BlockArchiveReader { Integer height = this.fetchHeightForSignature(signature, repository); if (height != null) { - return this.fetchSerializedBlockBytesForHeight(height); + byte[] blockBytes = this.fetchSerializedBlockBytesForHeight(height); + + // When responding to a peer with a BLOCK message, we must prefix the byte array with the block height + // This mimics the toData() method in BlockMessage and CachedBlockMessage + if (includeHeightPrefix) { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(blockBytes.length + INT_LENGTH); + try { + bytes.write(Ints.toByteArray(height)); + bytes.write(blockBytes); + return bytes.toByteArray(); + + } catch (IOException e) { + return null; + } + } + return blockBytes; } return null; }