Skip to content

Commit 85aab2a

Browse files
committed
Switch miner.cpp to use sha2 instead of OpenSSL.
1 parent cf0c47b commit 85aab2a

File tree

3 files changed

+29
-165
lines changed

3 files changed

+29
-165
lines changed

src/miner.cpp

Lines changed: 29 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -6,57 +6,20 @@
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-
1716
using 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
}

src/miner.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,8 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn);
2323
CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey);
2424
/** Modify the extranonce in a block */
2525
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
26-
/** Do mining precalculation */
27-
void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1);
2826
/** Check mined block */
2927
bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey);
30-
/** Base sha256 mining transform */
31-
void SHA256Transform(void* pstate, void* pinput, const void* pinit);
3228

3329
extern double dHashesPerSec;
3430
extern int64_t nHPSTimerStart;

src/test/miner_tests.cpp

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
#include <boost/test/unit_test.hpp>
1111

12-
extern void SHA256Transform(void* pstate, void* pinput, const void* pinit);
13-
1412
BOOST_AUTO_TEST_SUITE(miner_tests)
1513

1614
static
@@ -259,30 +257,4 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
259257

260258
}
261259

262-
BOOST_AUTO_TEST_CASE(sha256transform_equality)
263-
{
264-
unsigned int pSHA256InitState[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
265-
266-
267-
// unsigned char pstate[32];
268-
unsigned char pinput[64];
269-
270-
int i;
271-
272-
for (i = 0; i < 32; i++) {
273-
pinput[i] = i;
274-
pinput[i+32] = 0;
275-
}
276-
277-
uint256 hash;
278-
279-
SHA256Transform(&hash, pinput, pSHA256InitState);
280-
281-
BOOST_TEST_MESSAGE(hash.GetHex());
282-
283-
uint256 hash_reference("0x2df5e1c65ef9f8cde240d23cae2ec036d31a15ec64bc68f64be242b1da6631f3");
284-
285-
BOOST_CHECK(hash == hash_reference);
286-
}
287-
288260
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)