Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
| Show First 20 Lines • Show All 1,690 Lines • ▼ Show 20 Lines | for (unsigned int i = 0; i < tx->vout.size(); ++i) { | ||||
| // If we are receiving the output, add it as a "received" entry. | // If we are receiving the output, add it as a "received" entry. | ||||
| if (fIsMine & filter) { | if (fIsMine & filter) { | ||||
| listReceived.push_back(output); | listReceived.push_back(output); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void CWalletTx::GetAccountAmounts(const std::string &strAccount, | |||||
| Amount &nReceived, Amount &nSent, | |||||
| Amount &nFee, | |||||
| const isminefilter &filter) const { | |||||
| nReceived = nSent = nFee = Amount(0); | |||||
| Amount allFee; | |||||
| std::string strSentAccount; | |||||
| std::list<COutputEntry> listReceived; | |||||
| std::list<COutputEntry> listSent; | |||||
| GetAmounts(listReceived, listSent, allFee, strSentAccount, filter); | |||||
| if (strAccount == strSentAccount) { | |||||
| for (const COutputEntry &s : listSent) { | |||||
| nSent += s.amount; | |||||
| } | |||||
| nFee = allFee; | |||||
| } | |||||
| LOCK(pwallet->cs_wallet); | |||||
| for (const COutputEntry &r : listReceived) { | |||||
| if (pwallet->mapAddressBook.count(r.destination)) { | |||||
| std::map<CTxDestination, CAddressBookData>::const_iterator mi = | |||||
| pwallet->mapAddressBook.find(r.destination); | |||||
| if (mi != pwallet->mapAddressBook.end() && | |||||
| (*mi).second.name == strAccount) { | |||||
| nReceived += r.amount; | |||||
| } | |||||
| } else if (strAccount.empty()) { | |||||
| nReceived += r.amount; | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | /** | ||||
| * Scan the block chain (starting in pindexStart) for transactions from or to | * Scan the block chain (starting in pindexStart) for transactions from or to | ||||
| * us. If fUpdate is true, found transactions that already exist in the wallet | * us. If fUpdate is true, found transactions that already exist in the wallet | ||||
| * will be updated. | * will be updated. | ||||
| * | * | ||||
| * Returns pointer to the first block in the last contiguous range that was | * Returns pointer to the first block in the last contiguous range that was | ||||
| * successfully scanned or elided (elided if pIndexStart points at a block | * successfully scanned or elided (elided if pIndexStart points at a block | ||||
| * before CWallet::nTimeFirstKey). Returns null if there is no such range, or | * before CWallet::nTimeFirstKey). Returns null if there is no such range, or | ||||
| ▲ Show 20 Lines • Show All 505 Lines • ▼ Show 20 Lines | for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); | ||||
| it != mapWallet.end(); ++it) { | it != mapWallet.end(); ++it) { | ||||
| const CWalletTx *pcoin = &(*it).second; | const CWalletTx *pcoin = &(*it).second; | ||||
| nTotal += pcoin->GetImmatureWatchOnlyCredit(); | nTotal += pcoin->GetImmatureWatchOnlyCredit(); | ||||
| } | } | ||||
| return nTotal; | return nTotal; | ||||
| } | } | ||||
| // Calculate total balance in a different way from GetBalance. The biggest | |||||
| // difference is that GetBalance sums up all unspent TxOuts paying to the | |||||
| // wallet, while this sums up both spent and unspent TxOuts paying to the | |||||
| // wallet, and then subtracts the values of TxIns spending from the wallet. This | |||||
| // also has fewer restrictions on which unconfirmed transactions are considered | |||||
| // trusted. | |||||
| Amount CWallet::GetLegacyBalance(const isminefilter &filter, int minDepth, | |||||
| const std::string *account) const { | |||||
| LOCK2(cs_main, cs_wallet); | |||||
| Amount balance(0); | |||||
| for (const auto &entry : mapWallet) { | |||||
| const CWalletTx &wtx = entry.second; | |||||
| const int depth = wtx.GetDepthInMainChain(); | |||||
| if (depth < 0 || !CheckFinalTx(*wtx.tx) || | |||||
| wtx.GetBlocksToMaturity() > 0) { | |||||
| continue; | |||||
| } | |||||
| // Loop through tx outputs and add incoming payments. For outgoing txs, | |||||
| // treat change outputs specially, as part of the amount debited. | |||||
| Amount debit = wtx.GetDebit(filter); | |||||
| const bool outgoing = debit > Amount(0); | |||||
| for (const CTxOut &out : wtx.tx->vout) { | |||||
| if (outgoing && IsChange(out)) { | |||||
| debit -= out.nValue; | |||||
| } else if (IsMine(out) & filter && depth >= minDepth && | |||||
| (!account || | |||||
| *account == GetAccountName(out.scriptPubKey))) { | |||||
| balance += out.nValue; | |||||
| } | |||||
| } | |||||
| // For outgoing txs, subtract amount debited. | |||||
| if (outgoing && (!account || *account == wtx.strFromAccount)) { | |||||
| balance -= debit; | |||||
| } | |||||
| } | |||||
| if (account) { | |||||
| balance += CWalletDB(*dbw).GetAccountCreditDebit(*account); | |||||
| } | |||||
| return balance; | |||||
| } | |||||
| void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, | void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, | ||||
| const CCoinControl *coinControl, | const CCoinControl *coinControl, | ||||
| bool fIncludeZeroValue) const { | bool fIncludeZeroValue) const { | ||||
| vCoins.clear(); | vCoins.clear(); | ||||
| LOCK2(cs_main, cs_wallet); | LOCK2(cs_main, cs_wallet); | ||||
| for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); | for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); | ||||
| it != mapWallet.end(); ++it) { | it != mapWallet.end(); ++it) { | ||||
| ▲ Show 20 Lines • Show All 1,031 Lines • ▼ Show 20 Lines | bool CWallet::DelAddressBook(const CTxDestination &address) { | ||||
| NotifyAddressBookChanged(this, address, "", | NotifyAddressBookChanged(this, address, "", | ||||
| ::IsMine(*this, address) != ISMINE_NO, "", | ::IsMine(*this, address) != ISMINE_NO, "", | ||||
| CT_DELETED); | CT_DELETED); | ||||
| CWalletDB(*dbw).ErasePurpose(address); | CWalletDB(*dbw).ErasePurpose(address); | ||||
| return CWalletDB(*dbw).EraseName(address); | return CWalletDB(*dbw).EraseName(address); | ||||
| } | } | ||||
| const std::string &CWallet::GetAccountName(const CScript &scriptPubKey) const { | |||||
| CTxDestination address; | |||||
| if (ExtractDestination(scriptPubKey, address) && | |||||
| !scriptPubKey.IsUnspendable()) { | |||||
| auto mi = mapAddressBook.find(address); | |||||
| if (mi != mapAddressBook.end()) { | |||||
| return mi->second.name; | |||||
| } | |||||
| } | |||||
| // A scriptPubKey that doesn't have an entry in the address book is | |||||
| // associated with the default account (""). | |||||
| const static std::string DEFAULT_ACCOUNT_NAME; | |||||
| return DEFAULT_ACCOUNT_NAME; | |||||
| } | |||||
| /** | /** | ||||
| * Mark old keypool keys as used, and generate all new keys. | * Mark old keypool keys as used, and generate all new keys. | ||||
| */ | */ | ||||
| bool CWallet::NewKeyPool() { | bool CWallet::NewKeyPool() { | ||||
| LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
| CWalletDB walletdb(*dbw); | CWalletDB walletdb(*dbw); | ||||
| for (int64_t nIndex : setInternalKeyPool) { | for (int64_t nIndex : setInternalKeyPool) { | ||||
| ▲ Show 20 Lines • Show All 363 Lines • ▼ Show 20 Lines | std::set<std::set<CTxDestination>> CWallet::GetAddressGroupings() { | ||||
| for (std::set<CTxDestination> *uniqueGrouping : uniqueGroupings) { | for (std::set<CTxDestination> *uniqueGrouping : uniqueGroupings) { | ||||
| ret.insert(*uniqueGrouping); | ret.insert(*uniqueGrouping); | ||||
| delete uniqueGrouping; | delete uniqueGrouping; | ||||
| } | } | ||||
| return ret; | return ret; | ||||
| } | } | ||||
| Amount CWallet::GetAccountBalance(const std::string &strAccount, int nMinDepth, | |||||
| const isminefilter &filter) { | |||||
| CWalletDB walletdb(*dbw); | |||||
| return GetAccountBalance(walletdb, strAccount, nMinDepth, filter); | |||||
| } | |||||
| Amount CWallet::GetAccountBalance(CWalletDB &walletdb, | |||||
| const std::string &strAccount, int nMinDepth, | |||||
| const isminefilter &filter) { | |||||
| Amount nBalance(0); | |||||
| // Tally wallet transactions. | |||||
| for (std::map<uint256, CWalletTx>::iterator it = mapWallet.begin(); | |||||
| it != mapWallet.end(); ++it) { | |||||
| const CWalletTx &wtx = (*it).second; | |||||
| if (!CheckFinalTx(wtx) || wtx.GetBlocksToMaturity() > 0 || | |||||
| wtx.GetDepthInMainChain() < 0) { | |||||
| continue; | |||||
| } | |||||
| Amount nReceived, nSent, nFee; | |||||
| wtx.GetAccountAmounts(strAccount, nReceived, nSent, nFee, filter); | |||||
| if (nReceived != Amount(0) && wtx.GetDepthInMainChain() >= nMinDepth) { | |||||
| nBalance += nReceived; | |||||
| } | |||||
| nBalance -= nSent + nFee; | |||||
| } | |||||
| // Tally internal accounting entries. | |||||
| nBalance += walletdb.GetAccountCreditDebit(strAccount); | |||||
| return nBalance; | |||||
| } | |||||
| std::set<CTxDestination> | std::set<CTxDestination> | ||||
| CWallet::GetAccountAddresses(const std::string &strAccount) const { | CWallet::GetAccountAddresses(const std::string &strAccount) const { | ||||
| LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
| std::set<CTxDestination> result; | std::set<CTxDestination> result; | ||||
| for (const std::pair<CTxDestination, CAddressBookData> &item : | for (const std::pair<CTxDestination, CAddressBookData> &item : | ||||
| mapAddressBook) { | mapAddressBook) { | ||||
| const CTxDestination &address = item.first; | const CTxDestination &address = item.first; | ||||
| const std::string &strName = item.second.name; | const std::string &strName = item.second.name; | ||||
| ▲ Show 20 Lines • Show All 858 Lines • Show Last 20 Lines | |||||