1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
8 #include "pow/tromp/equi_miner.h"
12 #include "chainparams.h"
13 #include "cc/StakeGuard.h"
14 #include "importcoin.h"
15 #include "consensus/consensus.h"
16 #include "consensus/upgrades.h"
17 #include "consensus/validation.h"
19 #include "crypto/equihash.h"
20 #include "crypto/verus_hash.h"
28 #include "primitives/transaction.h"
31 #include "ui_interface.h"
33 #include "utilmoneystr.h"
35 #include "wallet/wallet.h"
38 #include "zcash/Address.hpp"
39 #include "transaction_builder.h"
43 #include <boost/thread.hpp>
44 #include <boost/tuple/tuple.hpp>
50 #include "pbaas/pbaas.h"
51 #include "pbaas/notarization.h"
55 //////////////////////////////////////////////////////////////////////////////
61 // Unconfirmed transactions in the memory pool often depend on other
62 // transactions in the memory pool. When we select transactions from the
63 // pool, we select by highest priority or fee rate, so we might consider
64 // transactions that depend on transactions that aren't yet in the block.
65 // The COrphan class keeps track of these 'temporary orphans' while
66 // CreateBlock is figuring out which transactions to include.
71 const CTransaction* ptx;
72 set<uint256> setDependsOn;
76 COrphan(const CTransaction* ptxIn) : ptx(ptxIn), feeRate(0), dPriority(0)
81 uint64_t nLastBlockTx = 0;
82 uint64_t nLastBlockSize = 0;
84 // We want to sort transactions by priority and fee rate, so:
85 typedef boost::tuple<double, CFeeRate, const CTransaction*> TxPriority;
86 class TxPriorityCompare
91 TxPriorityCompare(bool _byFee) : byFee(_byFee) { }
93 bool operator()(const TxPriority& a, const TxPriority& b)
97 if (a.get<1>() == b.get<1>())
98 return a.get<0>() < b.get<0>();
99 return a.get<1>() < b.get<1>();
103 if (a.get<0>() == b.get<0>())
104 return a.get<1>() < b.get<1>();
105 return a.get<0>() < b.get<0>();
110 void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
112 pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
114 // Updating time can change work required on testnet:
115 if (consensusParams.nPowAllowMinDifficultyBlocksAfterHeight != boost::none) {
116 pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams);
120 #include "komodo_defs.h"
122 extern CCriticalSection cs_metrics;
123 extern int32_t KOMODO_MININGTHREADS,KOMODO_LONGESTCHAIN,ASSETCHAINS_SEED,IS_KOMODO_NOTARY,USE_EXTERNAL_PUBKEY,KOMODO_CHOSEN_ONE,ASSETCHAIN_INIT,KOMODO_INITDONE,KOMODO_ON_DEMAND,KOMODO_INITDONE,KOMODO_PASSPORT_INITDONE;
124 extern uint64_t ASSETCHAINS_COMMISSION, ASSETCHAINS_STAKED;
125 extern bool VERUS_MINTBLOCKS;
126 extern uint64_t ASSETCHAINS_REWARD[ASSETCHAINS_MAX_ERAS], ASSETCHAINS_TIMELOCKGTE, ASSETCHAINS_NONCEMASK[];
127 extern const char *ASSETCHAINS_ALGORITHMS[];
128 extern int32_t VERUS_MIN_STAKEAGE, ASSETCHAINS_ALGO, ASSETCHAINS_EQUIHASH, ASSETCHAINS_VERUSHASH, ASSETCHAINS_LASTERA, ASSETCHAINS_LWMAPOS, ASSETCHAINS_NONCESHIFT[], ASSETCHAINS_HASHESPERROUND[];
129 extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
130 extern uint160 ASSETCHAINS_CHAINID;
131 extern uint160 VERUS_CHAINID;
132 extern std::string VERUS_CHAINNAME;
133 extern int32_t PBAAS_STARTBLOCK, PBAAS_ENDBLOCK;
134 extern string PBAAS_HOST, PBAAS_USERPASS;
135 extern int32_t PBAAS_PORT;
136 extern std::string NOTARY_PUBKEY,ASSETCHAINS_OVERRIDE_PUBKEY;
137 void vcalc_sha256(char deprecated[(256 >> 3) * 2 + 1],uint8_t hash[256 >> 3],uint8_t *src,int32_t len);
139 extern uint8_t NOTARY_PUBKEY33[33],ASSETCHAINS_OVERRIDE_PUBKEY33[33];
140 uint32_t Mining_start,Mining_height;
141 int32_t My_notaryid = -1;
142 int32_t komodo_chosennotary(int32_t *notaryidp,int32_t height,uint8_t *pubkey33,uint32_t timestamp);
143 int32_t komodo_pax_opreturn(int32_t height,uint8_t *opret,int32_t maxsize);
144 int32_t komodo_baseid(char *origbase);
145 int32_t komodo_validate_interest(const CTransaction &tx,int32_t txheight,uint32_t nTime,int32_t dispflag);
146 int64_t komodo_block_unlocktime(uint32_t nHeight);
147 uint64_t komodo_commission(const CBlock *block);
148 int32_t komodo_staked(CMutableTransaction &txNew,uint32_t nBits,uint32_t *blocktimep,uint32_t *txtimep,uint256 *utxotxidp,int32_t *utxovoutp,uint64_t *utxovaluep,uint8_t *utxosig);
149 int32_t verus_staked(CBlock *pBlock, CMutableTransaction &txNew, uint32_t &nBits, arith_uint256 &hashResult, uint8_t *utxosig, CPubKey &pk);
150 int32_t komodo_notaryvin(CMutableTransaction &txNew,uint8_t *notarypub33);
152 CBlockTemplate* CreateNewBlock(const CScript& _scriptPubKeyIn, int32_t gpucount, bool isStake)
154 CScript scriptPubKeyIn(_scriptPubKeyIn);
156 CPubKey pk = CPubKey();
157 std::vector<std::vector<unsigned char>> vAddrs;
159 if (Solver(scriptPubKeyIn, txT, vAddrs))
161 if (txT == TX_PUBKEY)
162 pk = CPubKey(vAddrs[0]);
165 uint64_t deposits; int32_t isrealtime,kmdheight; uint32_t blocktime; const CChainParams& chainparams = Params();
166 //fprintf(stderr,"create new block\n");
169 gpucount = KOMODO_MAXGPUCOUNT;
170 std::unique_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate());
171 if(!pblocktemplate.get())
173 fprintf(stderr,"pblocktemplate.get() failure\n");
176 CBlock *pblock = &pblocktemplate->block; // pointer for convenience
178 // set version according to the current tip height, add solution if it is
180 if (ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASH)
182 pblock->nSolution.resize(Eh200_9.SolutionWidth);
186 pblock->nSolution.clear();
188 pblock->SetVersionByHeight(chainActive.LastTip()->GetHeight() + 1);
190 // -regtest only: allow overriding block.nVersion with
191 // -blockversion=N to test forking scenarios
192 if (Params().MineBlocksOnDemand())
193 pblock->nVersion = GetArg("-blockversion", pblock->nVersion);
195 // Add dummy coinbase tx as first transaction
196 pblock->vtx.push_back(CTransaction());
197 pblocktemplate->vTxFees.push_back(-1); // updated at end
198 pblocktemplate->vTxSigOps.push_back(-1); // updated at end
200 // Largest block you're willing to create:
201 unsigned int nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE);
202 // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity:
203 nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize));
205 // How much of the block should be dedicated to high-priority transactions,
206 // included regardless of the fees they pay
207 unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", DEFAULT_BLOCK_PRIORITY_SIZE);
208 nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize);
210 // Minimum block size you want to create; block will be filled with free transactions
211 // until there are no more or the block reaches this size:
212 unsigned int nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE);
213 nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize);
215 // Collect memory pool transactions into the block
218 // we will attempt to spend any cheats we see
219 CTransaction cheatTx;
220 boost::optional<CTransaction> cheatSpend;
223 CBlockIndex* pindexPrev = 0;
225 LOCK2(cs_main, mempool.cs);
226 pindexPrev = chainActive.LastTip();
227 const int nHeight = pindexPrev->GetHeight() + 1;
228 const Consensus::Params &consensusParams = chainparams.GetConsensus();
229 uint32_t consensusBranchId = CurrentEpochBranchId(nHeight, consensusParams);
230 bool sapling = NetworkUpgradeActive(nHeight, consensusParams, Consensus::UPGRADE_SAPLING);
232 const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast();
233 uint32_t proposedTime = GetAdjustedTime();
234 if (proposedTime == nMedianTimePast)
236 // too fast or stuck, this addresses the too fast issue, while moving
237 // forward as quickly as possible
238 for (int i; i < 100; i++)
240 proposedTime = GetAdjustedTime();
241 if (proposedTime == nMedianTimePast)
245 pblock->nTime = GetAdjustedTime();
247 CCoinsViewCache view(pcoinsTip);
248 uint32_t expired; uint64_t commission;
250 SaplingMerkleTree sapling_tree;
251 assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
253 // Priority order to process transactions
254 list<COrphan> vOrphan; // list memory doesn't move
255 map<uint256, vector<COrphan*> > mapDependers;
256 bool fPrintPriority = GetBoolArg("-printpriority", false);
258 // This vector will be sorted into a priority queue:
259 vector<TxPriority> vecPriority;
260 vecPriority.reserve(mempool.mapTx.size() + 1);
262 // check if we should add cheat transaction
265 int cheatHeight = nHeight - COINBASE_MATURITY < 1 ? 1 : nHeight - COINBASE_MATURITY;
267 sapling && chainActive.Height() > 100 &&
268 (ppast = chainActive[cheatHeight]) &&
269 ppast->IsVerusPOSBlock() &&
270 cheatList.IsHeightOrGreaterInList(cheatHeight))
272 // get the block and see if there is a cheat candidate for the stake tx
274 if (!(fHavePruned && !(ppast->nStatus & BLOCK_HAVE_DATA) && ppast->nTx > 0) && ReadBlockFromDisk(b, ppast, 1))
276 CTransaction &stakeTx = b.vtx[b.vtx.size() - 1];
278 if (cheatList.IsCheatInList(stakeTx, &cheatTx))
280 // make and sign the cheat transaction to spend the coinbase to our address
281 CMutableTransaction mtx = CreateNewContextualCMutableTransaction(consensusParams, nHeight);
284 // get the first vout with value
285 for (voutNum = 0; voutNum < b.vtx[0].vout.size(); voutNum++)
287 if (b.vtx[0].vout[voutNum].nValue > 0)
291 // send to the same pub key as the destination of this block reward
292 if (MakeCheatEvidence(mtx, b.vtx[0], voutNum, cheatTx))
294 extern CWallet *pwalletMain;
295 LOCK(pwalletMain->cs_wallet);
296 TransactionBuilder tb = TransactionBuilder(consensusParams, nHeight);
298 cbHash = cb.GetHash();
300 bool hasInput = false;
301 for (uint32_t i = 0; i < cb.vout.size(); i++)
303 // add the spends with the cheat
304 if (cb.vout[i].nValue > 0)
306 tb.AddTransparentInput(COutPoint(cbHash,i), cb.vout[0].scriptPubKey, cb.vout[0].nValue);
313 // this is a send from a t-address to a sapling address, which we don't have an ovk for.
314 // Instead, generate a common one from the HD seed. This ensures the data is
315 // recoverable, at least for us, while keeping it logically separate from the ZIP 32
316 // Sapling key hierarchy, which the user might not be using.
319 if (pwalletMain->GetHDSeed(seed)) {
320 ovk = ovkForShieldingFromTaddr(seed);
322 // send everything to Sapling address
323 tb.SendChangeTo(cheatCatcher.value(), ovk);
325 tb.AddOpRet(mtx.vout[mtx.vout.size() - 1].scriptPubKey);
327 cheatSpend = tb.Build();
337 cheatTx = cheatSpend.value();
338 std::list<CTransaction> removed;
339 mempool.removeConflicts(cheatTx, removed);
340 printf("Found cheating stake! Adding cheat spend for %.8f at block #%d, coinbase tx\n%s\n",
341 (double)cb.GetValueOut() / (double)COIN, nHeight, cheatSpend.value().vin[0].prevout.hash.GetHex().c_str());
343 // add to mem pool and relay
344 if (myAddtomempool(cheatTx))
346 RelayTransaction(cheatTx);
350 // if we are a PBaaS chain, first make sure we don't start prematurely, and if
351 // we should make an earned notarization, make it and set index to non-zero value
352 int32_t pbaasNotarizationTx = 0;
353 int64_t pbaasTransparentIn = 0;
354 int64_t pbaasTransparentOut = 0;
355 if (!IsVerusActive())
357 // if we don't have a connected root PBaaS chain, we can't properly check
358 // and notarize the start block, so we have to pass and wait
359 if (nHeight != 1 || (ConnectedChains.IsVerusPBaaSAvailable() && ConnectedChains.notaryChainHeight >= PBAAS_STARTBLOCK))
361 // if we have access to our parent daemon
362 // create a notarization, if we would qualify, and add it to the mempool and block
363 CMutableTransaction newNotarizationTx;
364 CTransaction prevTx, crossTx;
365 ChainMerkleMountainView mmv = chainActive.GetMMV();
366 uint256 mmrRoot = mmv.GetRoot();
367 if (CreateEarnedNotarization(newNotarizationTx, prevTx, crossTx, nHeight, mmrRoot))
369 // we have a valid, earned notarization transaction. we still need to verify:
370 // 1. it has matching input for its outputs, since it can be returned with less than enough,
371 // if there is not enough, take it as instant-spend from the coinbase. if there is too much,
372 // increase the output on the main notarization thread.
373 // instant-spend and notarization
374 // transaction threads on a PBaaS chain can only be used for notarization, and can never convert to
377 // Fetch previous transactions (inputs):
378 for (const CTxIn& txin : newNotarizationTx.vin)
380 const uint256& prevHash = txin.prevout.hash;
381 const CCoins *pcoins = view.AccessCoins(prevHash); // this is certainly allowed to fail
382 pbaasTransparentIn += pcoins && (pcoins->vout.size() > txin.prevout.n) ? pcoins->vout[txin.prevout.n].nValue : 0;
385 for (auto txout : newNotarizationTx.vout)
387 pbaasTransparentOut += txout.nValue;
390 if (pbaasTransparentOut < pbaasTransparentIn)
392 // add excess to the notarization output
393 int notarizeOut = -1;
394 for (int outIdx = 0; outIdx < newNotarizationTx.vout.size(); outIdx++)
397 if (newNotarizationTx.vout[outIdx].scriptPubKey.IsPayToCryptoCondition(&ecode))
399 if (ecode == EVAL_EARNEDNOTARIZATION)
401 newNotarizationTx.vout[outIdx].nValue += pbaasTransparentIn - pbaasTransparentOut;
408 if (pbaasTransparentOut > pbaasTransparentIn)
410 // add an incomplete input to spend a coinbase instant spend output to fund the notarization
411 newNotarizationTx.vin.push_back(CTxIn());
414 pblock->vtx.push_back(CTransaction(newNotarizationTx));
415 pblocktemplate->vTxFees.push_back(0);
416 pblocktemplate->vTxSigOps.push_back(-1); // updated at end
417 pbaasNotarizationTx = pblock->vtx.size() - 1;
419 else if (nHeight == 1)
421 // failed to notarize at block 1
427 // can't mine block 1 unless we have a connection to Verus and can notarize
432 // now add transactions from the mem pool
433 for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin();
434 mi != mempool.mapTx.end(); ++mi)
436 const CTransaction& tx = mi->GetTx();
438 int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST)
440 : pblock->GetBlockTime();
442 if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, nLockTimeCutoff) || IsExpiredTx(tx, nHeight))
444 //fprintf(stderr,"coinbase.%d finaltx.%d expired.%d\n",tx.IsCoinBase(),IsFinalTx(tx, nHeight, nLockTimeCutoff),IsExpiredTx(tx, nHeight));
448 if ( ASSETCHAINS_SYMBOL[0] == 0 && komodo_validate_interest(tx,nHeight,(uint32_t)pblock->nTime,0) < 0 )
450 //fprintf(stderr,"CreateNewBlock: komodo_validate_interest failure nHeight.%d nTime.%u vs locktime.%u\n",nHeight,(uint32_t)pblock->nTime,(uint32_t)tx.nLockTime);
454 COrphan* porphan = NULL;
455 double dPriority = 0;
456 CAmount nTotalIn = 0;
457 bool fMissingInputs = false;
458 if (tx.IsCoinImport())
460 CAmount nValueIn = GetCoinImportValue(tx);
461 nTotalIn += nValueIn;
462 dPriority += (double)nValueIn * 1000; // flat multiplier
464 BOOST_FOREACH(const CTxIn& txin, tx.vin)
466 // Read prev transaction
467 if (!view.HaveCoins(txin.prevout.hash))
469 // This should never happen; all transactions in the memory
470 // pool should connect to either transactions in the chain
471 // or other transactions in the memory pool.
472 if (!mempool.mapTx.count(txin.prevout.hash))
474 LogPrintf("ERROR: mempool transaction missing input\n");
475 if (fDebug) assert("mempool transaction missing input" == 0);
476 fMissingInputs = true;
482 // Has to wait for dependencies
485 // Use list for automatic deletion
486 vOrphan.push_back(COrphan(&tx));
487 porphan = &vOrphan.back();
489 mapDependers[txin.prevout.hash].push_back(porphan);
490 porphan->setDependsOn.insert(txin.prevout.hash);
491 nTotalIn += mempool.mapTx.find(txin.prevout.hash)->GetTx().vout[txin.prevout.n].nValue;
494 const CCoins* coins = view.AccessCoins(txin.prevout.hash);
497 CAmount nValueIn = coins->vout[txin.prevout.n].nValue;
498 nTotalIn += nValueIn;
500 int nConf = nHeight - coins->nHeight;
502 dPriority += (double)nValueIn * nConf;
504 nTotalIn += tx.GetShieldedValueIn();
507 if (fMissingInputs) continue;
509 // Priority is sum(valuein * age) / modified_txsize
510 unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
511 dPriority = tx.ComputePriority(dPriority, nTxSize);
513 uint256 hash = tx.GetHash();
514 mempool.ApplyDeltas(hash, dPriority, nTotalIn);
516 CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);
520 porphan->dPriority = dPriority;
521 porphan->feeRate = feeRate;
524 vecPriority.push_back(TxPriority(dPriority, feeRate, &(mi->GetTx())));
527 // Collect transactions into block
528 uint64_t nBlockSize = 1000;
529 uint64_t nBlockTx = 0;
531 int nBlockSigOps = 100;
532 bool fSortedByFee = (nBlockPrioritySize <= 0);
534 TxPriorityCompare comparer(fSortedByFee);
535 std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
537 while (!vecPriority.empty())
539 // Take highest priority transaction off the priority queue:
540 double dPriority = vecPriority.front().get<0>();
541 CFeeRate feeRate = vecPriority.front().get<1>();
542 const CTransaction& tx = *(vecPriority.front().get<2>());
544 std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer);
545 vecPriority.pop_back();
548 unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
549 if (nBlockSize + nTxSize >= nBlockMaxSize-512) // room for extra autotx
551 //fprintf(stderr,"nBlockSize %d + %d nTxSize >= %d nBlockMaxSize\n",(int32_t)nBlockSize,(int32_t)nTxSize,(int32_t)nBlockMaxSize);
555 // Legacy limits on sigOps:
556 unsigned int nTxSigOps = GetLegacySigOpCount(tx);
557 if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS-1)
559 //fprintf(stderr,"A nBlockSigOps %d + %d nTxSigOps >= %d MAX_BLOCK_SIGOPS-1\n",(int32_t)nBlockSigOps,(int32_t)nTxSigOps,(int32_t)MAX_BLOCK_SIGOPS);
562 // Skip free transactions if we're past the minimum block size:
563 const uint256& hash = tx.GetHash();
564 double dPriorityDelta = 0;
565 CAmount nFeeDelta = 0;
566 mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
567 if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
569 //fprintf(stderr,"fee rate skip\n");
572 // Prioritise by fee once past the priority size or we run out of high-priority
575 ((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority)))
578 comparer = TxPriorityCompare(fSortedByFee);
579 std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
582 if (!view.HaveInputs(tx))
584 //fprintf(stderr,"dont have inputs\n");
587 CAmount nTxFees = view.GetValueIn(chainActive.LastTip()->GetHeight(),&interest,tx,chainActive.LastTip()->nTime)-tx.GetValueOut();
589 nTxSigOps += GetP2SHSigOpCount(tx, view);
590 if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS-1)
592 //fprintf(stderr,"B nBlockSigOps %d + %d nTxSigOps >= %d MAX_BLOCK_SIGOPS-1\n",(int32_t)nBlockSigOps,(int32_t)nTxSigOps,(int32_t)MAX_BLOCK_SIGOPS);
595 // Note that flags: we don't want to set mempool/IsStandard()
596 // policy here, but we still have to ensure that the block we
597 // create only contains transactions that are valid in new blocks.
598 CValidationState state;
599 PrecomputedTransactionData txdata(tx);
600 if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, Params().GetConsensus(), consensusBranchId))
602 //fprintf(stderr,"context failure\n");
605 UpdateCoins(tx, view, nHeight);
607 BOOST_FOREACH(const OutputDescription &outDescription, tx.vShieldedOutput) {
608 sapling_tree.append(outDescription.cm);
612 pblock->vtx.push_back(tx);
613 pblocktemplate->vTxFees.push_back(nTxFees);
614 pblocktemplate->vTxSigOps.push_back(nTxSigOps);
615 nBlockSize += nTxSize;
617 nBlockSigOps += nTxSigOps;
622 LogPrintf("priority %.1f fee %s txid %s\n",dPriority, feeRate.ToString(), tx.GetHash().ToString());
625 // Add transactions that depend on this one to the priority queue
626 if (mapDependers.count(hash))
628 BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
630 if (!porphan->setDependsOn.empty())
632 porphan->setDependsOn.erase(hash);
633 if (porphan->setDependsOn.empty())
635 vecPriority.push_back(TxPriority(porphan->dPriority, porphan->feeRate, porphan->ptx));
636 std::push_heap(vecPriority.begin(), vecPriority.end(), comparer);
643 nLastBlockTx = nBlockTx;
644 nLastBlockSize = nBlockSize;
645 blocktime = 1 + std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
646 //pblock->nTime = blocktime + 1;
647 pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
649 int32_t stakeHeight = chainActive.Height() + 1;
651 //LogPrintf("CreateNewBlock(): total size %u blocktime.%u nBits.%08x\n", nBlockSize,blocktime,pblock->nBits);
652 if ( ASSETCHAINS_SYMBOL[0] != 0 && isStake )
654 uint64_t txfees,utxovalue; uint32_t txtime; uint256 utxotxid; int32_t i,siglen,numsigs,utxovout; uint8_t utxosig[128],*ptr;
655 CMutableTransaction txStaked = CreateNewContextualCMutableTransaction(Params().GetConsensus(), stakeHeight);
657 //if ( blocktime > pindexPrev->GetMedianTimePast()+60 )
658 // blocktime = pindexPrev->GetMedianTimePast() + 60;
659 if (ASSETCHAINS_LWMAPOS != 0)
662 arith_uint256 posHash;
664 siglen = verus_staked(pblock, txStaked, nBitsPOS, posHash, utxosig, pk);
665 blocktime = GetAdjustedTime();
667 // change the scriptPubKeyIn to the same output script exactly as the staking transaction
669 scriptPubKeyIn = CScript(txStaked.vout[0].scriptPubKey);
673 siglen = komodo_staked(txStaked, pblock->nBits, &blocktime, &txtime, &utxotxid, &utxovout, &utxovalue, utxosig);
680 // after Sapling, stake transactions have a fee, but it is recovered in the reward
681 // this ensures that a rebroadcast goes through quickly to begin staking again
682 txfees = sapling ? DEFAULT_STAKE_TXFEE : 0;
684 pblock->vtx.push_back(txStaked);
685 pblocktemplate->vTxFees.push_back(txfees);
686 pblocktemplate->vTxSigOps.push_back(GetLegacySigOpCount(txStaked));
688 pblock->nTime = blocktime;
689 //printf("staking PoS ht.%d t%u lag.%u\n",(int32_t)chainActive.LastTip()->GetHeight()+1,blocktime,(uint32_t)(GetAdjustedTime() - (blocktime-13)));
690 } else return(0); //fprintf(stderr,"no utxos eligible for staking\n");
693 // Create coinbase tx
694 CMutableTransaction txNew = CreateNewContextualCMutableTransaction(consensusParams, nHeight);
696 txNew.vin[0].prevout.SetNull();
697 txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;
699 txNew.vout.resize(1);
700 txNew.vout[0].scriptPubKey = scriptPubKeyIn;
701 txNew.vout[0].nValue = GetBlockSubsidy(nHeight,consensusParams) + nFees;
703 // once we get to Sapling, enable CC StakeGuard for stake transactions
704 if (isStake && sapling)
706 // if there is a specific destination, use it
707 CTransaction stakeTx = pblock->vtx[pblock->vtx.size() - 1];
709 if (ValidateStakeTransaction(stakeTx, p, false))
711 if (!p.pk.IsValid() || !MakeGuardedOutput(txNew.vout[0].nValue, p.pk, stakeTx, txNew.vout[0]))
713 fprintf(stderr,"CreateNewBlock: failed to make GuardedOutput on staking coinbase\n");
719 fprintf(stderr,"CreateNewBlock: invalid stake transaction\n");
724 txNew.nExpiryHeight = 0;
725 txNew.nLockTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
727 if ( ASSETCHAINS_SYMBOL[0] == 0 && IS_KOMODO_NOTARY != 0 && My_notaryid >= 0 )
728 txNew.vout[0].nValue += 5000;
730 // check if coinbase transactions must be time locked at current subsidy and prepend the time lock
731 // to transaction if so, cast for GTE operator
732 if ((uint64_t)(txNew.vout[0].nValue) >= ASSETCHAINS_TIMELOCKGTE)
734 int32_t opretlen, p2shlen, scriptlen;
735 CScriptExt opretScript = CScriptExt();
737 txNew.vout.resize(2);
739 // prepend time lock to original script unless original script is P2SH, in which case, we will leave the coins
740 // protected only by the time lock rather than 100% inaccessible
741 opretScript.AddCheckLockTimeVerify(komodo_block_unlocktime(nHeight));
742 if (scriptPubKeyIn.IsPayToScriptHash() || scriptPubKeyIn.IsPayToCryptoCondition())
744 fprintf(stderr,"CreateNewBlock: attempt to add timelock to pay2sh or pay2cc\n");
748 opretScript += scriptPubKeyIn;
750 txNew.vout[0].scriptPubKey = CScriptExt().PayToScriptHash(CScriptID(opretScript));
751 txNew.vout[1].scriptPubKey = CScriptExt().OpReturnScript(opretScript, OPRETTYPE_TIMELOCK);
752 txNew.vout[1].nValue = 0;
753 } // timelocks and commissions are currently incompatible due to validation complexity of the combination
754 else if ( nHeight > 1 && ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 && ASSETCHAINS_COMMISSION != 0 && (commission= komodo_commission((CBlock*)&pblocktemplate->block)) != 0 )
756 int32_t i; uint8_t *ptr;
757 txNew.vout.resize(2);
758 txNew.vout[1].nValue = commission;
759 txNew.vout[1].scriptPubKey.resize(35);
760 ptr = (uint8_t *)&txNew.vout[1].scriptPubKey[0];
763 ptr[i+1] = ASSETCHAINS_OVERRIDE_PUBKEY33[i];
764 ptr[34] = OP_CHECKSIG;
765 //printf("autocreate commision vout\n");
768 // add final notarization and instant spend fixups
769 if (pbaasNotarizationTx)
771 extern CWallet *pwalletMain;
772 LOCK(pwalletMain->cs_wallet);
774 // now add an input from the coinbase to the notarization
775 CMutableTransaction mntx(pblock->vtx[pbaasNotarizationTx]);
777 // determine number of CB outputs
778 int numNotaryOutputs = mntx.vout.size() - (mntx.vout[mntx.vout.size() - 1].scriptPubKey.IsOpReturn() ? 1 : 0);
780 int64_t needed = pbaasTransparentOut - pbaasTransparentIn;
781 if (needed > PBAAS_MINNOTARIZATIONOUTPUT * numNotaryOutputs)
783 fprintf(stderr,"CreateNewBlock: too much output from earned notarization transaction\n");
788 int32_t pbaasCoinbaseInstantSpendOut;
790 // if we need an instant out to be a source of funds for the notarization transaction, make it here
793 // the new instant spend out will go where at the end and before any opret
794 pbaasCoinbaseInstantSpendOut = txNew.vout.size() - (txNew.vout[txNew.vout.size() - 1].scriptPubKey.IsOpReturn() ? 1 : 0);
796 auto coinbaseOutIt = txNew.vout.begin() + pbaasCoinbaseInstantSpendOut;
800 vector<CTxDestination> vKeys;
802 // make the earned notarization output
803 cp = CCinit(&CC, EVAL_EARNEDNOTARIZATION);
804 // need to be able to send this to EVAL_PBAASDEFINITION address as a destination, locked by the default pubkey
805 CPubKey pk = CPubKey(std::vector<unsigned char>(CC.CChexstr, CC.CChexstr + strlen(CC.CChexstr)));
807 vKeys.push_back(CTxDestination(CKeyID(CCrossChainRPCData::GetConditionID(VERUS_CHAINID, EVAL_EARNEDNOTARIZATION))));
809 // output duplicate notarization as coinbase output for instant spend to notarization
810 // these coins will never join the supply pool, so they do not need to be considered as
811 // part of the total value of this coinbase
812 CPBaaSNotarization pbn(pblock->vtx[pbaasNotarizationTx]);
813 txNew.vout.insert(coinbaseOutIt, MakeCC1of1Vout(EVAL_EARNEDNOTARIZATION, needed, pk, vKeys, pbn));
814 cbHash = txNew.GetHash();
815 mntx.vin[mntx.vin.size() - 1] = CTxIn(txNew.GetHash(), pbaasCoinbaseInstantSpendOut);
817 // put notarization back in the block
818 pblock->vtx[pbaasNotarizationTx] = mntx;
821 CTransaction ntx(mntx);
823 for (int i = 0; i < ntx.vin.size(); i++)
826 SignatureData sigdata;
828 const CScript *pScriptPubKey;
829 if (needed > 0 && cbHash == ntx.vin[i].prevout.hash)
831 pScriptPubKey = &txNew.vout[pbaasCoinbaseInstantSpendOut].scriptPubKey;
832 value = txNew.vout[pbaasCoinbaseInstantSpendOut].nValue;
836 const CCoins *coins = view.AccessCoins(ntx.vin[i].prevout.hash);
837 pScriptPubKey = &coins->vout[ntx.vin[i].prevout.n].scriptPubKey;
838 value = coins->vout[ntx.vin[i].prevout.n].nValue;
841 signSuccess = ProduceSignature(TransactionSignatureCreator(pwalletMain, &ntx, i, value, SIGHASH_ALL), *pScriptPubKey, sigdata, consensusBranchId);
845 fprintf(stderr,"CreateNewBlock: failure to sign earned notarization\n");
848 UpdateTransaction(mntx, i, sigdata);
851 pblocktemplate->vTxSigOps[pbaasNotarizationTx] = GetLegacySigOpCount(mntx);
854 pblock->vtx[0] = txNew;
855 pblocktemplate->vTxFees[0] = -nFees;
857 // if not Verus stake, setup nonce, otherwise, leave it alone
858 if (!isStake || ASSETCHAINS_LWMAPOS == 0)
861 arith_uint256 nonce = UintToArith256(GetRandHash());
863 // Clear the top 16 and bottom 16 or 24 bits (for local use as thread flags and counters)
864 nonce <<= ASSETCHAINS_NONCESHIFT[ASSETCHAINS_ALGO];
866 pblock->nNonce = ArithToUint256(nonce);
870 pblock->hashPrevBlock = pindexPrev->GetBlockHash();
871 pblock->hashFinalSaplingRoot = sapling_tree.root();
873 // all Verus PoS chains need this data in the block at all times
874 if ( ASSETCHAINS_LWMAPOS || ASSETCHAINS_SYMBOL[0] == 0 || ASSETCHAINS_STAKED == 0 || KOMODO_MININGTHREADS > 0 )
876 UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
877 pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
880 pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]);
882 if ( ASSETCHAINS_SYMBOL[0] == 0 && IS_KOMODO_NOTARY != 0 && My_notaryid >= 0 )
885 CMutableTransaction txNotary = CreateNewContextualCMutableTransaction(Params().GetConsensus(), chainActive.Height() + 1);
886 if ( pblock->nTime < pindexPrev->nTime+60 )
887 pblock->nTime = pindexPrev->nTime + 60;
890 uint8_t tmpbuffer[40]; uint32_t r; int32_t n=0; uint256 randvals;
891 memcpy(&tmpbuffer[n],&My_notaryid,sizeof(My_notaryid)), n += sizeof(My_notaryid);
892 memcpy(&tmpbuffer[n],&Mining_height,sizeof(Mining_height)), n += sizeof(Mining_height);
893 memcpy(&tmpbuffer[n],&pblock->hashPrevBlock,sizeof(pblock->hashPrevBlock)), n += sizeof(pblock->hashPrevBlock);
894 vcalc_sha256(0,(uint8_t *)&randvals,tmpbuffer,n);
895 memcpy(&r,&randvals,sizeof(r));
896 pblock->nTime += (r % (33 - gpucount)*(33 - gpucount));
898 if ( komodo_notaryvin(txNotary,NOTARY_PUBKEY33) > 0 )
900 CAmount txfees = 5000;
901 pblock->vtx.push_back(txNotary);
902 pblocktemplate->vTxFees.push_back(txfees);
903 pblocktemplate->vTxSigOps.push_back(GetLegacySigOpCount(txNotary));
905 pblocktemplate->vTxFees[0] = -nFees;
906 //*(uint64_t *)(&pblock->vtx[0].vout[0].nValue) += txfees;
907 //fprintf(stderr,"added notaryvin\n");
911 fprintf(stderr,"error adding notaryvin, need to create 0.0001 utxos\n");
915 else if ( ASSETCHAINS_CC == 0 && pindexPrev != 0 && ASSETCHAINS_STAKED == 0 && (ASSETCHAINS_SYMBOL[0] != 0 || IS_KOMODO_NOTARY == 0 || My_notaryid < 0) )
917 CValidationState state;
918 //fprintf(stderr,"check validity\n");
919 if ( !TestBlockValidity(state, *pblock, pindexPrev, false, false)) // invokes CC checks
921 throw std::runtime_error("CreateNewBlock(): TestBlockValidity failed");
923 //fprintf(stderr,"valid\n");
926 //fprintf(stderr,"done new block\n");
927 return pblocktemplate.release();
932 boost::optional<CScript> GetMinerScriptPubKey(CReserveKey& reservekey)
934 boost::optional<CScript> GetMinerScriptPubKey()
938 CBitcoinAddress addr;
939 if (addr.SetString(GetArg("-mineraddress", ""))) {
940 addr.GetKeyID(keyID);
944 if (!reservekey.GetReservedKey(pubkey)) {
945 return boost::optional<CScript>();
947 keyID = pubkey.GetID();
949 return boost::optional<CScript>();
953 CScript scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
958 CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
960 boost::optional<CScript> scriptPubKey = GetMinerScriptPubKey(reservekey);
962 CBlockTemplate* CreateNewBlockWithKey()
964 boost::optional<CScript> scriptPubKey = GetMinerScriptPubKey();
970 return CreateNewBlock(*scriptPubKey);
973 //////////////////////////////////////////////////////////////////////////////
980 void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
982 // Update nExtraNonce
983 static uint256 hashPrevBlock;
984 if (hashPrevBlock != pblock->hashPrevBlock)
987 hashPrevBlock = pblock->hashPrevBlock;
990 unsigned int nHeight = pindexPrev->GetHeight()+1; // Height first in coinbase required for block.version=2
991 CMutableTransaction txCoinbase(pblock->vtx[0]);
992 txCoinbase.vin[0].scriptSig = (CScript() << nHeight << CScriptNum(nExtraNonce)) + COINBASE_FLAGS;
993 assert(txCoinbase.vin[0].scriptSig.size() <= 100);
995 pblock->vtx[0] = txCoinbase;
996 pblock->hashMerkleRoot = pblock->BuildMerkleTree();
1000 //////////////////////////////////////////////////////////////////////////////
1005 CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, int32_t nHeight, int32_t gpucount, bool isStake)
1007 CPubKey pubkey; CScript scriptPubKey; uint8_t *ptr; int32_t i;
1008 if ( nHeight == 1 && ASSETCHAINS_OVERRIDE_PUBKEY33[0] != 0 )
1010 scriptPubKey = CScript() << ParseHex(ASSETCHAINS_OVERRIDE_PUBKEY) << OP_CHECKSIG;
1012 else if ( USE_EXTERNAL_PUBKEY != 0 )
1014 //fprintf(stderr,"use notary pubkey\n");
1015 scriptPubKey = CScript() << ParseHex(NOTARY_PUBKEY) << OP_CHECKSIG;
1021 if (!reservekey.GetReservedKey(pubkey))
1025 scriptPubKey.resize(35);
1026 ptr = (uint8_t *)pubkey.begin();
1027 scriptPubKey[0] = 33;
1028 for (i=0; i<33; i++)
1029 scriptPubKey[i+1] = ptr[i];
1030 scriptPubKey[34] = OP_CHECKSIG;
1031 //scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
1034 return CreateNewBlock(scriptPubKey, gpucount, isStake);
1037 void komodo_broadcast(CBlock *pblock,int32_t limit)
1040 //fprintf(stderr,"broadcast new block t.%u\n",(uint32_t)time(NULL));
1043 BOOST_FOREACH(CNode* pnode, vNodes)
1045 if ( pnode->hSocket == INVALID_SOCKET )
1047 if ( (rand() % n) == 0 )
1049 pnode->PushMessage("block", *pblock);
1055 //fprintf(stderr,"finished broadcast new block t.%u\n",(uint32_t)time(NULL));
1058 static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
1060 static bool ProcessBlockFound(CBlock* pblock)
1061 #endif // ENABLE_WALLET
1063 LogPrintf("%s\n", pblock->ToString());
1064 LogPrintf("generated %s height.%d\n", FormatMoney(pblock->vtx[0].vout[0].nValue),chainActive.LastTip()->GetHeight()+1);
1068 if (pblock->hashPrevBlock != chainActive.LastTip()->GetBlockHash())
1070 uint256 hash; int32_t i;
1071 hash = pblock->hashPrevBlock;
1072 for (i=31; i>=0; i--)
1073 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
1074 fprintf(stderr," <- prev (stale)\n");
1075 hash = chainActive.LastTip()->GetBlockHash();
1076 for (i=31; i>=0; i--)
1077 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
1078 fprintf(stderr," <- chainTip (stale)\n");
1080 return error("KomodoMiner: generated block is stale");
1084 #ifdef ENABLE_WALLET
1085 // Remove key from key pool
1086 if ( IS_KOMODO_NOTARY == 0 )
1088 if (GetArg("-mineraddress", "").empty()) {
1089 // Remove key from key pool
1090 reservekey.KeepKey();
1093 // Track how many getdata requests this block gets
1096 //fprintf(stderr,"lock cs_wallet\n");
1097 LOCK(wallet.cs_wallet);
1098 wallet.mapRequestCount[pblock->GetHash()] = 0;
1101 //fprintf(stderr,"process new block\n");
1103 // Process this block the same as if we had received it from another node
1104 CValidationState state;
1105 if (!ProcessNewBlock(1,chainActive.LastTip()->GetHeight()+1,state, NULL, pblock, true, NULL))
1106 return error("KomodoMiner: ProcessNewBlock, block not accepted");
1108 TrackMinedBlock(pblock->GetHash());
1109 komodo_broadcast(pblock,16);
1113 int32_t komodo_baseid(char *origbase);
1114 int32_t komodo_eligiblenotary(uint8_t pubkeys[66][33],int32_t *mids,uint32_t *blocktimes,int32_t *nonzpkeysp,int32_t height);
1115 arith_uint256 komodo_PoWtarget(int32_t *percPoSp,arith_uint256 target,int32_t height,int32_t goalperc);
1116 int32_t FOUND_BLOCK,KOMODO_MAYBEMINED;
1117 extern int32_t KOMODO_LASTMINED,KOMODO_INSYNC;
1118 int32_t roundrobin_delay;
1119 arith_uint256 HASHTarget,HASHTarget_POW;
1120 int32_t komodo_longestchain();
1122 // wait for peers to connect
1123 void waitForPeers(const CChainParams &chainparams)
1125 if (chainparams.MiningRequiresPeers())
1129 boost::this_thread::interruption_point();
1131 fvNodesEmpty = vNodes.empty();
1133 int longestchain = komodo_longestchain();
1134 int lastlongest = 0;
1135 if (fvNodesEmpty || IsNotInSync() || (longestchain != 0 && longestchain > chainActive.LastTip()->GetHeight()))
1137 int loops = 0, blockDiff = 0, newDiff = 0;
1142 MilliSleep(1000 + rand() % 4000);
1143 boost::this_thread::interruption_point();
1145 fvNodesEmpty = vNodes.empty();
1150 else if ((newDiff = IsNotInSync()) > 0)
1152 if (blockDiff != newDiff)
1154 blockDiff = newDiff;
1166 else if (!fvNodesEmpty && !IsNotInSync() && longestchain > chainActive.LastTip()->GetHeight())
1168 // the only thing may be that we are seeing a long chain that we'll never get
1169 // don't wait forever
1170 if (lastlongest == 0)
1173 lastlongest = longestchain;
1176 } while (fvNodesEmpty || IsNotInSync());
1177 MilliSleep(100 + rand() % 400);
1182 #ifdef ENABLE_WALLET
1183 CBlockIndex *get_chainactive(int32_t height)
1185 if ( chainActive.LastTip() != 0 )
1187 if ( height <= chainActive.LastTip()->GetHeight() )
1190 return(chainActive[height]);
1192 // else fprintf(stderr,"get_chainactive height %d > active.%d\n",height,chainActive.Tip()->GetHeight());
1194 //fprintf(stderr,"get_chainactive null chainActive.Tip() height %d\n",height);
1199 * When called, this checks to see if Verus daemon is running and available. If so, it calls to get the latest
1200 * notarization data and all information necessary to make a notarization transaction for the current chain, or the
1203 void static UpdateNotarizationData()
1209 * A separate thread to stake, while the miner threads mine.
1211 void static VerusStaker(CWallet *pwallet)
1213 LogPrintf("Verus staker thread started\n");
1214 RenameThread("verus-staker");
1216 const CChainParams& chainparams = Params();
1217 auto consensusParams = chainparams.GetConsensus();
1219 // Each thread has its own key
1220 CReserveKey reservekey(pwallet);
1222 // Each thread has its own counter
1223 unsigned int nExtraNonce = 0;
1225 uint8_t *script; uint64_t total,checktoshis; int32_t i,j;
1227 while ( (ASSETCHAIN_INIT == 0 || KOMODO_INITDONE == 0) ) //chainActive.Tip()->GetHeight() != 235300 &&
1230 if ( komodo_baseid(ASSETCHAINS_SYMBOL) < 0 )
1234 // try a nice clean peer connection to start
1235 CBlockIndex *pindexPrev, *pindexCur;
1237 pindexPrev = chainActive.LastTip();
1238 MilliSleep(5000 + rand() % 5000);
1239 waitForPeers(chainparams);
1240 pindexCur = chainActive.LastTip();
1241 } while (pindexPrev != pindexCur);
1244 static int32_t lastStakingHeight = 0;
1248 waitForPeers(chainparams);
1249 CBlockIndex* pindexPrev = chainActive.LastTip();
1252 unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
1254 if ( Mining_height != pindexPrev->GetHeight()+1 )
1256 Mining_height = pindexPrev->GetHeight()+1;
1257 Mining_start = (uint32_t)time(NULL);
1260 if ( Mining_height != lastStakingHeight )
1262 printf("Staking height %d for %s\n", Mining_height, ASSETCHAINS_SYMBOL);
1263 lastStakingHeight = Mining_height;
1266 // Check for stop or if block needs to be rebuilt
1267 boost::this_thread::interruption_point();
1269 // try to stake a block
1270 CBlockTemplate *ptr = NULL;
1271 if (Mining_height > VERUS_MIN_STAKEAGE)
1272 ptr = CreateNewBlockWithKey(reservekey, Mining_height, 0, true);
1276 // wait to try another staking block until after the tip moves again
1277 while ( chainActive.LastTip() == pindexPrev )
1282 unique_ptr<CBlockTemplate> pblocktemplate(ptr);
1283 if (!pblocktemplate.get())
1285 if (GetArg("-mineraddress", "").empty()) {
1286 LogPrintf("Error in %s staker: Keypool ran out, please call keypoolrefill before restarting the mining thread\n",
1287 ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO]);
1289 // Should never reach here, because -mineraddress validity is checked in init.cpp
1290 LogPrintf("Error in %s staker: Invalid %s -mineraddress\n", ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO], ASSETCHAINS_SYMBOL);
1295 CBlock *pblock = &pblocktemplate->block;
1296 LogPrintf("Staking with %u transactions in block (%u bytes)\n", pblock->vtx.size(),::GetSerializeSize(*pblock,SER_NETWORK,PROTOCOL_VERSION));
1300 int64_t nStart = GetTime();
1302 // we don't use this, but IncrementExtraNonce is the function that builds the merkle tree
1303 unsigned int nExtraNonce = 0;
1304 IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
1306 // update PBaaS header
1307 if (CConstVerusSolutionVector::activationHeight.ActiveVersion(Mining_height) == CActivationHeight::SOLUTION_VERUSV3)
1312 // set the PBaaS header
1313 ChainMerkleMountainView mmv = chainActive.GetMMV();
1314 mmvRoot = mmv.GetRoot();
1316 pblock->AddUpdatePBaaSHeader(mmvRoot);
1319 if (vNodes.empty() && chainparams.MiningRequiresPeers())
1321 if ( Mining_height > ASSETCHAINS_MINHEIGHT )
1323 fprintf(stderr,"no nodes, attempting reconnect\n");
1328 if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
1330 fprintf(stderr,"timeout, retrying\n");
1334 if ( pindexPrev != chainActive.LastTip() )
1336 printf("Block %d added to chain\n", chainActive.LastTip()->GetHeight());
1341 int32_t unlockTime = komodo_block_unlocktime(Mining_height);
1342 int64_t subsidy = (int64_t)(pblock->vtx[0].vout[0].nValue);
1344 uint256 hashTarget = ArithToUint256(arith_uint256().SetCompact(pblock->nBits));
1346 pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams);
1348 UpdateTime(pblock, consensusParams, pindexPrev);
1350 ProcessBlockFound(pblock, *pwallet, reservekey);
1352 LogPrintf("Using %s algorithm:\n", ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO]);
1353 LogPrintf("Staked block found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex());
1354 printf("Found block %d \n", Mining_height );
1355 printf("staking reward %.8f %s!\n", (double)subsidy / (double)COIN, ASSETCHAINS_SYMBOL);
1357 post.SetCompact(pblock->GetVerusPOSTarget());
1358 pindexPrev = get_chainactive(Mining_height - 100);
1359 CTransaction &sTx = pblock->vtx[pblock->vtx.size()-1];
1360 printf("POS hash: %s \ntarget: %s\n",
1361 CTransaction::_GetVerusPOSHash(&(pblock->nNonce), sTx.vin[0].prevout.hash, sTx.vin[0].prevout.n, Mining_height, pindexPrev->GetBlockHeader().GetVerusEntropyHash(Mining_height - 100), sTx.vout[0].nValue).GetHex().c_str(), ArithToUint256(post).GetHex().c_str());
1362 if (unlockTime > Mining_height && subsidy >= ASSETCHAINS_TIMELOCKGTE)
1363 printf("- timelocked until block %i\n", unlockTime);
1367 // Check for stop or if block needs to be rebuilt
1368 boost::this_thread::interruption_point();
1372 // In regression test mode, stop mining after a block is found.
1373 if (chainparams.MineBlocksOnDemand()) {
1374 throw boost::thread_interrupted();
1378 catch (const boost::thread_interrupted&)
1380 LogPrintf("VerusStaker terminated\n");
1383 catch (const std::runtime_error &e)
1385 LogPrintf("VerusStaker runtime error: %s\n", e.what());
1390 typedef bool (*minefunction)(CBlockHeader &bh, CVerusHashV2bWriter &vhw, uint256 &finalHash, uint256 &target, uint64_t start, uint64_t *count);
1391 bool mine_verus_v2(CBlockHeader &bh, CVerusHashV2bWriter &vhw, uint256 &finalHash, uint256 &target, uint64_t start, uint64_t *count);
1392 bool mine_verus_v2_port(CBlockHeader &bh, CVerusHashV2bWriter &vhw, uint256 &finalHash, uint256 &target, uint64_t start, uint64_t *count);
1394 void static BitcoinMiner_noeq(CWallet *pwallet)
1396 void static BitcoinMiner_noeq()
1399 LogPrintf("%s miner started\n", ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO]);
1400 RenameThread("verushash-miner");
1402 #ifdef ENABLE_WALLET
1403 // Each thread has its own key
1404 CReserveKey reservekey(pwallet);
1407 const CChainParams& chainparams = Params();
1408 // Each thread has its own counter
1409 unsigned int nExtraNonce = 0;
1411 uint8_t *script; uint64_t total,checktoshis; int32_t i,j;
1413 while ( (ASSETCHAIN_INIT == 0 || KOMODO_INITDONE == 0) ) //chainActive.Tip()->GetHeight() != 235300 &&
1416 if ( komodo_baseid(ASSETCHAINS_SYMBOL) < 0 )
1420 SetThreadPriority(THREAD_PRIORITY_LOWEST);
1422 // try a nice clean peer connection to start
1423 CBlockIndex *pindexPrev, *pindexCur;
1425 pindexPrev = chainActive.LastTip();
1426 MilliSleep(5000 + rand() % 5000);
1427 waitForPeers(chainparams);
1428 pindexCur = chainActive.LastTip();
1429 } while (pindexPrev != pindexCur);
1431 // this will not stop printing more than once in all cases, but it will allow us to print in all cases
1432 // and print duplicates rarely without having to synchronize
1433 static CBlockIndex *lastChainTipPrinted;
1434 static int32_t lastMiningHeight = 0;
1436 miningTimer.start();
1439 printf("Mining %s with %s\n", ASSETCHAINS_SYMBOL, ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO]);
1442 CVerusHashV2bWriter ss2 = CVerusHashV2bWriter(SER_GETHASH, PROTOCOL_VERSION);
1447 waitForPeers(chainparams);
1449 pindexPrev = chainActive.LastTip();
1451 // prevent forking on startup before the diff algorithm kicks in,
1452 // but only for a startup Verus test chain. PBaaS chains have the difficulty inherited from
1454 if (chainparams.MiningRequiresPeers() && ((IsVerusActive() && pindexPrev->GetHeight() < 50) || pindexPrev != chainActive.LastTip()))
1457 pindexPrev = chainActive.LastTip();
1458 MilliSleep(3000 + rand() % 3000);
1459 } while (pindexPrev != chainActive.LastTip());
1463 unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
1464 if ( Mining_height != pindexPrev->GetHeight()+1 )
1466 Mining_height = pindexPrev->GetHeight()+1;
1467 if (lastMiningHeight != Mining_height)
1469 lastMiningHeight = Mining_height;
1470 printf("Mining height %d\n", Mining_height);
1472 Mining_start = (uint32_t)time(NULL);
1475 miningTimer.start();
1477 #ifdef ENABLE_WALLET
1478 CBlockTemplate *ptr = CreateNewBlockWithKey(reservekey, Mining_height, 0);
1480 CBlockTemplate *ptr = CreateNewBlockWithKey();
1484 static uint32_t counter;
1485 if ( (counter++ < 10) || (counter % 40 == 0) )
1486 fprintf(stderr,"Unable to create valid block... will continue to try\n");
1491 unique_ptr<CBlockTemplate> pblocktemplate(ptr);
1492 if (!pblocktemplate.get())
1494 if (GetArg("-mineraddress", "").empty()) {
1495 LogPrintf("Error in %s miner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n",
1496 ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO]);
1498 // Should never reach here, because -mineraddress validity is checked in init.cpp
1499 LogPrintf("Error in %s miner: Invalid %s -mineraddress\n", ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO], ASSETCHAINS_SYMBOL);
1503 CBlock *pblock = &pblocktemplate->block;
1506 bool mergeMining = false;
1507 savebits = pblock->nBits;
1509 bool verusHashV2 = pblock->nVersion == CBlockHeader::VERUS_V2;
1510 bool verusSolutionV3 = CConstVerusSolutionVector::Version(pblock->nSolution) == CActivationHeight::SOLUTION_VERUSV3;
1512 if ( ASSETCHAINS_SYMBOL[0] != 0 )
1514 if ( ASSETCHAINS_REWARD[0] == 0 && !ASSETCHAINS_LASTERA )
1516 if ( pblock->vtx.size() == 1 && pblock->vtx[0].vout.size() == 1 && Mining_height > ASSETCHAINS_MINHEIGHT )
1518 static uint32_t counter;
1519 if ( counter++ < 10 )
1520 fprintf(stderr,"skip generating %s on-demand block, no tx avail\n",ASSETCHAINS_SYMBOL);
1523 } else fprintf(stderr,"%s vouts.%d mining.%d vs %d\n",ASSETCHAINS_SYMBOL,(int32_t)pblock->vtx[0].vout.size(),Mining_height,ASSETCHAINS_MINHEIGHT);
1527 // this builds the Merkle tree
1528 IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
1530 // update PBaaS header
1531 if (verusSolutionV3)
1536 ChainMerkleMountainView mmv = chainActive.GetMMV();
1537 mmvRoot = mmv.GetRoot();
1539 pblock->AddUpdatePBaaSHeader(mmvRoot);
1541 if (IsVerusActive())
1543 // combine all merge mined headers into this header
1544 // and get the easiest target of all chains in savebits
1545 if (!(savebits = ConnectedChains.CombineBlocks(*pblock)))
1547 savebits = pblock->nBits;
1551 // TODO: REMOVE OR COMMENT TESTS
1552 // tests to validate a few transactions and all past blocks
1553 ChainMerkleMountainView mmv = chainActive.GetMMV();
1554 mmvRoot = mmv.GetRoot();
1555 for (uint32_t i = 1; i <= pindexPrev->GetHeight(); i += 10)
1557 CBlockIndex *pindex = chainActive[i - 1];
1559 uint256 testRoot = mmv.GetRoot();
1560 uint32_t testHeight = ((unsigned char *)&testRoot)[0] < i ? (i - ((unsigned char *)&testRoot)[0]) - 1 : i - 1;
1561 CMerkleBranch branchMerkle, branchBlock;
1562 chainActive.GetBlockProof(mmv, branchBlock, testHeight);
1563 chainActive.GetMerkleProof(mmv, branchMerkle, testHeight);
1564 uint256 merkleAnswer = branchMerkle.SafeCheck(chainActive[testHeight]->hashMerkleRoot);
1565 uint256 blockAnswer = branchBlock.SafeCheck(chainActive[testHeight]->GetBlockHash());
1566 if (merkleAnswer != testRoot)
1568 printf("Failed merkle proof at testheight: %u\nexpected: %s\ncalculated: %s\n", testHeight, testRoot.GetHex().c_str(), merkleAnswer.GetHex().c_str());
1569 printf("Bits for left (0) and right (1): \n");
1570 std::vector<unsigned char> proofBits = ChainMerkleMountainView::GetProofBits(testHeight, i);
1572 for (auto bit : proofBits)
1574 printf("%s\n", bit ? "left" : "right");
1577 if (blockAnswer != testRoot)
1579 printf("Failed block proof at testheight: %u\nexpected: %s\ncalculated: %s\n", testHeight, testRoot.GetHex().c_str(), blockAnswer.GetHex().c_str());
1580 printf("Bits for left (0) and right (1): \n");
1581 std::vector<unsigned char> proofBits = ChainMerkleMountainView::GetProofBits(testHeight, i);
1583 for (auto bit : proofBits)
1585 printf("%s\n", bit ? "left" : "right");
1588 const CMMRPowerNode *ppower = mmv.GetRootNode();
1589 if (!ppower || ppower->Work() != pindex->chainPower.chainWork)
1591 printf("Work did not match:\nexpected: %s\ncalculated: %s\n", ArithToUint256(pindex->chainPower.chainWork).GetHex().c_str(), ArithToUint256(ppower->Work()).GetHex().c_str());
1593 if (!ppower || ppower->Stake() != pindex->chainPower.chainStake)
1595 printf("Stake did not match:\nexpected: %s\ncalculated: %s\n", ArithToUint256(pindex->chainPower.chainStake).GetHex().c_str(), ArithToUint256(ppower->Stake()).GetHex().c_str());
1602 // submit the block for merge mining if Verus is present
1603 // otherwise, mine solo
1604 if (ConnectedChains.IsVerusPBaaSAvailable())
1607 UniValue params(UniValue::VARR);
1608 params.push_back(EncodeHexBlk(*pblock));
1609 params.push_back(ASSETCHAINS_SYMBOL);
1610 params.push_back(PBAAS_HOST);
1611 params.push_back(PBAAS_PORT);
1612 params.push_back(PBAAS_USERPASS);
1615 params = RPCCallRoot("addmergedblock", params);
1616 } catch (std::exception e)
1618 printf("Failed to connect to %s chain\n", ConnectedChains.notaryChain.chainDefinition.name.c_str());
1619 params = UniValue(e.what());
1621 if (mergeMining = params.isNull())
1623 printf("Merge mining -- deferring to %s as the actual mining chain\n", ConnectedChains.notaryChain.chainDefinition.name.c_str());
1629 LogPrintf("Running %s miner with %u transactions in block (%u bytes)\n",ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO],
1630 pblock->vtx.size(),::GetSerializeSize(*pblock,SER_NETWORK,PROTOCOL_VERSION));
1634 int64_t nStart = GetTime();
1636 arith_uint256 hashTarget = arith_uint256().SetCompact(savebits);
1637 uint256 uintTarget = ArithToUint256(hashTarget);
1639 arith_uint256 ourTarget;
1640 ourTarget.SetCompact(pblock->nBits);
1644 if ( pindexPrev != chainActive.LastTip() )
1646 if (lastChainTipPrinted != chainActive.LastTip())
1648 lastChainTipPrinted = chainActive.LastTip();
1649 printf("Block %d added to chain\n", lastChainTipPrinted->GetHeight());
1655 if ( ASSETCHAINS_STAKED != 0 )
1658 hashTarget = komodo_PoWtarget(&percPoS,hashTarget,Mining_height,ASSETCHAINS_STAKED);
1659 for (z=31; z>=0; z--)
1660 fprintf(stderr,"%02x",((uint8_t *)&hashTarget)[z]);
1661 fprintf(stderr," PoW for staked coin PoS %d%% vs target %d%%\n",percPoS,(int32_t)ASSETCHAINS_STAKED);
1664 uint64_t count, hashesToGo = 0;
1667 // must not be in sync
1668 printf("Mining on incorrect block version.\n");
1673 count = ((ASSETCHAINS_NONCEMASK[ASSETCHAINS_ALGO] >> 3) + 1) / ASSETCHAINS_HASHESPERROUND[ASSETCHAINS_ALGO];
1674 CVerusHashV2 *vh2 = &ss2.GetState();
1676 verusclhasher &vclh = vh2->vclh;
1677 minefunction mine_verus;
1678 mine_verus = IsCPUVerusOptimized() ? &mine_verus_v2 : &mine_verus_v2_port;
1682 uint256 hashResult = uint256();
1684 unsigned char *curBuf;
1688 // loop for about one minute before refreshing the block
1689 for (uint64_t i = 0; i < 240; i++)
1691 boost::this_thread::interruption_point();
1694 if (vNodes.empty() && chainparams.MiningRequiresPeers())
1696 if ( Mining_height > ASSETCHAINS_MINHEIGHT )
1698 fprintf(stderr,"no nodes, attempting reconnect\n");
1703 if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
1708 if ( pindexPrev != chainActive.LastTip() )
1710 if (lastChainTipPrinted != chainActive.LastTip())
1712 lastChainTipPrinted = chainActive.LastTip();
1713 printf("Block %d added to chain\n\n", lastChainTipPrinted->GetHeight());
1721 // check NONCEMASK at a time
1722 for (uint64_t i = 0; i < count; i++)
1724 // this is the merge mining loop, which enables us to drop out and queue a header anytime we earn a block that is good enough for a
1725 // merge mined block, but not our own
1726 uint64_t totalDone = 0;
1728 arith_uint256 arithHash;
1731 // hashesToGo gets updated with actual number run for metrics
1732 hashesToGo = ASSETCHAINS_HASHESPERROUND[ASSETCHAINS_ALGO];
1733 uint64_t start = i * hashesToGo;
1734 hashesToGo -= totalDone;
1736 if (verusSolutionV3)
1738 // mine on canonical header for merge mining
1739 CPBaaSPreHeader savedHeader(*pblock);
1740 pblock->ClearNonCanonicalData();
1741 blockFound = (*mine_verus)(*pblock, ss2, hashResult, uintTarget, start, &hashesToGo);
1742 savedHeader.SetBlockData(*pblock);
1746 blockFound = (*mine_verus)(*pblock, ss2, hashResult, uintTarget, start, &hashesToGo);
1749 arithHash = UintToArith256(hashResult);
1750 totalDone += hashesToGo;
1751 if (blockFound && IsVerusActive())
1753 ConnectedChains.QueueNewBlockHeader(*pblock);
1754 if (arithHash > ourTarget)
1756 // all blocks qualified with this hash will be submitted
1757 // until we redo the block, we might as well not try again with anything over this hash
1758 hashTarget = arithHash;
1759 uintTarget = ArithToUint256(hashTarget);
1762 hashesToGo = totalDone;
1763 } while (blockFound && arithHash > ourTarget);
1765 if (!blockFound || arithHash > ourTarget)
1767 // Check for stop or if block needs to be rebuilt
1768 boost::this_thread::interruption_point();
1769 if ( pindexPrev != chainActive.LastTip() )
1771 if (lastChainTipPrinted != chainActive.LastTip())
1773 lastChainTipPrinted = chainActive.LastTip();
1774 printf("Block %d added to chain\n", lastChainTipPrinted->GetHeight());
1782 nHashCount += hashesToGo;
1789 // Check for stop or if block needs to be rebuilt
1790 boost::this_thread::interruption_point();
1792 if (pblock->nSolution.size() != 1344)
1794 LogPrintf("ERROR: Block solution is not 1344 bytes as it should be");
1798 SetThreadPriority(THREAD_PRIORITY_NORMAL);
1800 int32_t unlockTime = komodo_block_unlocktime(Mining_height);
1801 int64_t subsidy = (int64_t)(pblock->vtx[0].vout[0].nValue);
1803 #ifdef VERUSHASHDEBUG
1804 std::string validateStr = hashResult.GetHex();
1805 std::string hashStr = pblock->GetHash().GetHex();
1806 uint256 *bhalf1 = (uint256 *)vh2->CurBuffer();
1807 uint256 *bhalf2 = bhalf1 + 1;
1809 std::string hashStr = hashResult.GetHex();
1812 LogPrintf("Using %s algorithm:\n", ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO]);
1813 LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hashStr, ArithToUint256(ourTarget).GetHex());
1814 printf("Found block %d \n", Mining_height );
1815 printf("mining reward %.8f %s!\n", (double)subsidy / (double)COIN, ASSETCHAINS_SYMBOL);
1816 #ifdef VERUSHASHDEBUG
1817 printf(" hash: %s\n val: %s \ntarget: %s\n\n", hashStr.c_str(), validateStr.c_str(), ArithToUint256(ourTarget).GetHex().c_str());
1818 printf("intermediate %lx\n", intermediate);
1819 printf("Curbuf: %s%s\n", bhalf1->GetHex().c_str(), bhalf2->GetHex().c_str());
1820 bhalf1 = (uint256 *)verusclhasher_key.get();
1821 bhalf2 = bhalf1 + ((vh2->vclh.keyMask + 1) >> 5);
1822 printf(" Key: %s%s\n", bhalf1->GetHex().c_str(), bhalf2->GetHex().c_str());
1824 printf(" hash: %s\ntarget: %s", hashStr.c_str(), ArithToUint256(ourTarget).GetHex().c_str());
1826 if (unlockTime > Mining_height && subsidy >= ASSETCHAINS_TIMELOCKGTE)
1827 printf(" - timelocked until block %i\n", unlockTime);
1830 #ifdef ENABLE_WALLET
1831 ProcessBlockFound(pblock, *pwallet, reservekey);
1833 ProcessBlockFound(pblock);
1835 SetThreadPriority(THREAD_PRIORITY_LOWEST);
1842 nHashCount += hashesToGo;
1847 // Check for stop or if block needs to be rebuilt
1848 boost::this_thread::interruption_point();
1850 if (vNodes.empty() && chainparams.MiningRequiresPeers())
1852 if ( Mining_height > ASSETCHAINS_MINHEIGHT )
1854 fprintf(stderr,"no nodes, attempting reconnect\n");
1859 if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
1861 fprintf(stderr,"timeout, retrying\n");
1865 if ( pindexPrev != chainActive.LastTip() )
1867 if (lastChainTipPrinted != chainActive.LastTip())
1869 lastChainTipPrinted = chainActive.LastTip();
1870 printf("Block %d added to chain\n\n", lastChainTipPrinted->GetHeight());
1876 printf("%llu mega hashes complete - working\n", ((ASSETCHAINS_NONCEMASK[ASSETCHAINS_ALGO] >> 3) + 1) / 1048576);
1878 printf("%lu mega hashes complete - working\n", ((ASSETCHAINS_NONCEMASK[ASSETCHAINS_ALGO] >> 3) + 1) / 1048576);
1885 catch (const boost::thread_interrupted&)
1888 LogPrintf("%s miner terminated\n", ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO]);
1891 catch (const std::runtime_error &e)
1894 LogPrintf("%s miner runtime error: %s\n", ASSETCHAINS_ALGORITHMS[ASSETCHAINS_ALGO], e.what());
1900 #ifdef ENABLE_WALLET
1901 void static BitcoinMiner(CWallet *pwallet)
1903 void static BitcoinMiner()
1906 LogPrintf("KomodoMiner started\n");
1907 SetThreadPriority(THREAD_PRIORITY_LOWEST);
1908 RenameThread("komodo-miner");
1909 const CChainParams& chainparams = Params();
1911 #ifdef ENABLE_WALLET
1912 // Each thread has its own key
1913 CReserveKey reservekey(pwallet);
1916 // Each thread has its own counter
1917 unsigned int nExtraNonce = 0;
1919 unsigned int n = chainparams.EquihashN();
1920 unsigned int k = chainparams.EquihashK();
1921 uint8_t *script; uint64_t total,checktoshis; int32_t i,j,gpucount=KOMODO_MAXGPUCOUNT,notaryid = -1;
1922 while ( (ASSETCHAIN_INIT == 0 || KOMODO_INITDONE == 0) )
1925 if ( komodo_baseid(ASSETCHAINS_SYMBOL) < 0 )
1928 if ( ASSETCHAINS_SYMBOL[0] == 0 )
1929 komodo_chosennotary(¬aryid,chainActive.LastTip()->GetHeight(),NOTARY_PUBKEY33,(uint32_t)chainActive.LastTip()->GetBlockTime());
1930 if ( notaryid != My_notaryid )
1931 My_notaryid = notaryid;
1933 //if ( notaryid >= 0 || ASSETCHAINS_SYMBOL[0] != 0 )
1935 //else solver = "default";
1936 assert(solver == "tromp" || solver == "default");
1937 LogPrint("pow", "Using Equihash solver \"%s\" with n = %u, k = %u\n", solver, n, k);
1938 if ( ASSETCHAINS_SYMBOL[0] != 0 )
1939 fprintf(stderr,"notaryid.%d Mining.%s with %s\n",notaryid,ASSETCHAINS_SYMBOL,solver.c_str());
1941 bool cancelSolver = false;
1942 boost::signals2::connection c = uiInterface.NotifyBlockTip.connect(
1943 [&m_cs, &cancelSolver](const uint256& hashNewTip) mutable {
1944 std::lock_guard<std::mutex> lock{m_cs};
1945 cancelSolver = true;
1948 miningTimer.start();
1951 if ( ASSETCHAINS_SYMBOL[0] != 0 )
1952 fprintf(stderr,"try %s Mining with %s\n",ASSETCHAINS_SYMBOL,solver.c_str());
1955 if (chainparams.MiningRequiresPeers()) //chainActive.LastTip()->GetHeight() != 235300 &&
1957 //if ( ASSETCHAINS_SEED != 0 && chainActive.LastTip()->GetHeight() < 100 )
1959 // Busy-wait for the network to come online so we don't waste time mining
1960 // on an obsolete chain. In regtest mode we expect to fly solo.
1966 fvNodesEmpty = vNodes.empty();
1968 if (!fvNodesEmpty )//&& !IsInitialBlockDownload())
1971 //fprintf(stderr,"fvNodesEmpty %d IsInitialBlockDownload(%s) %d\n",(int32_t)fvNodesEmpty,ASSETCHAINS_SYMBOL,(int32_t)IsInitialBlockDownload());
1974 //fprintf(stderr,"%s Found peers\n",ASSETCHAINS_SYMBOL);
1975 miningTimer.start();
1980 unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
1981 CBlockIndex* pindexPrev = chainActive.LastTip();
1982 if ( Mining_height != pindexPrev->GetHeight()+1 )
1984 Mining_height = pindexPrev->GetHeight()+1;
1985 Mining_start = (uint32_t)time(NULL);
1987 if ( ASSETCHAINS_SYMBOL[0] != 0 && ASSETCHAINS_STAKED == 0 )
1989 //fprintf(stderr,"%s create new block ht.%d\n",ASSETCHAINS_SYMBOL,Mining_height);
1993 #ifdef ENABLE_WALLET
1994 // notaries always default to staking
1995 CBlockTemplate *ptr = CreateNewBlockWithKey(reservekey, pindexPrev->GetHeight()+1, gpucount, ASSETCHAINS_STAKED != 0 && GetArg("-genproclimit", 0) == 0);
1997 CBlockTemplate *ptr = CreateNewBlockWithKey();
2001 static uint32_t counter;
2002 if ( counter++ < 100 && ASSETCHAINS_STAKED == 0 )
2003 fprintf(stderr,"created illegal block, retry\n");
2007 //fprintf(stderr,"get template\n");
2008 unique_ptr<CBlockTemplate> pblocktemplate(ptr);
2009 if (!pblocktemplate.get())
2011 if (GetArg("-mineraddress", "").empty()) {
2012 LogPrintf("Error in KomodoMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
2014 // Should never reach here, because -mineraddress validity is checked in init.cpp
2015 LogPrintf("Error in KomodoMiner: Invalid -mineraddress\n");
2019 CBlock *pblock = &pblocktemplate->block;
2020 if ( ASSETCHAINS_SYMBOL[0] != 0 )
2022 if ( ASSETCHAINS_REWARD[0] == 0 && !ASSETCHAINS_LASTERA )
2024 if ( pblock->vtx.size() == 1 && pblock->vtx[0].vout.size() == 1 && Mining_height > ASSETCHAINS_MINHEIGHT )
2026 static uint32_t counter;
2027 if ( counter++ < 10 )
2028 fprintf(stderr,"skip generating %s on-demand block, no tx avail\n",ASSETCHAINS_SYMBOL);
2031 } else fprintf(stderr,"%s vouts.%d mining.%d vs %d\n",ASSETCHAINS_SYMBOL,(int32_t)pblock->vtx[0].vout.size(),Mining_height,ASSETCHAINS_MINHEIGHT);
2034 IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
2035 //fprintf(stderr,"Running KomodoMiner.%s with %u transactions in block\n",solver.c_str(),(int32_t)pblock->vtx.size());
2036 LogPrintf("Running KomodoMiner.%s with %u transactions in block (%u bytes)\n",solver.c_str(),pblock->vtx.size(),::GetSerializeSize(*pblock,SER_NETWORK,PROTOCOL_VERSION));
2040 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();
2041 pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
2042 savebits = pblock->nBits;
2043 HASHTarget = arith_uint256().SetCompact(savebits);
2044 roundrobin_delay = ROUNDROBIN_DELAY;
2045 if ( ASSETCHAINS_SYMBOL[0] == 0 && notaryid >= 0 )
2048 if ( (Mining_height >= 235300 && Mining_height < 236000) || (Mining_height % KOMODO_ELECTION_GAP) > 64 || (Mining_height % KOMODO_ELECTION_GAP) == 0 || Mining_height > 1000000 )
2050 int32_t dispflag = 0;
2051 if ( notaryid <= 3 || notaryid == 32 || (notaryid >= 43 && notaryid <= 45) &¬aryid == 51 || notaryid == 52 || notaryid == 56 || notaryid == 57 )
2053 komodo_eligiblenotary(pubkeys,mids,blocktimes,&nonzpkeys,pindexPrev->GetHeight());
2054 if ( nonzpkeys > 0 )
2056 for (i=0; i<33; i++)
2057 if( pubkeys[0][i] != 0 )
2061 else externalflag = 0;
2062 if ( IS_KOMODO_NOTARY != 0 )
2064 for (i=1; i<66; i++)
2065 if ( memcmp(pubkeys[i],pubkeys[0],33) == 0 )
2067 if ( externalflag == 0 && i != 66 && mids[i] >= 0 )
2068 printf("VIOLATION at %d, notaryid.%d\n",i,mids[i]);
2069 for (j=gpucount=0; j<65; j++)
2071 if ( dispflag != 0 )
2074 fprintf(stderr,"%d ",mids[j]);
2075 else fprintf(stderr,"GPU ");
2077 if ( mids[j] == -1 )
2080 if ( dispflag != 0 )
2081 fprintf(stderr," <- prev minerids from ht.%d notary.%d gpucount.%d %.2f%% t.%u\n",pindexPrev->GetHeight(),notaryid,gpucount,100.*(double)gpucount/j,(uint32_t)time(NULL));
2083 for (j=0; j<65; j++)
2084 if ( mids[j] == notaryid )
2087 KOMODO_LASTMINED = 0;
2088 } else fprintf(stderr,"no nonz pubkeys\n");
2089 if ( (Mining_height >= 235300 && Mining_height < 236000) || (j == 65 && Mining_height > KOMODO_MAYBEMINED+1 && Mining_height > KOMODO_LASTMINED+64) )
2091 HASHTarget = arith_uint256().SetCompact(KOMODO_MINDIFF_NBITS);
2092 fprintf(stderr,"I am the chosen one for %s ht.%d\n",ASSETCHAINS_SYMBOL,pindexPrev->GetHeight()+1);
2093 } //else fprintf(stderr,"duplicate at j.%d\n",j);
2094 } else Mining_start = 0;
2095 } else Mining_start = 0;
2096 if ( ASSETCHAINS_STAKED != 0 )
2098 int32_t percPoS,z; bool fNegative,fOverflow;
2099 HASHTarget_POW = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED);
2100 HASHTarget.SetCompact(KOMODO_MINDIFF_NBITS,&fNegative,&fOverflow);
2101 if ( ASSETCHAINS_STAKED < 100 )
2103 for (z=31; z>=0; z--)
2104 fprintf(stderr,"%02x",((uint8_t *)&HASHTarget_POW)[z]);
2105 fprintf(stderr," PoW for staked coin PoS %d%% vs target %d%%\n",percPoS,(int32_t)ASSETCHAINS_STAKED);
2110 if ( KOMODO_INSYNC == 0 )
2112 fprintf(stderr,"Mining when blockchain might not be in sync longest.%d vs %d\n",KOMODO_LONGESTCHAIN,Mining_height);
2113 if ( KOMODO_LONGESTCHAIN != 0 && Mining_height >= KOMODO_LONGESTCHAIN )
2118 KOMODO_CHOSEN_ONE = 0;
2120 crypto_generichash_blake2b_state state;
2121 EhInitialiseState(n, k, state);
2122 // I = the block header minus nonce and solution.
2123 CEquihashInput I{*pblock};
2124 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
2127 crypto_generichash_blake2b_update(&state, (unsigned char*)&ss[0], ss.size());
2129 crypto_generichash_blake2b_state curr_state;
2131 crypto_generichash_blake2b_update(&curr_state,pblock->nNonce.begin(),pblock->nNonce.size());
2132 // (x_1, x_2, ...) = A(I, V, n, k)
2133 LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",solver, pblock->nNonce.ToString());
2134 arith_uint256 hashTarget;
2135 if ( KOMODO_MININGTHREADS > 0 && ASSETCHAINS_STAKED > 0 && ASSETCHAINS_STAKED < 100 && Mining_height > 10 )
2136 hashTarget = HASHTarget_POW;
2137 else hashTarget = HASHTarget;
2138 std::function<bool(std::vector<unsigned char>)> validBlock =
2139 #ifdef ENABLE_WALLET
2140 [&pblock, &hashTarget, &pwallet, &reservekey, &m_cs, &cancelSolver, &chainparams]
2142 [&pblock, &hashTarget, &m_cs, &cancelSolver, &chainparams]
2144 (std::vector<unsigned char> soln) {
2145 int32_t z; arith_uint256 h; CBlock B;
2146 // Write the solution to the hash and compute the result.
2147 LogPrint("pow", "- Checking solution against target\n");
2148 pblock->nSolution = soln;
2149 solutionTargetChecks.increment();
2151 h = UintToArith256(B.GetHash());
2152 /*for (z=31; z>=16; z--)
2153 fprintf(stderr,"%02x",((uint8_t *)&h)[z]);
2154 fprintf(stderr," mined ");
2155 for (z=31; z>=16; z--)
2156 fprintf(stderr,"%02x",((uint8_t *)&HASHTarget)[z]);
2157 fprintf(stderr," hashTarget ");
2158 for (z=31; z>=16; z--)
2159 fprintf(stderr,"%02x",((uint8_t *)&HASHTarget_POW)[z]);
2160 fprintf(stderr," POW\n");*/
2161 if ( h > hashTarget )
2163 //if ( ASSETCHAINS_STAKED != 0 && KOMODO_MININGTHREADS == 0 )
2167 if ( IS_KOMODO_NOTARY != 0 && B.nTime > GetAdjustedTime() )
2169 //fprintf(stderr,"need to wait %d seconds to submit block\n",(int32_t)(B.nTime - GetAdjustedTime()));
2170 while ( GetAdjustedTime() < B.nTime-2 )
2173 if ( chainActive.LastTip()->GetHeight() >= Mining_height )
2175 fprintf(stderr,"new block arrived\n");
2180 if ( ASSETCHAINS_STAKED == 0 )
2182 if ( IS_KOMODO_NOTARY != 0 )
2185 if ( (r= ((Mining_height + NOTARY_PUBKEY33[16]) % 64) / 8) > 0 )
2186 MilliSleep((rand() % (r * 1000)) + 1000);
2191 while ( B.nTime-57 > GetAdjustedTime() )
2194 if ( chainActive.LastTip()->GetHeight() >= Mining_height )
2197 uint256 tmp = B.GetHash();
2198 int32_t z; for (z=31; z>=0; z--)
2199 fprintf(stderr,"%02x",((uint8_t *)&tmp)[z]);
2200 fprintf(stderr," mined %s block %d!\n",ASSETCHAINS_SYMBOL,Mining_height);
2202 CValidationState state;
2203 if ( !TestBlockValidity(state,B, chainActive.LastTip(), true, false))
2205 h = UintToArith256(B.GetHash());
2206 for (z=31; z>=0; z--)
2207 fprintf(stderr,"%02x",((uint8_t *)&h)[z]);
2208 fprintf(stderr," Invalid block mined, try again\n");
2211 KOMODO_CHOSEN_ONE = 1;
2213 SetThreadPriority(THREAD_PRIORITY_NORMAL);
2214 LogPrintf("KomodoMiner:\n");
2215 LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", B.GetHash().GetHex(), HASHTarget.GetHex());
2216 #ifdef ENABLE_WALLET
2217 if (ProcessBlockFound(&B, *pwallet, reservekey)) {
2219 if (ProcessBlockFound(&B)) {
2221 // Ignore chain updates caused by us
2222 std::lock_guard<std::mutex> lock{m_cs};
2223 cancelSolver = false;
2225 KOMODO_CHOSEN_ONE = 0;
2226 SetThreadPriority(THREAD_PRIORITY_LOWEST);
2227 // In regression test mode, stop mining after a block is found.
2228 if (chainparams.MineBlocksOnDemand()) {
2229 // Increment here because throwing skips the call below
2230 ehSolverRuns.increment();
2231 throw boost::thread_interrupted();
2235 std::function<bool(EhSolverCancelCheck)> cancelled = [&m_cs, &cancelSolver](EhSolverCancelCheck pos) {
2236 std::lock_guard<std::mutex> lock{m_cs};
2237 return cancelSolver;
2240 // TODO: factor this out into a function with the same API for each solver.
2241 if (solver == "tromp" ) { //&& notaryid >= 0 ) {
2242 // Create solver and initialize it.
2244 eq.setstate(&curr_state);
2246 // Initialization done, start algo driver.
2248 eq.xfull = eq.bfull = eq.hfull = 0;
2250 for (u32 r = 1; r < WK; r++) {
2251 (r&1) ? eq.digitodd(r, 0) : eq.digiteven(r, 0);
2252 eq.xfull = eq.bfull = eq.hfull = 0;
2256 ehSolverRuns.increment();
2258 // Convert solution indices to byte array (decompress) and pass it to validBlock method.
2259 for (size_t s = 0; s < eq.nsols; s++) {
2260 LogPrint("pow", "Checking solution %d\n", s+1);
2261 std::vector<eh_index> index_vector(PROOFSIZE);
2262 for (size_t i = 0; i < PROOFSIZE; i++) {
2263 index_vector[i] = eq.sols[s][i];
2265 std::vector<unsigned char> sol_char = GetMinimalFromIndices(index_vector, DIGITBITS);
2267 if (validBlock(sol_char)) {
2268 // If we find a POW solution, do not try other solutions
2269 // because they become invalid as we created a new block in blockchain.
2275 // If we find a valid block, we rebuild
2276 bool found = EhOptimisedSolve(n, k, curr_state, validBlock, cancelled);
2277 ehSolverRuns.increment();
2279 int32_t i; uint256 hash = pblock->GetHash();
2280 for (i=0; i<32; i++)
2281 fprintf(stderr,"%02x",((uint8_t *)&hash)[i]);
2282 fprintf(stderr," <- %s Block found %d\n",ASSETCHAINS_SYMBOL,Mining_height);
2284 KOMODO_MAYBEMINED = Mining_height;
2287 } catch (EhSolverCancelledException&) {
2288 LogPrint("pow", "Equihash solver cancelled\n");
2289 std::lock_guard<std::mutex> lock{m_cs};
2290 cancelSolver = false;
2294 // Check for stop or if block needs to be rebuilt
2295 boost::this_thread::interruption_point();
2296 // Regtest mode doesn't require peers
2297 if ( FOUND_BLOCK != 0 )
2300 fprintf(stderr,"FOUND_BLOCK!\n");
2303 if (vNodes.empty() && chainparams.MiningRequiresPeers())
2305 if ( ASSETCHAINS_SYMBOL[0] == 0 || Mining_height > ASSETCHAINS_MINHEIGHT )
2307 fprintf(stderr,"no nodes, break\n");
2311 if ((UintToArith256(pblock->nNonce) & 0xffff) == 0xffff)
2313 //if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
2314 fprintf(stderr,"0xffff, break\n");
2317 if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
2319 if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
2320 fprintf(stderr,"timeout, break\n");
2323 if ( pindexPrev != chainActive.LastTip() )
2325 if ( 0 && ASSETCHAINS_SYMBOL[0] != 0 )
2326 fprintf(stderr,"Tip advanced, break\n");
2329 // Update nNonce and nTime
2330 pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
2331 pblock->nBits = savebits;
2332 /*if ( NOTARY_PUBKEY33[0] == 0 )
2335 UpdateTime(pblock, consensusParams, pindexPrev);
2336 if (consensusParams.fPowAllowMinDifficultyBlocks)
2338 // Changing pblock->nTime can change work required on testnet:
2339 HASHTarget.SetCompact(pblock->nBits);
2340 HASHTarget_POW = komodo_PoWtarget(&percPoS,HASHTarget,Mining_height,ASSETCHAINS_STAKED);
2346 catch (const boost::thread_interrupted&)
2350 LogPrintf("KomodoMiner terminated\n");
2353 catch (const std::runtime_error &e)
2357 LogPrintf("KomodoMiner runtime error: %s\n", e.what());
2364 #ifdef ENABLE_WALLET
2365 void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
2367 void GenerateBitcoins(bool fGenerate, int nThreads)
2370 if (!AreParamsInitialized())
2375 // if we are supposed to catch stake cheaters, there must be a valid sapling parameter, we need it at
2376 // initialization, and this is the first time we can get it. store the Sapling address here
2377 extern boost::optional<libzcash::SaplingPaymentAddress> cheatCatcher;
2378 extern std::string VERUS_CHEATCATCHER;
2379 libzcash::PaymentAddress addr = DecodePaymentAddress(VERUS_CHEATCATCHER);
2380 if (VERUS_CHEATCATCHER.size() > 0 && IsValidPaymentAddress(addr))
2384 cheatCatcher = boost::get<libzcash::SaplingPaymentAddress>(addr);
2391 VERUS_MINTBLOCKS = (VERUS_MINTBLOCKS && ASSETCHAINS_LWMAPOS != 0);
2393 if (fGenerate == true || VERUS_MINTBLOCKS)
2395 mapArgs["-gen"] = "1";
2397 if (VERUS_CHEATCATCHER.size() > 0)
2399 if (cheatCatcher == boost::none)
2401 LogPrintf("ERROR: -cheatcatcher parameter is invalid Sapling payment address\n");
2402 fprintf(stderr, "-cheatcatcher parameter is invalid Sapling payment address\n");
2406 LogPrintf("StakeGuard searching for double stakes on %s\n", VERUS_CHEATCATCHER.c_str());
2407 fprintf(stderr, "StakeGuard searching for double stakes on %s\n", VERUS_CHEATCATCHER.c_str());
2412 static boost::thread_group* minerThreads = NULL;
2415 nThreads = GetNumCores();
2417 if (minerThreads != NULL)
2419 minerThreads->interrupt_all();
2420 delete minerThreads;
2421 minerThreads = NULL;
2424 //fprintf(stderr,"nThreads.%d fGenerate.%d\n",(int32_t)nThreads,fGenerate);
2425 if ( nThreads == 0 && ASSETCHAINS_STAKED )
2431 minerThreads = new boost::thread_group();
2433 // add the PBaaS thread when mining or staking
2434 minerThreads->create_thread(boost::bind(&CConnectedChains::SubmissionThreadStub));
2436 #ifdef ENABLE_WALLET
2437 if (VERUS_MINTBLOCKS && pwallet != NULL)
2439 minerThreads->create_thread(boost::bind(&VerusStaker, pwallet));
2443 for (int i = 0; i < nThreads; i++) {
2445 #ifdef ENABLE_WALLET
2446 if (ASSETCHAINS_ALGO == ASSETCHAINS_EQUIHASH)
2447 minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet));
2449 minerThreads->create_thread(boost::bind(&BitcoinMiner_noeq, pwallet));
2451 if (ASSETCHAINS_ALGO == ASSETCHAINS_EQUIHASH)
2452 minerThreads->create_thread(&BitcoinMiner);
2454 minerThreads->create_thread(&BitcoinMiner_noeq);
2459 #endif // ENABLE_MINING