package org.ripple.power.txns.btc; import java.io.EOFException; import java.math.BigInteger; public class BlockEntry { /** Previous block hash */ private final Sha256Hash prevHash; /** Block height */ private int blockHeight; /** Chain work */ private BigInteger chainWork; /** Block timestamp */ private final long timeStamp; /** Block chain status */ private boolean onChain; /** Block hold status */ private boolean onHold; /** Block file number */ private int fileNumber; /** Block file offset */ private int fileOffset; /** Block header */ private byte[] header; /** * Creates a new BlockEntry * * @param prevHash Previous block hash * @param blockHeight Block height * @param chainWork Chain work * @param onChain TRUE if the block is on the chain * @param onHold TRUE if the block is held * @param timeStamp Block timestamp * @param fileNumber Block file number * @param fileOffset Block file offset * @param header Block header */ public BlockEntry(Sha256Hash prevHash, int blockHeight, BigInteger chainWork, boolean onChain, boolean onHold, long timeStamp, int fileNumber, int fileOffset, byte[] header) { this.prevHash = prevHash; this.blockHeight = blockHeight; this.chainWork = chainWork; this.onChain = onChain; this.onHold = onHold; this.timeStamp = timeStamp; this.fileNumber = fileNumber; this.fileOffset = fileOffset; this.header = header; } /** * Creates a new BlockEntry from the serialized entry data * * @param entryData Serialized entry data * @throws EOFException End-of-data processing the serialized data */ public BlockEntry(byte[] entryData) throws EOFException { SerializedBuffer inBuffer = new SerializedBuffer(entryData); onChain = inBuffer.getBoolean(); onHold = inBuffer.getBoolean(); prevHash = new Sha256Hash(inBuffer.getBytes(32)); chainWork = new BigInteger(inBuffer.getBytes()); timeStamp = inBuffer.getVarLong(); blockHeight = inBuffer.getVarInt(); fileNumber = inBuffer.getVarInt(); fileOffset = inBuffer.getVarInt(); if (inBuffer.available() >= BlockHeader.HEADER_SIZE) header = inBuffer.getBytes(BlockHeader.HEADER_SIZE); else header = new byte[0]; } /** * Returns the serialized entry data * * @return Serialized data stream */ public byte[] getBytes() { byte[] workBytes = chainWork.toByteArray(); SerializedBuffer outBuffer = new SerializedBuffer(); outBuffer.putBoolean(onChain) .putBoolean(onHold) .putBytes(prevHash.getBytes()) .putVarInt(workBytes.length) .putBytes(workBytes) .putVarLong(timeStamp) .putVarInt(blockHeight) .putVarInt(fileNumber) .putVarInt(fileOffset) .putBytes(header); return outBuffer.toByteArray(); } /** * Returns the previous block hash * * @return Block hash */ public Sha256Hash getPrevHash() { return prevHash; } /** * Returns the block timestamp * * @return Block timestamp */ public long getTimeStamp() { return timeStamp; } /** * Returns the block height * * @return Block height */ public int getHeight() { return blockHeight; } /** * Sets the block height * * @param blockHeight Tne block height */ public void setHeight(int blockHeight) { this.blockHeight = blockHeight; } /** * Returns the chain work * * @return Chain work */ public BigInteger getChainWork() { return chainWork; } /** * Sets the chain work * * @param chainWork Chain work */ public void setChainWork(BigInteger chainWork) { this.chainWork = chainWork; } /** * Returns the block chain status * * @return TRUE if the block is on the chain */ public boolean isOnChain() { return onChain; } /** * Sets the block chain status * * @param onChain TRUE if the block is on the chain */ public void setChain(boolean onChain) { this.onChain = onChain; } /** * Return the block hold status * * @return TRUE if the block is held */ public boolean isOnHold() { return onHold; } /** * Sets the block hold status * * @param onHold TRUE if the block is held */ public void setHold(boolean onHold) { this.onHold = onHold; } /** * Returns the block file number * * @return Block file number */ public int getFileNumber() { return fileNumber; } /** * Sets the block file number * * @param fileNumber The new block file number */ public void setFileNumber(int fileNumber) { this.fileNumber = fileNumber; } /** * Returns the block file offset * * @return Block file offset */ public int getFileOffset() { return fileOffset; } /** * Sets the block file offset * * @param fileOffset The new block file offset */ public void setFileOffset(int fileOffset) { this.fileOffset = fileOffset; } /** * Return the block header bytes * * @return Header bytes */ public byte[] getHeaderBytes() { return header; } /** * Set the block header bytes * * @param headerBytes Header bytes */ public void setHeaderBytes(byte[] headerBytes) { header = headerBytes; } /** * Return the block version * * @return Block version */ public int getVersion() { // // The version is stored in the first 4 bytes of the header in little-endian format // return ((int)header[0]&255) | (((int)header[1]&255)<<8) | (((int)header[2]&255)<<16) | (((int)header[3]&255)<<24); } }