11package org .twostack .bitcoin4j .block ;
22
33import com .google .common .annotations .VisibleForTesting ;
4+ import com .google .common .base .Preconditions ;
45import com .google .common .collect .ImmutableList ;
56import org .twostack .bitcoin4j .Sha256Hash ;
67import 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