Skip to content

Commit 261bd22

Browse files
committed
Staking process: calculate the stakeable utxo only once.
We were calculating the stakeable utxo before calling CreateNewBlock and inside the method (CreateCoinStake). Looping over the wallet's transactions map twice.
1 parent 6ec609f commit 261bd22

File tree

5 files changed

+34
-24
lines changed

5 files changed

+34
-24
lines changed

src/miner.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,13 +168,13 @@ bool CreateCoinbaseTx(CBlock* pblock, const CScript& scriptPubKeyIn, CBlockIndex
168168
return true;
169169
}
170170

171-
bool SolveProofOfStake(CBlock* pblock, CBlockIndex* pindexPrev, CWallet* pwallet)
171+
bool SolveProofOfStake(CBlock* pblock, CBlockIndex* pindexPrev, CWallet* pwallet, std::vector<COutput>* availableCoins)
172172
{
173173
boost::this_thread::interruption_point();
174174
pblock->nBits = GetNextWorkRequired(pindexPrev, pblock);
175175
CMutableTransaction txCoinStake;
176176
int64_t nTxNewTime = 0;
177-
if (!pwallet->CreateCoinStake(*pwallet, pindexPrev, pblock->nBits, txCoinStake, nTxNewTime)) {
177+
if (!pwallet->CreateCoinStake(*pwallet, pindexPrev, pblock->nBits, txCoinStake, nTxNewTime, availableCoins)) {
178178
LogPrint(BCLog::STAKING, "%s : stake not found\n", __func__);
179179
return false;
180180
}
@@ -190,7 +190,7 @@ bool SolveProofOfStake(CBlock* pblock, CBlockIndex* pindexPrev, CWallet* pwallet
190190
return true;
191191
}
192192

193-
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, bool fProofOfStake)
193+
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, bool fProofOfStake, std::vector<COutput>* availableCoins)
194194
{
195195
// Create new block
196196
std::unique_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate());
@@ -214,7 +214,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
214214
}
215215

216216
// Depending on the tip height, try to find a coinstake who solves the block or create a coinbase tx.
217-
if (!(fProofOfStake ? SolveProofOfStake(pblock, pindexPrev, pwallet)
217+
if (!(fProofOfStake ? SolveProofOfStake(pblock, pindexPrev, pwallet, availableCoins)
218218
: CreateCoinbaseTx(pblock, scriptPubKeyIn, pindexPrev))) {
219219
return nullptr;
220220
}
@@ -556,13 +556,13 @@ bool fGenerateBitcoins = false;
556556
bool fStakeableCoins = false;
557557
int nMintableLastCheck = 0;
558558

559-
void CheckForCoins(CWallet* pwallet, const int minutes)
559+
void CheckForCoins(CWallet* pwallet, const int minutes, std::vector<COutput>* availableCoins)
560560
{
561561
//control the amount of times the client will check for mintable coins
562562
int nTimeNow = GetTime();
563563
if ((nTimeNow - nMintableLastCheck > minutes * 60)) {
564564
nMintableLastCheck = nTimeNow;
565-
fStakeableCoins = pwallet->StakeableCoins();
565+
fStakeableCoins = pwallet->StakeableCoins(availableCoins);
566566
}
567567
}
568568

@@ -578,9 +578,10 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake)
578578
Optional<CReserveKey> opReservekey{nullopt};
579579
if (!fProofOfStake) {
580580
opReservekey = CReserveKey(pwallet);
581-
582581
}
583582

583+
// Available UTXO set
584+
std::vector<COutput> availableCoins;
584585
unsigned int nExtraNonce = 0;
585586

586587
while (fGenerateBitcoins || fProofOfStake) {
@@ -597,13 +598,13 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake)
597598
}
598599

599600
// update fStakeableCoins (5 minute check time);
600-
CheckForCoins(pwallet, 5);
601+
CheckForCoins(pwallet, 5, &availableCoins);
601602

602603
while ((g_connman && g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0 && Params().MiningRequiresPeers())
603604
|| pwallet->IsLocked() || !fStakeableCoins || masternodeSync.NotCompleted()) {
604605
MilliSleep(5000);
605606
// Do a separate 1 minute check here to ensure fStakeableCoins is updated
606-
if (!fStakeableCoins) CheckForCoins(pwallet, 1);
607+
if (!fStakeableCoins) CheckForCoins(pwallet, 1, &availableCoins);
607608
}
608609

609610
//search our map of hashed blocks, see if bestblock has been hashed yet
@@ -626,7 +627,7 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake)
626627
unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
627628

