|
|
@ -1049,6 +1049,18 @@ class RandomXSolverCanceledException : public std::exception |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
class RamhashSolverCanceledException : public std::exception |
|
|
|
{ |
|
|
|
virtual const char* what() const throw() { |
|
|
|
return "Ramhash solver was canceled"; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
enum RamhashSolverCancelCheck |
|
|
|
{ |
|
|
|
Reason1 |
|
|
|
}; |
|
|
|
|
|
|
|
enum RandomXSolverCancelCheck |
|
|
|
{ |
|
|
|
Reason1, |
|
|
@ -1610,8 +1622,116 @@ void static RamhashMiner() |
|
|
|
// Use the current block as input
|
|
|
|
ramhashInput << pblocktemplate->block; |
|
|
|
//TODO: calculate actual ramhash hash with input
|
|
|
|
//TODO: Use hash to build a valid block
|
|
|
|
} |
|
|
|
// ramHash = ...
|
|
|
|
// Use hash to build a valid block
|
|
|
|
std::function<bool(std::vector<unsigned char>)> validBlock = |
|
|
|
#ifdef ENABLE_WALLET |
|
|
|
[&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams] |
|
|
|
#else |
|
|
|
[&pblock, &hashTarget, &m_cs, &cancelSolver, &chainparams] |
|
|
|
#endif |
|
|
|
(std::vector<unsigned char> soln) { |
|
|
|
int32_t z; arith_uint256 h; CBlock B; |
|
|
|
// Write the solution to the hash and compute the result.
|
|
|
|
rhdebug("%s: Checking solution against target\n"); |
|
|
|
pblock->nSolution = soln; |
|
|
|
solutionTargetChecks.increment(); |
|
|
|
// fprintf(stderr,"%s: solutionTargetChecks=%lu\n", __func__, solutionTargetChecks.get());
|
|
|
|
B = *pblock; |
|
|
|
h = UintToArith256(B.GetHash()); |
|
|
|
|
|
|
|
rhdebug("%s: h="); |
|
|
|
if (fRamhashDebug) { |
|
|
|
for (z=31; z>=0; z--) |
|
|
|
fprintf(stderr,"%02x",((uint8_t *)&h)[z]); |
|
|
|
fprintf(stderr," , hashTarget="); |
|
|
|
for (z=31; z>=0; z--) |
|
|
|
fprintf(stderr,"%02x",((uint8_t *)&hashTarget)[z]); |
|
|
|
fprintf(stderr,"\n"); |
|
|
|
} |
|
|
|
|
|
|
|
if ( h > hashTarget ) |
|
|
|
{ |
|
|
|
rhdebug("%s: h > hashTarget"); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
CValidationState state; |
|
|
|
if ( !TestBlockValidity(state,B, chainActive.LastTip(), true, false)) |
|
|
|
{ |
|
|
|
h = UintToArith256(B.GetHash()); |
|
|
|
fprintf(stderr,"RamhashMiner: Invalid ramhash block mined, try again "); |
|
|
|
for (z=31; z>=0; z--) |
|
|
|
fprintf(stderr,"%02x",((uint8_t *)&h)[z]); |
|
|
|
gotinvalid = 1; |
|
|
|
fprintf(stderr,"\n"); |
|
|
|
return(false); |
|
|
|
} |
|
|
|
SetThreadPriority(THREAD_PRIORITY_NORMAL); |
|
|
|
LogPrintf("HushRamhashMiner:\n"); |
|
|
|
LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", B.GetHash().GetHex(), HASHTarget.GetHex()); |
|
|
|
#ifdef ENABLE_WALLET |
|
|
|
if (ProcessBlockFound(&B, *pwallet, reservekey)) { |
|
|
|
#else |
|
|
|
if (ProcessBlockFound(&B)) { |
|
|
|
#endif |
|
|
|
// Ignore chain updates caused by us
|
|
|
|
std::lock_guard<std::mutex> lock{m_cs}; |
|
|
|
cancelSolver = false; |
|
|
|
} |
|
|
|
SetThreadPriority(THREAD_PRIORITY_LOWEST); |
|
|
|
// In regression test mode, stop mining after a block is found.
|
|
|
|
if (chainparams.MineBlocksOnDemand()) { |
|
|
|
// Increment here because throwing skips the call below
|
|
|
|
// TODO: equivalent of ehSolverRuns.increment();
|
|
|
|
throw boost::thread_interrupted(); |
|
|
|
} |
|
|
|
return true; |
|
|
|
}; |
|
|
|
std::function<bool(RamhashSolverCancelCheck)> cancelled = [&m_cs, &cancelSolver](RamhashSolverCancelCheck pos) { |
|
|
|
std::lock_guard<std::mutex> lock{m_cs}; |
|
|
|
return cancelSolver; |
|
|
|
}; |
|
|
|
|
|
|
|
try { |
|
|
|
// Use the ramhash hash as the block solution
|
|
|
|
std::vector<unsigned char> sol_char(ramhashHash, ramhashHash+32); |
|
|
|
bool found = validBlock(sol_char); |
|
|
|
if (found) { |
|
|
|
rhdebug("%s: found solution!\n"); |
|
|
|
// If we find a POW solution, do not try other solutions
|
|
|
|
// because they become invalid as we created a new block in blockchain.
|
|
|
|
break; |
|
|
|
} else { |
|
|
|
rhdebug("%s: solution not found, validBlock=false\n"); |
|
|
|
} |
|
|
|
} catch (RamhashSolverCanceledException&) { |
|
|
|
LogPrintf("HushRamhashMiner solver canceled\n"); |
|
|
|
std::lock_guard<std::mutex> lock{m_cs}; |
|
|
|
cancelSolver = false; |
|
|
|
} |
|
|
|
|
|
|
|
boost::this_thread::interruption_point(); |
|
|
|
|
|
|
|
if (vNodes.empty() && chainparams.MiningRequiresPeers()) |
|
|
|
{ |
|
|
|
if ( Mining_height > ASSETCHAINS_MINHEIGHT ) |
|
|
|
{ |
|
|
|
fprintf(stderr,"%s: no nodes, break\n", __func__); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
if ((UintToArith256(pblock->nNonce) & 0xffff) == 0xffff) |
|
|
|
{ |
|
|
|
fprintf(stderr,"%s: nonce & 0xffff == 0xffff, break\n", __func__); |
|
|
|
break; |
|
|
|
} |
|
|
|
// Update nNonce and nTime
|
|
|
|
pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1); |
|
|
|
pblock->nBits = savebits; |
|
|
|
} |
|
|
|
|
|
|
|
} // while(true)
|
|
|
|
} |
|
|
|
} catch (const boost::thread_interrupted&) { |
|
|
|
miningTimer.stop(); |
|
|
|