X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fwallet.cpp;h=2455b272488ca34727b73fc80b801bdc2a7f4f34;hb=HEAD;hp=04ce99531a300dcb8ce527960e62a4c8089d8975;hpb=5098ea454db9132aa0f576921ca9d1a69429d146;p=novacoin.git diff --git a/src/wallet.cpp b/src/wallet.cpp index 04ce995..83cb307 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -3,20 +3,21 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "txdb-leveldb.h" #include "wallet.h" -#include "walletdb.h" -#include "crypter.h" -#include "interface.h" +#include "txdb-leveldb.h" #include "base58.h" -#include "kernel.h" #include "coincontrol.h" -#include +#include "crypter.h" +#include "kernel.h" +#include "random.h" +#include "walletdb.h" + #include + #include -#include "main.h" +#include + -using namespace std; extern int64_t nReserveBalance; ////////////////////////////////////////////////////////////////////////////// @@ -26,8 +27,8 @@ extern int64_t nReserveBalance; struct CompareValueOnly { - bool operator()(const pair >& t1, - const pair >& t2) const + bool operator()(const std::pair >& t1, + const std::pair >& t2) const { return t1.first < t2.first; } @@ -134,7 +135,9 @@ bool CWallet::AddCryptedMalleableKey(const CMalleableKeyView& keyView, const std return true; } -bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector &vchCryptedSecret) +bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret) { SetMinVersion(FEATURE_WALLETCRYPT); return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); } + +bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const std::vector &vchCryptedSecret) { if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret)) return false; @@ -176,6 +179,12 @@ bool CWallet::LoadKeyMetadata(const CMalleableKeyView &keyView, const CKeyMetada return true; } +bool CWallet::LoadKey(const CMalleableKeyView &keyView, const CSecret &vchSecretH) { return CCryptoKeyStore::AddMalleableKey(keyView, vchSecretH); } + +bool CWallet::LoadCryptedKey(const CMalleableKeyView &keyView, const std::vector &vchCryptedSecretH) { return CCryptoKeyStore::AddCryptedMalleableKey(keyView, vchCryptedSecretH); } + +bool CWallet::LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; } + bool CWallet::AddCScript(const CScript& redeemScript) { if (!CCryptoKeyStore::AddCScript(redeemScript)) @@ -371,13 +380,13 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) RandAddSeedPerfmon(); vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE); - RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE); + GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE); CMasterKey kMasterKey; RandAddSeedPerfmon(); kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE); - RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE); + GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE); CCrypter crypter; int64_t nStartTime = GetTimeMillis(); @@ -549,13 +558,13 @@ CWallet::TxItems CWallet::OrderedTxItems(std::list& acentries, for (auto & it : mapWallet) { CWalletTx* wtx = &(it.second); - txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)nullptr))); + txOrdered.insert(std::make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)nullptr))); } acentries.clear(); walletdb.ListAccountCreditDebit(strAccount, acentries); for (CAccountingEntry& entry : acentries) { - txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)nullptr, &entry))); + txOrdered.insert(std::make_pair(entry.nOrderPos, TxPair((CWalletTx*)nullptr, &entry))); } return txOrdered; @@ -570,7 +579,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx, bool fBlock) LOCK(cs_wallet); for (const CTxIn& txin : tx.vin) { - map::iterator mi = mapWallet.find(txin.prevout.hash); + auto mi = mapWallet.find(txin.prevout.hash); if (mi != mapWallet.end()) { CWalletTx& wtx = (*mi).second; @@ -590,7 +599,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx, bool fBlock) if (fBlock) { uint256 hash = tx.GetHash(); - map::iterator mi = mapWallet.find(hash); + auto mi = mapWallet.find(hash); CWalletTx& wtx = (*mi).second; for (const CTxOut& txout : tx.vout) @@ -623,7 +632,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) { LOCK(cs_wallet); // Inserts only if not already there, returns tx inserted or tx found - pair::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn)); + auto ret = mapWallet.insert(std::make_pair(hash, wtxIn)); CWalletTx& wtx = (*ret.first).second; wtx.BindWallet(this); bool fInsertedNew = ret.second; @@ -736,10 +745,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn) std::string strCmd = GetArg("-walletnotify", ""); if ( !strCmd.empty()) - { - boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex()); - boost::thread t(runCommand, strCmd); // thread runs free - } + // thread runs free + boost::thread t(runCommand, regex_replace(strCmd, static_cast("%s"), wtxIn.GetHash().GetHex())); } return true; @@ -786,7 +793,7 @@ isminetype CWallet::IsMine(const CTxIn &txin) const { { LOCK(cs_wallet); - map::const_iterator mi = mapWallet.find(txin.prevout.hash); + auto mi = mapWallet.find(txin.prevout.hash); if (mi != mapWallet.end()) { const CWalletTx& prev = (*mi).second; @@ -869,7 +876,7 @@ int64_t CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const { { LOCK(cs_wallet); - map::const_iterator mi = mapWallet.find(txin.prevout.hash); + auto mi = mapWallet.find(txin.prevout.hash); if (mi != mapWallet.end()) { const CWalletTx& prev = (*mi).second; @@ -987,7 +994,7 @@ int CWalletTx::GetRequestCount() const // Generated block if (hashBlock != 0) { - map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); + auto mi = pwallet->mapRequestCount.find(hashBlock); if (mi != pwallet->mapRequestCount.end()) nRequests = (*mi).second; } @@ -995,7 +1002,7 @@ int CWalletTx::GetRequestCount() const else { // Did anyone request this transaction? - map::const_iterator mi = pwallet->mapRequestCount.find(GetHash()); + auto mi = pwallet->mapRequestCount.find(GetHash()); if (mi != pwallet->mapRequestCount.end()) { nRequests = (*mi).second; @@ -1003,7 +1010,7 @@ int CWalletTx::GetRequestCount() const // How about the block it's in? if (nRequests == 0 && hashBlock != 0) { - map::const_iterator mi = pwallet->mapRequestCount.find(hashBlock); + auto mi = pwallet->mapRequestCount.find(hashBlock); if (mi != pwallet->mapRequestCount.end()) nRequests = (*mi).second; else @@ -1215,8 +1222,8 @@ int64_t CWalletTx::GetChange() const return nChangeCached; } -void CWalletTx::GetAmounts(int64_t& nGeneratedImmature, int64_t& nGeneratedMature, list >& listReceived, - list >& listSent, int64_t& nFee, string& strSentAccount, const isminefilter& filter) const +void CWalletTx::GetAmounts(int64_t& nGeneratedImmature, int64_t& nGeneratedMature, std::list >& listReceived, + std::list >& listSent, int64_t& nFee, std::string& strSentAccount, const isminefilter& filter) const { nGeneratedImmature = nGeneratedMature = nFee = 0; listReceived.clear(); @@ -1267,25 +1274,25 @@ void CWalletTx::GetAmounts(int64_t& nGeneratedImmature, int64_t& nGeneratedMatur // If we are debited by the transaction, add the output as a "sent" entry if (nDebit > 0) - listSent.push_back(make_pair(address, txout.nValue)); + listSent.push_back(std::make_pair(address, txout.nValue)); // If we are receiving the output, add it as a "received" entry if (fIsMine & filter) - listReceived.push_back(make_pair(address, txout.nValue)); + listReceived.push_back(std::make_pair(address, txout.nValue)); } } -void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nGenerated, int64_t& nReceived, +void CWalletTx::GetAccountAmounts(const std::string& strAccount, int64_t& nGenerated, int64_t& nReceived, int64_t& nSent, int64_t& nFee, const isminefilter& filter) const { nGenerated = nReceived = nSent = nFee = 0; int64_t allGeneratedImmature, allGeneratedMature, allFee; allGeneratedImmature = allGeneratedMature = allFee = 0; - string strSentAccount; - list > listReceived; - list > listSent; + std::string strSentAccount; + std::list > listReceived; + std::list > listSent; GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount, filter); if (strAccount.empty()) @@ -1302,7 +1309,7 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nGenerated, { if (pwallet->mapAddressBook.count(r.first)) { - map::const_iterator mi = pwallet->mapAddressBook.find(r.first); + auto mi = pwallet->mapAddressBook.find(r.first); if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount) nReceived += r.second; } @@ -1314,6 +1321,11 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nGenerated, } } +bool CWalletTx::IsFromMe(const isminefilter &filter) const +{ + return (GetDebit(filter) > 0); +} + void CWalletTx::AddSupportingTransactions(CTxDB& txdb) { vtxPrev.clear(); @@ -1321,15 +1333,15 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb) const int COPY_DEPTH = 3; if (SetMerkleBranch() < COPY_DEPTH) { - vector vWorkQueue; + std::vector vWorkQueue; for (const CTxIn& txin : vin) vWorkQueue.push_back(txin.prevout.hash); // This critsect is OK because txdb is already open { LOCK(pwallet->cs_wallet); - map mapWalletPrev; - set setAlreadyDone; + std::map mapWalletPrev; + std::set setAlreadyDone; for (unsigned int i = 0; i < vWorkQueue.size(); i++) { uint256 hash = vWorkQueue[i]; @@ -1338,7 +1350,7 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb) setAlreadyDone.insert(hash); CMerkleTx tx; - map::const_iterator mi = pwallet->mapWallet.find(hash); + auto mi = pwallet->mapWallet.find(hash); if (mi != pwallet->mapWallet.end()) { tx = (*mi).second; @@ -1374,6 +1386,32 @@ void CWalletTx::AddSupportingTransactions(CTxDB& txdb) reverse(vtxPrev.begin(), vtxPrev.end()); } +bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs) +{ + + { + LOCK(mempool.cs); + // Add previous supporting transactions first + for (CMerkleTx& tx : vtxPrev) + { + if (!(tx.IsCoinBase() || tx.IsCoinStake())) + { + uint256 hash = tx.GetHash(); + if (!mempool.exists(hash) && !txdb.ContainsTx(hash)) + tx.AcceptToMemoryPool(txdb, fCheckInputs); + } + } + return AcceptToMemoryPool(txdb, fCheckInputs); + } + return false; +} + +bool CWalletTx::AcceptWalletTransaction() +{ + CTxDB txdb("r"); + return AcceptWalletTransaction(txdb); +} + bool CWalletTx::WriteToDisk() { return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this); @@ -1421,7 +1459,7 @@ void CWallet::ReacceptWalletTransactions() { LOCK(cs_wallet); fRepeat = false; - vector vMissingTx; + std::vector vMissingTx; for (auto& item : mapWallet) { CWalletTx& wtx = item.second; @@ -1507,14 +1545,14 @@ std::vector CWallet::ResendWalletTransactionsBefore(int64_t nTime) LOCK(cs_wallet); // Sort them in chronological order - map mapSorted; + std::map mapSorted; for (auto& item : mapWallet) { CWalletTx& wtx = item.second; // Don't rebroadcast if newer than nTime: if (wtx.nTimeReceived > nTime) continue; - mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx)); + mapSorted.insert(std::make_pair(wtx.nTimeReceived, &wtx)); } for (auto& item : mapSorted) { @@ -1562,7 +1600,7 @@ int64_t CWallet::GetBalance() const int64_t nTotal = 0; { LOCK(cs_wallet); - for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + for (auto it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; if (pcoin->IsTrusted()) @@ -1578,7 +1616,7 @@ int64_t CWallet::GetWatchOnlyBalance() const int64_t nTotal = 0; { LOCK(cs_wallet); - for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + for (auto it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; if (pcoin->IsTrusted()) @@ -1594,7 +1632,7 @@ int64_t CWallet::GetUnconfirmedBalance() const int64_t nTotal = 0; { LOCK(cs_wallet); - for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + for (auto it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; if (!pcoin->IsFinal() || !pcoin->IsTrusted()) @@ -1609,7 +1647,7 @@ int64_t CWallet::GetUnconfirmedWatchOnlyBalance() const int64_t nTotal = 0; { LOCK(cs_wallet); - for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + for (auto it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; if (!pcoin->IsFinal() || !pcoin->IsTrusted()) @@ -1624,7 +1662,7 @@ int64_t CWallet::GetImmatureBalance() const int64_t nTotal = 0; { LOCK(cs_wallet); - for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + for (auto it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; nTotal += pcoin->GetImmatureCredit(); @@ -1638,7 +1676,7 @@ int64_t CWallet::GetImmatureWatchOnlyBalance() const int64_t nTotal = 0; { LOCK(cs_wallet); - for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + for (auto it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; nTotal += pcoin->GetImmatureWatchOnlyCredit(); @@ -1648,13 +1686,13 @@ int64_t CWallet::GetImmatureWatchOnlyBalance() const } // populate vCoins with vector of spendable COutputs -void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl) const +void CWallet::AvailableCoins(std::vector& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl) const { vCoins.clear(); { LOCK(cs_wallet); - for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + for (auto it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; @@ -1683,13 +1721,13 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const } } -void CWallet::AvailableCoinsMinConf(vector& vCoins, int nConf, int64_t nMinValue, int64_t nMaxValue) const +void CWallet::AvailableCoinsMinConf(std::vector& vCoins, int nConf, int64_t nMinValue, int64_t nMaxValue) const { vCoins.clear(); { LOCK(cs_wallet); - for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + for (auto it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; @@ -1714,10 +1752,10 @@ void CWallet::AvailableCoinsMinConf(vector& vCoins, int nConf, int64_t } } -static void ApproximateBestSubset(vector > >vValue, int64_t nTotalLower, int64_t nTargetValue, - vector& vfBest, int64_t& nBest, int iterations = 1000) +static void ApproximateBestSubset(std::vector > >vValue, int64_t nTotalLower, int64_t nTargetValue, + std::vector& vfBest, int64_t& nBest, int iterations = 1000) { - vector vfIncluded; + std::vector vfIncluded; vfBest.assign(vValue.size(), true); nBest = nTotalLower; @@ -1756,7 +1794,7 @@ int64_t CWallet::GetStake() const { int64_t nTotal = 0; LOCK(cs_wallet); - for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + for (auto it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; if (pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0) @@ -1769,7 +1807,7 @@ int64_t CWallet::GetWatchOnlyStake() const { int64_t nTotal = 0; LOCK(cs_wallet); - for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + for (auto it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; if (pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0) @@ -1782,7 +1820,7 @@ int64_t CWallet::GetNewMint() const { int64_t nTotal = 0; LOCK(cs_wallet); - for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + for (auto it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0) @@ -1795,7 +1833,7 @@ int64_t CWallet::GetWatchOnlyNewMint() const { int64_t nTotal = 0; LOCK(cs_wallet); - for (map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + for (auto it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx* pcoin = &(*it).second; if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0) @@ -1804,16 +1842,16 @@ int64_t CWallet::GetWatchOnlyNewMint() const return nTotal; } -bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, vector vCoins, set >& setCoinsRet, int64_t& nValueRet) const +bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, std::vector vCoins, std::set >& setCoinsRet, int64_t& nValueRet) const { setCoinsRet.clear(); nValueRet = 0; // List of values less than target - pair > coinLowestLarger; + std::pair > coinLowestLarger; coinLowestLarger.first = std::numeric_limits::max(); coinLowestLarger.second.first = NULL; - vector > > vValue; + std::vector > > vValue; int64_t nTotalLower = 0; std::random_device rd; @@ -1838,7 +1876,7 @@ bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, unsigned int nSpendTime, int64_t n = pcoin->vout[i].nValue; - pair > coin = make_pair(n,make_pair(pcoin, i)); + auto coin = std::make_pair(n, std::make_pair(pcoin, i)); if (n == nTargetValue) { @@ -1879,7 +1917,7 @@ bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, unsigned int nSpendTime, // Solve subset sum by stochastic approximation std::sort(vValue.begin(), vValue.end(), CompareValueOnly()); std::reverse(vValue.begin(), vValue.end()); - vector vfBest; + std::vector vfBest; int64_t nBest; ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000); @@ -1916,9 +1954,9 @@ bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, unsigned int nSpendTime, return true; } -bool CWallet::SelectCoins(int64_t nTargetValue, unsigned int nSpendTime, set >& setCoinsRet, int64_t& nValueRet, const CCoinControl* coinControl) const +bool CWallet::SelectCoins(int64_t nTargetValue, unsigned int nSpendTime, std::set >& setCoinsRet, int64_t& nValueRet, const CCoinControl* coinControl) const { - vector vCoins; + std::vector vCoins; AvailableCoins(vCoins, true, coinControl); // coin control -> return all selected outputs (we want all selected to go into the transaction for sure) @@ -1929,7 +1967,7 @@ bool CWallet::SelectCoins(int64_t nTargetValue, unsigned int nSpendTime, setvout[out.i].nValue; - setCoinsRet.insert(make_pair(out.tx, out.i)); + setCoinsRet.insert(std::make_pair(out.tx, out.i)); } return (nValueRet >= nTargetValue); } @@ -1939,10 +1977,39 @@ bool CWallet::SelectCoins(int64_t nTargetValue, unsigned int nSpendTime, set >& setCoinsRet, int64_t& nValueRet) const +bool CWallet::SelectCoinsSimple(int64_t nTargetValue, int64_t nMinValue, int64_t nMaxValue, unsigned int nSpendTime, int nMinConf, std::set >& setCoinsRet, int64_t& nValueRet) const { - vector vCoins; + std::vector vCoins; AvailableCoinsMinConf(vCoins, nMinConf, nMinValue, nMaxValue); setCoinsRet.clear(); @@ -1969,7 +2036,7 @@ bool CWallet::SelectCoinsSimple(int64_t nTargetValue, int64_t nMinValue, int64_t int64_t n = pcoin->vout[i].nValue; - pair > coin = make_pair(n,make_pair(pcoin, i)); + auto coin = std::make_pair(n, std::make_pair(pcoin, i)); if (n >= nTargetValue) { @@ -1989,7 +2056,7 @@ bool CWallet::SelectCoinsSimple(int64_t nTargetValue, int64_t nMinValue, int64_t return true; } -bool CWallet::CreateTransaction(const vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, const CCoinControl* coinControl) +bool CWallet::CreateTransaction(const std::vector >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, const CCoinControl* coinControl) { int64_t nValue = 0; for (const auto& s : vecSend) @@ -2022,7 +2089,7 @@ bool CWallet::CreateTransaction(const vector >& vecSend, wtxNew.vout.push_back(CTxOut(s.second, s.first)); // Choose coins to use - set > setCoins; + std::set > setCoins; int64_t nValueIn = 0; if (!SelectCoins(nTotalValue, wtxNew.nTime, setCoins, nValueIn, coinControl)) return false; @@ -2061,7 +2128,7 @@ bool CWallet::CreateTransaction(const vector >& vecSend, } // Insert change txn at random position: - vector::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size()); + auto position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size()); wtxNew.vout.insert(position, CTxOut(nChange, scriptChange)); } else @@ -2088,9 +2155,9 @@ bool CWallet::CreateTransaction(const vector >& vecSend, int64_t nPayFee = nTransactionFee * (1 + (int64_t)nBytes / 1000); int64_t nMinFee = wtxNew.GetMinFee(1, fAllowFree, GMF_SEND, nBytes); - if (nFeeRet < max(nPayFee, nMinFee)) + if (nFeeRet < std::max(nPayFee, nMinFee)) { - nFeeRet = max(nPayFee, nMinFee); + nFeeRet = std::max(nPayFee, nMinFee); continue; } @@ -2107,8 +2174,8 @@ bool CWallet::CreateTransaction(const vector >& vecSend, bool CWallet::CreateTransaction(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, const CCoinControl* coinControl) { - vector< pair > vecSend; - vecSend.push_back(make_pair(scriptPubKey, nValue)); + std::vector< std::pair > vecSend; + vecSend.push_back(std::make_pair(scriptPubKey, nValue)); return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, coinControl); } @@ -2127,7 +2194,7 @@ void CWallet::GetStakeWeightFromValue(const int64_t& nTime, const int64_t& nValu nWeight = bnCoinDayWeight.getuint64(); } -bool CWallet::MergeCoins(const int64_t& nAmount, const int64_t& nMinValue, const int64_t& nOutputValue, list& listMerged) +bool CWallet::MergeCoins(const int64_t& nAmount, const int64_t& nMinValue, const int64_t& nOutputValue, std::list& listMerged) { int64_t nBalance = GetBalance(); @@ -2136,7 +2203,7 @@ bool CWallet::MergeCoins(const int64_t& nAmount, const int64_t& nMinValue, const listMerged.clear(); int64_t nValueIn = 0; - set > setCoins; + std::set > setCoins; // Simple coins selection - no randomization if (!SelectCoinsSimple(nAmount, nMinValue, nOutputValue, GetTime(), 1, setCoins, nValueIn)) @@ -2146,7 +2213,7 @@ bool CWallet::MergeCoins(const int64_t& nAmount, const int64_t& nMinValue, const return false; CWalletTx wtxNew; - vector vwtxPrev; + std::vector vwtxPrev; // Reserve a new key pair from key pool CReserveKey reservekey(this); @@ -2256,7 +2323,7 @@ bool CWallet::CreateCoinStake(uint256 &hashTx, uint32_t nOut, uint32_t nGenerati if (!GetTransaction(hashTx, wtx)) return error("Transaction %s is not found\n", hashTx.GetHex().c_str()); - vector vSolutions; + std::vector vSolutions; txnouttype whichType; CScript scriptPubKeyOut; CScript scriptPubKeyKernel = wtx.vout[nOut].scriptPubKey; @@ -2298,7 +2365,7 @@ bool CWallet::CreateCoinStake(uint256 &hashTx, uint32_t nOut, uint32_t nGenerati txNew.vout.clear(); // List of constake dependencies - vector vwtxPrev; + std::vector vwtxPrev; vwtxPrev.push_back(&wtx); // Set generation time, and kernel input @@ -2494,7 +2561,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) -string CWallet::SendMoney(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNew, bool fAskFee) +std::string CWallet::SendMoney(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNew, bool fAskFee) { // Check amount if (nValue <= 0) @@ -2507,19 +2574,19 @@ string CWallet::SendMoney(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNe if (IsLocked()) { - string strError = _("Error: Wallet locked, unable to create transaction "); + std::string strError = _("Error: Wallet locked, unable to create transaction "); printf("SendMoney() : %s", strError.c_str()); return strError; } if (fWalletUnlockMintOnly) { - string strError = _("Error: Wallet unlocked for block minting only, unable to create transaction."); + std::string strError = _("Error: Wallet unlocked for block minting only, unable to create transaction."); printf("SendMoney() : %s", strError.c_str()); return strError; } if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired)) { - string strError; + std::string strError; if (nValue + nFeeRequired > GetBalance()) strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds "), FormatMoney(nFeeRequired).c_str()); else @@ -2585,14 +2652,14 @@ DBErrors CWallet::ZapWalletTx() return DB_LOAD_OK; } -bool CWallet::SetAddressBookName(const CTxDestination& address, const string& strName) +bool CWallet::SetAddressBookName(const CTxDestination& address, const std::string& strName) { return SetAddressBookName(CBitcoinAddress(address), strName); } -bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const string& strName) +bool CWallet::SetAddressBookName(const CBitcoinAddress& address, const std::string& strName) { - std::map::iterator mi = mapAddressBook.find(address); + auto mi = mapAddressBook.find(address); mapAddressBook[address] = strName; NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != MINE_NO, (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED); if (!fFileBacked) @@ -2628,11 +2695,26 @@ void CWallet::PrintWallet(const CBlock& block) printf("\n"); } +void CWallet::Inventory(const uint256 &hash) +{ + { + LOCK(cs_wallet); + auto mi = mapRequestCount.find(hash); + if (mi != mapRequestCount.end()) + (*mi).second++; + } +} + +unsigned int CWallet::GetKeyPoolSize() +{ + return (unsigned int)(setKeyPool.size()); +} + bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx) { { LOCK(cs_wallet); - map::iterator mi = mapWallet.find(hashTx); + auto mi = mapWallet.find(hashTx); if (mi != mapWallet.end()) { wtx = (*mi).second; @@ -2653,7 +2735,7 @@ bool CWallet::SetDefaultKey(const CPubKey &vchPubKey) return true; } -bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut) +bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut) { if (!pwallet->fFileBacked) return false; @@ -2681,7 +2763,7 @@ bool CWallet::NewKeyPool(unsigned int nSize) if (nSize > 0) nKeys = nSize; else - nKeys = max(GetArg("-keypool", 100), 0); + nKeys = std::max(GetArg("-keypool", 100), 0); for (uint64_t i = 0; i < nKeys; i++) { @@ -2709,7 +2791,7 @@ bool CWallet::TopUpKeyPool(unsigned int nSize) if (nSize > 0) nTargetSize = nSize; else - nTargetSize = max(GetArg("-keypool", 100), 0); + nTargetSize = std::max(GetArg("-keypool", 100), 0); while (setKeyPool.size() < (nTargetSize + 1)) { @@ -2717,7 +2799,7 @@ bool CWallet::TopUpKeyPool(unsigned int nSize) if (!setKeyPool.empty()) nEnd = *(--setKeyPool.end()) + 1; if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey()))) - throw runtime_error("TopUpKeyPool() : writing generated key failed"); + throw std::runtime_error("TopUpKeyPool() : writing generated key failed"); setKeyPool.insert(nEnd); printf("keypool added key %" PRIu64 ", size=%" PRIszu "\n", nEnd, setKeyPool.size()); } @@ -2744,9 +2826,9 @@ void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool) nIndex = *(setKeyPool.begin()); setKeyPool.erase(setKeyPool.begin()); if (!walletdb.ReadPool(nIndex, keypool)) - throw runtime_error("ReserveKeyFromKeyPool() : read failed"); + throw std::runtime_error("ReserveKeyFromKeyPool() : read failed"); if (!HaveKey(keypool.vchPubKey.GetID())) - throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool"); + throw std::runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool"); assert(keypool.vchPubKey.IsValid()); if (fDebug && GetBoolArg("-printkeypool")) printf("keypool reserve %" PRId64 "\n", nIndex); @@ -2761,7 +2843,7 @@ int64_t CWallet::AddReserveKey(const CKeyPool& keypool) int64_t nIndex = 1 + *(--setKeyPool.end()); if (!walletdb.WritePool(nIndex, keypool)) - throw runtime_error("AddReserveKey() : writing added key failed"); + throw std::runtime_error("AddReserveKey() : writing added key failed"); setKeyPool.insert(nIndex); return nIndex; } @@ -2828,7 +2910,7 @@ int64_t CWallet::GetOldestKeyPoolTime() std::map CWallet::GetAddressBalances() { - map balances; + std::map balances; { LOCK(cs_wallet); @@ -2866,10 +2948,10 @@ std::map CWallet::GetAddressBalances() return balances; } -set< set > CWallet::GetAddressGroupings() +std::set< std::set > CWallet::GetAddressGroupings() { - set< set > groupings; - set grouping; + std::set< std::set > groupings; + std::set grouping; for (auto& walletEntry : mapWallet) { @@ -2922,20 +3004,20 @@ set< set > CWallet::GetAddressGroupings() } } - set< set* > uniqueGroupings; // a set of pointers to groups of addresses - map< CBitcoinAddress, set* > setmap; // map addresses to the unique group containing it - for (set grouping : groupings) + std::set< std::set* > uniqueGroupings; // a set of pointers to groups of addresses + std::map< CBitcoinAddress, std::set* > setmap; // map addresses to the unique group containing it + for (std::set grouping : groupings) { // make a set of all the groups hit by this new group - set< set* > hits; - map< CBitcoinAddress, set* >::iterator it; + std::set< std::set* > hits; + std::map< CBitcoinAddress, std::set* >::iterator it; for (CBitcoinAddress address : grouping) if ((it = setmap.find(address)) != setmap.end()) hits.insert((*it).second); // merge all hit groups into a new single group and delete old groups - set* merged = new set(grouping); - for (set* hit : hits) + std::set* merged = new std::set(grouping); + for (std::set* hit : hits) { merged->insert(hit->begin(), hit->end()); uniqueGroupings.erase(hit); @@ -2948,8 +3030,8 @@ set< set > CWallet::GetAddressGroupings() setmap[element] = merged; } - set< set > ret; - for (set* uniqueGrouping : uniqueGroupings) + std::set< std::set > ret; + for (std::set* uniqueGrouping : uniqueGroupings) { ret.insert(*uniqueGrouping); delete uniqueGrouping; @@ -2966,9 +3048,9 @@ void CWallet::FixSpentCoins(int& nMismatchFound, int64_t& nBalanceInQuestion, bo nBalanceInQuestion = 0; LOCK(cs_wallet); - vector vCoins; + std::vector vCoins; vCoins.reserve(mapWallet.size()); - for (map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + for (auto it = mapWallet.begin(); it != mapWallet.end(); ++it) vCoins.push_back(&(*it).second); CTxDB txdb("r"); @@ -3027,7 +3109,7 @@ void CWallet::DisableTransaction(const CTransaction &tx) LOCK(cs_wallet); for (const CTxIn& txin : tx.vin) { - map::iterator mi = mapWallet.find(txin.prevout.hash); + auto mi = mapWallet.find(txin.prevout.hash); if (mi != mapWallet.end()) { CWalletTx& prev = (*mi).second; @@ -3066,6 +3148,18 @@ void CReserveKey::KeepKey() vchPubKey = CPubKey(); } +CReserveKey::CReserveKey(CWallet *pwalletIn) +{ + nIndex = -1; + pwallet = pwalletIn; +} + +CReserveKey::~CReserveKey() +{ + if (!fShutdown) + ReturnKey(); +} + void CReserveKey::ReturnKey() { if (nIndex != -1) @@ -3074,7 +3168,7 @@ void CReserveKey::ReturnKey() vchPubKey = CPubKey(); } -void CWallet::GetAllReserveKeys(set& setAddress) const +void CWallet::GetAllReserveKeys(std::set& setAddress) const { setAddress.clear(); @@ -3085,11 +3179,11 @@ void CWallet::GetAllReserveKeys(set& setAddress) const { CKeyPool keypool; if (!walletdb.ReadPool(id, keypool)) - throw runtime_error("GetAllReserveKeyHashes() : read failed"); + throw std::runtime_error("GetAllReserveKeyHashes() : read failed"); assert(keypool.vchPubKey.IsValid()); CKeyID keyID = keypool.vchPubKey.GetID(); if (!HaveKey(keyID)) - throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool"); + throw std::runtime_error("GetAllReserveKeyHashes() : unknown key in key pool"); setAddress.insert(keyID); } } @@ -3099,7 +3193,7 @@ void CWallet::UpdatedTransaction(const uint256 &hashTx) { LOCK(cs_wallet); // Only notify UI if this transaction is in this wallet - map::const_iterator mi = mapWallet.find(hashTx); + auto mi = mapWallet.find(hashTx); if (mi != mapWallet.end()) { NotifyTransactionChanged(this, hashTx, CT_UPDATED); @@ -3135,7 +3229,7 @@ void CWallet::GetAddresses(std::map &mapAddresses) con std::vector vAffected; ::ExtractAffectedKeys(*this, out.scriptPubKey, vAffected); - for(std::vector::const_iterator it3 = vAffected.begin(); it3 != vAffected.end(); it3++) { + for(auto it3 = vAffected.begin(); it3 != vAffected.end(); it3++) { CBitcoinAddress addrAffected(*it3); if (mapAddresses.find(addrAffected) != mapAddresses.end() && (mapAddresses[addrAffected] == 0 || mapAddresses[addrAffected] > wtx.nTime)) mapAddresses[addrAffected] = wtx.nTime; @@ -3148,10 +3242,10 @@ void CWallet::GetAddresses(std::map &mapAddresses) con void CWallet::ClearOrphans() { - list orphans; + std::list orphans; LOCK(cs_wallet); - for(map::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) + for(auto it = mapWallet.begin(); it != mapWallet.end(); ++it) { const CWalletTx *wtx = &(*it).second; if((wtx->IsCoinBase() || wtx->IsCoinStake()) && !wtx->IsInMainChain()) @@ -3160,7 +3254,112 @@ void CWallet::ClearOrphans() } } - for(list::const_iterator it = orphans.begin(); it != orphans.end(); ++it) + for(auto it = orphans.begin(); it != orphans.end(); ++it) EraseFromWallet(*it); } + +CWalletTx::CWalletTx() +{ + Init(nullptr); +} + +CWalletTx::CWalletTx(const CWallet *pwalletIn) +{ + Init(pwalletIn); +} + +CWalletTx::CWalletTx(const CWallet *pwalletIn, const CMerkleTx &txIn) : CMerkleTx(txIn) +{ + Init(pwalletIn); +} + +CWalletTx::CWalletTx(const CWallet *pwalletIn, const CTransaction &txIn) : CMerkleTx(txIn) +{ + Init(pwalletIn); +} + +void CWalletTx::Init(const CWallet *pwalletIn) +{ + pwallet = pwalletIn; + vtxPrev.clear(); + mapValue.clear(); + vOrderForm.clear(); + fTimeReceivedIsTxTime = false; + nTimeReceived = 0; + nTimeSmart = 0; + fFromMe = false; + strFromAccount.clear(); + vfSpent.clear(); + fDebitCached = false; + fWatchDebitCached = false; + fCreditCached = false; + fWatchCreditCached = false; + fAvailableCreditCached = false; + fAvailableWatchCreditCached = false; + fImmatureCreditCached = false; + fImmatureWatchCreditCached = false; + fChangeCached = false; + nDebitCached = 0; + nWatchDebitCached = 0; + nCreditCached = 0; + nWatchCreditCached = 0; + nAvailableCreditCached = 0; + nAvailableWatchCreditCached = 0; + nImmatureCreditCached = 0; + nImmatureWatchCreditCached = 0; + nChangeCached = 0; + nOrderPos = -1; +} + +COutput::COutput(const CWalletTx *txIn, int iIn, int nDepthIn, bool fSpendableIn) +{ + tx = txIn; i = iIn; nDepth = nDepthIn; fSpendable = fSpendableIn; +} + +std::string COutput::ToString() const +{ + return strprintf("COutput(%s, %d, %d, %d) [%s]", tx->GetHash().ToString().substr(0,10).c_str(), i, fSpendable, nDepth, FormatMoney(tx->vout[i].nValue).c_str()); +} + +CAccount::CAccount() +{ + SetNull(); +} + +void CAccount::SetNull() +{ + vchPubKey = CPubKey(); +} + +CAccountingEntry::CAccountingEntry() +{ + SetNull(); +} + +void CAccountingEntry::SetNull() +{ + nCreditDebit = 0; + nTime = 0; + strAccount.clear(); + strOtherAccount.clear(); + strComment.clear(); + nOrderPos = -1; +} + +CWalletKey::CWalletKey(int64_t nExpires) +{ + nTimeCreated = (nExpires ? GetTime() : 0); + nTimeExpires = nExpires; +} + +CKeyPool::CKeyPool() +{ + nTime = GetTime(); +} + +CKeyPool::CKeyPool(const CPubKey &vchPubKeyIn) +{ + nTime = GetTime(); + vchPubKey = vchPubKeyIn; +}