628629
std::unique_ptr<CBlockTemplate> pblocktemplate((fProofOfStake ?
629-
CreateNewBlock(CScript(), pwallet, fProofOfStake) :
630+
CreateNewBlock(CScript(), pwallet, true, &availableCoins) :
630631
CreateNewBlockWithKey(*opReservekey, pwallet)));
631632
if (!pblocktemplate.get()) continue;
632633
CBlock* pblock = &pblocktemplate->block;

src/miner.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
class CBlock;
1515
class CBlockHeader;
1616
class CBlockIndex;
17+
class COutput;
1718
class CReserveKey;
1819
class CScript;
1920
class CWallet;
@@ -23,7 +24,7 @@ static const bool DEFAULT_PRINTPRIORITY = false;
2324
struct CBlockTemplate;
2425

2526
/** Generate a new block, without valid proof-of-work */
26-
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, bool fProofOfStake);
27+
CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet, bool fProofOfStake, std::vector<COutput>* availableCoins = nullptr);
2728
/** Modify the extranonce in a block */
2829
void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);
2930
/** Check mined block */

src/rpc/mining.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,17 @@ UniValue generate(const JSONRPCRequest& request)
157157
UniValue blockHashes(UniValue::VARR);
158158
CReserveKey reservekey(pwalletMain);
159159
unsigned int nExtraNonce = 0;
160-
while (nHeight < nHeightEnd && !ShutdownRequested())
161-
{
160+
161+
while (nHeight < nHeightEnd && !ShutdownRequested()) {
162+
163+
// Get available coins
164+
std::vector<COutput> availableCoins;
165+
if (fPoS && !pwalletMain->StakeableCoins(&availableCoins)) {
166+
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "No available coins to stake");
167+
}
168+
162169
std::unique_ptr<CBlockTemplate> pblocktemplate(fPoS ?
163-
CreateNewBlock(CScript(), pwalletMain, fPoS) :
170+
CreateNewBlock(CScript(), pwalletMain, true, &availableCoins) :
164171
CreateNewBlockWithKey(reservekey, pwalletMain));
165172
if (!pblocktemplate.get()) break;
166173
CBlock *pblock = &pblocktemplate->block;

src/wallet/wallet.cpp

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2724,14 +2724,10 @@ bool CWallet::CreateCoinStake(
27242724
const CBlockIndex* pindexPrev,
27252725
unsigned int nBits,
27262726
CMutableTransaction& txNew,
2727-
int64_t& nTxNewTime)
2727+
int64_t& nTxNewTime,
2728+
std::vector<COutput>* availableCoins
2729+
)
27282730
{
2729-
// Get the list of stakable utxos
2730-
std::vector<COutput> vCoins;
2731-
if (!StakeableCoins(&vCoins)) {
2732-
LogPrintf("%s: No coin available to stake.\n", __func__);
2733-
return false;
2734-
}
27352731

27362732
const Consensus::Params& consensus = Params().GetConsensus();
27372733

@@ -2742,7 +2738,7 @@ bool CWallet::CreateCoinStake(
27422738

27432739
// update staker status (hash)
27442740
pStakerStatus->SetLastTip(pindexPrev);
2745-
pStakerStatus->SetLastCoins((int) vCoins.size());
2741+
pStakerStatus->SetLastCoins((int) availableCoins->size());
27462742

27472743
// P2PKH block signatures were not accepted before v5 update.
27482744
bool onlyP2PK = !consensus.NetworkUpgradeActive(pindexPrev->nHeight + 1, Consensus::UPGRADE_V5_DUMMY);
@@ -2752,7 +2748,7 @@ bool CWallet::CreateCoinStake(
27522748
CScript scriptPubKeyKernel;
27532749
bool fKernelFound = false;
27542750
int nAttempts = 0;
2755-
for (const COutput &out : vCoins) {
2751+
for (const COutput &out : *availableCoins) {
27562752
CPivStake stakeInput;
27572753
stakeInput.SetPrevout((CTransaction) *out.tx, out.i);
27582754

src/wallet/wallet.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,12 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
567567
};
568568
CWallet::CommitResult CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, std::string strCommand = NetMsgType::TX);
569569
bool AddAccountingEntry(const CAccountingEntry&, CWalletDB & pwalletdb);
570-
bool CreateCoinStake(const CKeyStore& keystore, const CBlockIndex* pindexPrev, unsigned int nBits, CMutableTransaction& txNew, int64_t& nTxNewTime);
570+
bool CreateCoinStake(const CKeyStore& keystore,
571+
const CBlockIndex* pindexPrev,
572+
unsigned int nBits,
573+
CMutableTransaction& txNew,
574+
int64_t& nTxNewTime,
575+
std::vector<COutput>* availableCoins);
571576
bool MultiSend();
572577
void AutoCombineDust(CConnman* connman);
573578

0 commit comments

Comments
 (0)