Skip to content

Commit 7431f09

Browse files
committed
[Wallet][Cleanup] Remove SelectStakeCoins
Use MintableCoins instead of SelectStakeCoins to avoid duplicated code in yet another function, and remove extra checks in CreateCoinStake. MintableCoins first argument is now a pointer defaulted to nullptr. When the function is called with this default value, it checks for the existence of *at least one* stakeable utxo. Otherwise populates the vector referenced by the pointer with *all* stakeable utxos.
1 parent 33c3973 commit 7431f09

File tree

6 files changed

+54
-108
lines changed

6 files changed

+54
-108
lines changed

src/activemasternode.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ std::vector<COutput> CActiveMasternode::SelectCoinsMasternode()
458458
}
459459

460460
// Retrieve all possible outputs
461-
pwalletMain->AvailableCoins(vCoins);
461+
pwalletMain->AvailableCoins(&vCoins);
462462

463463
// Lock MN coins from masternode.conf back if they where temporary unlocked
464464
if (!confLockedCoins.empty()) {

src/qt/walletmodel.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ CAmount WalletModel::getBalance(const CCoinControl* coinControl) const
7575
if (coinControl) {
7676
CAmount nBalance = 0;
7777
std::vector<COutput> vCoins;
78-
wallet->AvailableCoins(vCoins, true, coinControl);
78+
wallet->AvailableCoins(&vCoins, true, coinControl);
7979
for (const COutput& out : vCoins)
8080
if (out.fSpendable)
8181
nBalance += out.tx->vout[out.i].nValue;
@@ -1003,7 +1003,7 @@ bool WalletModel::isSpent(const COutPoint& outpoint) const
10031003
void WalletModel::listCoins(std::map<QString, std::vector<COutput> >& mapCoins) const
10041004
{
10051005
std::vector<COutput> vCoins;
1006-
wallet->AvailableCoins(vCoins);
1006+
wallet->AvailableCoins(&vCoins);
10071007

10081008
LOCK2(cs_main, wallet->cs_wallet); // ListLockedCoins, mapWallet
10091009
std::vector<COutPoint> vLockedCoins;

src/rpc/rawtransaction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ UniValue listunspent(const UniValue& params, bool fHelp)
279279
std::vector<COutput> vecOutputs;
280280
assert(pwalletMain != NULL);
281281
LOCK2(cs_main, pwalletMain->cs_wallet);
282-
pwalletMain->AvailableCoins(vecOutputs, false, NULL, false, ALL_COINS, false, nWatchonlyConfig);
282+
pwalletMain->AvailableCoins(&vecOutputs, false, NULL, false, ALL_COINS, false, nWatchonlyConfig);
283283
for (const COutput& out : vecOutputs) {
284284
if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth)
285285
continue;

src/wallet/rpcwallet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2919,7 +2919,7 @@ UniValue printMultiSend()
29192919
UniValue printAddresses()
29202920
{
29212921
std::vector<COutput> vCoins;
2922-
pwalletMain->AvailableCoins(vCoins);
2922+
pwalletMain->AvailableCoins(&vCoins);
29232923
std::map<std::string, double> mapAddresses;
29242924
for (const COutput& out : vCoins) {
29252925
CTxDestination utxoAddress;

src/wallet/wallet.cpp

Lines changed: 47 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ bool CWallet::GetMasternodeVinAndKeys(CTxIn& txinRet, CPubKey& pubKeyRet, CKey&
551551

552552
// Find possible candidates (remove delegated)
553553
std::vector<COutput> vPossibleCoins;
554-
AvailableCoins(vPossibleCoins, true, NULL, false, ONLY_10000, false, 1, false, false);
554+
AvailableCoins(&vPossibleCoins, true, NULL, false, ONLY_10000, false, 1, false, false);
555555

556556
if (vPossibleCoins.empty()) {
557557
LogPrintf("CWallet::GetMasternodeVinAndKeys -- Could not locate any valid masternode vin\n");
@@ -1950,19 +1950,18 @@ void CWallet::GetAvailableP2CSCoins(std::vector<COutput>& vCoins) const {
19501950
/**
19511951
* populate vCoins with vector of available COutputs.
19521952
*/
1953-
void CWallet::AvailableCoins(
1954-
std::vector<COutput>& vCoins,
1953+
bool CWallet::AvailableCoins(
1954+
std::vector<COutput>* pCoins,
19551955
bool fOnlyConfirmed,
19561956
const CCoinControl* coinControl,
19571957
bool fIncludeZeroValue,
19581958
AvailableCoinsType nCoinType,
19591959
bool fUseIX,
19601960
int nWatchonlyConfig,
19611961
bool fIncludeColdStaking,
1962-
bool fIncludeDelegated,
1963-
bool fJustOne) const
1962+
bool fIncludeDelegated) const
19641963
{
1965-
vCoins.clear();
1964+
if (pCoins) pCoins->clear();
19661965
const bool fCoinsSelected = (coinControl != nullptr) && coinControl->HasSelected();
19671966
// include delegated coins when coinControl is active
19681967
if (!fIncludeDelegated && fCoinsSelected)
@@ -2032,18 +2031,19 @@ void CWallet::AvailableCoins(
20322031
(fIncludeDelegated ? ISMINE_SPENDABLE_DELEGATED : ISMINE_NO) )) != ISMINE_NO));
20332032

20342033
// found valid coin
2035-
vCoins.emplace_back(COutput(pcoin, i, nDepth, fIsValid));
2036-
if (fJustOne) return;
2034+
if (!pCoins) return true;
2035+
pCoins->emplace_back(COutput(pcoin, i, nDepth, fIsValid));
20372036
}
20382037
}
2038+
return (pCoins && pCoins->size() > 0);
20392039
}
20402040
}
20412041

20422042
std::map<CBitcoinAddress, std::vector<COutput> > CWallet::AvailableCoinsByAddress(bool fConfirmed, CAmount maxCoinValue)
20432043
{
20442044
std::vector<COutput> vCoins;
20452045
// include cold and delegated coins
2046-
AvailableCoins(vCoins, fConfirmed, nullptr, false, ALL_COINS, false, 1, true, true);
2046+
AvailableCoins(&vCoins, fConfirmed, nullptr, false, ALL_COINS, false, 1, true, true);
20472047

20482048
std::map<CBitcoinAddress, std::vector<COutput> > mapCoins;
20492049
for (COutput out : vCoins) {
@@ -2123,47 +2123,7 @@ bool less_then_denom(const COutput& out1, const COutput& out2)
21232123
return (!found1 && found2);
21242124
}
21252125

2126-
bool CWallet::SelectStakeCoins(std::list<std::unique_ptr<CStakeInput> >& listInputs, CAmount nTargetAmount, int blockHeight)
2127-
{
2128-
LOCK(cs_main);
2129-
//Add PIV
2130-
std::vector<COutput> vCoins;
2131-
2132-
// include cold, exclude delegated
2133-
const bool fIncludeCold = sporkManager.IsSporkActive(SPORK_17_COLDSTAKING_ENFORCEMENT) && GetBoolArg("-coldstaking", true);
2134-
AvailableCoins(vCoins, true, NULL, false, STAKABLE_COINS, false, 1, fIncludeCold, false);
2135-
2136-
CAmount nAmountSelected = 0;
2137-
if (GetBoolArg("-pivstake", true)) {
2138-
for (const COutput &out : vCoins) {
2139-
//make sure not to outrun target amount
2140-
if (nAmountSelected + out.tx->vout[out.i].nValue > nTargetAmount)
2141-
continue;
2142-
2143-
if (out.tx->vin[0].IsZerocoinSpend() && !out.tx->IsInMainChain())
2144-
continue;
2145-
2146-
if (!out.tx->hashBlock)
2147-
continue;
2148-
2149-
CBlockIndex* utxoBlock = mapBlockIndex.at(out.tx->hashBlock);
2150-
//check for maturity (min age/depth)
2151-
if (!Params().HasStakeMinAgeOrDepth(blockHeight, GetAdjustedTime(), utxoBlock->nHeight, utxoBlock->GetBlockTime()))
2152-
continue;
2153-
2154-
//add to our stake set
2155-
nAmountSelected += out.tx->vout[out.i].nValue;
2156-
2157-
std::unique_ptr<CPivStake> input(new CPivStake());
2158-
input->SetInput((CTransaction) *out.tx, out.i);
2159-
listInputs.emplace_back(std::move(input));
2160-
}
2161-
}
2162-
2163-
return true;
2164-
}
2165-
2166-
bool CWallet::MintableCoins()
2126+
bool CWallet::MintableCoins(std::vector<COutput>* pCoins)
21672127
{
21682128
CAmount nBalance = GetStakingBalance(GetBoolArg("-coldstaking", true));
21692129

@@ -2172,23 +2132,26 @@ bool CWallet::MintableCoins()
21722132
return error("%s : invalid reserve balance amount", __func__);
21732133
if (nBalance <= nReserveBalance) return false;
21742134

2175-
std::vector<COutput> vCoins;
21762135
const bool fIncludeCold = (sporkManager.IsSporkActive(SPORK_17_COLDSTAKING_ENFORCEMENT) &&
21772136
GetBoolArg("-coldstaking", true));
2178-
AvailableCoins(vCoins,
2179-
true, // fOnlyConfirmed
2180-
nullptr, // coinControl
2181-
false, // fIncludeZeroValue
2182-
STAKABLE_COINS, // nCoinType
2183-
false, // fUseIX
2184-
1, // nWatchonlyConfig
2185-
fIncludeCold, // fIncludeColdStaking
2186-
false, // fIncludeDelegated
2187-
true // fJustOne
2188-
);
2189-
2190-
// check that we have at least one utxo eligible for staking.
2191-
return (vCoins.size() > 0);
2137+
2138+
if (!AvailableCoins(pCoins, true, nullptr, false, STAKABLE_COINS, false, 1, fIncludeCold, false))
2139+
return false;
2140+
2141+
if (!pCoins || nReserveBalance == 0)
2142+
// there is at least one stakeable utxo
2143+
return true;
2144+
2145+
CAmount nTargetAmount = nBalance - nReserveBalance;
2146+
CAmount nAmountSelected = 0;
2147+
// leave some utxo for reserve balance
2148+
for (const COutput &out : *pCoins) {
2149+
const CAmount& nAmountUtxo = out.tx->vout[out.i].nValue;
2150+
if (nAmountSelected + nAmountUtxo > nTargetAmount) continue;
2151+
nAmountSelected += out.tx->vout[out.i].nValue;
2152+
}
2153+
2154+
return (pCoins->size() > 0);
21922155
}
21932156

21942157
bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*, unsigned int> >& setCoinsRet, CAmount& nValueRet) const
@@ -2302,7 +2265,7 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, std::set<std::pair<const
23022265
{
23032266
// Note: this function should never be used for "always free" tx types like dstx
23042267
std::vector<COutput> vCoins;
2305-
AvailableCoins(vCoins, true, coinControl, false, coin_type, useIX, 1, fIncludeColdStaking, fIncludeDelegated);
2268+
AvailableCoins(&vCoins, true, coinControl, false, coin_type, useIX, 1, fIncludeColdStaking, fIncludeDelegated);
23062269

23072270
// coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
23082271
if (coinControl && coinControl->HasSelected()) {
@@ -2627,50 +2590,34 @@ bool CWallet::CreateCoinStake(
26272590
int64_t& nTxNewTime
26282591
)
26292592
{
2630-
txNew.vin.clear();
2631-
txNew.vout.clear();
2632-
2633-
// Mark coin stake transaction
2634-
CScript scriptEmpty;
2635-
scriptEmpty.clear();
2636-
txNew.vout.push_back(CTxOut(0, scriptEmpty));
2637-
2638-
// Choose coins to use
2639-
CAmount nBalance = GetStakingBalance();
2640-
2641-
if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance))
2642-
return error("CreateCoinStake : invalid reserve balance amount");
2643-
2644-
if (nBalance > 0 && nBalance <= nReserveBalance)
2593+
// Get the list of stakable utxos
2594+
std::vector<COutput> vCoins;
2595+
if (!MintableCoins(&vCoins)) {
2596+
LogPrintf("%s: No coin available to stake.\n", __func__);
26452597
return false;
2598+
}
26462599

2647-
// Get the list of stakable inputs
2600+
// Parse utxos into CPivStakes
26482601
std::list<std::unique_ptr<CStakeInput> > listInputs;
2649-
if (!SelectStakeCoins(listInputs, nBalance - nReserveBalance, pindexPrev->nHeight + 1)) {
2650-
LogPrintf("CreateCoinStake(): selectStakeCoins failed\n");
2651-
return false;
2602+
for (const COutput &out : vCoins) {
2603+
std::unique_ptr<CPivStake> input(new CPivStake());
2604+
input->SetInput((CTransaction) *out.tx, out.i);
2605+
listInputs.emplace_back(std::move(input));
26522606
}
26532607

2654-
if (listInputs.empty()) {
2655-
LogPrint("staking", "CreateCoinStake(): listInputs empty\n");
2656-
MilliSleep(50000);
2657-
return false;
2658-
}
2608+
// Mark coin stake transaction
2609+
txNew.vin.clear();
2610+
txNew.vout.clear();
2611+
txNew.vout.push_back(CTxOut(0, CScript()));
26592612

2660-
if (GetAdjustedTime() - pindexPrev->GetBlockTime() < 60) {
2661-
if (Params().NetworkID() == CBaseChainParams::REGTEST) {
2662-
MilliSleep(1000);
2663-
}
2664-
}
2613+
// update staker status (hash)
2614+
pStakerStatus->SetLastTip(pindexPrev);
26652615

2616+
// Kernel Search
26662617
CAmount nCredit;
26672618
CScript scriptPubKeyKernel;
26682619
bool fKernelFound = false;
26692620
int nAttempts = 0;
2670-
2671-
// update staker status (hash)
2672-
pStakerStatus->SetLastTip(pindexPrev);
2673-
26742621
for (std::unique_ptr<CStakeInput>& stakeInput : listInputs) {
26752622
//new block came in, move on
26762623
if (chainActive.Height() != pindexPrev->nHeight) return false;
@@ -3819,7 +3766,7 @@ bool CWallet::MultiSend()
38193766
}
38203767

38213768
std::vector<COutput> vCoins;
3822-
AvailableCoins(vCoins);
3769+
AvailableCoins(&vCoins);
38233770
bool stakeSent = false;
38243771
bool mnSent = false;
38253772
for (const COutput& out : vCoins) {

src/wallet/wallet.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
209209

210210
static const int STAKE_SPLIT_THRESHOLD = 2000;
211211

212-
bool MintableCoins();
213-
bool SelectStakeCoins(std::list<std::unique_ptr<CStakeInput> >& listInputs, CAmount nTargetAmount, int blockHeight);
212+
bool MintableCoins(std::vector<COutput>* pCoins = nullptr);
214213
bool IsCollateralAmount(CAmount nInputAmount) const;
215214

216215
// Zerocoin additions
@@ -350,7 +349,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
350349
//! check whether we are allowed to upgrade (or already support) to the named feature
351350
bool CanSupportFeature(enum WalletFeature wf);
352351

353-
void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed = true, const CCoinControl* coinControl = NULL, bool fIncludeZeroValue = false, AvailableCoinsType nCoinType = ALL_COINS, bool fUseIX = false, int nWatchonlyConfig = 1, bool fIncludeColdStaking=false, bool fIncludeDelegated=true, bool fJustOne=false) const;
352+
bool AvailableCoins(std::vector<COutput>* pCoins, bool fOnlyConfirmed = true, const CCoinControl* coinControl = NULL, bool fIncludeZeroValue = false, AvailableCoinsType nCoinType = ALL_COINS, bool fUseIX = false, int nWatchonlyConfig = 1, bool fIncludeColdStaking=false, bool fIncludeDelegated=true) const;
354353

355354
// Get available p2cs utxo
356355
void GetAvailableP2CSCoins(std::vector<COutput>& vCoins) const;

0 commit comments

Comments
 (0)