Skip to content

Commit 01173e9

Browse files
committed
[Core][PoS] Replace mapHashedBlocks and nLastCoinStakeSearchInterval
Streamline the logic to update the wallet's staking status using two single variables timeLastStakeAttempt and hashLastStakeAttempt. The Staking Status is Active whenever timeLastStakeAttempt is less than 30 seconds in the past. The logic is implemented with a new class CStakerStatus, member of the wallet. Time and hash are now updated directly in the wallet (CreateCoinStake) instead of in the kernel (Stake)
1 parent 6b2b813 commit 01173e9

File tree

10 files changed

+49
-54
lines changed

10 files changed

+49
-54
lines changed

src/kernel.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -362,10 +362,6 @@ bool Stake(const CBlockIndex* pindexPrev, CStakeInput* stakeInput, unsigned int
362362

363363
// Time protocol V2: one-try
364364
if (Params().IsTimeProtocolV2(nHeight)) {
365-
// store a time stamp of when we last hashed on this block
366-
mapHashedBlocks.clear();
367-
mapHashedBlocks[pindexPrev->nHeight] = GetTime();
368-
369365
// check required min depth for stake
370366
const int nHeightBlockFrom = pindexFrom->nHeight;
371367
if (nHeight < nHeightBlockFrom + Params().COINSTAKE_MIN_DEPTH())
@@ -402,10 +398,6 @@ bool StakeV1(const CBlockIndex* pindexPrev, CStakeInput* stakeInput, const uint3
402398
}
403399

404400
while (nTryTime > minTime) {
405-
// store a time stamp of when we last hashed on this block
406-
mapHashedBlocks.clear();
407-
mapHashedBlocks[pindexPrev->nHeight] = GetTime();
408-
409401
//new block came in, move on
410402
if (chainActive.Height() != pindexPrev->nHeight) break;
411403

@@ -420,10 +412,6 @@ bool StakeV1(const CBlockIndex* pindexPrev, CStakeInput* stakeInput, const uint3
420412
}
421413

422414
nTimeTx = nTryTime;
423-
424-
mapHashedBlocks.clear();
425-
mapHashedBlocks[pindexPrev->nHeight] = GetTime(); //store a time stamp of when we last hashed on this block
426-
427415
return fSuccess;
428416
}
429417

src/main.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ CCriticalSection cs_main;
6666

6767
BlockMap mapBlockIndex;
6868
std::map<uint256, uint256> mapProofOfStake;
69-
std::map<unsigned int, unsigned int> mapHashedBlocks;
7069
CChain chainActive;
7170
CBlockIndex* pindexBestHeader = NULL;
7271
int64_t nTimeBestReceived = 0;

src/main.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,9 @@ extern bool fVerifyingBlocks;
166166
extern bool fLargeWorkForkFound;
167167
extern bool fLargeWorkInvalidChainFound;
168168

169-
extern int64_t nLastCoinStakeSearchInterval;
170-
extern int64_t nLastCoinStakeSearchTime;
171169
extern int64_t nReserveBalance;
172170

173171
extern std::map<uint256, int64_t> mapRejectedBlocks;
174-
extern std::map<unsigned int, unsigned int> mapHashedBlocks;
175172
extern std::map<uint256, int64_t> mapZerocoinspends; //txid, time received
176173

177174
/** Best header we've seen so far (used for getheaders queries' starting points). */

src/miner.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ class COrphan
6666

6767
uint64_t nLastBlockTx = 0;
6868
uint64_t nLastBlockSize = 0;
69-
int64_t nLastCoinStakeSearchInterval = 0;
7069

7170
// We want to sort transactions by priority and fee rate, so:
7271
typedef boost::tuple<double, CFeeRate, const CTransaction*> TxPriority;
@@ -176,7 +175,6 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn, CWallet* pwallet,
176175
pblock->vtx.push_back(CTransaction(txCoinStake));
177176
fStakeFound = true;
178177
}
179-
nLastCoinStakeSearchInterval = nSearchTime - nLastCoinStakeSearchTime;
180178
nLastCoinStakeSearchTime = nSearchTime;
181179
}
182180

@@ -695,7 +693,6 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake)
695693

