package jelectrum; import org.apache.commons.codec.binary.Hex; import java.io.ByteArrayOutputStream; import org.bitcoinj.core.StoredBlock; import org.bitcoinj.core.Sha256Hash; public class HeaderChunkAgent extends Thread { private Jelectrum jelly; private volatile int height; private int last_saved_height; public HeaderChunkAgent(Jelectrum jelly) { this.jelly = jelly; setName("HeaderChunkAgent"); setDaemon(true); } public String getChunk(int index) { return jelly.getDB().getHeaderChunkMap().get(index); } public void poke(int new_height) { height = new_height; synchronized(this) { this.notifyAll(); } } public void run() { boolean first=true; while(true) { try { if (first) { height = jelly.getBlockStore().getChainHead().getHeight(); first=false; } doPass(); } catch(Throwable t) { t.printStackTrace(); } try { synchronized(this) { this.wait(); } } catch(java.lang.InterruptedException e) { e.printStackTrace(); } } } private void doPass() throws org.bitcoinj.store.BlockStoreException { int h = height; for(int i=0; i<h; i+=2016) { int index= i /2016; //System.out.println("index: " + index+ " i: " + i + " h: " + h); //if (i+2016 <= h) { checkChunk(i/2016); last_saved_height = i+2016; } } } private void checkChunk(int index) throws org.bitcoinj.store.BlockStoreException { { String old = jelly.getDB().getHeaderChunkMap().get(index); if ((old != null) && (old.length() == 2 * 2016 * 80)) return; } jelly.getEventLog().log("Building header chunk " + index); ByteArrayOutputStream b_out = new ByteArrayOutputStream(); int start = index * 2016; for(int i=0; i<2016; i++) { if (start+i <= height) { Sha256Hash hash = jelly.getBlockChainCache().getBlockHashAtHeight(start+i); if (hash == null) { int h = start+i; System.out.println("unable to find hash for height: " + h); } StoredBlock blk = jelly.getBlockStore().get(hash); byte[] b = blk.getHeader().bitcoinSerialize(); b_out.write(b,0,80); } } byte[] buff = b_out.toByteArray(); String chunk = new String(Hex.encodeHex(buff)); jelly.getDB().getHeaderChunkMap().put(index, chunk); } }