public AuxPoW(NetworkParameters params, @Nullable Message parent) { super(params); transaction = new Transaction(params); hashBlock = Sha256Hash.ZERO_HASH; coinbaseBranch = new MerkleBranch(params, this); chainMerkleBranch = new MerkleBranch(params, this); parentBlockHeader = null; }
protected static int calcLength(byte[] buf, int offset) { VarInt varint; // jump past transaction int cursor = offset + Transaction.calcLength(buf, offset); // jump past header hash cursor += 4; // Coin base branch cursor += MerkleBranch.calcLength(buf, offset); // Block chain branch cursor += MerkleBranch.calcLength(buf, offset); // Block header cursor += Block.HEADER_SIZE; return cursor - offset + 4; }
public int getOptimalEncodingMessageSize() { if (optimalEncodingMessageSize != 0) return optimalEncodingMessageSize; if (optimalEncodingMessageSize != 0) return optimalEncodingMessageSize; optimalEncodingMessageSize = getMessageSize(); return optimalEncodingMessageSize; }
@Override protected void parse() throws ProtocolException { cursor = offset; final int hashCount = (int) readVarInt(); optimalEncodingMessageSize += VarInt.sizeOf(hashCount); hashes = new ArrayList<Sha256Hash>(hashCount); for (int hashIdx = 0; hashIdx < hashCount; hashIdx++) { hashes.add(readHash()); } optimalEncodingMessageSize += 32 * hashCount; setIndex(readUint32()); optimalEncodingMessageSize += 4; length = cursor - offset; }
if (0 != this.getCoinbaseBranch().getIndex()) { if (throwException) { if (this.getChainMerkleBranch().size() > 30) { if (throwException) { throw new VerificationException("Aux POW chain merkle branch too long"); Sha256Hash nRootHash = getChainMerkleBranch().calculateMerkleRoot(hashAuxBlock); final byte[] vchRootHash = nRootHash.getBytes(); if (!getCoinbaseBranch().calculateMerkleRoot(getCoinbase().getHash()).equals(parentBlockHeader.getMerkleRoot())) { if (throwException) { throw new VerificationException("Aux POW merkle root incorrect"); if (branchSize != (1 << getChainMerkleBranch().size())) { if (throwException) { throw new VerificationException("Aux POW merkle branch size does not match parent coinbase"); if (getChainMerkleBranch().getIndex() != getExpectedIndex(nonce, ((AuxPoWNetworkParameters) params).getChainID(), getChainMerkleBranch().size())) { if (throwException) { throw new VerificationException("Aux POW wrong index in chain merkle branch for chain ID " + ((AuxPoWNetworkParameters) params).getChainID() + ". Was " + getChainMerkleBranch().getIndex() + ", expected " + getExpectedIndex(nonce, ((AuxPoWNetworkParameters) params).getChainID(), getChainMerkleBranch().size()));
@Override protected void parse() throws ProtocolException { cursor = offset; transaction = new Transaction(params, payload, cursor, this, serializer, Message.UNKNOWN_LENGTH); cursor += transaction.getOptimalEncodingMessageSize(); optimalEncodingMessageSize = transaction.getOptimalEncodingMessageSize(); hashBlock = readHash(); optimalEncodingMessageSize += 32; // Add the hash size to the optimal encoding coinbaseBranch = new MerkleBranch(params, this, payload, cursor, serializer); cursor += coinbaseBranch.getOptimalEncodingMessageSize(); optimalEncodingMessageSize += coinbaseBranch.getOptimalEncodingMessageSize(); chainMerkleBranch = new MerkleBranch(params, this, payload, cursor, serializer); cursor += chainMerkleBranch.getOptimalEncodingMessageSize(); optimalEncodingMessageSize += chainMerkleBranch.getOptimalEncodingMessageSize(); // Make a copy of JUST the contained block header, so the block parser doesn't try reading // transactions past the end byte[] blockBytes = Arrays.copyOfRange(payload, cursor, cursor + Block.HEADER_SIZE); cursor += Block.HEADER_SIZE; parentBlockHeader = new AltcoinBlock(params, blockBytes, 0, this, serializer, Block.HEADER_SIZE); length = cursor - offset; }
@Override public int hashCode() { int result = 1; result = 31 * result + transaction.hashCode(); result = 31 * result + hashBlock.hashCode(); result = 31 * result + coinbaseBranch.hashCode(); result = 31 * result + chainMerkleBranch.hashCode(); result = 31 * result + parentBlockHeader.hashCode(); return result; }
@Override protected void bitcoinSerializeToStream(OutputStream stream) throws IOException { transaction.bitcoinSerialize(stream); stream.write(Utils.reverseBytes(hashBlock.getBytes())); coinbaseBranch.bitcoinSerialize(stream); chainMerkleBranch.bitcoinSerialize(stream); parentBlockHeader.bitcoinSerializeToStream(stream); }
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; AuxPoW input = (AuxPoW) o; if (!transaction.equals(input.transaction)) return false; if (!hashBlock.equals(input.hashBlock)) return false; if (!coinbaseBranch.equals(input.coinbaseBranch)) return false; if (!chainMerkleBranch.equals(input.chainMerkleBranch)) return false; if (!parentBlockHeader.equals(input.parentBlockHeader)) return false; return getHash().equals(input.getHash()); }