DataFile updates to simplify integration with arbitrary transactions.

This commit is contained in:
CalDescent 2021-07-03 17:41:52 +01:00
parent 5f4649ee2b
commit 56da7deb4c
2 changed files with 57 additions and 0 deletions

View File

@ -4,9 +4,11 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.qortal.crypto.Crypto;
import org.qortal.settings.Settings;
import org.qortal.transform.transaction.TransactionTransformer;
import org.qortal.utils.Base58;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@ -173,6 +175,21 @@ public class DataFile {
this.chunks.add(chunk);
}
public void addChunkHashes(byte[] chunks) {
ByteBuffer byteBuffer = ByteBuffer.wrap(chunks);
while (byteBuffer.remaining() > 0) {
byte[] chunkData = new byte[TransactionTransformer.SHA256_LENGTH];
byteBuffer.get(chunkData);
if (chunkData.length == TransactionTransformer.SHA256_LENGTH) {
DataFileChunk chunk = new DataFileChunk(chunkData);
this.addChunk(chunk);
}
else {
throw new IllegalStateException(String.format("Invalid chunk hash length: %d", chunkData.length));
}
}
}
public int split(int chunkSize) {
try {
@ -252,7 +269,14 @@ public class DataFile {
public boolean delete() {
// Delete the complete file
// ... but only if it's inside the Qortal data directory
Path path = Paths.get(this.filePath);
String dataPath = Settings.getInstance().getDataPath();
Path dataDirectory = Paths.get(dataPath);
if (!path.toAbsolutePath().startsWith(dataDirectory)) {
return false;
}
if (Files.exists(path)) {
try {
Files.delete(path);
@ -330,6 +354,34 @@ public class DataFile {
return file.exists();
}
public boolean chunkExists(byte[] digest) {
for (DataFileChunk chunk : this.chunks) {
if (digest.equals(chunk.digest())) { // TODO: this is too heavy on the filesystem. We need a cache
return chunk.exists();
}
}
File file = new File(this.filePath);
return file.exists();
}
public boolean allChunksExist(byte[] chunks) {
ByteBuffer byteBuffer = ByteBuffer.wrap(chunks);
while (byteBuffer.remaining() > 0) {
byte[] chunkDigest = new byte[TransactionTransformer.SHA256_LENGTH];
byteBuffer.get(chunkDigest);
if (chunkDigest.length == TransactionTransformer.SHA256_LENGTH) {
DataFileChunk chunk = DataFileChunk.fromDigest(chunkDigest);
if (chunk.exists() == false) {
return false;
}
}
else {
throw new IllegalStateException(String.format("Invalid chunk hash length: %d", chunkDigest.length));
}
}
return true;
}
public long size() {
Path path = Paths.get(this.filePath);
try {

View File

@ -2,6 +2,7 @@ package org.qortal.storage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.qortal.utils.Base58;
import java.io.File;
import java.io.IOException;
@ -34,6 +35,10 @@ public class DataFileChunk extends DataFile {
return new DataFileChunk(filePath);
}
public static DataFileChunk fromDigest(byte[] digest) {
return DataFileChunk.fromBase58Digest(Base58.encode(digest));
}
@Override
public ValidationResult isValid() {
// DataChunk validation applies here too