diff --git a/src/miner.cpp b/src/miner.cpp index ee85a52eb..d18072040 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -118,7 +118,7 @@ public: }; extern int8_t ASSETCHAINS_ADAPTIVEPOW; -extern uint32_t ASSETCHAINS_RANDOMX; +extern uint32_t ASSETCHAINS_RANDOMX, ASSETCHAINS_MEMHASH; extern bool fRandomXDebug; void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev) @@ -1412,6 +1412,172 @@ void static RandomXMiner() c.disconnect(); } +#ifdef ENABLE_WALLET +void static MemhashMiner(CWallet *pwallet) +#else +void static MemhashMiner() +#endif +{ + LogPrintf("HushMemhashMiner started\n"); + SetThreadPriority(THREAD_PRIORITY_LOWEST); + RenameThread("hush-memhash"); + const CChainParams& chainparams = Params(); + +#ifdef ENABLE_WALLET + // Each thread has its own key + CReserveKey reservekey(pwallet); +#endif + // Each thread has its own counter + unsigned int nExtraNonce = 0; + + uint8_t *script; uint64_t total; int32_t i,j,gpucount=HUSH_MAXGPUCOUNT,notaryid = -1; + while ( (ASSETCHAIN_INIT == 0 || HUSH_INITDONE == 0) ) + { + sleep(1); + if ( hush_baseid(SMART_CHAIN_SYMBOL) < 0 ) + break; + } + + std::mutex m_cs; + bool cancelSolver = false; + boost::signals2::connection c = uiInterface.NotifyBlockTip.connect( + [&m_cs, &cancelSolver](const uint256& hashNewTip) mutable { + std::lock_guard lock{m_cs}; + cancelSolver = true; + } + ); + miningTimer.start(); + + // TODO: Start actual memhash stuff + try { + fprintf(stderr,"MemhashMiner: mining %s with memhash\n",SMART_CHAIN_SYMBOL); + while(true) { + fprintf(stderr,"MemhashMiner: beginning mining loop on %s with nExtraNonce=%u\n",SMART_CHAIN_SYMBOL, nExtraNonce); + if (chainparams.MiningRequiresPeers()) { + miningTimer.stop(); + do { + bool fvNodesEmpty; + { + fvNodesEmpty = vNodes.empty(); + } + if (!fvNodesEmpty ) + break; + MilliSleep(15000); + + } while (true); + miningTimer.start(); + } + + // Create new block + unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); + CBlockIndex* pindexPrev = chainActive.LastTip(); + + // If we don't have a valid chain tip to work from, wait and try again. + if (pindexPrev == nullptr) { + fprintf(stderr,"%s: null pindexPrev, trying again...\n",__func__); + MilliSleep(1000); + continue; + } + + if ( Mining_height != pindexPrev->GetHeight()+1 ) + { + Mining_height = pindexPrev->GetHeight()+1; + Mining_start = (uint32_t)time(NULL); + } + +#ifdef ENABLE_WALLET + CBlockTemplate *ptr = CreateNewBlockWithKey(reservekey, pindexPrev->GetHeight()+1, gpucount, 0); +#else + CBlockTemplate *ptr = CreateNewBlockWithKey(); +#endif + if ( ptr == 0 ) + { + if ( !GetBoolArg("-gen",false)) + { + miningTimer.stop(); + c.disconnect(); + LogPrintf("HushMemhashMiner terminated\n"); + return; + } + static uint32_t counter; + if ( counter++ < 10 ) + fprintf(stderr,"MemhashMiner: created illegal blockB, retry with counter=%u\n", counter); + sleep(1); + continue; + } + + unique_ptr pblocktemplate(ptr); + if (!pblocktemplate.get()) + { + if (GetArg("-mineraddress", "").empty()) { + LogPrintf("Error in HushMemhashMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n"); + } else { + // Should never reach here, because -mineraddress validity is checked in init.cpp + LogPrintf("Error in HushMemhashMiner: Invalid -mineraddress\n"); + } + return; + } + CBlock *pblock = &pblocktemplate->block; + if ( ASSETCHAINS_REWARD[0] == 0 && !ASSETCHAINS_LASTERA ) + { + if ( pblock->vtx.size() == 1 && pblock->vtx[0].vout.size() == 1 && Mining_height > ASSETCHAINS_MINHEIGHT ) + { + static uint32_t counter; + if ( counter++ < 10 ) + fprintf(stderr,"skip generating %s on-demand block, no tx avail\n",SMART_CHAIN_SYMBOL); + sleep(10); + continue; + } else fprintf(stderr,"%s vouts.%d mining.%d vs %d\n",SMART_CHAIN_SYMBOL,(int32_t)pblock->vtx[0].vout.size(),Mining_height,ASSETCHAINS_MINHEIGHT); + } + + IncrementExtraNonce(pblock, pindexPrev, nExtraNonce); + LogPrintf("Running HushMemhashMiner with %u transactions in block (%u bytes)\n",pblock->vtx.size(),::GetSerializeSize(*pblock,SER_NETWORK,PROTOCOL_VERSION)); + + // Search + uint8_t pubkeys[66][33]; arith_uint256 bnMaxPoSdiff; uint32_t blocktimes[66]; int mids[256],nonzpkeys,i,j,externalflag; + uint32_t savebits; + int64_t nStart = GetTime(); + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus()); + savebits = pblock->nBits; + HASHTarget = arith_uint256().SetCompact(savebits); + roundrobin_delay = ROUNDROBIN_DELAY; + Mining_start = 0; + gotinvalid = 0; + + while (true) + { + if ( gotinvalid != 0 ) { + fprintf(stderr,"HushMemhashMiner: gotinvalid=%d\n",gotinvalid); + break; + } + hush_longestchain(); + fprintf(stderr,"HushMemhashMiner: solving with nNonce = %s\n",pblock->nNonce.ToString().c_str()); + + arith_uint256 hashTarget; + hashTarget = HASHTarget; + + CDataStream memhashInput(SER_NETWORK, PROTOCOL_VERSION); + // Use the current block as input + memhashInput << pblocktemplate->block; + //TODO: calculate actual memhash hash with input + //TODO: Use hash to build a valid block + } + } + } catch (const boost::thread_interrupted&) { + miningTimer.stop(); + c.disconnect(); + LogPrintf("HushRandomXMiner terminated\n"); + throw; + } catch (const std::runtime_error &e) { + miningTimer.stop(); + c.disconnect(); + fprintf(stderr,"RandomXMiner: runtime error: %s\n", e.what()); + return; + } + miningTimer.stop(); + c.disconnect(); +} + #ifdef ENABLE_WALLET void static BitcoinMiner(CWallet *pwallet) #else @@ -1869,12 +2035,16 @@ void static BitcoinMiner() minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet)); } else if (ASSETCHAINS_ALGO == ASSETCHAINS_RANDOMX ) { minerThreads->create_thread(boost::bind(&RandomXMiner, pwallet)); + } else if (ASSETCHAINS_ALGO == ASSETCHAINS_MEMHASH ) { + minerThreads->create_thread(boost::bind(&MemhashMiner, pwallet)); } #else if (ASSETCHAINS_ALGO == ASSETCHAINS_EQUIHASH ) { minerThreads->create_thread(&BitcoinMiner); } else if (ASSETCHAINS_ALGO == ASSETCHAINS_RANDOMX) { minerThreads->create_thread(&RandomXMiner); + } else if (ASSETCHAINS_ALGO == ASSETCHAINS_MEMHASH ) { + minerThreads->create_thread(boost::bind(&MemhashMiner)); } #endif }