Added "validateAllDataLayers" setting (default false)

When true, the hashes of every layer are validated when building a data resource. When false, only the final layer's hash is validated.
This commit is contained in:
CalDescent 2021-10-24 14:37:29 +01:00
parent a418fb18b6
commit 52a94e3256
4 changed files with 36 additions and 0 deletions

View File

@ -10,6 +10,7 @@ import org.qortal.repository.DataException;
import org.qortal.repository.Repository;
import org.qortal.repository.RepositoryManager;
import org.qortal.arbitrary.ArbitraryDataFile.ResourceIdType;
import org.qortal.settings.Settings;
import org.qortal.utils.Base58;
import org.qortal.utils.NTP;
@ -153,13 +154,23 @@ public class ArbitraryDataBuilder {
}
Path pathBefore = this.paths.get(0);
boolean validateAllLayers = Settings.getInstance().shouldValidateAllDataLayers();
// Loop from the second path onwards
for (int i=1; i<paths.size(); i++) {
LOGGER.info(String.format("[%s][%s] Applying layer %d...", this.service, this.name, i));
// Create an instance of ArbitraryDataCombiner
Path pathAfter = this.paths.get(i);
byte[] signatureBefore = this.transactions.get(i-1).getSignature();
ArbitraryDataCombiner combiner = new ArbitraryDataCombiner(pathBefore, pathAfter, signatureBefore);
// We only want to validate this layer's hash if it's the final layer, or if the settings
// indicate that we should validate interim layers too
boolean isFinalLayer = (i == paths.size() - 1);
combiner.setShouldValidateHashes(isFinalLayer || validateAllLayers);
// Now combine this layer with the last, and set the output path to the "before" path for the next cycle
combiner.combine();
combiner.cleanup();
pathBefore = combiner.getFinalPath();

View File

@ -23,6 +23,7 @@ public class ArbitraryDataCombiner {
private Path pathBefore;
private Path pathAfter;
private byte[] signatureBefore;
private boolean shouldValidateHashes;
private Path finalPath;
private ArbitraryDataMetadataPatch metadata;
@ -112,6 +113,10 @@ public class ArbitraryDataCombiner {
}
private void validatePreviousHash() throws IOException {
if (!this.shouldValidateHashes) {
return;
}
byte[] previousHash = this.metadata.getPreviousHash();
if (previousHash == null) {
throw new IllegalStateException("Unable to extract previous hash from patch metadata");
@ -134,6 +139,10 @@ public class ArbitraryDataCombiner {
}
private void validateCurrentHash() throws IOException {
if (!this.shouldValidateHashes) {
return;
}
byte[] currentHash = this.metadata.getCurrentHash();
if (currentHash == null) {
throw new IllegalStateException("Unable to extract current hash from patch metadata");
@ -147,6 +156,10 @@ public class ArbitraryDataCombiner {
throw new InvalidObjectException(String.format("Current state hash mismatch. " +
"Patch curHash: %s, actual: %s", currentHash58, digest.getHash58()));
}
}
public void setShouldValidateHashes(boolean shouldValidateHashes) {
this.shouldValidateHashes = shouldValidateHashes;
}
public Path getFinalPath() {

View File

@ -263,6 +263,9 @@ public class Settings {
/** Data storage path (for temporary data). */
private String tempDataPath = "data/_temp";
/** Whether to validate every layer when building arbitrary data, or just the final layer */
private boolean validateAllDataLayers = false;
// Domain mapping
public static class DomainMap {
@ -761,4 +764,8 @@ public class Settings {
public String getTempDataPath() {
return this.tempDataPath;
}
public boolean shouldValidateAllDataLayers() {
return this.validateAllDataLayers;
}
}

View File

@ -95,6 +95,7 @@ public class ArbitraryDataMergeTests extends Common {
// Now merge the patch with the original path
ArbitraryDataCombiner combiner = new ArbitraryDataCombiner(path1, patchPath, signature);
combiner.setShouldValidateHashes(true);
combiner.combine();
Path finalPath = combiner.getFinalPath();
@ -214,6 +215,7 @@ public class ArbitraryDataMergeTests extends Common {
// Now merge the patch with the original path
ArbitraryDataCombiner combiner = new ArbitraryDataCombiner(tempDir1, patchPath, signature);
combiner.setShouldValidateHashes(true);
combiner.combine();
Path finalPath = combiner.getFinalPath();
@ -281,6 +283,7 @@ public class ArbitraryDataMergeTests extends Common {
// Now merge the patch with the original path
ArbitraryDataCombiner combiner = new ArbitraryDataCombiner(tempDir1, patchPath, signature);
combiner.setShouldValidateHashes(true);
combiner.combine();
Path finalPath = combiner.getFinalPath();
@ -354,6 +357,7 @@ public class ArbitraryDataMergeTests extends Common {
// Now merge the patch with the original path
ArbitraryDataCombiner combiner = new ArbitraryDataCombiner(tempDir1, patchPath, signature);
combiner.setShouldValidateHashes(true);
combiner.combine();
Path finalPath = combiner.getFinalPath();
@ -425,6 +429,7 @@ public class ArbitraryDataMergeTests extends Common {
// Now merge the patch with the original path
ArbitraryDataCombiner combiner = new ArbitraryDataCombiner(tempDir1, patchPath, signature);
combiner.setShouldValidateHashes(true);
combiner.combine();
Path finalPath = combiner.getFinalPath();