package org.ripple.power.txns.btc;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
import org.ripple.power.Helper;
import org.ripple.power.config.LSystem;
public class CreateBootstrap {
/**
* Create the bootstrap files
*
* @param dirPath Bootstrap directory
* @param startHeight Start chain height
* @param stopHeight Stop chain height
*/
public static void process(String dirPath, int startHeight, int stopHeight) {
//
// Make sure the bootstrap directory exists
//
File dirFile = new File(dirPath);
if (!dirFile.exists() || !dirFile.isDirectory()) {
BTCLoader.error(String.format("'%s' is not a directory", dirPath));
return;
}
BTCLoader.info(String.format("Creating bootstrap files in %s", dirPath));
//
// Create the 'blocks' subdirectory if it does not exist
//
dirFile = new File(String.format("%s%sblocks", dirPath, LSystem.FS));
if (!dirFile.exists())
dirFile.mkdir();
//
// Erase existing bootstrap files
//
File fileList[] = dirFile.listFiles();
if (fileList != null && fileList.length > 0) {
for (File file : fileList) {
String fileName = file.getName();
if (fileName.startsWith("blk") && fileName.endsWith(".gz"))
file.delete();
}
}
//
// Process the block chain
//
String fileName = "";
int fileNumber = -1;
int byteCount = 0;
int start = Math.max(startHeight, 0);
int stop = Math.min(stopHeight, BTCLoader.blockStore.getChainHeight());
File file = null;
GZIPOutputStream zipOut = null;
byte[] prefix = new byte[8];
try {
for (int height=start; height<=stop; height++) {
//
// Close the current bootstrap file after processing 1GB
//
if (byteCount > 1024*1024*1024) {
zipOut.close();
zipOut = null;
}
//
// Open the next bootstrap file
//
if (zipOut == null) {
fileName = String.format("blk%05d.dat.gz", ++fileNumber);
byteCount = 0;
file = new File(String.format("%s%sblocks%s%s",
dirPath, LSystem.FS, LSystem.FS, fileName));
zipOut = new GZIPOutputStream(new FileOutputStream(file), 1024*1024);
BTCLoader.info(String.format("Creating bootstrap file %s", fileName));
}
//
// Write the block to the bootstrap file
//
Block block = BTCLoader.blockStore.getBlock(BTCLoader.blockStore.getBlockId(height));
byte[] blockBytes = block.getBytes();
Helper.uint32ToByteArrayLE(NetParams.MAGIC_NUMBER, prefix, 0);
Helper.uint32ToByteArrayLE(blockBytes.length, prefix, 4);
zipOut.write(prefix);
zipOut.write(blockBytes);
byteCount += blockBytes.length;
}
} catch (IOException exc) {
BTCLoader.error(String.format("I/O error creating bootstrap file %s", fileName), exc);
} catch (BlockStoreException exc) {
BTCLoader.error("Unable to get block from database", exc);
} catch (Exception exc) {
BTCLoader.error("Exception while creating bootstrap files", exc);
} finally {
if (file != null && zipOut != null) {
try {
zipOut.close();
if (file.length() == 0)
file.delete();
} catch (IOException exc) {
BTCLoader.error(String.format("Unable to close bootstrap file %s", fileName), exc);
}
}
}
}
}