@@ -133,6 +133,7 @@ public enum VerifyFlag {
133
133
134
134
/** Stores the hash of the block. If null, getHash() will recalculate it. */
135
135
private Sha256Hash hash ;
136
+ private Sha256Hash scryptHash ;
136
137
137
138
/**
138
139
* Deserialize this message from a given payload.
@@ -151,13 +152,20 @@ public static Block read(ByteBuffer payload) throws BufferUnderflowException, Pr
151
152
long difficultyTarget = ByteUtils .readUint32 (payload );
152
153
long nonce = ByteUtils .readUint32 (payload );
153
154
payload .reset (); // read again from the mark for the hash
154
- Sha256Hash hash = Sha256Hash .wrapReversed (Sha256Hash .hashTwice (Buffers .readBytes (payload , HEADER_SIZE )));
155
+ byte [] header = Buffers .readBytes (payload , HEADER_SIZE );
156
+ Sha256Hash hash = Sha256Hash .wrapReversed (Sha256Hash .hashTwice (header ));
157
+ byte [] scryptDigest = ByteUtils .scryptDigest (header );
158
+ if (scryptDigest == null ) {
159
+ throw new RuntimeException ("Scrypt digest is null." );
160
+ }
161
+ Sha256Hash scryptHash = Sha256Hash .wrap (ByteUtils .reverseBytes (scryptDigest ));
155
162
// transactions
156
163
List <Transaction > transactions = payload .hasRemaining () ? // otherwise this message is just a header
157
164
readTransactions (payload ) :
158
165
null ;
159
166
Block block = new Block (version , prevBlockHash , merkleRoot , time , difficultyTarget , nonce , transactions );
160
167
block .hash = hash ;
168
+ block .scryptHash = scryptHash ;
161
169
return block ;
162
170
}
163
171
@@ -242,14 +250,14 @@ public static Block createGenesis() {
242
250
//
243
251
// "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"
244
252
private static final byte [] genesisTxInputScriptBytes = ByteUtils .parseHex
245
- ("04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73 " );
253
+ ("04ffff001d0104404e592054696d65732030352f4f63742f32303131205374657665204a6f62732c204170706c65e280997320566973696f6e6172792c2044696573206174203536 " );
246
254
247
255
private static final byte [] genesisTxScriptPubKeyBytes ;
248
256
static {
249
257
ByteArrayOutputStream scriptPubKeyBytes = new ByteArrayOutputStream ();
250
258
try {
251
259
Script .writeBytes (scriptPubKeyBytes , ByteUtils .parseHex
252
- ("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f " ));
260
+ ("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9 " ));
253
261
} catch (IOException e ) {
254
262
throw new RuntimeException (e ); // Cannot happen.
255
263
}
@@ -307,6 +315,7 @@ protected void unCache() {
307
315
308
316
private void unCacheHeader () {
309
317
hash = null ;
318
+ scryptHash = null ;
310
319
}
311
320
312
321
private void unCacheTransactions () {
@@ -318,6 +327,10 @@ private void unCacheTransactions() {
318
327
merkleRoot = null ;
319
328
}
320
329
330
+ /**
331
+ * Calculates the block hash by serializing the block and hashing the
332
+ * resulting bytes.
333
+ */
321
334
/**
322
335
* Calculates the block hash by serializing the block and hashing the
323
336
* resulting bytes.
@@ -332,6 +345,20 @@ private Sha256Hash calculateHash() {
332
345
}
333
346
}
334
347
348
+ private Sha256Hash calculateScryptHash () {
349
+ try {
350
+ ByteArrayOutputStream bos = new ByteArrayOutputStream (HEADER_SIZE );
351
+ writeHeader (bos );
352
+ byte [] scryptDigest = ByteUtils .scryptDigest (bos .toByteArray ());
353
+ if (scryptDigest == null ) {
354
+ throw new RuntimeException ("Scrypt digest is null." );
355
+ }
356
+ return Sha256Hash .wrap (ByteUtils .reverseBytes (scryptDigest ));
357
+ } catch (IOException e ) {
358
+ throw new RuntimeException (e ); // Cannot happen.
359
+ }
360
+ }
361
+
335
362
/**
336
363
* Returns the hash of the block (which for a valid, solved block should be below the target) in the form seen on
337
364
* the block explorer. If you call this on block 1 in the mainnet chain
@@ -341,6 +368,10 @@ public String getHashAsString() {
341
368
return getHash ().toString ();
342
369
}
343
370
371
+ public String getScryptHashAsString () {
372
+ return getScryptHash ().toString ();
373
+ }
374
+
344
375
/**
345
376
* Returns the hash of the block (which for a valid, solved block should be
346
377
* below the target). Big endian.
@@ -351,6 +382,12 @@ public Sha256Hash getHash() {
351
382
return hash ;
352
383
}
353
384
385
+ public Sha256Hash getScryptHash () {
386
+ if (scryptHash == null )
387
+ scryptHash = calculateScryptHash ();
388
+ return scryptHash ;
389
+ }
390
+
354
391
/**
355
392
* The number that is one greater than the largest representable SHA-256
356
393
* hash.
@@ -383,6 +420,7 @@ public Block cloneAsHeader() {
383
420
block .merkleRoot = getMerkleRoot ();
384
421
block .hash = getHash ();
385
422
block .transactions = null ;
423
+ block .scryptHash = getScryptHash ();
386
424
return block ;
387
425
}
388
426
@@ -456,10 +494,6 @@ public BigInteger getDifficultyTargetAsInteger() {
456
494
457
495
/** Returns true if the hash of the block is OK (lower than difficulty target). */
458
496
protected boolean checkProofOfWork (boolean throwException ) throws VerificationException {
459
- // shortcut for unit-testing
460
- if (Context .get ().isRelaxProofOfWork ())
461
- return true ;
462
-
463
497
// This part is key - it is what proves the block was as difficult to make as it claims
464
498
// to be. Note however that in the context of this function, the block can claim to be
465
499
// as difficult as it wants to be .... if somebody was able to take control of our network
@@ -470,11 +504,11 @@ protected boolean checkProofOfWork(boolean throwException) throws VerificationEx
470
504
// field is of the right value. This requires us to have the preceding blocks.
471
505
BigInteger target = getDifficultyTargetAsInteger ();
472
506
473
- BigInteger h = getHash ().toBigInteger ();
507
+ BigInteger h = getScryptHash ().toBigInteger ();
474
508
if (h .compareTo (target ) > 0 ) {
475
509
// Proof of work check failed!
476
510
if (throwException )
477
- throw new VerificationException ("Hash is higher than target: " + getHashAsString () + " vs "
511
+ throw new VerificationException ("Hash is higher than target: " + getScryptHashAsString () + " vs "
478
512
+ target .toString (16 ));
479
513
else
480
514
return false ;
@@ -659,6 +693,7 @@ void setMerkleRoot(Sha256Hash value) {
659
693
unCacheHeader ();
660
694
merkleRoot = value ;
661
695
hash = null ;
696
+ scryptHash = null ;
662
697
}
663
698
664
699
/**
@@ -689,6 +724,7 @@ else if (runSanityChecks && transactions.size() > 0 && t.isCoinBase())
689
724
// Force a recalculation next time the values are needed.
690
725
merkleRoot = null ;
691
726
hash = null ;
727
+ scryptHash = null ;
692
728
}
693
729
694
730
/** Returns the version of the block data structure as defined by the Bitcoin protocol. */
@@ -708,6 +744,7 @@ void setPrevBlockHash(Sha256Hash prevBlockHash) {
708
744
unCacheHeader ();
709
745
this .prevBlockHash = prevBlockHash ;
710
746
this .hash = null ;
747
+ this .scryptHash = null ;
711
748
}
712
749
713
750
/**
@@ -741,6 +778,7 @@ public void setTime(Instant time) {
741
778
unCacheHeader ();
742
779
this .time = time .truncatedTo (ChronoUnit .SECONDS ); // convert to Bitcoin time
743
780
this .hash = null ;
781
+ this .scryptHash = null ;
744
782
}
745
783
746
784
/**
@@ -762,6 +800,7 @@ public void setDifficultyTarget(long compactForm) {
762
800
unCacheHeader ();
763
801
this .difficultyTarget = compactForm ;
764
802
this .hash = null ;
803
+ this .scryptHash = null ;
765
804
}
766
805
767
806
/**
@@ -778,6 +817,7 @@ public void setNonce(long nonce) {
778
817
unCacheHeader ();
779
818
this .nonce = nonce ;
780
819
this .hash = null ;
820
+ this .scryptHash = null ;
781
821
}
782
822
783
823
/** Returns an unmodifiable list of transactions held in this block, or null if this object represents just a header. */
0 commit comments