66#include " miner.h"
77
88#include " core.h"
9+ #include " hash.h"
910#include " main.h"
1011#include " net.h"
1112#ifdef ENABLE_WALLET
1213#include " wallet.h"
1314#endif
1415
15- #include < openssl/sha.h>
16-
1716using namespace std ;
1817
1918// ////////////////////////////////////////////////////////////////////////////
2019//
2120// BitcoinMiner
2221//
2322
24- int static FormatHashBlocks (void * pbuffer, unsigned int len)
25- {
26- unsigned char * pdata = (unsigned char *)pbuffer;
27- unsigned int blocks = 1 + ((len + 8 ) / 64 );
28- unsigned char * pend = pdata + 64 * blocks;
29- memset (pdata + len, 0 , 64 * blocks - len);
30- pdata[len] = 0x80 ;
31- unsigned int bits = len * 8 ;
32- pend[-1 ] = (bits >> 0 ) & 0xff ;
33- pend[-2 ] = (bits >> 8 ) & 0xff ;
34- pend[-3 ] = (bits >> 16 ) & 0xff ;
35- pend[-4 ] = (bits >> 24 ) & 0xff ;
36- return blocks;
37- }
38-
39- static const unsigned int pSHA256InitState[8 ] =
40- {0x6a09e667 , 0xbb67ae85 , 0x3c6ef372 , 0xa54ff53a , 0x510e527f , 0x9b05688c , 0x1f83d9ab , 0x5be0cd19 };
41-
42- void SHA256Transform (void * pstate, void * pinput, const void * pinit)
43- {
44- SHA256_CTX ctx;
45- unsigned char data[64 ];
46-
47- SHA256_Init (&ctx);
48-
49- for (int i = 0 ; i < 16 ; i++)
50- ((uint32_t *)data)[i] = ByteReverse (((uint32_t *)pinput)[i]);
51-
52- for (int i = 0 ; i < 8 ; i++)
53- ctx.h [i] = ((uint32_t *)pinit)[i];
54-
55- SHA256_Update (&ctx, data, sizeof (data));
56- for (int i = 0 ; i < 8 ; i++)
57- ((uint32_t *)pstate)[i] = ctx.h [i];
58- }
59-
6023//
6124// Unconfirmed transactions in the memory pool often depend on other
6225// transactions in the memory pool. When we select transactions from the
@@ -372,51 +335,6 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
372335}
373336
374337
375- void FormatHashBuffers (CBlock* pblock, char * pmidstate, char * pdata, char * phash1)
376- {
377- //
378- // Pre-build hash buffers
379- //
380- struct
381- {
382- struct unnamed2
383- {
384- int nVersion;
385- uint256 hashPrevBlock;
386- uint256 hashMerkleRoot;
387- unsigned int nTime;
388- unsigned int nBits;
389- unsigned int nNonce;
390- }
391- block;
392- unsigned char pchPadding0[64 ];
393- uint256 hash1;
394- unsigned char pchPadding1[64 ];
395- }
396- tmp;
397- memset (&tmp, 0 , sizeof (tmp));
398-
399- tmp.block .nVersion = pblock->nVersion ;
400- tmp.block .hashPrevBlock = pblock->hashPrevBlock ;
401- tmp.block .hashMerkleRoot = pblock->hashMerkleRoot ;
402- tmp.block .nTime = pblock->nTime ;
403- tmp.block .nBits = pblock->nBits ;
404- tmp.block .nNonce = pblock->nNonce ;
405-
406- FormatHashBlocks (&tmp.block , sizeof (tmp.block ));
407- FormatHashBlocks (&tmp.hash1 , sizeof (tmp.hash1 ));
408-
409- // Byte swap all the input buffer
410- for (unsigned int i = 0 ; i < sizeof (tmp)/4 ; i++)
411- ((unsigned int *)&tmp)[i] = ByteReverse (((unsigned int *)&tmp)[i]);
412-
413- // Precalc the first half of the first hash, which stays constant
414- SHA256Transform (pmidstate, &tmp.block , pSHA256InitState);
415-
416- memcpy (pdata, &tmp.block , 128 );
417- memcpy (phash1, &tmp.hash1 , 64 );
418- }
419-
420338#ifdef ENABLE_WALLET
421339// ////////////////////////////////////////////////////////////////////////////
422340//
@@ -427,34 +345,33 @@ int64_t nHPSTimerStart = 0;
427345
428346//
429347// ScanHash scans nonces looking for a hash with at least some zero bits.
430- // It operates on big endian data. Caller does the byte reversing.
431- // All input buffers are 16-byte aligned. nNonce is usually preserved
432- // between calls, but periodically or if nNonce is 0xffff0000 or above,
433- // the block is rebuilt and nNonce starts over at zero.
348+ // The nonce is usually preserved between calls, but periodically or if the
349+ // nonce is 0xffff0000 or above, the block is rebuilt and nNonce starts over at
350+ // zero.
434351//
435- unsigned int static ScanHash_CryptoPP (char * pmidstate, char * pdata, char * phash1, char * phash, unsigned int & nHashesDone)
436- {
437- unsigned int & nNonce = *(unsigned int *)(pdata + 12 );
438- for (;;)
439- {
440- // Crypto++ SHA256
441- // Hash pdata using pmidstate as the starting state into
442- // pre-formatted buffer phash1, then hash phash1 into phash
352+ bool static ScanHash (const CBlockHeader *pblock, uint32_t & nNonce, uint256 *phash) {
353+ // Write the first 76 bytes of the block header to a double-SHA256 state.
354+ CHash256 hasher;
355+ CDataStream ss (SER_NETWORK, PROTOCOL_VERSION);
356+ ss << *pblock;
357+ assert (ss.size () == 80 );
358+ hasher.Write ((unsigned char *)&ss[0 ], 76 );
359+
360+ for (;;) {
443361 nNonce++;
444- SHA256Transform (phash1, pdata, pmidstate);
445- SHA256Transform (phash, phash1, pSHA256InitState);
362+
363+ // Write the last 4 bytes of the block header (the nonce) to a copy of
364+ // the double-SHA256 state, and compute the result.
365+ CHash256 (hasher).Write ((unsigned char *)&nNonce, 4 ).Finalize ((unsigned char *)phash);
446366
447367 // Return the nonce if the hash has at least some zero bits,
448368 // caller will check if it has enough to reach the target
449- if (((unsigned short *)phash)[14 ] == 0 )
450- return nNonce ;
369+ if (((uint16_t *)phash)[15 ] == 0 )
370+ return true ;
451371
452372 // If nothing found after trying for a while, return -1
453373 if ((nNonce & 0xffff ) == 0 )
454- {
455- nHashesDone = 0xffff +1 ;
456- return (unsigned int ) -1 ;
457- }
374+ return false ;
458375 if ((nNonce & 0xfff ) == 0 )
459376 boost::this_thread::interruption_point ();
460377 }
@@ -541,46 +458,27 @@ void static BitcoinMiner(CWallet *pwallet)
541458 LogPrintf (" Running BitcoinMiner with %u transactions in block (%u bytes)\n " , pblock->vtx .size (),
542459 ::GetSerializeSize (*pblock, SER_NETWORK, PROTOCOL_VERSION));
543460
544- //
545- // Pre-build hash buffers
546- //
547- char pmidstatebuf[32 +16 ]; char * pmidstate = alignup<16 >(pmidstatebuf);
548- char pdatabuf[128 +16 ]; char * pdata = alignup<16 >(pdatabuf);
549- char phash1buf[64 +16 ]; char * phash1 = alignup<16 >(phash1buf);
550-
551- FormatHashBuffers (pblock, pmidstate, pdata, phash1);
552-
553- unsigned int & nBlockTime = *(unsigned int *)(pdata + 64 + 4 );
554- unsigned int & nBlockBits = *(unsigned int *)(pdata + 64 + 8 );
555- unsigned int & nBlockNonce = *(unsigned int *)(pdata + 64 + 12 );
556-
557-
558461 //
559462 // Search
560463 //
561464 int64_t nStart = GetTime ();
562465 uint256 hashTarget = uint256 ().SetCompact (pblock->nBits );
563- uint256 hashbuf[2 ];
564- uint256& hash = *alignup<16 >(hashbuf);
466+ uint256 hash;
467+ uint32_t nNonce = 0 ;
468+ uint32_t nOldNonce = 0 ;
565469 while (true )
566470 {
567- unsigned int nHashesDone = 0 ;
568- unsigned int nNonceFound;
569-
570- // Crypto++ SHA256
571- nNonceFound = ScanHash_CryptoPP (pmidstate, pdata + 64 , phash1,
572- (char *)&hash, nHashesDone);
471+ bool fFound = ScanHash (pblock, nNonce, &hash);
472+ uint32_t nHashesDone = nNonce - nOldNonce;
473+ nOldNonce = nNonce;
573474
574475 // Check if something found
575- if (nNonceFound != ( unsigned int ) - 1 )
476+ if (fFound )
576477 {
577- for (unsigned int i = 0 ; i < sizeof (hash)/4 ; i++)
578- ((unsigned int *)&hash)[i] = ByteReverse (((unsigned int *)&hash)[i]);
579-
580478 if (hash <= hashTarget)
581479 {
582480 // Found a solution
583- pblock->nNonce = ByteReverse (nNonceFound) ;
481+ pblock->nNonce = nNonce ;
584482 assert (hash == pblock->GetHash ());
585483
586484 SetThreadPriority (THREAD_PRIORITY_NORMAL);
@@ -629,7 +527,7 @@ void static BitcoinMiner(CWallet *pwallet)
629527 // Regtest mode doesn't require peers
630528 if (vNodes.empty () && Params ().MiningRequiresPeers ())
631529 break ;
632- if (nBlockNonce >= 0xffff0000 )
530+ if (nNonce >= 0xffff0000 )
633531 break ;
634532 if (mempool.GetTransactionsUpdated () != nTransactionsUpdatedLast && GetTime () - nStart > 60 )
635533 break ;
@@ -638,11 +536,9 @@ void static BitcoinMiner(CWallet *pwallet)
638536
639537 // Update nTime every few seconds
640538 UpdateTime (*pblock, pindexPrev);
641- nBlockTime = ByteReverse (pblock->nTime );
642539 if (Params ().AllowMinDifficultyBlocks ())
643540 {
644541 // Changing pblock->nTime can change work required on testnet:
645- nBlockBits = ByteReverse (pblock->nBits );
646542 hashTarget.SetCompact (pblock->nBits );
647543 }
648544 }
0 commit comments