Skip to content

Commit 0c8dc23

Browse files
committed
Bug fix - reversed hashes
- placed internal hashes in correct byte order
1 parent f77896d commit 0c8dc23

File tree

1 file changed

+51
-4
lines changed
  • src/main/java/org/twostack/bitcoin4j/block

1 file changed

+51
-4
lines changed

src/main/java/org/twostack/bitcoin4j/block/Block.java

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.twostack.bitcoin4j.block;
22

33
import com.google.common.annotations.VisibleForTesting;
4+
import com.google.common.base.Preconditions;
45
import com.google.common.collect.ImmutableList;
56
import org.twostack.bitcoin4j.Sha256Hash;
67
import org.twostack.bitcoin4j.UnsafeByteArrayOutputStream;
@@ -99,8 +100,6 @@ public class Block {
99100
protected boolean headerBytesValid;
100101
protected boolean transactionBytesValid;
101102

102-
protected boolean headerParsed;
103-
protected boolean transactionsParsed;
104103

105104
// The raw message payload bytes themselves.
106105
protected byte[] payload;
@@ -137,8 +136,8 @@ void parse(byte[] payload) throws ProtocolException, IOException {
137136
ByteArrayInputStream bis = new ByteArrayInputStream(payload);
138137

139138
version = Utils.readUint32FromStream(bis);
140-
prevBlockHash = Sha256Hash.wrap(bis.readNBytes(32));
141-
merkleRoot = Sha256Hash.wrap(bis.readNBytes(32));
139+
prevBlockHash = Sha256Hash.wrapReversed(bis.readNBytes(32));
140+
merkleRoot = Sha256Hash.wrapReversed(bis.readNBytes(32));
142141
time = Utils.readUint32FromStream(bis);
143142
difficultyTarget = Utils.readUint32FromStream(bis);
144143
nonce = Utils.readUint32FromStream(bis);
@@ -148,6 +147,8 @@ void parse(byte[] payload) throws ProtocolException, IOException {
148147
// transactions
149148
VarInt numTransactionsVarInt = VarInt.fromStream(bis);
150149

150+
if (numTransactionsVarInt.intValue() <= 0) return;
151+
151152
optimalEncodingMessageSize = HEADER_SIZE;
152153
if (payload.length == cursor) {
153154
// This message is just a header, it has no transactions.
@@ -349,4 +350,50 @@ public void clearTxids() {
349350
txids = null;
350351
}
351352

353+
354+
private void writeTransactions(OutputStream stream) throws IOException {
355+
// check for no transaction conditions first
356+
// must be a more efficient way to do this but I'm tired atm.
357+
if (transactions == null || transactions.isEmpty()) {
358+
return;
359+
}
360+
361+
// confirmed we must have transactions either cached or as objects.
362+
// if (transactionBytesValid && payload != null && payload.length >= offset + length()) {
363+
// stream.write(payload, offset + HEADER_SIZE, length() - HEADER_SIZE);
364+
// return;
365+
// }
366+
367+
if (transactions != null) {
368+
stream.write(new VarInt(transactions.size()).encode());
369+
for (Transaction tx : transactions) {
370+
stream.write(tx.serialize());
371+
}
372+
}
373+
}
374+
375+
376+
/**
377+
* Special handling to check if we have a valid byte array for both header
378+
* and transactions
379+
*
380+
*/
381+
public byte[] bitcoinSerialize() {
382+
ByteArrayOutputStream stream = new UnsafeByteArrayOutputStream();
383+
try {
384+
writeHeader(stream);
385+
writeTransactions(stream);
386+
} catch (IOException e) {
387+
// Cannot happen, we are serializing to a memory stream.
388+
}
389+
return stream.toByteArray();
390+
}
391+
392+
public void bitcoinSerializeToStream(OutputStream stream) throws IOException {
393+
writeHeader(stream);
394+
// We may only have enough data to write the header.
395+
writeTransactions(stream);
396+
}
397+
398+
352399
}

0 commit comments

Comments
 (0)