Added "cache" file to the .qortal metadata folder.

This is used to store the transaction signature and build timestamp for each built data resource. It involved a refactor of the ArbitraryDataMetadata class to introduce a subclass for each file ("patch" and "cache"). This allows more files to be easily added later.
This commit is contained in:
CalDescent 2021-08-15 21:49:45 +01:00
parent 94da1a30dc
commit c7d88ed95b
7 changed files with 229 additions and 113 deletions

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);

View File

@ -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();
}

View File

@ -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<Path> addedPaths;
private List<Path> modifiedPaths;
private List<Path> 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<added.length(); i++) {
String pathString = (String)added.get(i);
this.addedPaths.add(Paths.get(pathString));
}
}
}
if (patch.has("modified")) {
JSONArray modified = (JSONArray) patch.get("modified");
if (modified != null) {
for (int i=0; i<modified.length(); i++) {
String pathString = (String)modified.get(i);
this.modifiedPaths.add(Paths.get(pathString));
}
}
}
if (patch.has("removed")) {
JSONArray removed = (JSONArray) patch.get("removed");
if (removed != null) {
for (int i=0; i<removed.length(); i++) {
String pathString = (String)removed.get(i);
this.removedPaths.add(Paths.get(pathString));
}
}
}
}
private void buildJson() {
JSONArray addedPathsJson = new JSONArray(this.addedPaths);
JSONArray modifiedPathsJson = new JSONArray(this.modifiedPaths);
JSONArray removedPathsJson = new JSONArray(this.removedPaths);
String previousSignature58 = Base58.encode(this.previousSignature);
JSONObject patch = new JSONObject();
patch.put("prevSig", previousSignature58);
patch.put("added", addedPathsJson);
patch.put("modified", modifiedPathsJson);
patch.put("removed", removedPathsJson);
this.jsonString = patch.toString(2);
}
private void createQortalDirectory() {
protected void createQortalDirectory() {
try {
Files.createDirectories(this.qortalDirectoryPath);
} catch (IOException e) {
@ -126,46 +72,14 @@ public class ArbitraryDataMetadata {
}
}
private void writeToQortalPath() throws IOException {
Path patchPath = Paths.get(this.qortalDirectoryPath.toString(), "patch");
protected void writeToQortalPath() throws IOException {
Path patchPath = Paths.get(this.qortalDirectoryPath.toString(), this.fileName());
BufferedWriter writer = new BufferedWriter(new FileWriter(patchPath.toString()));
writer.write(this.jsonString);
writer.close();
}
public void setAddedPaths(List<Path> addedPaths) {
this.addedPaths = addedPaths;
}
public List<Path> getAddedPaths() {
return this.addedPaths;
}
public void setModifiedPaths(List<Path> modifiedPaths) {
this.modifiedPaths = modifiedPaths;
}
public List<Path> getModifiedPaths() {
return this.modifiedPaths;
}
public void setRemovedPaths(List<Path> removedPaths) {
this.removedPaths = removedPaths;
}
public List<Path> getRemovedPaths() {
return this.removedPaths;
}
public void setPreviousSignature(byte[] previousSignature) {
this.previousSignature = previousSignature;
}
public byte[] getPreviousSignature() {
return this.previousSignature;
}
public String getJsonString() {
return this.jsonString;
}

View File

@ -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;
}
}

View File

@ -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<Path> addedPaths;
private List<Path> modifiedPaths;
private List<Path> 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<added.length(); i++) {
String pathString = added.getString(i);
this.addedPaths.add(Paths.get(pathString));
}
}
}
if (patch.has("modified")) {
JSONArray modified = (JSONArray) patch.get("modified");
if (modified != null) {
for (int i=0; i<modified.length(); i++) {
String pathString = modified.getString(i);
this.modifiedPaths.add(Paths.get(pathString));
}
}
}
if (patch.has("removed")) {
JSONArray removed = (JSONArray) patch.get("removed");
if (removed != null) {
for (int i=0; i<removed.length(); i++) {
String pathString = removed.getString(i);
this.removedPaths.add(Paths.get(pathString));
}
}
}
}
@Override
protected void buildJson() {
JSONObject patch = new JSONObject();
patch.put("prevSig", Base58.encode(this.previousSignature));
patch.put("added", new JSONArray(this.addedPaths));
patch.put("modified", new JSONArray(this.modifiedPaths));
patch.put("removed", new JSONArray(this.removedPaths));
this.jsonString = patch.toString(2);
LOGGER.info("Patch metadata: {}", this.jsonString);
}
public void setAddedPaths(List<Path> addedPaths) {
this.addedPaths = addedPaths;
}
public List<Path> getAddedPaths() {
return this.addedPaths;
}
public void setModifiedPaths(List<Path> modifiedPaths) {
this.modifiedPaths = modifiedPaths;
}
public List<Path> getModifiedPaths() {
return this.modifiedPaths;
}
public void setRemovedPaths(List<Path> removedPaths) {
this.removedPaths = removedPaths;
}
public List<Path> getRemovedPaths() {
return this.removedPaths;
}
public void setPreviousSignature(byte[] previousSignature) {
this.previousSignature = previousSignature;
}
public byte[] getPreviousSignature() {
return this.previousSignature;
}
}