31 #include <boost/thread.hpp> 32 #include <boost/tuple/tuple.hpp> 64 int64_t nOldTime = pblock->
nTime;
67 if (nOldTime < nNewTime)
68 pblock->
nTime = nNewTime;
74 return nNewTime - nOldTime;
80 std::unique_ptr<CBlockTemplate> pblocktemplate(
new CBlockTemplate());
81 if(!pblocktemplate.get())
83 CBlock *pblock = &pblocktemplate->block;
88 txNew.
vin[0].prevout.SetNull();
90 txNew.
vout[0].scriptPubKey = scriptPubKeyIn;
100 nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize);
105 nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize);
112 vector<TxCoinAgePriority> vecPriority;
114 std::map<CTxMemPool::txiter, double, CTxMemPool::CompareIteratorByHash> waitPriMap;
115 typedef std::map<CTxMemPool::txiter, double, CTxMemPool::CompareIteratorByHash>::iterator waitPriIter;
116 double actualPriority = -1;
118 std::priority_queue<CTxMemPool::txiter, std::vector<CTxMemPool::txiter>,
ScoreCompare> clearedTxs;
120 uint64_t nBlockSize = 1000;
121 uint64_t nBlockTx = 0;
122 unsigned int nBlockSigOps = 100;
130 const int nHeight = pindexPrev->
nHeight + 1;
135 pblock->
vtx.push_back(txNew);
136 pblocktemplate->vTxFees.push_back(-1);
137 pblocktemplate->vTxSigOps.push_back(-1);
151 bool fPriorityBlock = nBlockPrioritySize > 0;
152 if (fPriorityBlock) {
154 for (CTxMemPool::indexed_transaction_set::iterator mi =
mempool.
mapTx.begin();
157 double dPriority = mi->GetPriority(nHeight);
162 std::make_heap(vecPriority.begin(), vecPriority.end(), pricomparer);
165 CTxMemPool::indexed_transaction_set::nth_index<3>::type::iterator mi =
mempool.
mapTx.get<3>().begin();
168 while (mi !=
mempool.
mapTx.get<3>().end() || !clearedTxs.empty())
170 bool priorityTx =
false;
171 if (fPriorityBlock && !vecPriority.empty()) {
173 iter = vecPriority.front().second;
174 actualPriority = vecPriority.front().first;
175 std::pop_heap(vecPriority.begin(), vecPriority.end(), pricomparer);
176 vecPriority.pop_back();
178 else if (clearedTxs.empty()) {
183 iter = clearedTxs.top();
187 if (inBlock.count(iter))
192 bool fOrphan =
false;
195 if (!inBlock.count(parent)) {
202 waitPriMap.insert(std::make_pair(iter,actualPriority));
204 waitSet.insert(iter);
208 unsigned int nTxSize = iter->GetTxSize();
209 if (fPriorityBlock &&
210 (nBlockSize + nTxSize >= nBlockPrioritySize || !
AllowFree(actualPriority))) {
211 fPriorityBlock =
false;
218 if (nBlockSize + nTxSize >= nBlockMaxSize) {
219 if (nBlockSize > nBlockMaxSize - 100 || lastFewTxs > 50) {
224 if (nBlockSize > nBlockMaxSize - 1000) {
230 if (!
IsFinalTx(tx, nHeight, nLockTimeCutoff))
233 unsigned int nTxSigOps = iter->GetSigOpCount();
235 if (nBlockSigOps + nTxSigOps >= nMaxBlockSigOps) {
236 if (nBlockSigOps > nMaxBlockSigOps - 2) {
242 CAmount nTxFees = iter->GetFee();
244 pblock->
vtx.push_back(tx);
245 pblocktemplate->vTxFees.push_back(nTxFees);
246 pblocktemplate->vTxSigOps.push_back(nTxSigOps);
247 nBlockSize += nTxSize;
249 nBlockSigOps += nTxSigOps;
254 double dPriority = iter->GetPriority(nHeight);
257 LogPrintf(
"priority %.1f fee %s txid %s\n",
261 inBlock.insert(iter);
266 if (fPriorityBlock) {
267 waitPriIter wpiter = waitPriMap.find(
child);
268 if (wpiter != waitPriMap.end()) {
270 std::push_heap(vecPriority.begin(), vecPriority.end(), pricomparer);
271 waitPriMap.erase(wpiter);
275 if (waitSet.count(
child)) {
276 clearedTxs.push(
child);
277 waitSet.erase(
child);
289 txNew.
vout[0].nValue = blockReward;
300 LogPrintf(
"CreateNewBlock(): total size %u txs: %u fees: %ld sigops %d\n", nBlockSize, nBlockTx, nFees, nBlockSigOps);
303 pblock->
vtx[0] = txNew;
304 pblocktemplate->vTxFees[0] = -nFees;
319 return pblocktemplate.release();
332 unsigned int nHeight = pindexPrev->
nHeight+1;
335 assert(txCoinbase.
vin[0].scriptSig.size() <= 100);
337 pblock->
vtx[0] = txCoinbase;
389 return error(
"ProcessBlockFound -- generated block is stale");
397 return error(
"ProcessBlockFound -- ProcessNewBlock() failed, block not accepted");
409 unsigned int nExtraNonce = 0;
411 boost::shared_ptr<CReserveScript> coinbaseScript;
418 if (!coinbaseScript || coinbaseScript->reserveScript.empty())
419 throw std::runtime_error(
"No coinbase script available (mining requires a wallet)");
439 if(!pindexPrev)
break;
441 std::unique_ptr<CBlockTemplate> pblocktemplate(
CreateNewBlock(chainparams, coinbaseScript->reserveScript));
442 if (!pblocktemplate.get())
444 LogPrintf(
"DashMiner -- Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
447 CBlock *pblock = &pblocktemplate->block;
450 LogPrintf(
"DashMiner -- Running miner with %u transactions in block (%u bytes)\n", pblock->
vtx.size(),
460 unsigned int nHashesDone = 0;
470 LogPrintf(
"DashMiner:\n proof-of-work found\n hash: %s\n target: %s\n", hash.
GetHex(), hashTarget.
GetHex());
473 coinbaseScript->KeepScript();
478 throw boost::thread_interrupted();
484 if ((pblock->
nNonce & 0xFF) == 0)
489 boost::this_thread::interruption_point();
493 if (pblock->
nNonce >= 0xffff0000)
512 catch (
const boost::thread_interrupted&)
517 catch (
const std::runtime_error &e)
519 LogPrintf(
"DashMiner -- runtime error: %s\n", e.what());
526 static boost::thread_group* minerThreads = NULL;
531 if (minerThreads != NULL)
533 minerThreads->interrupt_all();
538 if (nThreads == 0 || !fGenerate)
541 minerThreads =
new boost::thread_group();
542 for (
int i = 0; i < nThreads; i++)
543 minerThreads->create_thread(boost::bind(&
BitcoinMiner, boost::cref(chainparams), boost::ref(connman)));
boost::signals2::signal< void(boost::shared_ptr< CReserveScript > &)> ScriptForMining
int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, const Consensus::Params ¶ms, bool fAssumeMasternodeIsUpgraded)
CMasternodeSync masternodeSync
void SetThreadPriority(int nPriority)
void MilliSleep(int64_t n)
static const unsigned int STANDARD_LOCKTIME_VERIFY_FLAGS
int64_t UpdateTime(CBlockHeader *pblock, const Consensus::Params &consensusParams, const CBlockIndex *pindexPrev)
unsigned int MaxBlockSize(bool fDIP0001Active)
const Consensus::Params & GetConsensus() const
bool operator()(const CTxMemPool::txiter a, const CTxMemPool::txiter b)
bool fPowAllowMinDifficultyBlocks
arith_uint256 & SetCompact(uint32_t nCompact, bool *pfNegative=NULL, bool *pfOverflow=NULL)
CAmount GetFee(size_t size) const
std::vector< CTxOut > voutSuperblock
indexed_transaction_set mapTx
std::pair< double, CTxMemPool::txiter > TxCoinAgePriority
boost::signals2::signal< void(const uint256 &)> BlockFound
void RenameThread(const char *name)
arith_uint256 UintToArith256(const uint256 &a)
std::vector< CTransaction > vtx
bool ProcessNewBlock(const CChainParams &chainparams, const CBlock *pblock, bool fForceProcessing, const CDiskBlockPos *dbp, bool *fNewBlock)
size_t GetNodeCount(NumConnections num)
void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta) const
#define THREAD_PRIORITY_NORMAL
bool GetBoolArg(const std::string &strArg, bool fDefault)
indexed_transaction_set::nth_index< 0 >::type::iterator txiter
#define THREAD_PRIORITY_LOWEST
const setEntries & GetMemPoolParents(txiter entry) const
unsigned int GetSerializeSize(char a, int, int=0)
unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock, const Consensus::Params ¶ms)
unsigned int MaxBlockSigOps(bool fDIP0001Active)
static void BitcoinMiner(const CChainParams &chainparams, CConnman &connman)
void GenerateBitcoins(bool fGenerate, int nThreads, const CChainParams &chainparams, CConnman &connman)
static bool error(const char *format)
bool IsInitialBlockDownload()
std::atomic< bool > fDIP0001ActiveAtTip
CMainSignals & GetMainSignals()
bool AllowFree(double dPriority)
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
static const unsigned int DEFAULT_BLOCK_MAX_SIZE
std::string ToString() const
std::string FormatMoney(const CAmount &n)
std::set< txiter, CompareIteratorByHash > setEntries
unsigned int GetLegacySigOpCount(const CTransaction &tx)
static const unsigned int DEFAULT_BLOCK_MIN_SIZE
static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE
std::vector< CTxOut > vout
std::string ToString() const
void IncrementExtraNonce(CBlock *pblock, const CBlockIndex *pindexPrev, unsigned int &nExtraNonce)
std::string FormatStateMessage(const CValidationState &state)
const setEntries & GetMemPoolChildren(txiter entry) const
static bool ProcessBlockFound(const CBlock *pblock, const CChainParams &chainparams)
const CChainParams & Params()
static const int PROTOCOL_VERSION
const uint256 & GetHash() const
int64_t GetAdjustedTime()
bool TestBlockValidity(CValidationState &state, const CChainParams &chainparams, const CBlock &block, CBlockIndex *pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot)
uint256 GetBlockHash() const
std::string GetHex() const
CBlockIndex * Tip() const
int64_t GetMedianTimePast() const
std::string GetArg(const std::string &strArg, const std::string &strDefault)
std::string GetHex() const
int64_t GetTime()
For unit testing.
bool MiningRequiresPeers() const
static const bool DEFAULT_PRINTPRIORITY
CAmount GetBlockSubsidy(int nPrevBits, int nPrevHeight, const Consensus::Params &consensusParams, bool fSuperblockPartOnly)
CBlockTemplate * CreateNewBlock(const CChainParams &chainparams, const CScript &scriptPubKeyIn)
int nHeight
height of the entry in the chain. The genesis block has height 0
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
bool MineBlocksOnDemand() const
void FillBlockPayments(CMutableTransaction &txNew, int nBlockHeight, CAmount blockReward, CTxOut &txoutMasternodeRet, std::vector< CTxOut > &voutSuperblockRet)
unsigned int GetTransactionsUpdated() const