696694
while (vNodes.empty() || pwallet->IsLocked() || !fMintableCoins ||
697695
(stakingBalance > 0 && nReserveBalance >= stakingBalance) || masternodeSync.NotCompleted()) {
698-
nLastCoinStakeSearchInterval = 0;
699696
MilliSleep(5000);
700697
// Do a separate 1 minute check here to ensure fMintableCoins is updated
701698
if (!fMintableCoins && (GetTime() - nMintableLastCheck > 1 * 60)) // 1 minute check time
@@ -708,12 +705,12 @@ void BitcoinMiner(CWallet* pwallet, bool fProofOfStake)
708705

709706
const bool fTimeV2 = Params().IsTimeProtocolV2(chainActive.Height()+1);
710707
//search our map of hashed blocks, see if bestblock has been hashed yet
711-
const int chainHeight = chainActive.Height();
712-
if (mapHashedBlocks.count(chainHeight) && !fLastLoopOrphan)
708+
if (pwallet->pStakerStatus->GetLastHash() == chainActive.Tip()->GetBlockHash()
709+
&& !fLastLoopOrphan)
713710
{
714-
int64_t tipHashTime = mapHashedBlocks[chainHeight];
715-
if ( (!fTimeV2 && GetTime() < tipHashTime + 22) ||
716-
(fTimeV2 && GetCurrentTimeSlot() <= tipHashTime) )
711+
uint256 lastHashTime = pwallet->pStakerStatus->GetLastTime();
712+
if ( (!fTimeV2 && GetTime() < lastHashTime + 22) ||
713+
(fTimeV2 && GetCurrentTimeSlot() <= lastHashTime) )
717714
{
718715
MilliSleep(2000);
719716
continue;

src/qt/pivx/topbar.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ void TopBar::updateAutoMintStatus(){
354354
}
355355

356356
void TopBar::updateStakingStatus(){
357-
if (nLastCoinStakeSearchInterval) {
357+
if (walletModel && walletModel->isStakingStatusActive()) {
358358
if (!ui->pushButtonStack->isChecked()) {
359359
ui->pushButtonStack->setButtonText(tr("Staking active"));
360360
ui->pushButtonStack->setChecked(true);
@@ -582,4 +582,4 @@ void TopBar::expandSync() {
582582
progressBar->setFixedWidth(ui->pushButtonSync->width());
583583
progressBar->setMinimumWidth(ui->pushButtonSync->width() - 2);
584584
}
585-
}
585+
}

src/qt/walletmodel.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ bool WalletModel::isColdStakingNetworkelyEnabled() const {
6666
return sporkManager.IsSporkActive(SPORK_17_COLDSTAKING_ENFORCEMENT);
6767
}
6868

69+
bool WalletModel::isStakingStatusActive() const {
70+
return wallet->pStakerStatus->IsActive();
71+
}
72+
6973
CAmount WalletModel::getBalance(const CCoinControl* coinControl) const
7074
{
7175
if (coinControl) {

src/qt/walletmodel.h

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ class WalletModel : public QObject
145145
/** Whether cold staking is enabled or disabled in the network **/
146146
bool isColdStakingNetworkelyEnabled() const;
147147
CAmount getMinColdStakingAmount() const;
148+
/* current staking status from the miner thread **/
149+
bool isStakingStatusActive() const;
148150

149151
CAmount getBalance(const CCoinControl* coinControl = NULL) const;
150152
CAmount getUnconfirmedBalance() const;
@@ -223,18 +225,6 @@ class WalletModel : public QObject
223225
CZerocoinSpendReceipt &receipt
224226
);
225227

226-
// ###################
227-
// Cold Staking
228-
// ###################
229-
230-
231-
232-
// ###################
233-
// End Cold Staking
234-
// ###################
235-
236-
237-
238228
// Wallet encryption
239229
bool setWalletEncrypted(bool encrypted, const SecureString& passphrase);
240230
// Passphrase only needed when unlocking

src/rpc/misc.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,9 @@ UniValue getinfo(const UniValue& params, bool fHelp)
160160
obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
161161
#endif
162162
obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
163-
bool nStaking = false;
164-
if (mapHashedBlocks.count(chainActive.Tip()->nHeight))
165-
nStaking = true;
166-
else if (mapHashedBlocks.count(chainActive.Tip()->nHeight - 1) && nLastCoinStakeSearchInterval)
167-
nStaking = true;
168-
obj.push_back(Pair("staking status", (nStaking ? "Staking Active" : "Staking Not Active")));
163+
obj.push_back(Pair("staking status", (pwalletMain->pStakerStatus->IsActive() ?
164+
"Staking Active" :
165+
"Staking Not Active")));
169166
obj.push_back(Pair("errors", GetWarnings("statusbar")));
170167
return obj;
171168
}
@@ -624,13 +621,7 @@ UniValue getstakingstatus(const UniValue& params, bool fHelp)
624621
obj.push_back(Pair("enoughcoins", nReserveBalance <= pwalletMain->GetBalance()));
625622
}
626623
obj.push_back(Pair("mnsync", masternodeSync.IsSynced()));
627-
628-
bool nStaking = false;
629-
if (mapHashedBlocks.count(chainActive.Tip()->nHeight))
630-
nStaking = true;
631-
else if (mapHashedBlocks.count(chainActive.Tip()->nHeight - 1) && nLastCoinStakeSearchInterval)
632-
nStaking = true;
633-
obj.push_back(Pair("staking status", nStaking));
624+
obj.push_back(Pair("staking status", pwalletMain->pStakerStatus->IsActive()));
634625

635626
return obj;
636627
}

src/wallet/wallet.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2700,12 +2700,20 @@ bool CWallet::CreateCoinStake(
27002700
bool fKernelFound = false;
27012701
int nAttempts = 0;
27022702

2703+
// update staker status (hash)
2704+
pStakerStatus->SetLastHash(pindexPrev->GetBlockHash());
2705+
27032706
for (std::unique_ptr<CStakeInput>& stakeInput : listInputs) {
2704-
nCredit = 0;
2707+
//new block came in, move on
2708+
if (chainActive.Height() != pindexPrev->nHeight) return false;
2709+
27052710
// Make sure the wallet is unlocked and shutdown hasn't been requested
2706-
if (IsLocked() || ShutdownRequested())
2707-
return false;
2711+
if (IsLocked() || ShutdownRequested()) return false;
2712+
2713+
// update staker status (time)
2714+
pStakerStatus->SetLastTime(GetCurrentTimeSlot());
27082715

2716+
nCredit = 0;
27092717
uint256 hashProofOfStake = 0;
27102718
nAttempts++;
27112719
//iterates each utxo inside of CheckStakeKernelHash()
@@ -5135,6 +5143,7 @@ CWallet::CWallet(std::string strWalletFileIn)
51355143
CWallet::~CWallet()
51365144
{
51375145
delete pwalletdbEncryption;
5146+
delete pStakerStatus;
51385147
}
51395148

51405149
void CWallet::SetNull()
@@ -5152,6 +5161,7 @@ void CWallet::SetNull()
51525161
fBackupMints = false;
51535162

51545163
// Stake Settings
5164+
pStakerStatus = new CStakerStatus();
51555165
nStakeSplitThreshold = STAKE_SPLIT_THRESHOLD;
51565166
nStakeSetUpdateTime = 300; // 5 minutes
51575167

src/wallet/wallet.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,24 @@ class CKeyPool
147147
}
148148
};
149149

150+
/** Record metadata about last kernel stake operation (time and prev hash)**/
151+
class CStakerStatus {
152+
private:
153+
uint256 hashLastStakeAttempt;
154+
int64_t timeLastStakeAttempt;
155+
public:
156+
uint256 GetLastHash() const { return hashLastStakeAttempt; }
157+
int64_t GetLastTime() const { return timeLastStakeAttempt; }
158+
void SetLastHash(const uint256& lastHash) { hashLastStakeAttempt = lastHash; }
159+
void SetLastTime(const uint64_t lastTime) { timeLastStakeAttempt = lastTime; }
160+
void Update(const uint256& lastHash, const uint64_t lastTime)
161+
{
162+
SetLastHash(lastHash);
163+
SetLastTime(lastTime);
164+
}
165+
bool IsActive() { return (timeLastStakeAttempt + 30) >= GetTime(); }
166+
};
167+
150168
/**
151169
* A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
152170
* and provides the ability to create new transactions.
@@ -278,6 +296,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
278296
// Stake Settings
279297
uint64_t nStakeSplitThreshold;
280298
int nStakeSetUpdateTime;
299+
CStakerStatus* pStakerStatus;
281300

282301
//MultiSend
283302
std::vector<std::pair<std::string, int> > vMultiSend;

0 commit comments

Comments
 (0)