Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show First 20 Lines • Show All 778 Lines • ▼ Show 20 Lines | DBErrors CWallet::ReorderTransactions() { | ||||
// Old wallets didn't have any defined order for transactions. Probably a | // Old wallets didn't have any defined order for transactions. Probably a | ||||
// bad idea to change the output of this. | // bad idea to change the output of this. | ||||
// First: get all CWalletTx and CAccountingEntry into a sorted-by-time | // First: get all CWalletTx and CAccountingEntry into a sorted-by-time | ||||
// multimap. | // multimap. | ||||
TxItems txByTime; | TxItems txByTime; | ||||
for (std::map<TxId, CWalletTx>::iterator it = mapWallet.begin(); | for (auto &entry : mapWallet) { | ||||
it != mapWallet.end(); ++it) { | CWalletTx *wtx = &entry.second; | ||||
CWalletTx *wtx = &((*it).second); | |||||
txByTime.insert( | txByTime.insert( | ||||
std::make_pair(wtx->nTimeReceived, TxPair(wtx, nullptr))); | std::make_pair(wtx->nTimeReceived, TxPair(wtx, nullptr))); | ||||
} | } | ||||
std::list<CAccountingEntry> acentries; | std::list<CAccountingEntry> acentries; | ||||
walletdb.ListAccountCreditDebit("", acentries); | walletdb.ListAccountCreditDebit("", acentries); | ||||
for (CAccountingEntry &entry : acentries) { | for (CAccountingEntry &entry : acentries) { | ||||
txByTime.insert(std::make_pair(entry.nTime, TxPair(nullptr, &entry))); | txByTime.insert(std::make_pair(entry.nTime, TxPair(nullptr, &entry))); | ||||
▲ Show 20 Lines • Show All 1,352 Lines • ▼ Show 20 Lines | |||||
* @defgroup Actions | * @defgroup Actions | ||||
* | * | ||||
* @{ | * @{ | ||||
*/ | */ | ||||
Amount CWallet::GetBalance() const { | Amount CWallet::GetBalance() const { | ||||
LOCK2(cs_main, cs_wallet); | LOCK2(cs_main, cs_wallet); | ||||
Amount nTotal = Amount::zero(); | Amount nTotal = Amount::zero(); | ||||
for (const std::pair<uint256, CWalletTx> &p : mapWallet) { | for (const auto &entry : mapWallet) { | ||||
const CWalletTx *pcoin = &p.second; | const CWalletTx *pcoin = &entry.second; | ||||
if (pcoin->IsTrusted()) { | if (pcoin->IsTrusted()) { | ||||
nTotal += pcoin->GetAvailableCredit(); | nTotal += pcoin->GetAvailableCredit(); | ||||
} | } | ||||
} | } | ||||
return nTotal; | return nTotal; | ||||
} | } | ||||
Amount CWallet::GetUnconfirmedBalance() const { | Amount CWallet::GetUnconfirmedBalance() const { | ||||
LOCK2(cs_main, cs_wallet); | LOCK2(cs_main, cs_wallet); | ||||
Amount nTotal = Amount::zero(); | Amount nTotal = Amount::zero(); | ||||
for (const std::pair<uint256, CWalletTx> &p : mapWallet) { | for (const auto &entry : mapWallet) { | ||||
const CWalletTx *pcoin = &p.second; | const CWalletTx *pcoin = &entry.second; | ||||
if (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0 && | if (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0 && | ||||
pcoin->InMempool()) { | pcoin->InMempool()) { | ||||
nTotal += pcoin->GetAvailableCredit(); | nTotal += pcoin->GetAvailableCredit(); | ||||
} | } | ||||
} | } | ||||
return nTotal; | return nTotal; | ||||
} | } | ||||
Amount CWallet::GetImmatureBalance() const { | Amount CWallet::GetImmatureBalance() const { | ||||
LOCK2(cs_main, cs_wallet); | LOCK2(cs_main, cs_wallet); | ||||
Amount nTotal = Amount::zero(); | Amount nTotal = Amount::zero(); | ||||
for (const std::pair<uint256, CWalletTx> &p : mapWallet) { | for (const auto &entry : mapWallet) { | ||||
const CWalletTx *pcoin = &p.second; | const CWalletTx *pcoin = &entry.second; | ||||
nTotal += pcoin->GetImmatureCredit(); | nTotal += pcoin->GetImmatureCredit(); | ||||
} | } | ||||
return nTotal; | return nTotal; | ||||
} | } | ||||
Amount CWallet::GetWatchOnlyBalance() const { | Amount CWallet::GetWatchOnlyBalance() const { | ||||
LOCK2(cs_main, cs_wallet); | LOCK2(cs_main, cs_wallet); | ||||
Amount nTotal = Amount::zero(); | Amount nTotal = Amount::zero(); | ||||
for (const std::pair<uint256, CWalletTx> &p : mapWallet) { | for (const auto &entry : mapWallet) { | ||||
const CWalletTx *pcoin = &p.second; | const CWalletTx *pcoin = &entry.second; | ||||
if (pcoin->IsTrusted()) { | if (pcoin->IsTrusted()) { | ||||
nTotal += pcoin->GetAvailableWatchOnlyCredit(); | nTotal += pcoin->GetAvailableWatchOnlyCredit(); | ||||
} | } | ||||
} | } | ||||
return nTotal; | return nTotal; | ||||
} | } | ||||
Amount CWallet::GetUnconfirmedWatchOnlyBalance() const { | Amount CWallet::GetUnconfirmedWatchOnlyBalance() const { | ||||
LOCK2(cs_main, cs_wallet); | LOCK2(cs_main, cs_wallet); | ||||
Amount nTotal = Amount::zero(); | Amount nTotal = Amount::zero(); | ||||
for (const std::pair<uint256, CWalletTx> &p : mapWallet) { | for (const auto &entry : mapWallet) { | ||||
const CWalletTx *pcoin = &p.second; | const CWalletTx *pcoin = &entry.second; | ||||
if (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0 && | if (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0 && | ||||
pcoin->InMempool()) { | pcoin->InMempool()) { | ||||
nTotal += pcoin->GetAvailableWatchOnlyCredit(); | nTotal += pcoin->GetAvailableWatchOnlyCredit(); | ||||
} | } | ||||
} | } | ||||
return nTotal; | return nTotal; | ||||
} | } | ||||
Amount CWallet::GetImmatureWatchOnlyBalance() const { | Amount CWallet::GetImmatureWatchOnlyBalance() const { | ||||
LOCK2(cs_main, cs_wallet); | LOCK2(cs_main, cs_wallet); | ||||
Amount nTotal = Amount::zero(); | Amount nTotal = Amount::zero(); | ||||
for (const std::pair<uint256, CWalletTx> &p : mapWallet) { | for (const auto &entry : mapWallet) { | ||||
const CWalletTx *pcoin = &p.second; | const CWalletTx *pcoin = &entry.second; | ||||
nTotal += pcoin->GetImmatureWatchOnlyCredit(); | nTotal += pcoin->GetImmatureWatchOnlyCredit(); | ||||
} | } | ||||
return nTotal; | return nTotal; | ||||
} | } | ||||
// Calculate total balance in a different way from GetBalance. The biggest | // Calculate total balance in a different way from GetBalance. The biggest | ||||
// difference is that GetBalance sums up all unspent TxOuts paying to the | // difference is that GetBalance sums up all unspent TxOuts paying to the | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, | ||||
const Amount nMaximumAmount, | const Amount nMaximumAmount, | ||||
const Amount nMinimumSumAmount, | const Amount nMinimumSumAmount, | ||||
const uint64_t nMaximumCount, const int nMinDepth, | const uint64_t nMaximumCount, const int nMinDepth, | ||||
const int nMaxDepth) const { | const int nMaxDepth) const { | ||||
vCoins.clear(); | vCoins.clear(); | ||||
Amount nTotal = Amount::zero(); | Amount nTotal = Amount::zero(); | ||||
LOCK2(cs_main, cs_wallet); | LOCK2(cs_main, cs_wallet); | ||||
for (std::map<TxId, CWalletTx>::const_iterator it = mapWallet.begin(); | for (const auto &entry : mapWallet) { | ||||
it != mapWallet.end(); ++it) { | const TxId &wtxid = entry.first; | ||||
const TxId &wtxid = it->first; | const CWalletTx *pcoin = &entry.second; | ||||
const CWalletTx *pcoin = &(*it).second; | |||||
if (!CheckFinalTx(*pcoin)) { | if (!CheckFinalTx(*pcoin)) { | ||||
continue; | continue; | ||||
} | } | ||||
if (pcoin->IsImmatureCoinBase()) { | if (pcoin->IsImmatureCoinBase()) { | ||||
continue; | continue; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | for (const auto &entry : mapWallet) { | ||||
for (uint32_t i = 0; i < pcoin->tx->vout.size(); i++) { | for (uint32_t i = 0; i < pcoin->tx->vout.size(); i++) { | ||||
if (pcoin->tx->vout[i].nValue < nMinimumAmount || | if (pcoin->tx->vout[i].nValue < nMinimumAmount || | ||||
pcoin->tx->vout[i].nValue > nMaximumAmount) { | pcoin->tx->vout[i].nValue > nMaximumAmount) { | ||||
continue; | continue; | ||||
} | } | ||||
if (coinControl && coinControl->HasSelected() && | if (coinControl && coinControl->HasSelected() && | ||||
!coinControl->fAllowOtherInputs && | !coinControl->fAllowOtherInputs && | ||||
!coinControl->IsSelected(COutPoint((*it).first, i))) { | !coinControl->IsSelected(COutPoint(entry.first, i))) { | ||||
continue; | continue; | ||||
} | } | ||||
if (IsLockedCoin((*it).first, i)) { | if (IsLockedCoin(entry.first, i)) { | ||||
continue; | continue; | ||||
} | } | ||||
if (IsSpent(wtxid, i)) { | if (IsSpent(wtxid, i)) { | ||||
continue; | continue; | ||||
} | } | ||||
isminetype mine = IsMine(pcoin->tx->vout[i]); | isminetype mine = IsMine(pcoin->tx->vout[i]); | ||||
▲ Show 20 Lines • Show All 1,617 Lines • ▼ Show 20 Lines | void CWallet::GetKeyBirthTimes( | ||||
// If there are no such keys, we're done. | // If there are no such keys, we're done. | ||||
if (mapKeyFirstBlock.empty()) { | if (mapKeyFirstBlock.empty()) { | ||||
return; | return; | ||||
} | } | ||||
// Find first block that affects those keys, if there are any left. | // Find first block that affects those keys, if there are any left. | ||||
std::vector<CKeyID> vAffected; | std::vector<CKeyID> vAffected; | ||||
for (std::map<TxId, CWalletTx>::const_iterator it = mapWallet.begin(); | for (const auto &entry : mapWallet) { | ||||
it != mapWallet.end(); it++) { | // iterate over all wallet transactions... | ||||
// Iterate over all wallet transactions... | const CWalletTx &wtx = entry.second; | ||||
const CWalletTx &wtx = (*it).second; | |||||
BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock); | BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock); | ||||
if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) { | if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) { | ||||
// ... which are already in a block. | // ... which are already in a block. | ||||
int nHeight = blit->second->nHeight; | int nHeight = blit->second->nHeight; | ||||
for (const CTxOut &txout : wtx.tx->vout) { | for (const CTxOut &txout : wtx.tx->vout) { | ||||
// Iterate over all their outputs... | // Iterate over all their outputs... | ||||
CAffectedKeysVisitor(*this, vAffected) | CAffectedKeysVisitor(*this, vAffected) | ||||
.Process(txout.scriptPubKey); | .Process(txout.scriptPubKey); | ||||
for (const CKeyID &keyid : vAffected) { | for (const CKeyID &keyid : vAffected) { | ||||
// ... and all their affected keys. | // ... and all their affected keys. | ||||
std::map<CKeyID, CBlockIndex *>::iterator rit = | std::map<CKeyID, CBlockIndex *>::iterator rit = | ||||
mapKeyFirstBlock.find(keyid); | mapKeyFirstBlock.find(keyid); | ||||
if (rit != mapKeyFirstBlock.end() && | if (rit != mapKeyFirstBlock.end() && | ||||
nHeight < rit->second->nHeight) { | nHeight < rit->second->nHeight) { | ||||
rit->second = blit->second; | rit->second = blit->second; | ||||
} | } | ||||
} | } | ||||
vAffected.clear(); | vAffected.clear(); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// Extract block timestamps for those keys. | // Extract block timestamps for those keys. | ||||
for (const std::pair<CKeyID, CBlockIndex *> &p : mapKeyFirstBlock) { | for (const auto &entry : mapKeyFirstBlock) { | ||||
// Block times can be 2h off. | // block times can be 2h off | ||||
mapKeyBirth[p.first] = p.second->GetBlockTime() - TIMESTAMP_WINDOW; | mapKeyBirth[entry.first] = | ||||
entry.second->GetBlockTime() - TIMESTAMP_WINDOW; | |||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Compute smart timestamp for a transaction being added to the wallet. | * Compute smart timestamp for a transaction being added to the wallet. | ||||
* | * | ||||
* Logic: | * Logic: | ||||
* - If sending a transaction, assign its timestamp to the current time. | * - If sending a transaction, assign its timestamp to the current time. | ||||
▲ Show 20 Lines • Show All 425 Lines • Show Last 20 Lines |