1
1
package org .twostack .bitcoin4j .block ;
2
2
3
3
import com .google .common .annotations .VisibleForTesting ;
4
+ import com .google .common .base .Preconditions ;
4
5
import com .google .common .collect .ImmutableList ;
5
6
import org .twostack .bitcoin4j .Sha256Hash ;
6
7
import org .twostack .bitcoin4j .UnsafeByteArrayOutputStream ;
@@ -99,8 +100,6 @@ public class Block {
99
100
protected boolean headerBytesValid ;
100
101
protected boolean transactionBytesValid ;
101
102
102
- protected boolean headerParsed ;
103
- protected boolean transactionsParsed ;
104
103
105
104
// The raw message payload bytes themselves.
106
105
protected byte [] payload ;
@@ -137,8 +136,8 @@ void parse(byte[] payload) throws ProtocolException, IOException {
137
136
ByteArrayInputStream bis = new ByteArrayInputStream (payload );
138
137
139
138
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 ));
142
141
time = Utils .readUint32FromStream (bis );
143
142
difficultyTarget = Utils .readUint32FromStream (bis );
144
143
nonce = Utils .readUint32FromStream (bis );
@@ -148,6 +147,8 @@ void parse(byte[] payload) throws ProtocolException, IOException {
148
147
// transactions
149
148
VarInt numTransactionsVarInt = VarInt .fromStream (bis );
150
149
150
+ if (numTransactionsVarInt .intValue () <= 0 ) return ;
151
+
151
152
optimalEncodingMessageSize = HEADER_SIZE ;
152
153
if (payload .length == cursor ) {
153
154
// This message is just a header, it has no transactions.
@@ -349,4 +350,50 @@ public void clearTxids() {
349
350
txids = null ;
350
351
}
351
352
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
+
352
399
}
0 commit comments