mirror of https://github.com/qortal/qortal
Browse Source
This allows archived blocks to be imported back into HSQLDB in order to make them SQL-compatible again.block-archive
CalDescent
3 years ago
4 changed files with 120 additions and 0 deletions
@ -0,0 +1,78 @@
|
||||
package org.qortal.utils; |
||||
|
||||
import org.qortal.data.at.ATStateData; |
||||
import org.qortal.data.block.BlockData; |
||||
import org.qortal.data.transaction.TransactionData; |
||||
import org.qortal.repository.BlockArchiveReader; |
||||
import org.qortal.repository.DataException; |
||||
import org.qortal.repository.Repository; |
||||
|
||||
import java.util.List; |
||||
|
||||
public class BlockArchiveUtils { |
||||
|
||||
/** |
||||
* importFromArchive |
||||
* <p> |
||||
* Reads the requested block range from the archive |
||||
* and imports the BlockData and AT state data hashes |
||||
* This can be used to convert a block archive back |
||||
* into the HSQLDB, in order to make it SQL-compatible |
||||
* again. |
||||
* <p> |
||||
* Note: calls discardChanges() and saveChanges(), so |
||||
* make sure that you commit any existing repository |
||||
* changes before calling this method. |
||||
* |
||||
* @param startHeight The earliest block to import
|
||||
* @param endHeight The latest block to import
|
||||
* @param repository A clean repository session |
||||
* @throws DataException |
||||
*/ |
||||
public static void importFromArchive(int startHeight, int endHeight, Repository repository) throws DataException { |
||||
repository.discardChanges(); |
||||
final int requestedRange = endHeight+1-startHeight; |
||||
|
||||
List<Triple<BlockData, List<TransactionData>, List<ATStateData>>> blockInfoList = |
||||
BlockArchiveReader.getInstance().fetchBlocksFromRange(startHeight, endHeight); |
||||
|
||||
// Ensure that we have received all of the requested blocks
|
||||
if (blockInfoList == null || blockInfoList.isEmpty()) { |
||||
throw new IllegalStateException("No blocks found when importing from archive"); |
||||
} |
||||
if (blockInfoList.size() != requestedRange) { |
||||
throw new IllegalStateException("Non matching block count when importing from archive"); |
||||
} |
||||
Triple<BlockData, List<TransactionData>, List<ATStateData>> firstBlock = blockInfoList.get(0); |
||||
if (firstBlock == null || firstBlock.getA().getHeight() != startHeight) { |
||||
throw new IllegalStateException("Non matching first block when importing from archive"); |
||||
} |
||||
if (blockInfoList.size() > 0) { |
||||
Triple<BlockData, List<TransactionData>, List<ATStateData>> lastBlock = |
||||
blockInfoList.get(blockInfoList.size() - 1); |
||||
if (lastBlock == null || lastBlock.getA().getHeight() != endHeight) { |
||||
throw new IllegalStateException("Non matching last block when importing from archive"); |
||||
} |
||||
} |
||||
|
||||
// Everything seems okay, so go ahead with the import
|
||||
for (Triple<BlockData, List<TransactionData>, List<ATStateData>> blockInfo : blockInfoList) { |
||||
try { |
||||
// Save block
|
||||
repository.getBlockRepository().save(blockInfo.getA()); |
||||
|
||||
// Save AT state data hashes
|
||||
for (ATStateData atStateData : blockInfo.getC()) { |
||||
atStateData.setHeight(blockInfo.getA().getHeight()); |
||||
repository.getATRepository().save(atStateData); |
||||
} |
||||
|
||||
} catch (DataException e) { |
||||
repository.discardChanges(); |
||||
throw new IllegalStateException("Unable to import blocks from archive"); |
||||
} |
||||
} |
||||
repository.saveChanges(); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue