| 214 | } |
| 215 | |
| 216 | CAmountMap CachedTxGetAvailableCredit(const CWallet& wallet, const CWalletTx& wtx, bool fUseCache, const isminefilter& filter) |
| 217 | { |
| 218 | // Avoid caching ismine for NO or ALL cases (could remove this check and simplify in the future). |
| 219 | bool allow_cache = (filter & ISMINE_ALL) && (filter & ISMINE_ALL) != ISMINE_ALL; |
| 220 | |
| 221 | // Must wait until coinbase is safely deep enough in the chain before valuing it |
| 222 | if (wallet.IsTxImmatureCoinBase(wtx)) |
| 223 | return CAmountMap(); |
| 224 | |
| 225 | if (fUseCache && allow_cache && wtx.m_amounts[CWalletTx::AVAILABLE_CREDIT].m_cached[filter]) { |
| 226 | return wtx.m_amounts[CWalletTx::AVAILABLE_CREDIT].m_value[filter]; |
| 227 | } |
| 228 | |
| 229 | bool allow_used_addresses = (filter & ISMINE_USED) || !wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE); |
| 230 | CAmountMap nCredit; |
| 231 | uint256 hashTx = wtx.GetHash(); |
| 232 | CAsset pegged_asset{Params().GetConsensus().pegged_asset}; |
| 233 | for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) |
| 234 | { |
| 235 | if (!wallet.IsSpent(hashTx, i) && (allow_used_addresses || !wallet.IsSpentKey(hashTx, i))) { |
| 236 | if (wallet.IsMine(wtx.tx->vout[i]) & filter) { |
| 237 | CAsset asset = wtx.GetOutputAsset(wallet, i); |
| 238 | CAmount credit = std::max<CAmount>(0, wtx.GetOutputValueOut(wallet, i)); |
| 239 | if (asset == pegged_asset && !MoneyRange(credit)) |
| 240 | throw std::runtime_error(std::string(__func__) + ": value out of range"); |
| 241 | |
| 242 | nCredit[wtx.GetOutputAsset(wallet, i)] += std::max<CAmount>(0, wtx.GetOutputValueOut(wallet, i)); |
| 243 | if (!MoneyRange(nCredit, pegged_asset)) |
| 244 | throw std::runtime_error(std::string(__func__) + ": value out of range"); |
| 245 | } |
| 246 | } |
| 247 | } |
| 248 | |
| 249 | if (allow_cache) { |
| 250 | wtx.m_amounts[CWalletTx::AVAILABLE_CREDIT].Set(filter, nCredit); |
| 251 | wtx.m_is_cache_empty = false; |
| 252 | } |
| 253 | |
| 254 | return nCredit; |
| 255 | } |
| 256 | |
| 257 | void CachedTxGetAmounts(const CWallet& wallet, const CWalletTx& wtx, |
| 258 | std::list<COutputEntry>& listReceived, |
no test coverage detected