31 #include <boost/thread.hpp>
41 std::unique_ptr<CBlockTemplate> CreateNewBlockWithKey(std::unique_ptr<CReserveKey>& reservekey,
CWallet* pwallet)
44 if (!reservekey->GetReservedKey(pubkey))
return nullptr;
48 std::unique_ptr<CBlockTemplate> CreateNewBlockWithScript(
const CScript& coinbaseScript,
CWallet* pwallet)
55 LogPrintf(
"%s: Aborting PoW block creation during PoS phase\n", __func__);
64 bool ProcessBlockFound(
const std::shared_ptr<const CBlock>& pblock,
CWallet& wallet, std::unique_ptr<CReserveKey>& reservekey)
66 LogPrintf(
"%s\n", pblock->ToString());
67 LogPrintf(
"generated %s\n",
FormatMoney(pblock->vtx[0]->vout[0].nValue));
73 return error(
"PIVXMiner : generated block is stale");
78 reservekey->KeepKey();
84 if (!res || sc.get().stateErrorFound()) {
85 return error(
"PIVXMiner : ProcessNewBlock, block not accepted");
96 bool fGenerateBitcoins =
false;
97 bool fStakeableCoins =
false;
99 void CheckForCoins(
CWallet* pwallet, std::vector<CStakeableOutput>* availableCoins)
113 void BitcoinMiner(
CWallet* pwallet,
bool fProofOfStake)
115 LogPrintf(
"PIVXMiner started\n");
122 std::unique_ptr<CReserveKey> pReservekey = fProofOfStake ? nullptr : std::make_unique<CReserveKey>(pwallet);
125 std::vector<CStakeableOutput> availableCoins;
126 unsigned int nExtraNonce = 0;
128 while (fGenerateBitcoins || fProofOfStake) {
142 CheckForCoins(pwallet, &availableCoins);
148 if (!fStakeableCoins) CheckForCoins(pwallet, &availableCoins);
161 LogPrintf(
"%s: Exiting PoW Mining Thread at height: %d\n", __func__, pindexPrev->
nHeight);
170 std::unique_ptr<CBlockTemplate> pblocktemplate((fProofOfStake ?
172 CreateNewBlockWithKey(pReservekey, pwallet)));
173 if (!pblocktemplate)
continue;
174 std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>(pblocktemplate->block);
178 LogPrintf(
"%s : proof-of-stake block was signed %s \n", __func__, pblock->GetHash().ToString().c_str());
180 if (!ProcessBlockFound(pblock, *pwallet, pReservekey)) {
181 LogPrintf(
"%s: New block orphaned\n", __func__);
191 LogPrintf(
"Running PIVXMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(),
200 unsigned int nHashesDone = 0;
205 if (hash <= hashTarget) {
208 LogPrintf(
"%s:\n", __func__);
209 LogPrintf(
"proof-of-work found \n hash: %s \ntarget: %s\n", hash.
GetHex(), hashTarget.
GetHex());
210 ProcessBlockFound(pblock, *pwallet, pReservekey);
215 if (
Params().IsRegTestNet())
216 throw boost::thread_interrupted();
222 if ((pblock->nNonce & 0xFF) == 0)
227 static int64_t nHashCounter;
232 nHashCounter += nHashesDone;
241 static int64_t nLogTime;
242 if (
GetTime() - nLogTime > 30 * 60) {
244 LogPrintf(
"hashmeter %6.0f khash/s\n",
dHashesPerSec / 1000.0);
251 boost::this_thread::interruption_point();
253 (pblock->nNonce >= 0xffff0000) ||
259 UpdateTime(pblock.get(), consensus, pindexPrev);
260 if (
Params().GetConsensus().fPowAllowMinDifficultyBlocks) {
269 void static ThreadBitcoinMiner(
void* parg)
271 boost::this_thread::interruption_point();
274 BitcoinMiner(pwallet,
false);
275 boost::this_thread::interruption_point();
276 }
catch (
const std::exception& e) {
277 LogPrintf(
"PIVXMiner exception\n");
279 LogPrintf(
"PIVXMiner exception\n");
282 LogPrintf(
"PIVXMiner exiting\n");
285 void GenerateBitcoins(
bool fGenerate,
CWallet* pwallet,
int nThreads)
287 static boost::thread_group* minerThreads =
nullptr;
288 fGenerateBitcoins = fGenerate;
290 if (minerThreads !=
nullptr) {
291 minerThreads->interrupt_all();
293 minerThreads =
nullptr;
296 if (nThreads == 0 || !fGenerate)
299 minerThreads =
new boost::thread_group();
300 for (
int i = 0; i < nThreads; i++)
301 minerThreads->create_thread(std::bind(&ThreadBitcoinMiner, pwallet));
304 void ThreadStakeMinter()
306 boost::this_thread::interruption_point();
307 LogPrintf(
"ThreadStakeMinter started. Using wallet-0\n");
310 BitcoinMiner(pwallet,
true);
311 boost::this_thread::interruption_point();
312 }
catch (
const std::exception& e) {
313 LogPrintf(
"ThreadStakeMinter() exception \n");
315 LogPrintf(
"ThreadStakeMinter() error \n");
317 LogPrintf(
"ThreadStakeMinter exiting,\n");
arith_uint256 UintToArith256(const uint256 &a)
void IncrementExtraNonce(std::shared_ptr< CBlock > &pblock, int nHeight, unsigned int &nExtraNonce)
int64_t UpdateTime(CBlockHeader *pblock, const Consensus::Params &consensusParams, const CBlockIndex *pindexPrev)
const CChainParams & Params()
Return the currently selected parameters.
std::unique_ptr< CBlockTemplate > CreateNewBlock(const CScript &scriptPubKeyIn, CWallet *pwallet=nullptr, bool fProofOfStake=false, std::vector< CStakeableOutput > *availableCoins=nullptr, bool fNoMempoolTx=false, bool fTestValidity=true, CBlockIndex *prevBlock=nullptr, bool stopPoSOnNewBlock=true, bool fIncludeQfc=true)
Construct a new block template with coinbase to scriptPubKeyIn.
The block chain is a tree shaped structure starting with the genesis block at the root,...
uint256 GetBlockHash() const
int nHeight
height of the entry in the chain. The genesis block has height 0
CBlockIndex * Tip(bool fProofOfStake=false) const
Returns the index entry for the tip of this chain, or nullptr if none.
const Consensus::Params & GetConsensus() const
Information about a peer.
void PushInventory(const CInv &inv)
An encapsulated public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Serialized script, used inside transaction inputs and outputs.
int64_t GetLastTime() const
uint256 GetLastHash() const
unsigned int GetTransactionsUpdated() const
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,...
CStakerStatus * pStakerStatus
256-bit unsigned big integer.
arith_uint256 & SetCompact(uint32_t nCompact, bool *pfNegative=nullptr, bool *pfOverflow=nullptr)
The "compact" format is a representation of a whole number N using an unsigned 32bit number similar t...
std::string GetHex() const
#define THREAD_PRIORITY_LOWEST
#define THREAD_PRIORITY_NORMAL
bool StakeableCoins(std::vector< CStakeableOutput > *pCoins=nullptr)
Available coins (staking)
std::unique_ptr< CConnman > g_connman
CMasternodeSync masternodeSync
void ThreadRename(std::string &&)
Rename a thread both in terms of an internal (in-memory) name as well as its system thread name.
unsigned int GetSerializeSize(const std::array< T, N > &item)
array
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a PIVX scriptPubKey for the given CTxDestination.
Parameters that influence chain consensus.
bool NetworkUpgradeActive(int nHeight, Consensus::UpgradeIndex idx) const
Returns true if the given network upgrade is active as of the given block height.
#define WAIT_LOCK(cs, name)
void SetThreadPriority(int nPriority)
bool error(const char *fmt, const Args &... args)
int64_t GetCurrentTimeSlot()
bool NetworkUpgradeActive(int nHeight, const Consensus::Params ¶ms, Consensus::UpgradeIndex idx)
Returns true if the given network upgrade is active as of the given block height.
std::string FormatMoney(const CAmount &n, bool fPlus)
Money parsing/formatting utilities.
int64_t GetTimeMillis()
Returns the system time (not mockable)
void MilliSleep(int64_t n)
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)
CTxMemPool mempool(::minRelayTxFee)
bool ProcessNewBlock(const std::shared_ptr< const CBlock > &pblock, const FlatFilePos *dbp)
Process an incoming block.
CBlockIndex * GetChainTip()
Return a reliable pointer (in mapBlockIndex) to the chain's tip index.
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
std::vector< CWalletRef > vpwallets