Auto merge of #1060 - str4d:1033-randomise-nonce, r=ebfull
Randomise the nonce in the block header The top and bottom 16 bits of the nonce are left clear for local use as thread flags and counters. This does not leak any more local information about the miner than is currently exposed. The cleared bits should not be considered a consensus rule, as miners are free to set all bits of the nonce however they wish. Closes #1033
This commit is contained in:
commit
16abefdd22
|
@ -14,6 +14,7 @@
|
|||
#include "net.h"
|
||||
#include "pow.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "random.h"
|
||||
#include "timedata.h"
|
||||
#include "util.h"
|
||||
#include "utilmoneystr.h"
|
||||
|
@ -352,12 +353,18 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
|
|||
pblock->vtx[0] = txNew;
|
||||
pblocktemplate->vTxFees[0] = -nFees;
|
||||
|
||||
// Randomise nonce
|
||||
arith_uint256 nonce = UintToArith256(GetRandHash());
|
||||
// Clear the top and bottom 16 bits (for local use as thread flags and counters)
|
||||
nonce <<= 32;
|
||||
nonce >>= 16;
|
||||
pblock->nNonce = ArithToUint256(nonce);
|
||||
|
||||
// Fill in header
|
||||
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
|
||||
pblock->hashReserved = uint256();
|
||||
UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
|
||||
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
|
||||
pblock->nNonce = uint256();
|
||||
pblock->nSolution.clear();
|
||||
pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]);
|
||||
|
||||
|
@ -501,63 +508,56 @@ void static BitcoinMiner(CWallet *pwallet)
|
|||
// H(I||...
|
||||
crypto_generichash_blake2b_update(&state, (unsigned char*)&ss[0], ss.size());
|
||||
|
||||
// Find valid nonce
|
||||
while (true)
|
||||
{
|
||||
// H(I||V||...
|
||||
crypto_generichash_blake2b_state curr_state;
|
||||
curr_state = state;
|
||||
crypto_generichash_blake2b_update(&curr_state,
|
||||
pblock->nNonce.begin(),
|
||||
pblock->nNonce.size());
|
||||
// H(I||V||...
|
||||
crypto_generichash_blake2b_state curr_state;
|
||||
curr_state = state;
|
||||
crypto_generichash_blake2b_update(&curr_state,
|
||||
pblock->nNonce.begin(),
|
||||
pblock->nNonce.size());
|
||||
|
||||
// (x_1, x_2, ...) = A(I, V, n, k)
|
||||
LogPrint("pow", "Running Equihash solver with nNonce = %s\n",
|
||||
pblock->nNonce.ToString());
|
||||
std::set<std::vector<unsigned int>> solns;
|
||||
EhOptimisedSolve(n, k, curr_state, solns);
|
||||
LogPrint("pow", "Solutions: %d\n", solns.size());
|
||||
// (x_1, x_2, ...) = A(I, V, n, k)
|
||||
LogPrint("pow", "Running Equihash solver with nNonce = %s\n",
|
||||
pblock->nNonce.ToString());
|
||||
std::set<std::vector<unsigned int>> solns;
|
||||
EhOptimisedSolve(n, k, curr_state, solns);
|
||||
LogPrint("pow", "Solutions: %d\n", solns.size());
|
||||
|
||||
// Write the solution to the hash and compute the result.
|
||||
for (auto soln : solns) {
|
||||
pblock->nSolution = soln;
|
||||
// Write the solution to the hash and compute the result.
|
||||
for (auto soln : solns) {
|
||||
pblock->nSolution = soln;
|
||||
|
||||
if (UintToArith256(pblock->GetHash()) > hashTarget) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Found a solution
|
||||
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
||||
LogPrintf("ZcashMiner:\n");
|
||||
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex());
|
||||
ProcessBlockFound(pblock, *pwallet, reservekey);
|
||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||
|
||||
// In regression test mode, stop mining after a block is found.
|
||||
if (chainparams.MineBlocksOnDemand())
|
||||
throw boost::thread_interrupted();
|
||||
|
||||
goto updateblock;
|
||||
if (UintToArith256(pblock->GetHash()) > hashTarget) {
|
||||
continue;
|
||||
}
|
||||
pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
|
||||
if ((UintToArith256(pblock->nNonce) & 0x1) == 0)
|
||||
break;
|
||||
|
||||
// Found a solution
|
||||
SetThreadPriority(THREAD_PRIORITY_NORMAL);
|
||||
LogPrintf("ZcashMiner:\n");
|
||||
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex());
|
||||
ProcessBlockFound(pblock, *pwallet, reservekey);
|
||||
SetThreadPriority(THREAD_PRIORITY_LOWEST);
|
||||
|
||||
// In regression test mode, stop mining after a block is found.
|
||||
if (chainparams.MineBlocksOnDemand())
|
||||
throw boost::thread_interrupted();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
updateblock:
|
||||
// Check for stop or if block needs to be rebuilt
|
||||
boost::this_thread::interruption_point();
|
||||
// Regtest mode doesn't require peers
|
||||
if (vNodes.empty() && chainparams.MiningRequiresPeers())
|
||||
break;
|
||||
if (UintToArith256(pblock->nNonce) >= 0xffff)
|
||||
if ((UintToArith256(pblock->nNonce) & 0xffff) == 0xffff)
|
||||
break;
|
||||
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
|
||||
break;
|
||||
if (pindexPrev != chainActive.Tip())
|
||||
break;
|
||||
|
||||
// Update nTime every few seconds
|
||||
// Update nNonce and nTime
|
||||
pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
|
||||
UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
|
||||
if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue