Browse Source

Rework of Blockchain.validate() to account for pruning mode.

block-archive
CalDescent 3 years ago
parent
commit
925e10b19b
  1. 49
      src/main/java/org/qortal/block/BlockChain.java

49
src/main/java/org/qortal/block/BlockChain.java

@ -506,28 +506,51 @@ public class BlockChain {
* @throws SQLException * @throws SQLException
*/ */
public static void validate() throws DataException { public static void validate() throws DataException {
// Check first block is Genesis Block
if (!isGenesisBlockValid())
rebuildBlockchain();
try (final Repository repository = RepositoryManager.getRepository()) { try (final Repository repository = RepositoryManager.getRepository()) {
boolean pruningEnabled = Settings.getInstance().isPruningEnabled();
BlockData chainTip = repository.getBlockRepository().getLastBlock();
boolean hasBlocks = (chainTip != null && chainTip.getHeight() > 1);
if (pruningEnabled && hasBlocks) {
// Pruning is enabled and we have blocks, so it's possible that the genesis block has been pruned
// It's best not to validate it, and there's no real need to
}
else {
// Check first block is Genesis Block
if (!isGenesisBlockValid()) {
rebuildBlockchain();
}
}
repository.checkConsistency(); repository.checkConsistency();
int startHeight = Math.max(repository.getBlockRepository().getBlockchainHeight() - 1440, 1); // Set the number of blocks to validate based on the pruned state of the chain
// If pruned, subtract an extra 10 to allow room for error
int blocksToValidate = pruningEnabled ? Settings.getInstance().getPruneBlockLimit() - 10 : 1440;
int startHeight = Math.max(repository.getBlockRepository().getBlockchainHeight() - blocksToValidate, 1);
BlockData detachedBlockData = repository.getBlockRepository().getDetachedBlockSignature(startHeight); BlockData detachedBlockData = repository.getBlockRepository().getDetachedBlockSignature(startHeight);
if (detachedBlockData != null) { if (detachedBlockData != null) {
LOGGER.error(String.format("Block %d's reference does not match any block's signature", detachedBlockData.getHeight())); LOGGER.error(String.format("Block %d's reference does not match any block's signature", detachedBlockData.getHeight()));
// Wait for blockchain lock (whereas orphan() only tries to get lock) // Orphan if we aren't a pruning node
ReentrantLock blockchainLock = Controller.getInstance().getBlockchainLock(); if (!Settings.getInstance().isPruningEnabled()) {
blockchainLock.lock();
try { // Wait for blockchain lock (whereas orphan() only tries to get lock)
LOGGER.info(String.format("Orphaning back to block %d", detachedBlockData.getHeight() - 1)); ReentrantLock blockchainLock = Controller.getInstance().getBlockchainLock();
orphan(detachedBlockData.getHeight() - 1); blockchainLock.lock();
} finally { try {
blockchainLock.unlock(); LOGGER.info(String.format("Orphaning back to block %d", detachedBlockData.getHeight() - 1));
orphan(detachedBlockData.getHeight() - 1);
} finally {
blockchainLock.unlock();
}
}
else {
LOGGER.error(String.format("Not orphaning because we are in pruning mode. You may be on an " +
"invalid chain and should consider bootstrapping or re-syncing from genesis."));
} }
} }
} }

Loading…
Cancel
Save