@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; }
/** * Parse transactions from the block. * * @param transactionsOffset Offset of the transactions within the block. * Useful for non-Bitcoin chains where the block header may not be a fixed * size. */ protected void parseTransactions(final int transactionsOffset) throws ProtocolException { cursor = transactionsOffset; optimalEncodingMessageSize = HEADER_SIZE; if (payload.length == cursor) { // This message is just a header, it has no transactions. transactionBytesValid = false; return; } int numTransactions = (int) readVarInt(); optimalEncodingMessageSize += VarInt.sizeOf(numTransactions); transactions = new ArrayList<Transaction>(numTransactions); for (int i = 0; i < numTransactions; i++) { Transaction tx = new Transaction(params, payload, cursor, this, serializer, UNKNOWN_LENGTH); // Label the transaction as coming from the P2P network, so code that cares where we first saw it knows. tx.getConfidence().setSource(TransactionConfidence.Source.NETWORK); transactions.add(tx); cursor += tx.getMessageSize(); optimalEncodingMessageSize += tx.getOptimalEncodingMessageSize(); } transactionBytesValid = serializer.isParseRetainMode(); }
/** * Parse transactions from the block. * * @param transactionsOffset Offset of the transactions within the block. * Useful for non-Bitcoin chains where the block header may not be a fixed * size. */ protected void parseTransactions(final int transactionsOffset) throws ProtocolException { cursor = transactionsOffset; optimalEncodingMessageSize = HEADER_SIZE; if (payload.length == cursor) { // This message is just a header, it has no transactions. transactionBytesValid = false; return; } int numTransactions = (int) readVarInt(); optimalEncodingMessageSize += VarInt.sizeOf(numTransactions); transactions = new ArrayList<>(numTransactions); for (int i = 0; i < numTransactions; i++) { Transaction tx = new Transaction(params, payload, cursor, this, serializer, UNKNOWN_LENGTH); // Label the transaction as coming from the P2P network, so code that cares where we first saw it knows. tx.getConfidence().setSource(TransactionConfidence.Source.NETWORK); transactions.add(tx); cursor += tx.getMessageSize(); optimalEncodingMessageSize += tx.getOptimalEncodingMessageSize(); } transactionBytesValid = serializer.isParseRetainMode(); }
/** * Parse transactions from the block. * * @param transactionsOffset Offset of the transactions within the block. * Useful for non-Bitcoin chains where the block header may not be a fixed * size. */ protected void parseTransactions(final int transactionsOffset) throws ProtocolException { cursor = transactionsOffset; optimalEncodingMessageSize = HEADER_SIZE; if (payload.length == cursor) { // This message is just a header, it has no transactions. transactionBytesValid = false; return; } int numTransactions = (int) readVarInt(); optimalEncodingMessageSize += VarInt.sizeOf(numTransactions); transactions = new ArrayList<Transaction>(numTransactions); for (int i = 0; i < numTransactions; i++) { Transaction tx = new Transaction(params, payload, cursor, this, serializer, UNKNOWN_LENGTH); // Label the transaction as coming from the P2P network, so code that cares where we first saw it knows. tx.getConfidence().setSource(TransactionConfidence.Source.NETWORK); transactions.add(tx); cursor += tx.getMessageSize(); optimalEncodingMessageSize += tx.getOptimalEncodingMessageSize(); } transactionBytesValid = serializer.isParseRetainMode(); }
/** * Parse transactions from the block. * * @param transactionsOffset Offset of the transactions within the block. * Useful for non-Bitcoin chains where the block header may not be a fixed * size. */ protected void parseTransactions(final int transactionsOffset) throws ProtocolException { cursor = transactionsOffset; optimalEncodingMessageSize = HEADER_SIZE; if (payload.length == cursor) { // This message is just a header, it has no transactions. transactionBytesValid = false; return; } int numTransactions = (int) readVarInt(); optimalEncodingMessageSize += VarInt.sizeOf(numTransactions); transactions = new ArrayList<>(numTransactions); for (int i = 0; i < numTransactions; i++) { Transaction tx = new Transaction(params, payload, cursor, this, serializer, UNKNOWN_LENGTH); // Label the transaction as coming from the P2P network, so code that cares where we first saw it knows. tx.getConfidence().setSource(TransactionConfidence.Source.NETWORK); transactions.add(tx); cursor += tx.getMessageSize(); optimalEncodingMessageSize += tx.getOptimalEncodingMessageSize(); } transactionBytesValid = serializer.isParseRetainMode(); }
@Test public void testOptimalEncodingMessageSize() { Transaction tx = new Transaction(PARAMS); int length = tx.length; // add basic transaction input, check the length tx.addOutput(new TransactionOutput(PARAMS, null, Coin.COIN, ADDRESS)); length += getCombinedLength(tx.getOutputs()); // add basic output, check the length length += getCombinedLength(tx.getInputs()); // optimal encoding size should equal the length we just calculated assertEquals(tx.getOptimalEncodingMessageSize(), length); }