diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataBuilder.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataBuilder.java index f8c95596..4db89688 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataBuilder.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataBuilder.java @@ -10,6 +10,7 @@ import org.qortal.repository.Repository; import org.qortal.repository.RepositoryManager; import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType; import org.qortal.utils.Base58; +import org.qortal.utils.NTP; import java.io.IOException; import java.nio.file.Files; @@ -44,6 +45,7 @@ public class ArbitraryDataBuilder { this.validatePaths(); this.findLatestSignature(); this.buildLatestState(); + this.cacheLatestSignature(); } private void fetchTransactions() throws DataException { @@ -163,6 +165,18 @@ public class ArbitraryDataBuilder { this.finalPath = pathBefore; } + private void cacheLatestSignature() throws IOException { + byte[] latestTransactionSignature = this.transactions.get(this.transactions.size()-1).getSignature(); + if (latestTransactionSignature == null) { + throw new IllegalStateException("Missing latest transaction signature"); + } + + ArbitraryDataMetadataCache cache = new ArbitraryDataMetadataCache(this.finalPath); + cache.setSignature(latestTransactionSignature); + cache.setTimestamp(NTP.getTime()); + cache.write(); + } + public Path getFinalPath() { return this.finalPath; } diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataCombiner.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataCombiner.java index 3d3fbe9f..bf49ae99 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataCombiner.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataCombiner.java @@ -87,7 +87,7 @@ public class ArbitraryDataCombiner { throw new IllegalStateException("No previous signature passed to the combiner"); } - ArbitraryDataMetadata metadata = new ArbitraryDataMetadata(this.pathAfter); + ArbitraryDataMetadataPatch metadata = new ArbitraryDataMetadataPatch(this.pathAfter); metadata.read(); byte[] previousSignature = metadata.getPreviousSignature(); if (previousSignature == null) { diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataDiff.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataDiff.java index 06976e72..84280738 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataDiff.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataDiff.java @@ -214,7 +214,7 @@ public class ArbitraryDataDiff { } private void writeMetadata() throws IOException { - ArbitraryDataMetadata metadata = new ArbitraryDataMetadata(this.diffPath); + ArbitraryDataMetadataPatch metadata = new ArbitraryDataMetadataPatch(this.diffPath); metadata.setAddedPaths(this.addedPaths); metadata.setModifiedPaths(this.modifiedPaths); metadata.setRemovedPaths(this.removedPaths); diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataMerge.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataMerge.java index 88b910f7..79fc5eaa 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataMerge.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataMerge.java @@ -20,7 +20,7 @@ public class ArbitraryDataMerge { private Path pathAfter; private Path mergePath; private String identifier; - private ArbitraryDataMetadata metadata; + private ArbitraryDataMetadataPatch metadata; public ArbitraryDataMerge(Path pathBefore, Path pathAfter) { this.pathBefore = pathBefore; @@ -70,7 +70,7 @@ public class ArbitraryDataMerge { } private void loadMetadata() throws IOException { - this.metadata = new ArbitraryDataMetadata(this.pathAfter); + this.metadata = new ArbitraryDataMetadataPatch(this.pathAfter); this.metadata.read(); } diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataMetadata.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataMetadata.java index 7de9cab2..5cf04b5d 100644 --- a/src/main/java/org/qortal/arbitrary/ArbitraryDataMetadata.java +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataMetadata.java @@ -13,31 +13,35 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; public class ArbitraryDataMetadata { - private static final Logger LOGGER = LogManager.getLogger(ArbitraryDataMetadata.class); + protected static final Logger LOGGER = LogManager.getLogger(ArbitraryDataMetadata.class); - private List addedPaths; - private List modifiedPaths; - private List removedPaths; - private Path filePath; - private Path qortalDirectoryPath; - private byte[] previousSignature; + protected Path filePath; + protected Path qortalDirectoryPath; - private String jsonString; + protected String jsonString; public ArbitraryDataMetadata(Path filePath) { this.filePath = filePath; this.qortalDirectoryPath = Paths.get(filePath.toString(), ".qortal"); - - this.addedPaths = new ArrayList<>(); - this.modifiedPaths = new ArrayList<>(); - this.removedPaths = new ArrayList<>(); } + protected String fileName() { + // To be overridden + return null; + } + + protected void readJson() { + // To be overridden + } + + protected void buildJson() { + // To be overridden + } + + public void read() throws IOException { this.loadJson(); this.readJson(); @@ -50,8 +54,8 @@ public class ArbitraryDataMetadata { } - private void loadJson() throws IOException { - Path path = Paths.get(this.qortalDirectoryPath.toString(), "patch"); + protected void loadJson() throws IOException { + Path path = Paths.get(this.qortalDirectoryPath.toString(), this.fileName()); File patchFile = new File(path.toString()); if (!patchFile.exists()) { throw new IOException(String.format("Patch file doesn't exist: %s", path.toString())); @@ -60,65 +64,7 @@ public class ArbitraryDataMetadata { this.jsonString = new String(Files.readAllBytes(path)); } - private void readJson() { - if (this.jsonString == null) { - throw new IllegalStateException("Patch JSON string is null"); - } - - JSONObject patch = new JSONObject(this.jsonString); - if (patch.has("prevSig")) { - String prevSig = (String)patch.get("prevSig"); - if (prevSig != null) { - this.previousSignature = Base58.decode(prevSig); - } - } - if (patch.has("added")) { - JSONArray added = (JSONArray) patch.get("added"); - if (added != null) { - for (int i=0; i addedPaths) { - this.addedPaths = addedPaths; - } - - public List getAddedPaths() { - return this.addedPaths; - } - - public void setModifiedPaths(List modifiedPaths) { - this.modifiedPaths = modifiedPaths; - } - - public List getModifiedPaths() { - return this.modifiedPaths; - } - - public void setRemovedPaths(List removedPaths) { - this.removedPaths = removedPaths; - } - - public List getRemovedPaths() { - return this.removedPaths; - } - - public void setPreviousSignature(byte[] previousSignature) { - this.previousSignature = previousSignature; - } - - public byte[] getPreviousSignature() { - return this.previousSignature; - } - public String getJsonString() { return this.jsonString; } diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataMetadataCache.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataMetadataCache.java new file mode 100644 index 00000000..cfe56593 --- /dev/null +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataMetadataCache.java @@ -0,0 +1,69 @@ +package org.qortal.arbitrary; + +import org.json.JSONObject; +import org.qortal.utils.Base58; +import org.qortal.utils.NTP; + +import java.nio.file.Path; + +public class ArbitraryDataMetadataCache extends ArbitraryDataMetadata { + + private byte[] signature; + private long timestamp; + + public ArbitraryDataMetadataCache(Path filePath) { + super(filePath); + + } + + @Override + protected String fileName() { + return "cache"; + } + + @Override + protected void readJson() { + if (this.jsonString == null) { + throw new IllegalStateException("Patch JSON string is null"); + } + + JSONObject cache = new JSONObject(this.jsonString); + if (cache.has("signature")) { + String sig = cache.getString("signature"); + if (sig != null) { + this.signature = Base58.decode(sig); + } + } + if (cache.has("timestamp")) { + this.timestamp = cache.getLong("timestamp"); + } + } + + @Override + protected void buildJson() { + JSONObject patch = new JSONObject(); + patch.put("signature", Base58.encode(this.signature)); + patch.put("timestamp", this.timestamp); + + this.jsonString = patch.toString(2); + LOGGER.info("Cache metadata: {}", this.jsonString); + } + + + public void setSignature(byte[] signature) { + this.signature = signature; + } + + public byte[] getSignature() { + return this.signature; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public long getTimestamp() { + return this.timestamp; + } + +} diff --git a/src/main/java/org/qortal/arbitrary/ArbitraryDataMetadataPatch.java b/src/main/java/org/qortal/arbitrary/ArbitraryDataMetadataPatch.java new file mode 100644 index 00000000..2c1f4a7c --- /dev/null +++ b/src/main/java/org/qortal/arbitrary/ArbitraryDataMetadataPatch.java @@ -0,0 +1,119 @@ +package org.qortal.arbitrary; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.qortal.utils.Base58; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +public class ArbitraryDataMetadataPatch extends ArbitraryDataMetadata { + + private List addedPaths; + private List modifiedPaths; + private List removedPaths; + private byte[] previousSignature; + + public ArbitraryDataMetadataPatch(Path filePath) { + super(filePath); + + this.addedPaths = new ArrayList<>(); + this.modifiedPaths = new ArrayList<>(); + this.removedPaths = new ArrayList<>(); + } + + @Override + protected String fileName() { + return "patch"; + } + + @Override + protected void readJson() { + if (this.jsonString == null) { + throw new IllegalStateException("Patch JSON string is null"); + } + + JSONObject patch = new JSONObject(this.jsonString); + if (patch.has("prevSig")) { + String prevSig = patch.getString("prevSig"); + if (prevSig != null) { + this.previousSignature = Base58.decode(prevSig); + } + } + if (patch.has("added")) { + JSONArray added = (JSONArray) patch.get("added"); + if (added != null) { + for (int i=0; i addedPaths) { + this.addedPaths = addedPaths; + } + + public List getAddedPaths() { + return this.addedPaths; + } + + public void setModifiedPaths(List modifiedPaths) { + this.modifiedPaths = modifiedPaths; + } + + public List getModifiedPaths() { + return this.modifiedPaths; + } + + public void setRemovedPaths(List removedPaths) { + this.removedPaths = removedPaths; + } + + public List getRemovedPaths() { + return this.removedPaths; + } + + public void setPreviousSignature(byte[] previousSignature) { + this.previousSignature = previousSignature; + } + + public byte[] getPreviousSignature() { + return this.previousSignature; + } + +}