|
|
|
@ -6,14 +6,13 @@
@@ -6,14 +6,13 @@
|
|
|
|
|
#include "miner.h" |
|
|
|
|
|
|
|
|
|
#include "core.h" |
|
|
|
|
#include "hash.h" |
|
|
|
|
#include "main.h" |
|
|
|
|
#include "net.h" |
|
|
|
|
#ifdef ENABLE_WALLET |
|
|
|
|
#include "wallet.h" |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#include <openssl/sha.h> |
|
|
|
|
|
|
|
|
|
using namespace std; |
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
@ -21,42 +20,6 @@ using namespace std;
@@ -21,42 +20,6 @@ using namespace std;
|
|
|
|
|
// BitcoinMiner
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
int static FormatHashBlocks(void* pbuffer, unsigned int len) |
|
|
|
|
{ |
|
|
|
|
unsigned char* pdata = (unsigned char*)pbuffer; |
|
|
|
|
unsigned int blocks = 1 + ((len + 8) / 64); |
|
|
|
|
unsigned char* pend = pdata + 64 * blocks; |
|
|
|
|
memset(pdata + len, 0, 64 * blocks - len); |
|
|
|
|
pdata[len] = 0x80; |
|
|
|
|
unsigned int bits = len * 8; |
|
|
|
|
pend[-1] = (bits >> 0) & 0xff; |
|
|
|
|
pend[-2] = (bits >> 8) & 0xff; |
|
|
|
|
pend[-3] = (bits >> 16) & 0xff; |
|
|
|
|
pend[-4] = (bits >> 24) & 0xff; |
|
|
|
|
return blocks; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static const unsigned int pSHA256InitState[8] = |
|
|
|
|
{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; |
|
|
|
|
|
|
|
|
|
void SHA256Transform(void* pstate, void* pinput, const void* pinit) |
|
|
|
|
{ |
|
|
|
|
SHA256_CTX ctx; |
|
|
|
|
unsigned char data[64]; |
|
|
|
|
|
|
|
|
|
SHA256_Init(&ctx); |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 16; i++) |
|
|
|
|
((uint32_t*)data)[i] = ByteReverse(((uint32_t*)pinput)[i]); |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 8; i++) |
|
|
|
|
ctx.h[i] = ((uint32_t*)pinit)[i]; |
|
|
|
|
|
|
|
|
|
SHA256_Update(&ctx, data, sizeof(data)); |
|
|
|
|
for (int i = 0; i < 8; i++) |
|
|
|
|
((uint32_t*)pstate)[i] = ctx.h[i]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Unconfirmed transactions in the memory pool often depend on other
|
|
|
|
|
// transactions in the memory pool. When we select transactions from the
|
|
|
|
@ -372,51 +335,6 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
@@ -372,51 +335,6 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1) |
|
|
|
|
{ |
|
|
|
|
//
|
|
|
|
|
// Pre-build hash buffers
|
|
|
|
|
//
|
|
|
|
|
struct |
|
|
|
|
{ |
|
|
|
|
struct unnamed2 |
|
|
|
|
{ |
|
|
|
|
int nVersion; |
|
|
|
|
uint256 hashPrevBlock; |
|
|
|
|
uint256 hashMerkleRoot; |
|
|
|
|
unsigned int nTime; |
|
|
|
|
unsigned int nBits; |
|
|
|
|
unsigned int nNonce; |
|
|
|
|
} |
|
|
|
|
block; |
|
|
|
|
unsigned char pchPadding0[64]; |
|
|
|
|
uint256 hash1; |
|
|
|
|
unsigned char pchPadding1[64]; |
|
|
|
|
} |
|
|
|
|
tmp; |
|
|
|
|
memset(&tmp, 0, sizeof(tmp)); |
|
|
|
|
|
|
|
|
|
tmp.block.nVersion = pblock->nVersion; |
|
|
|
|
tmp.block.hashPrevBlock = pblock->hashPrevBlock; |
|
|
|
|
tmp.block.hashMerkleRoot = pblock->hashMerkleRoot; |
|
|
|
|
tmp.block.nTime = pblock->nTime; |
|
|
|
|
tmp.block.nBits = pblock->nBits; |
|
|
|
|
tmp.block.nNonce = pblock->nNonce; |
|
|
|
|
|
|
|
|
|
FormatHashBlocks(&tmp.block, sizeof(tmp.block)); |
|
|
|
|
FormatHashBlocks(&tmp.hash1, sizeof(tmp.hash1)); |
|
|
|
|
|
|
|
|
|
// Byte swap all the input buffer
|
|
|
|
|
for (unsigned int i = 0; i < sizeof(tmp)/4; i++) |
|
|
|
|
((unsigned int*)&tmp)[i] = ByteReverse(((unsigned int*)&tmp)[i]); |
|
|
|
|
|
|
|
|
|
// Precalc the first half of the first hash, which stays constant
|
|
|
|
|
SHA256Transform(pmidstate, &tmp.block, pSHA256InitState); |
|
|
|
|
|
|
|
|
|
memcpy(pdata, &tmp.block, 128); |
|
|
|
|
memcpy(phash1, &tmp.hash1, 64); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef ENABLE_WALLET |
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
@ -427,34 +345,33 @@ int64_t nHPSTimerStart = 0;
@@ -427,34 +345,33 @@ int64_t nHPSTimerStart = 0;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// ScanHash scans nonces looking for a hash with at least some zero bits.
|
|
|
|
|
// It operates on big endian data. Caller does the byte reversing.
|
|
|
|
|
// All input buffers are 16-byte aligned. nNonce is usually preserved
|
|
|
|
|
// between calls, but periodically or if nNonce is 0xffff0000 or above,
|
|
|
|
|
// the block is rebuilt and nNonce starts over at zero.
|
|
|
|
|
// The nonce is usually preserved between calls, but periodically or if the
|
|
|
|
|
// nonce is 0xffff0000 or above, the block is rebuilt and nNonce starts over at
|
|
|
|
|
// zero.
|
|
|
|
|
//
|
|
|
|
|
unsigned int static ScanHash_CryptoPP(char* pmidstate, char* pdata, char* phash1, char* phash, unsigned int& nHashesDone) |
|
|
|
|
{ |
|
|
|
|
unsigned int& nNonce = *(unsigned int*)(pdata + 12); |
|
|
|
|
for (;;) |
|
|
|
|
{ |
|
|
|
|
// Crypto++ SHA256
|
|
|
|
|
// Hash pdata using pmidstate as the starting state into
|
|
|
|
|
// pre-formatted buffer phash1, then hash phash1 into phash
|
|
|
|
|
bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phash) { |
|
|
|
|
// Write the first 76 bytes of the block header to a double-SHA256 state.
|
|
|
|
|
CHash256 hasher; |
|
|
|
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); |
|
|
|
|
ss << *pblock; |
|
|
|
|
assert(ss.size() == 80); |
|
|
|
|
hasher.Write((unsigned char*)&ss[0], 76); |
|
|
|
|
|
|
|
|
|
for (;;) { |
|
|
|
|
nNonce++; |
|
|
|
|
SHA256Transform(phash1, pdata, pmidstate); |
|
|
|
|
SHA256Transform(phash, phash1, pSHA256InitState); |
|
|
|
|
|
|
|
|
|
// Write the last 4 bytes of the block header (the nonce) to a copy of
|
|
|
|
|
// the double-SHA256 state, and compute the result.
|
|
|
|
|
CHash256(hasher).Write((unsigned char*)&nNonce, 4).Finalize((unsigned char*)phash); |
|
|
|
|
|
|
|
|
|
// Return the nonce if the hash has at least some zero bits,
|
|
|
|
|
// caller will check if it has enough to reach the target
|
|
|
|
|
if (((unsigned short*)phash)[14] == 0) |
|
|
|
|
return nNonce; |
|
|
|
|
if (((uint16_t*)phash)[15] == 0) |
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
// If nothing found after trying for a while, return -1
|
|
|
|
|
if ((nNonce & 0xffff) == 0) |
|
|
|
|
{ |
|
|
|
|
nHashesDone = 0xffff+1; |
|
|
|
|
return (unsigned int) -1; |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
if ((nNonce & 0xfff) == 0) |
|
|
|
|
boost::this_thread::interruption_point(); |
|
|
|
|
} |
|
|
|
@ -541,46 +458,27 @@ void static BitcoinMiner(CWallet *pwallet)
@@ -541,46 +458,27 @@ void static BitcoinMiner(CWallet *pwallet)
|
|
|
|
|
LogPrintf("Running BitcoinMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(), |
|
|
|
|
::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION)); |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Pre-build hash buffers
|
|
|
|
|
//
|
|
|
|
|
char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf); |
|
|
|
|
char pdatabuf[128+16]; char* pdata = alignup<16>(pdatabuf); |
|
|
|
|
char phash1buf[64+16]; char* phash1 = alignup<16>(phash1buf); |
|
|
|
|
|
|
|
|
|
FormatHashBuffers(pblock, pmidstate, pdata, phash1); |
|
|
|
|
|
|
|
|
|
unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4); |
|
|
|
|
unsigned int& nBlockBits = *(unsigned int*)(pdata + 64 + 8); |
|
|
|
|
unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Search
|
|
|
|
|
//
|
|
|
|
|
int64_t nStart = GetTime(); |
|
|
|
|
uint256 hashTarget = uint256().SetCompact(pblock->nBits); |
|
|
|
|
uint256 hashbuf[2]; |
|
|
|
|
uint256& hash = *alignup<16>(hashbuf); |
|
|
|
|
uint256 hash; |
|
|
|
|
uint32_t nNonce = 0; |
|
|
|
|
uint32_t nOldNonce = 0; |
|
|
|
|
while (true) |
|
|
|
|
{ |
|
|
|
|
unsigned int nHashesDone = 0; |
|
|
|
|
unsigned int nNonceFound; |
|
|
|
|
|
|
|
|
|
// Crypto++ SHA256
|
|
|
|
|
nNonceFound = ScanHash_CryptoPP(pmidstate, pdata + 64, phash1, |
|
|
|
|
(char*)&hash, nHashesDone); |
|
|
|
|
bool fFound = ScanHash(pblock, nNonce, &hash); |
|
|
|
|
uint32_t nHashesDone = nNonce - nOldNonce; |
|
|
|
|
nOldNonce = nNonce; |
|
|
|
|
|
|
|
|
|
// Check if something found
|
|
|
|
|
if (nNonceFound != (unsigned int) -1) |
|
|
|
|
if (fFound) |
|
|
|
|
{ |
|
|
|
|
for (unsigned int i = 0; i < sizeof(hash)/4; i++) |
|
|
|
|
((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]); |
|
|
|
|
|
|
|
|
|
if (hash <= hashTarget) |
|
|
|
|
{ |
|
|
|
|
// Found a solution
|
|
|
|
|
pblock->nNonce = ByteReverse(nNonceFound); |
|
|
|
|
pblock->nNonce = nNonce; |
|
|
|
|
assert(hash == pblock->GetHash()); |
|
|
|
|
|
|
|
|
|
SetThreadPriority(THREAD_PRIORITY_NORMAL); |
|
|
|
@ -629,7 +527,7 @@ void static BitcoinMiner(CWallet *pwallet)
@@ -629,7 +527,7 @@ void static BitcoinMiner(CWallet *pwallet)
|
|
|
|
|
// Regtest mode doesn't require peers
|
|
|
|
|
if (vNodes.empty() && Params().MiningRequiresPeers()) |
|
|
|
|
break; |
|
|
|
|
if (nBlockNonce >= 0xffff0000) |
|
|
|
|
if (nNonce >= 0xffff0000) |
|
|
|
|
break; |
|
|
|
|
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60) |
|
|
|
|
break; |
|
|
|
@ -638,11 +536,9 @@ void static BitcoinMiner(CWallet *pwallet)
@@ -638,11 +536,9 @@ void static BitcoinMiner(CWallet *pwallet)
|
|
|
|
|
|
|
|
|
|
// Update nTime every few seconds
|
|
|
|
|
UpdateTime(*pblock, pindexPrev); |
|
|
|
|
nBlockTime = ByteReverse(pblock->nTime); |
|
|
|
|
if (Params().AllowMinDifficultyBlocks()) |
|
|
|
|
{ |
|
|
|
|
// Changing pblock->nTime can change work required on testnet:
|
|
|
|
|
nBlockBits = ByteReverse(pblock->nBits); |
|
|
|
|
hashTarget.SetCompact(pblock->nBits); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|