]> Git Repo - VerusCoin.git/blame - src/miner.cpp
Update contrib/debian/copyright for ax_boost_thread.m4
[VerusCoin.git] / src / miner.cpp
CommitLineData
d247a5d1 1// Copyright (c) 2009-2010 Satoshi Nakamoto
f914f1a7 2// Copyright (c) 2009-2014 The Bitcoin Core developers
78253fcb 3// Distributed under the MIT software license, see the accompanying
d247a5d1
JG
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
d247a5d1 6#include "miner.h"
8e8b6d70 7#ifdef ENABLE_MINING
c7aaab7a 8#include "pow/tromp/equi_miner.h"
2cc0a252 9#endif
51ed9ec9 10
eda37330 11#include "amount.h"
bebe7282 12#include "chainparams.h"
691161d4 13#include "consensus/consensus.h"
be126699 14#include "consensus/upgrades.h"
da29ecbc 15#include "consensus/validation.h"
8e8b6d70
JG
16#ifdef ENABLE_MINING
17#include "crypto/equihash.h"
18#endif
85aab2a0 19#include "hash.h"
93bd00a0 20#include "key_io.h"
d247a5d1 21#include "main.h"
a6df7ab5 22#include "metrics.h"
51ed9ec9 23#include "net.h"
df852d2b 24#include "pow.h"
bebe7282 25#include "primitives/transaction.h"
8e165d57 26#include "random.h"
22c4272b 27#include "timedata.h"
8e8b6d70 28#include "ui_interface.h"
ad49c256
WL
29#include "util.h"
30#include "utilmoneystr.h"
b2993bc5 31#include "validationinterface.h"
09eb201b 32
fdda3c50
JG
33#include "sodium.h"
34
ad49c256 35#include <boost/thread.hpp>
a3c26c2e 36#include <boost/tuple/tuple.hpp>
8e8b6d70
JG
37#ifdef ENABLE_MINING
38#include <functional>
39#endif
5a360a5c 40#include <mutex>
ad49c256 41
09eb201b 42using namespace std;
7b4737c8 43
d247a5d1
JG
44//////////////////////////////////////////////////////////////////////////////
45//
46// BitcoinMiner
47//
48
c6cb21d1
GA
49//
50// Unconfirmed transactions in the memory pool often depend on other
51// transactions in the memory pool. When we select transactions from the
52// pool, we select by highest priority or fee rate, so we might consider
53// transactions that depend on transactions that aren't yet in the block.
54// The COrphan class keeps track of these 'temporary orphans' while
55// CreateBlock is figuring out which transactions to include.
56//
d247a5d1
JG
57class COrphan
58{
59public:
4d707d51 60 const CTransaction* ptx;
d247a5d1 61 set<uint256> setDependsOn;
c6cb21d1 62 CFeeRate feeRate;
02bec4b2 63 double dPriority;
d247a5d1 64
c6cb21d1 65 COrphan(const CTransaction* ptxIn) : ptx(ptxIn), feeRate(0), dPriority(0)
d247a5d1 66 {
d247a5d1 67 }
d247a5d1
JG
68};
69
51ed9ec9
BD
70uint64_t nLastBlockTx = 0;
71uint64_t nLastBlockSize = 0;
d247a5d1 72
c6cb21d1
GA
73// We want to sort transactions by priority and fee rate, so:
74typedef boost::tuple<double, CFeeRate, const CTransaction*> TxPriority;
d247a5d1
JG
75class TxPriorityCompare
76{
77 bool byFee;
0655fac0 78
d247a5d1
JG
79public:
80 TxPriorityCompare(bool _byFee) : byFee(_byFee) { }
0655fac0 81
d247a5d1
JG
82 bool operator()(const TxPriority& a, const TxPriority& b)
83 {
84 if (byFee)
85 {
86 if (a.get<1>() == b.get<1>())
87 return a.get<0>() < b.get<0>();
88 return a.get<1>() < b.get<1>();
89 }
90 else
91 {
92 if (a.get<0>() == b.get<0>())
93 return a.get<1>() < b.get<1>();
94 return a.get<0>() < b.get<0>();
95 }
96 }
97};
98
bebe7282 99void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
22c4272b 100{
101 pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
5ead4b17
JG
102
103 // Updating time can change work required on testnet:
4c902704 104 if (consensusParams.nPowAllowMinDifficultyBlocksAfterHeight != boost::none) {
5ead4b17 105 pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams);
b86dc980 106 }
22c4272b 107}
108
793a72e3 109CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& scriptPubKeyIn)
d247a5d1
JG
110{
111 // Create new block
08c58194 112 std::unique_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate());
d247a5d1
JG
113 if(!pblocktemplate.get())
114 return NULL;
115 CBlock *pblock = &pblocktemplate->block; // pointer for convenience
116
dbca89b7
GA
117 // -regtest only: allow overriding block.nVersion with
118 // -blockversion=N to test forking scenarios
793a72e3 119 if (chainparams.MineBlocksOnDemand())
dbca89b7
GA
120 pblock->nVersion = GetArg("-blockversion", pblock->nVersion);
121
4949004d
PW
122 // Add dummy coinbase tx as first transaction
123 pblock->vtx.push_back(CTransaction());
d247a5d1
JG
124 pblocktemplate->vTxFees.push_back(-1); // updated at end
125 pblocktemplate->vTxSigOps.push_back(-1); // updated at end
126
127 // Largest block you're willing to create:
ad898b40 128 unsigned int nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE);
d247a5d1
JG
129 // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity:
130 nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize));
131
132 // How much of the block should be dedicated to high-priority transactions,
133 // included regardless of the fees they pay
134 unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", DEFAULT_BLOCK_PRIORITY_SIZE);
135 nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize);
136
137 // Minimum block size you want to create; block will be filled with free transactions
138 // until there are no more or the block reaches this size:
037b4f14 139 unsigned int nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE);
d247a5d1
JG
140 nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize);
141
142 // Collect memory pool transactions into the block
a372168e 143 CAmount nFees = 0;
0655fac0 144
d247a5d1
JG
145 {
146 LOCK2(cs_main, mempool.cs);
48265f3c 147 CBlockIndex* pindexPrev = chainActive.Tip();
b867e409 148 const int nHeight = pindexPrev->nHeight + 1;
be126699 149 uint32_t consensusBranchId = CurrentEpochBranchId(nHeight, chainparams.GetConsensus());
75a4d512 150 pblock->nTime = GetAdjustedTime();
a1d3c6fb 151 const int64_t nMedianTimePast = pindexPrev->GetMedianTimePast();
7c70438d 152 CCoinsViewCache view(pcoinsTip);
d247a5d1 153
4fc309f0 154 SaplingMerkleTree sapling_tree;
31a04d28
SB
155 assert(view.GetSaplingAnchorAt(view.GetBestAnchor(SAPLING), sapling_tree));
156
d247a5d1
JG
157 // Priority order to process transactions
158 list<COrphan> vOrphan; // list memory doesn't move
159 map<uint256, vector<COrphan*> > mapDependers;
160 bool fPrintPriority = GetBoolArg("-printpriority", false);
161
162 // This vector will be sorted into a priority queue:
163 vector<TxPriority> vecPriority;
164 vecPriority.reserve(mempool.mapTx.size());
e328fa32 165 for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin();
4d707d51 166 mi != mempool.mapTx.end(); ++mi)
d247a5d1 167 {
e328fa32 168 const CTransaction& tx = mi->GetTx();
a1d3c6fb
MF
169
170 int64_t nLockTimeCutoff = (STANDARD_LOCKTIME_VERIFY_FLAGS & LOCKTIME_MEDIAN_TIME_PAST)
171 ? nMedianTimePast
172 : pblock->GetBlockTime();
173
9bb37bf0 174 if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, nLockTimeCutoff) || IsExpiredTx(tx, nHeight))
d247a5d1
JG
175 continue;
176
177 COrphan* porphan = NULL;
178 double dPriority = 0;
a372168e 179 CAmount nTotalIn = 0;
d247a5d1
JG
180 bool fMissingInputs = false;
181 BOOST_FOREACH(const CTxIn& txin, tx.vin)
182 {
183 // Read prev transaction
184 if (!view.HaveCoins(txin.prevout.hash))
185 {
186 // This should never happen; all transactions in the memory
187 // pool should connect to either transactions in the chain
188 // or other transactions in the memory pool.
189 if (!mempool.mapTx.count(txin.prevout.hash))
190 {
881a85a2 191 LogPrintf("ERROR: mempool transaction missing input\n");
d247a5d1
JG
192 if (fDebug) assert("mempool transaction missing input" == 0);
193 fMissingInputs = true;
194 if (porphan)
195 vOrphan.pop_back();
196 break;
197 }
198
199 // Has to wait for dependencies
200 if (!porphan)
201 {
202 // Use list for automatic deletion
203 vOrphan.push_back(COrphan(&tx));
204 porphan = &vOrphan.back();
205 }
206 mapDependers[txin.prevout.hash].push_back(porphan);
207 porphan->setDependsOn.insert(txin.prevout.hash);
e328fa32 208 nTotalIn += mempool.mapTx.find(txin.prevout.hash)->GetTx().vout[txin.prevout.n].nValue;
d247a5d1
JG
209 continue;
210 }
629d75fa
PW
211 const CCoins* coins = view.AccessCoins(txin.prevout.hash);
212 assert(coins);
d247a5d1 213
a372168e 214 CAmount nValueIn = coins->vout[txin.prevout.n].nValue;
d247a5d1
JG
215 nTotalIn += nValueIn;
216
b867e409 217 int nConf = nHeight - coins->nHeight;
d247a5d1
JG
218
219 dPriority += (double)nValueIn * nConf;
220 }
97b46f00 221 nTotalIn += tx.GetShieldedValueIn();
2b2bc69e 222
d247a5d1
JG
223 if (fMissingInputs) continue;
224
d6eb2599 225 // Priority is sum(valuein * age) / modified_txsize
d247a5d1 226 unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
4d707d51 227 dPriority = tx.ComputePriority(dPriority, nTxSize);
d247a5d1 228
805344dc 229 uint256 hash = tx.GetHash();
2a72d459
LD
230 mempool.ApplyDeltas(hash, dPriority, nTotalIn);
231
c6cb21d1 232 CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);
d247a5d1
JG
233
234 if (porphan)
235 {
236 porphan->dPriority = dPriority;
c6cb21d1 237 porphan->feeRate = feeRate;
d247a5d1
JG
238 }
239 else
e328fa32 240 vecPriority.push_back(TxPriority(dPriority, feeRate, &(mi->GetTx())));
d247a5d1
JG
241 }
242
243 // Collect transactions into block
51ed9ec9
BD
244 uint64_t nBlockSize = 1000;
245 uint64_t nBlockTx = 0;
d247a5d1
JG
246 int nBlockSigOps = 100;
247 bool fSortedByFee = (nBlockPrioritySize <= 0);
248
249 TxPriorityCompare comparer(fSortedByFee);
250 std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
251
bf4de896
SB
252 // We want to track the value pool, but if the miner gets
253 // invoked on an old block before the hardcoded fallback
254 // is active we don't want to trip up any assertions. So,
255 // we only adhere to the turnstile (as a miner) if we
256 // actually have all of the information necessary to do
257 // so.
258 CAmount sproutValue = 0;
259 CAmount saplingValue = 0;
260 bool monitoring_pool_balances = true;
b5c7e63b 261 if (chainparams.ZIP209Enabled()) {
bf4de896
SB
262 if (pindexPrev->nChainSproutValue) {
263 sproutValue = *pindexPrev->nChainSproutValue;
264 } else {
265 monitoring_pool_balances = false;
266 }
267 if (pindexPrev->nChainSaplingValue) {
268 saplingValue = *pindexPrev->nChainSaplingValue;
269 } else {
270 monitoring_pool_balances = false;
271 }
272 }
273
d247a5d1
JG
274 while (!vecPriority.empty())
275 {
276 // Take highest priority transaction off the priority queue:
277 double dPriority = vecPriority.front().get<0>();
c6cb21d1 278 CFeeRate feeRate = vecPriority.front().get<1>();
4d707d51 279 const CTransaction& tx = *(vecPriority.front().get<2>());
d247a5d1
JG
280
281 std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer);
282 vecPriority.pop_back();
283
284 // Size limits
285 unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
286 if (nBlockSize + nTxSize >= nBlockMaxSize)
287 continue;
288
289 // Legacy limits on sigOps:
290 unsigned int nTxSigOps = GetLegacySigOpCount(tx);
291 if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
292 continue;
293
294 // Skip free transactions if we're past the minimum block size:
805344dc 295 const uint256& hash = tx.GetHash();
2a72d459 296 double dPriorityDelta = 0;
a372168e 297 CAmount nFeeDelta = 0;
2a72d459 298 mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
13fc83c7 299 if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
d247a5d1
JG
300 continue;
301
2a72d459 302 // Prioritise by fee once past the priority size or we run out of high-priority
d247a5d1
JG
303 // transactions:
304 if (!fSortedByFee &&
305 ((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority)))
306 {
307 fSortedByFee = true;
308 comparer = TxPriorityCompare(fSortedByFee);
309 std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
310 }
311
312 if (!view.HaveInputs(tx))
313 continue;
314
a372168e 315 CAmount nTxFees = view.GetValueIn(tx)-tx.GetValueOut();
d247a5d1
JG
316
317 nTxSigOps += GetP2SHSigOpCount(tx, view);
318 if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
319 continue;
320
68f7d1d7
PT
321 // Note that flags: we don't want to set mempool/IsStandard()
322 // policy here, but we still have to ensure that the block we
323 // create only contains transactions that are valid in new blocks.
d247a5d1 324 CValidationState state;
6514771a 325 PrecomputedTransactionData txdata(tx);
793a72e3 326 if (!ContextualCheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true, txdata, chainparams.GetConsensus(), consensusBranchId))
d247a5d1
JG
327 continue;
328
b5c7e63b 329 if (chainparams.ZIP209Enabled() && monitoring_pool_balances) {
bf4de896
SB
330 // Does this transaction lead to a turnstile violation?
331
332 CAmount sproutValueDummy = sproutValue;
333 CAmount saplingValueDummy = saplingValue;
334
cb6df4b0 335 saplingValueDummy += -tx.valueBalance;
bf4de896 336
f57f76d7 337 for (auto js : tx.vJoinSplit) {
bf4de896
SB
338 sproutValueDummy += js.vpub_old;
339 sproutValueDummy -= js.vpub_new;
340 }
341
2b1252af 342 if (sproutValueDummy < 0) {
ebe2edce 343 LogPrintf("CreateNewBlock(): tx %s appears to violate Sprout turnstile\n", tx.GetHash().ToString());
2b1252af
SB
344 continue;
345 }
346 if (saplingValueDummy < 0) {
ebe2edce 347 LogPrintf("CreateNewBlock(): tx %s appears to violate Sapling turnstile\n", tx.GetHash().ToString());
2b1252af
SB
348 continue;
349 }
bf4de896
SB
350
351 sproutValue = sproutValueDummy;
352 saplingValue = saplingValueDummy;
353 }
354
8cb98d91 355 UpdateCoins(tx, view, nHeight);
d247a5d1 356
31a04d28
SB
357 BOOST_FOREACH(const OutputDescription &outDescription, tx.vShieldedOutput) {
358 sapling_tree.append(outDescription.cm);
359 }
360
d247a5d1
JG
361 // Added
362 pblock->vtx.push_back(tx);
363 pblocktemplate->vTxFees.push_back(nTxFees);
364 pblocktemplate->vTxSigOps.push_back(nTxSigOps);
365 nBlockSize += nTxSize;
366 ++nBlockTx;
367 nBlockSigOps += nTxSigOps;
368 nFees += nTxFees;
369
370 if (fPrintPriority)
371 {
c6cb21d1 372 LogPrintf("priority %.1f fee %s txid %s\n",
805344dc 373 dPriority, feeRate.ToString(), tx.GetHash().ToString());
d247a5d1
JG
374 }
375
376 // Add transactions that depend on this one to the priority queue
377 if (mapDependers.count(hash))
378 {
379 BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
380 {
381 if (!porphan->setDependsOn.empty())
382 {
383 porphan->setDependsOn.erase(hash);
384 if (porphan->setDependsOn.empty())
385 {
c6cb21d1 386 vecPriority.push_back(TxPriority(porphan->dPriority, porphan->feeRate, porphan->ptx));
d247a5d1
JG
387 std::push_heap(vecPriority.begin(), vecPriority.end(), comparer);
388 }
389 }
390 }
391 }
392 }
393
394 nLastBlockTx = nBlockTx;
395 nLastBlockSize = nBlockSize;
f48742c2 396 LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize);
d247a5d1 397
f3ffa3d2 398 // Create coinbase tx
072099d7 399 CMutableTransaction txNew = CreateNewContextualCMutableTransaction(chainparams.GetConsensus(), nHeight);
f3ffa3d2
SB
400 txNew.vin.resize(1);
401 txNew.vin[0].prevout.SetNull();
402 txNew.vout.resize(1);
403 txNew.vout[0].scriptPubKey = scriptPubKeyIn;
404 txNew.vout[0].nValue = GetBlockSubsidy(nHeight, chainparams.GetConsensus());
9bb37bf0
JG
405 // Set to 0 so expiry height does not apply to coinbase txs
406 txNew.nExpiryHeight = 0;
f3ffa3d2 407
22dadb35 408 if ((nHeight > 0) && (nHeight <= chainparams.GetConsensus().GetLastFoundersRewardBlockHeight())) {
f3ffa3d2
SB
409 // Founders reward is 20% of the block subsidy
410 auto vFoundersReward = txNew.vout[0].nValue / 5;
411 // Take some reward away from us
412 txNew.vout[0].nValue -= vFoundersReward;
413
f3ffa3d2 414 // And give it to the founders
3b30d836 415 txNew.vout.push_back(CTxOut(vFoundersReward, chainparams.GetFoundersRewardScriptAtHeight(nHeight)));
f3ffa3d2
SB
416 }
417
418 // Add fees
419 txNew.vout[0].nValue += nFees;
b867e409 420 txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;
f3ffa3d2 421
4949004d 422 pblock->vtx[0] = txNew;
d247a5d1
JG
423 pblocktemplate->vTxFees[0] = -nFees;
424
8e165d57
JG
425 // Randomise nonce
426 arith_uint256 nonce = UintToArith256(GetRandHash());
427 // Clear the top and bottom 16 bits (for local use as thread flags and counters)
428 nonce <<= 32;
429 nonce >>= 16;
430 pblock->nNonce = ArithToUint256(nonce);
431
d247a5d1
JG
432 // Fill in header
433 pblock->hashPrevBlock = pindexPrev->GetBlockHash();
31a04d28 434 pblock->hashFinalSaplingRoot = sapling_tree.root();
793a72e3
JT
435 UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
436 pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus());
fdda3c50 437 pblock->nSolution.clear();
d247a5d1
JG
438 pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]);
439
d247a5d1 440 CValidationState state;
8e5d8ca5 441 if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false))
5262fde0 442 throw std::runtime_error("CreateNewBlock(): TestBlockValidity failed");
d247a5d1
JG
443 }
444
445 return pblocktemplate.release();
446}
447
c1de826f
JG
448//////////////////////////////////////////////////////////////////////////////
449//
450// Internal miner
451//
452
2cc0a252 453#ifdef ENABLE_MINING
c1de826f 454
f4055fe1
JS
455class MinerAddressScript : public CReserveScript
456{
c233f6fd
JG
457 // CReserveScript requires implementing this function, so that if an
458 // internal (not-visible) wallet address is used, the wallet can mark it as
459 // important when a block is mined (so it then appears to the user).
460 // If -mineraddress is set, the user already knows about and is managing the
461 // address, so we don't need to do anything here.
f4055fe1
JS
462 void KeepScript() {}
463};
464
465void GetScriptForMinerAddress(boost::shared_ptr<CReserveScript> &script)
b2993bc5
JS
466{
467 CTxDestination addr = DecodeDestination(GetArg("-mineraddress", ""));
468 if (!IsValidDestination(addr)) {
469 return;
470 }
471
f4055fe1 472 boost::shared_ptr<MinerAddressScript> mAddr(new MinerAddressScript());
b2993bc5 473 CKeyID keyID = boost::get<CKeyID>(addr);
f4055fe1
JS
474
475 script = mAddr;
476 script->reserveScript = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
b2993bc5
JS
477}
478
9a529fd2 479void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
c1de826f
JG
480{
481 // Update nExtraNonce
482 static uint256 hashPrevBlock;
483 if (hashPrevBlock != pblock->hashPrevBlock)
484 {
485 nExtraNonce = 0;
486 hashPrevBlock = pblock->hashPrevBlock;
487 }
488 ++nExtraNonce;
489 unsigned int nHeight = pindexPrev->nHeight+1; // Height first in coinbase required for block.version=2
490 CMutableTransaction txCoinbase(pblock->vtx[0]);
491 txCoinbase.vin[0].scriptSig = (CScript() << nHeight << CScriptNum(nExtraNonce)) + COINBASE_FLAGS;
492 assert(txCoinbase.vin[0].scriptSig.size() <= 100);
493
494 pblock->vtx[0] = txCoinbase;
495 pblock->hashMerkleRoot = pblock->BuildMerkleTree();
496}
497
9a529fd2 498static bool ProcessBlockFound(const CBlock* pblock, const CChainParams& chainparams)
d247a5d1 499{
81212588 500 LogPrintf("%s\n", pblock->ToString());
7d9d134b 501 LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
d247a5d1
JG
502
503 // Found a solution
504 {
505 LOCK(cs_main);
4c6d41b8 506 if (pblock->hashPrevBlock != chainActive.Tip()->GetBlockHash())
fdda3c50 507 return error("ZcashMiner: generated block is stale");
18e72167 508 }
d247a5d1 509
b2993bc5 510 // Inform about the new block
648d6bee 511 GetMainSignals().BlockFound(pblock->GetHash());
d247a5d1 512
18e72167
PW
513 // Process this block the same as if we had received it from another node
514 CValidationState state;
8e5d8ca5 515 if (!ProcessNewBlock(state, chainparams, NULL, pblock, true, NULL))
fdda3c50 516 return error("ZcashMiner: ProcessNewBlock, block not accepted");
18e72167 517
d793f94b 518 TrackMinedBlock(pblock->GetHash());
a6df7ab5 519
d247a5d1
JG
520 return true;
521}
522
f4055fe1 523void static BitcoinMiner(const CChainParams& chainparams)
d247a5d1 524{
fdda3c50 525 LogPrintf("ZcashMiner started\n");
d247a5d1 526 SetThreadPriority(THREAD_PRIORITY_LOWEST);
fdda3c50 527 RenameThread("zcash-miner");
8e8b6d70
JG
528
529 // Each thread has its own counter
d247a5d1
JG
530 unsigned int nExtraNonce = 0;
531
f4055fe1
JS
532 boost::shared_ptr<CReserveScript> coinbaseScript;
533 GetMainSignals().ScriptForMining(coinbaseScript);
534
cea06a4f
JG
535 unsigned int n = chainparams.GetConsensus().nEquihashN;
536 unsigned int k = chainparams.GetConsensus().nEquihashK;
fdda3c50 537
c7aaab7a 538 std::string solver = GetArg("-equihashsolver", "default");
5f0009b2 539 assert(solver == "tromp" || solver == "default");
c7aaab7a
DH
540 LogPrint("pow", "Using Equihash solver \"%s\" with n = %u, k = %u\n", solver, n, k);
541
5a360a5c
JG
542 std::mutex m_cs;
543 bool cancelSolver = false;
544 boost::signals2::connection c = uiInterface.NotifyBlockTip.connect(
545 [&m_cs, &cancelSolver](const uint256& hashNewTip) mutable {
546 std::lock_guard<std::mutex> lock{m_cs};
547 cancelSolver = true;
548 }
549 );
07be8f7e 550 miningTimer.start();
5a360a5c 551
0655fac0 552 try {
f4055fe1
JS
553 //throw an error if no script was provided
554 if (!coinbaseScript->reserveScript.size())
555 throw std::runtime_error("No coinbase script available (mining requires a wallet or -mineraddress)");
556
0655fac0 557 while (true) {
bebe7282 558 if (chainparams.MiningRequiresPeers()) {
0655fac0
PK
559 // Busy-wait for the network to come online so we don't waste time mining
560 // on an obsolete chain. In regtest mode we expect to fly solo.
07be8f7e 561 miningTimer.stop();
bba7c249
GM
562 do {
563 bool fvNodesEmpty;
564 {
565 LOCK(cs_vNodes);
566 fvNodesEmpty = vNodes.empty();
567 }
3ffc29b8 568 if (!fvNodesEmpty && !IsInitialBlockDownload(chainparams))
bba7c249 569 break;
0655fac0 570 MilliSleep(1000);
bba7c249 571 } while (true);
07be8f7e 572 miningTimer.start();
0655fac0 573 }
d247a5d1 574
0655fac0
PK
575 //
576 // Create new block
577 //
578 unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
48265f3c 579 CBlockIndex* pindexPrev = chainActive.Tip();
0655fac0 580
793a72e3 581 unique_ptr<CBlockTemplate> pblocktemplate(CreateNewBlock(chainparams, coinbaseScript->reserveScript));
0655fac0 582 if (!pblocktemplate.get())
6c37f7fd 583 {
8e8b6d70
JG
584 if (GetArg("-mineraddress", "").empty()) {
585 LogPrintf("Error in ZcashMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
586 } else {
587 // Should never reach here, because -mineraddress validity is checked in init.cpp
588 LogPrintf("Error in ZcashMiner: Invalid -mineraddress\n");
589 }
0655fac0 590 return;
6c37f7fd 591 }
0655fac0
PK
592 CBlock *pblock = &pblocktemplate->block;
593 IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
594
fdda3c50 595 LogPrintf("Running ZcashMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(),
0655fac0
PK
596 ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
597
598 //
599 // Search
600 //
601 int64_t nStart = GetTime();
48265f3c 602 arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
fdda3c50 603
7213c0b1
JG
604 while (true) {
605 // Hash state
606 crypto_generichash_blake2b_state state;
e9574728 607 EhInitialiseState(n, k, state);
fdda3c50 608
7213c0b1
JG
609 // I = the block header minus nonce and solution.
610 CEquihashInput I{*pblock};
611 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
612 ss << I;
fdda3c50 613
7213c0b1
JG
614 // H(I||...
615 crypto_generichash_blake2b_update(&state, (unsigned char*)&ss[0], ss.size());
fdda3c50 616
8e165d57
JG
617 // H(I||V||...
618 crypto_generichash_blake2b_state curr_state;
619 curr_state = state;
620 crypto_generichash_blake2b_update(&curr_state,
621 pblock->nNonce.begin(),
622 pblock->nNonce.size());
623
624 // (x_1, x_2, ...) = A(I, V, n, k)
c7aaab7a
DH
625 LogPrint("pow", "Running Equihash solver \"%s\" with nNonce = %s\n",
626 solver, pblock->nNonce.ToString());
8e165d57 627
5be6abbf 628 std::function<bool(std::vector<unsigned char>)> validBlock =
f4055fe1 629 [&pblock, &hashTarget, &chainparams, &m_cs, &cancelSolver, &coinbaseScript]
5be6abbf 630 (std::vector<unsigned char> soln) {
51eb5273
JG
631 // Write the solution to the hash and compute the result.
632 LogPrint("pow", "- Checking solution against target\n");
8e165d57 633 pblock->nSolution = soln;
e7d59bbc 634 solutionTargetChecks.increment();
8e165d57
JG
635
636 if (UintToArith256(pblock->GetHash()) > hashTarget) {
51eb5273 637 return false;
8e165d57 638 }
48265f3c 639
8e165d57
JG
640 // Found a solution
641 SetThreadPriority(THREAD_PRIORITY_NORMAL);
642 LogPrintf("ZcashMiner:\n");
643 LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", pblock->GetHash().GetHex(), hashTarget.GetHex());
b2993bc5 644 if (ProcessBlockFound(pblock, chainparams)) {
5a360a5c
JG
645 // Ignore chain updates caused by us
646 std::lock_guard<std::mutex> lock{m_cs};
647 cancelSolver = false;
648 }
8e165d57 649 SetThreadPriority(THREAD_PRIORITY_LOWEST);
f4055fe1 650 coinbaseScript->KeepScript();
48265f3c 651
8e165d57 652 // In regression test mode, stop mining after a block is found.
a6df7ab5
JG
653 if (chainparams.MineBlocksOnDemand()) {
654 // Increment here because throwing skips the call below
655 ehSolverRuns.increment();
8e165d57 656 throw boost::thread_interrupted();
a6df7ab5 657 }
48265f3c 658
51eb5273
JG
659 return true;
660 };
661 std::function<bool(EhSolverCancelCheck)> cancelled = [&m_cs, &cancelSolver](EhSolverCancelCheck pos) {
662 std::lock_guard<std::mutex> lock{m_cs};
663 return cancelSolver;
664 };
c7aaab7a 665
5f0009b2 666 // TODO: factor this out into a function with the same API for each solver.
c7aaab7a
DH
667 if (solver == "tromp") {
668 // Create solver and initialize it.
669 equi eq(1);
670 eq.setstate(&curr_state);
671
c938fb1f 672 // Initialization done, start algo driver.
c7aaab7a
DH
673 eq.digit0(0);
674 eq.xfull = eq.bfull = eq.hfull = 0;
675 eq.showbsizes(0);
676 for (u32 r = 1; r < WK; r++) {
677 (r&1) ? eq.digitodd(r, 0) : eq.digiteven(r, 0);
678 eq.xfull = eq.bfull = eq.hfull = 0;
679 eq.showbsizes(r);
680 }
681 eq.digitK(0);
a6df7ab5 682 ehSolverRuns.increment();
c7aaab7a
DH
683
684 // Convert solution indices to byte array (decompress) and pass it to validBlock method.
685 for (size_t s = 0; s < eq.nsols; s++) {
686 LogPrint("pow", "Checking solution %d\n", s+1);
687 std::vector<eh_index> index_vector(PROOFSIZE);
688 for (size_t i = 0; i < PROOFSIZE; i++) {
689 index_vector[i] = eq.sols[s][i];
690 }
691 std::vector<unsigned char> sol_char = GetMinimalFromIndices(index_vector, DIGITBITS);
692
693 if (validBlock(sol_char)) {
694 // If we find a POW solution, do not try other solutions
695 // because they become invalid as we created a new block in blockchain.
696 break;
697 }
698 }
699 } else {
700 try {
701 // If we find a valid block, we rebuild
a6df7ab5
JG
702 bool found = EhOptimisedSolve(n, k, curr_state, validBlock, cancelled);
703 ehSolverRuns.increment();
704 if (found) {
c7aaab7a 705 break;
a6df7ab5 706 }
c7aaab7a
DH
707 } catch (EhSolverCancelledException&) {
708 LogPrint("pow", "Equihash solver cancelled\n");
709 std::lock_guard<std::mutex> lock{m_cs};
710 cancelSolver = false;
711 }
48265f3c 712 }
d247a5d1 713
0655fac0
PK
714 // Check for stop or if block needs to be rebuilt
715 boost::this_thread::interruption_point();
716 // Regtest mode doesn't require peers
bebe7282 717 if (vNodes.empty() && chainparams.MiningRequiresPeers())
0655fac0 718 break;
8e165d57 719 if ((UintToArith256(pblock->nNonce) & 0xffff) == 0xffff)
0655fac0
PK
720 break;
721 if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
722 break;
723 if (pindexPrev != chainActive.Tip())
724 break;
725
8e165d57
JG
726 // Update nNonce and nTime
727 pblock->nNonce = ArithToUint256(UintToArith256(pblock->nNonce) + 1);
bebe7282 728 UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
4c902704 729 if (chainparams.GetConsensus().nPowAllowMinDifficultyBlocksAfterHeight != boost::none)
5ead4b17
JG
730 {
731 // Changing pblock->nTime can change work required on testnet:
732 hashTarget.SetCompact(pblock->nBits);
733 }
d247a5d1
JG
734 }
735 }
0655fac0 736 }
27df4123 737 catch (const boost::thread_interrupted&)
d247a5d1 738 {
07be8f7e 739 miningTimer.stop();
5e9b555f 740 c.disconnect();
fdda3c50 741 LogPrintf("ZcashMiner terminated\n");
d247a5d1
JG
742 throw;
743 }
bba7c249
GM
744 catch (const std::runtime_error &e)
745 {
07be8f7e 746 miningTimer.stop();
5e9b555f 747 c.disconnect();
fdda3c50 748 LogPrintf("ZcashMiner runtime error: %s\n", e.what());
bba7c249
GM
749 return;
750 }
07be8f7e 751 miningTimer.stop();
5a360a5c 752 c.disconnect();
d247a5d1
JG
753}
754
b2993bc5 755void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams& chainparams)
d247a5d1
JG
756{
757 static boost::thread_group* minerThreads = NULL;
758
2854c4e3
WL
759 if (nThreads < 0)
760 nThreads = GetNumCores();
d247a5d1
JG
761
762 if (minerThreads != NULL)
763 {
764 minerThreads->interrupt_all();
a17646b1 765 minerThreads->join_all();
d247a5d1
JG
766 delete minerThreads;
767 minerThreads = NULL;
768 }
769
770 if (nThreads == 0 || !fGenerate)
771 return;
772
773 minerThreads = new boost::thread_group();
8e8b6d70 774 for (int i = 0; i < nThreads; i++) {
f4055fe1 775 minerThreads->create_thread(boost::bind(&BitcoinMiner, boost::cref(chainparams)));
8e8b6d70 776 }
d247a5d1
JG
777}
778
2cc0a252 779#endif // ENABLE_MINING
This page took 0.304989 seconds and 4 git commands to generate.