From b6803490b9f84309bc518ca9cc3e7af5467420be Mon Sep 17 00:00:00 2001 From: CalDescent Date: Mon, 6 Mar 2023 14:13:58 +0000 Subject: [PATCH] Archive version is now loaded from the version of block 2 in the existing archive, or "defaultArchiveVersion" in settings if not available (default: 1). --- .../qortal/api/resource/AdminResource.java | 24 ++++++++++++++----- .../qortal/repository/BlockArchiveReader.java | 13 ++++++++++ .../qortal/repository/BlockArchiveWriter.java | 24 +++++++++++++++---- .../java/org/qortal/settings/Settings.java | 6 ++--- 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/qortal/api/resource/AdminResource.java b/src/main/java/org/qortal/api/resource/AdminResource.java index 0531f60d..ef2a3f95 100644 --- a/src/main/java/org/qortal/api/resource/AdminResource.java +++ b/src/main/java/org/qortal/api/resource/AdminResource.java @@ -738,8 +738,17 @@ public class AdminResource { @POST @Path("/repository/archive/rebuild") @Operation( - summary = "Rebuild archive.", - description = "Rebuilds archive files, using the serialization version specified via the archiveVersion setting.", + summary = "Rebuild archive", + description = "Rebuilds archive files, using the specified serialization version", + requestBody = @RequestBody( + required = true, + content = @Content( + mediaType = MediaType.TEXT_PLAIN, + schema = @Schema( + type = "number", example = "2" + ) + ) + ), responses = { @ApiResponse( description = "\"true\"", @@ -749,9 +758,14 @@ public class AdminResource { ) @ApiErrors({ApiError.REPOSITORY_ISSUE}) @SecurityRequirement(name = "apiKey") - public String rebuildArchive(@HeaderParam(Security.API_KEY_HEADER) String apiKey) { + public String rebuildArchive(@HeaderParam(Security.API_KEY_HEADER) String apiKey, Integer serializationVersion) { Security.checkApiCallAllowed(request); + // Default serialization version to value specified in settings + if (serializationVersion == null) { + serializationVersion = Settings.getInstance().getDefaultArchiveVersion(); + } + try { // We don't actually need to lock the blockchain here, but we'll do it anyway so that // the node can focus on rebuilding rather than synchronizing / minting. @@ -760,9 +774,7 @@ public class AdminResource { blockchainLock.lockInterruptibly(); try { - int archiveVersion = Settings.getInstance().getArchiveVersion(); - - BlockArchiveRebuilder blockArchiveRebuilder = new BlockArchiveRebuilder(archiveVersion); + BlockArchiveRebuilder blockArchiveRebuilder = new BlockArchiveRebuilder(serializationVersion); blockArchiveRebuilder.start(); return "true"; diff --git a/src/main/java/org/qortal/repository/BlockArchiveReader.java b/src/main/java/org/qortal/repository/BlockArchiveReader.java index e45f1fdf..1f04bced 100644 --- a/src/main/java/org/qortal/repository/BlockArchiveReader.java +++ b/src/main/java/org/qortal/repository/BlockArchiveReader.java @@ -64,6 +64,19 @@ public class BlockArchiveReader { this.fileListCache = Map.copyOf(map); } + public Integer fetchSerializationVersionForHeight(int height) { + if (this.fileListCache == null) { + this.fetchFileList(); + } + + Triple serializedBlock = this.fetchSerializedBlockBytesForHeight(height); + if (serializedBlock == null) { + return null; + } + Integer serializationVersion = serializedBlock.getB(); + return serializationVersion; + } + public BlockTransformation fetchBlockAtHeight(int height) { if (this.fileListCache == null) { this.fetchFileList(); diff --git a/src/main/java/org/qortal/repository/BlockArchiveWriter.java b/src/main/java/org/qortal/repository/BlockArchiveWriter.java index 87d0a93c..8f4d4498 100644 --- a/src/main/java/org/qortal/repository/BlockArchiveWriter.java +++ b/src/main/java/org/qortal/repository/BlockArchiveWriter.java @@ -43,7 +43,7 @@ public class BlockArchiveWriter { private int startHeight; private final int endHeight; - private final int serializationVersion; + private final Integer serializationVersion; private final Path archivePath; private final Repository repository; @@ -65,12 +65,17 @@ public class BlockArchiveWriter { * @param endHeight * @param repository */ - public BlockArchiveWriter(int startHeight, int endHeight, int serializationVersion, Path archivePath, Repository repository) { + public BlockArchiveWriter(int startHeight, int endHeight, Integer serializationVersion, Path archivePath, Repository repository) { this.startHeight = startHeight; this.endHeight = endHeight; - this.serializationVersion = serializationVersion; this.archivePath = archivePath.toAbsolutePath(); this.repository = repository; + + if (serializationVersion == null) { + // When serialization version isn't specified, fetch it from the existing archive + serializationVersion = this.findSerializationVersion(); + } + this.serializationVersion = serializationVersion; } /** @@ -80,7 +85,18 @@ public class BlockArchiveWriter { * @param repository */ public BlockArchiveWriter(int startHeight, int endHeight, Repository repository) { - this(startHeight, endHeight, Settings.getInstance().getArchiveVersion(), Paths.get(Settings.getInstance().getRepositoryPath(), "archive"), repository); + this(startHeight, endHeight, null, Paths.get(Settings.getInstance().getRepositoryPath(), "archive"), repository); + } + + private int findSerializationVersion() { + // Attempt to fetch the serialization version from the existing archive + Integer block2SerializationVersion = BlockArchiveReader.getInstance().fetchSerializationVersionForHeight(2); + if (block2SerializationVersion != null) { + return block2SerializationVersion; + } + + // Default to version specified in settings + return Settings.getInstance().getDefaultArchiveVersion(); } public static int getMaxArchiveHeight(Repository repository) throws DataException { diff --git a/src/main/java/org/qortal/settings/Settings.java b/src/main/java/org/qortal/settings/Settings.java index 52b3aed5..d3405d4e 100644 --- a/src/main/java/org/qortal/settings/Settings.java +++ b/src/main/java/org/qortal/settings/Settings.java @@ -179,7 +179,7 @@ public class Settings { /** How often to attempt archiving (ms). */ private long archiveInterval = 7171L; // milliseconds /** Serialization version to use when building an archive */ - private int archiveVersion = 1; + private int defaultArchiveVersion = 1; /** Whether to automatically bootstrap instead of syncing from genesis */ @@ -928,8 +928,8 @@ public class Settings { return this.archiveInterval; } - public int getArchiveVersion() { - return this.archiveVersion; + public int getDefaultArchiveVersion() { + return this.defaultArchiveVersion; }