From 1153519d788934e852a3568b7f84905d186acadd Mon Sep 17 00:00:00 2001 From: CalDescent Date: Sun, 26 Feb 2023 16:53:43 +0000 Subject: [PATCH] Various fixes as a result of moving to archive version 2. --- .../qortal/repository/BlockArchiveReader.java | 6 +++++ .../qortal/repository/BlockArchiveWriter.java | 6 ++++- .../org/qortal/utils/BlockArchiveUtils.java | 25 ++++++++++++++++--- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/qortal/repository/BlockArchiveReader.java b/src/main/java/org/qortal/repository/BlockArchiveReader.java index c5878563..e45f1fdf 100644 --- a/src/main/java/org/qortal/repository/BlockArchiveReader.java +++ b/src/main/java/org/qortal/repository/BlockArchiveReader.java @@ -70,6 +70,9 @@ public class BlockArchiveReader { } Triple serializedBlock = this.fetchSerializedBlockBytesForHeight(height); + if (serializedBlock == null) { + return null; + } byte[] serializedBytes = serializedBlock.getA(); Integer serializationVersion = serializedBlock.getB(); if (serializedBytes == null || serializationVersion == null) { @@ -188,6 +191,9 @@ public class BlockArchiveReader { Integer height = this.fetchHeightForSignature(signature, repository); if (height != null) { Triple serializedBlock = this.fetchSerializedBlockBytesForHeight(height); + if (serializedBlock == null) { + return null; + } byte[] blockBytes = serializedBlock.getA(); Integer version = serializedBlock.getB(); if (blockBytes == null || version == null) { diff --git a/src/main/java/org/qortal/repository/BlockArchiveWriter.java b/src/main/java/org/qortal/repository/BlockArchiveWriter.java index 1799f3c4..87d0a93c 100644 --- a/src/main/java/org/qortal/repository/BlockArchiveWriter.java +++ b/src/main/java/org/qortal/repository/BlockArchiveWriter.java @@ -134,6 +134,7 @@ public class BlockArchiveWriter { return BlockArchiveWriteResult.STOPPING; } if (Synchronizer.getInstance().isSynchronizing()) { + Thread.sleep(1000L); continue; } @@ -180,9 +181,12 @@ public class BlockArchiveWriter { if (atStatesHash != null) { block = new Block(repository, blockData, transactions, atStatesHash); } - else { + else if (atStates != null) { block = new Block(repository, blockData, transactions, atStates); } + else { + block = new Block(repository, blockData); + } // Write the block data to some byte buffers int blockIndex = bytes.size(); diff --git a/src/main/java/org/qortal/utils/BlockArchiveUtils.java b/src/main/java/org/qortal/utils/BlockArchiveUtils.java index 84de1a31..807faef9 100644 --- a/src/main/java/org/qortal/utils/BlockArchiveUtils.java +++ b/src/main/java/org/qortal/utils/BlockArchiveUtils.java @@ -21,6 +21,16 @@ public class BlockArchiveUtils { * into the HSQLDB, in order to make it SQL-compatible * again. *

+ * This is only fully compatible with archives that use + * serialization version 1. For version 2 (or above), + * we are unable to import individual AT states as we + * only have a single combined hash, so the use cases + * for this are greatly limited. + *

+ * A version 1 archive should ultimately be rebuildable + * via a resync or reindex from genesis, allowing + * access to this feature once again. + *

* Note: calls discardChanges() and saveChanges(), so * make sure that you commit any existing repository * changes before calling this method. @@ -61,9 +71,18 @@ public class BlockArchiveUtils { repository.getBlockRepository().save(blockInfo.getBlockData()); // Save AT state data hashes - for (ATStateData atStateData : blockInfo.getAtStates()) { - atStateData.setHeight(blockInfo.getBlockData().getHeight()); - repository.getATRepository().save(atStateData); + if (blockInfo.getAtStates() != null) { + for (ATStateData atStateData : blockInfo.getAtStates()) { + atStateData.setHeight(blockInfo.getBlockData().getHeight()); + repository.getATRepository().save(atStateData); + } + } + else { + // We don't have AT state hashes, so we are only importing a partial state. + // This can still be useful to allow orphaning to very old blocks, when we + // need to access other chainstate info (such as balances) at an earlier block. + // In order to do this, the orphan process must be temporarily adjusted to avoid + // orphaning AT states, as it will otherwise fail due to having no previous state. } } catch (DataException e) {