forked from Qortal/qortal
Added Blockchain.validateAllBlocks() to check every block back to genesis.
This is extremely slow and shouldn't be needed in normal use cases. It currently checks that each block references the one before, but can ultimately be expanded to check more information about each block and its derived data.
This commit is contained in:
parent
e2a62f88a6
commit
de8e96cd75
@ -556,6 +556,46 @@ public class BlockChain {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* More thorough blockchain validation method. Useful for validating bootstraps.
|
||||
* A DataException is thrown if anything is invalid.
|
||||
*
|
||||
* @throws DataException
|
||||
*/
|
||||
public static void validateAllBlocks() throws DataException {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
BlockData chainTip = repository.getBlockRepository().getLastBlock();
|
||||
final int chainTipHeight = chainTip.getHeight();
|
||||
final int oldestBlock = 1; // TODO: increase if in pruning mode
|
||||
byte[] lastReference = null;
|
||||
|
||||
for (int height = chainTipHeight; height > oldestBlock; height--) {
|
||||
BlockData blockData = repository.getBlockRepository().fromHeight(height);
|
||||
if (blockData == null) {
|
||||
blockData = repository.getBlockArchiveRepository().fromHeight(height);
|
||||
}
|
||||
|
||||
if (blockData == null) {
|
||||
String error = String.format("Missing block at height %d", height);
|
||||
LOGGER.error(error);
|
||||
throw new DataException(error);
|
||||
}
|
||||
|
||||
if (height != chainTipHeight) {
|
||||
// Check reference
|
||||
if (!Arrays.equals(blockData.getSignature(), lastReference)) {
|
||||
String error = String.format("Invalid reference for block at height %d: %s (should be %s)",
|
||||
height, Base58.encode(blockData.getReference()), Base58.encode(lastReference));
|
||||
LOGGER.error(error);
|
||||
throw new DataException(error);
|
||||
}
|
||||
}
|
||||
|
||||
lastReference = blockData.getReference();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isGenesisBlockValid() {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
BlockRepository blockRepository = repository.getBlockRepository();
|
||||
|
Loading…
x
Reference in New Issue
Block a user