Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251std::set<Txid> trusted_parents;252for (const auto& [outpoint, txo] : wallet.GetTXOs()) {253const CWalletTx& wtx = txo.GetWalletTx();255const bool is_trusted{CachedTxIsTrusted(wallet, wtx, trusted_parents)};256const int tx_depth{wallet.GetTxDepthInMainChain(wtx)};258bool nonmempool_spent = false;259switch (wallet.HowSpent(outpoint)) {260case CWallet::SpendType::CONFIRMED:261case CWallet::SpendType::MEMPOOL:262// treat as spent; ignore263break;264case CWallet::SpendType::NONMEMPOOL:265if (!include_nonmempool) break;266nonmempool_spent = true;267[[fallthrough]];268case CWallet::SpendType::UNSPENT:269CAmount* bucket = nullptr;271// Set the amounts in the return object272if (wallet.IsTxImmatureCoinBase(wtx) && wtx.isConfirmed()) {273bucket = &ret.m_mine_immature;274} else if (is_trusted && tx_depth >= min_depth) {275bucket = &ret.m_mine_trusted;276} else if (!is_trusted && wtx.InMempool()) {277bucket = &ret.m_mine_untrusted_pending;278}279if (bucket) {280// Get the amounts for mine281CAmount credit_mine = txo.GetTxOut().nValue;283if (!allow_used_addresses && wallet.IsSpentKey(txo.GetTxOut().scriptPubKey)) {284bucket = &ret.m_mine_used;285}286*bucket += credit_mine;287if (nonmempool_spent) {288ret.m_mine_nonmempool -= credit_mine;289}290}291}292}293}294return ret;295}297std::map<CTxDestination, CAmount> GetAddressBalances(const CWallet& wallet)298{299std::map<CTxDestination, CAmount> balances;301{302LOCK(wallet.cs_wallet);303std::set<Txid> trusted_parents;304for (const auto& [outpoint, txo] : wallet.GetTXOs()) {305const CWalletTx& wtx = txo.GetWalletTx();307if (!CachedTxIsTrusted(wallet, wtx, trusted_parents)) continue;308if (wallet.IsTxImmatureCoinBase(wtx)) continue;310int nDepth = wallet.GetTxDepthInMainChain(wtx);311if (nDepth < (CachedTxIsFromMe(wallet, wtx) ? 0 : 1)) continue;313CTxDestination addr;314Assume(wallet.IsMine(txo.GetTxOut()));315if(!ExtractDestination(txo.GetTxOut().scriptPubKey, addr)) continue;317CAmount n = wallet.IsSpent(outpoint) ? 0 : txo.GetTxOut().nValue;318balances[addr] += n;319}320}322return balances;323}325std::set< std::set<CTxDestination> > GetAddressGroupings(const CWallet& wallet)326{327AssertLockHeld(wallet.cs_wallet);328std::set< std::set<CTxDestination> > groupings;329std::set<CTxDestination> grouping;331for (const auto& walletEntry : wallet.mapWallet)332{333const CWalletTx& wtx = walletEntry.second;335if (wtx.GetTx()->vin.size() > 0)336{337bool any_mine = false;338// group all input addresses with each other339for (const CTxIn& txin : wtx.GetTx()->vin)340{341CTxDestination address;342if(!InputIsMine(wallet, txin)) /* If this input isn't mine, ignore it */343continue;344if(!ExtractDestination(wallet.mapWallet.at(txin.prevout.hash).GetTx()->vout[txin.prevout.n].scriptPubKey, address))345continue;346grouping.insert(address);347any_mine = true;348}350// group change with input addresses351if (any_mine)352{353for (const CTxOut& txout : wtx.GetTx()->vout)354if (OutputIsChange(wallet, txout))355{356CTxDestination txoutAddr;357if(!ExtractDestination(txout.scriptPubKey, txoutAddr))358continue;359grouping.insert(txoutAddr);360}361}362if (grouping.size() > 0)363{364groupings.insert(grouping);365grouping.clear();366}367}369// group lone addrs by themselves370for (const auto& txout : wtx.GetTx()->vout)371if (wallet.IsMine(txout))372{373CTxDestination address;374if(!ExtractDestination(txout.scriptPubKey, address))375continue;376grouping.insert(address);377groupings.insert(grouping);378grouping.clear();379}380}382std::set< std::set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses383std::map< CTxDestination, std::set<CTxDestination>* > setmap; // map addresses to the unique group containing it384for (const std::set<CTxDestination>& _grouping : groupings)385{386// make a set of all the groups hit by this new group387std::set< std::set<CTxDestination>* > hits;388std::map< CTxDestination, std::set<CTxDestination>* >::iterator it;389for (const CTxDestination& address : _grouping)390if ((it = setmap.find(address)) != setmap.end())391hits.insert((*it).second);393// merge all hit groups into a new single group and delete old groups394std::set<CTxDestination>* merged = new std::set<CTxDestination>(_grouping);395for (std::set<CTxDestination>* hit : hits)396{397merged->insert(hit->begin(), hit->end());398uniqueGroupings.erase(hit);399delete hit;400}401uniqueGroupings.insert(merged);403// update setmap404for (const CTxDestination& element : *merged)405setmap[element] = merged;406}408std::set< std::set<CTxDestination> > ret;409for (const std::set<CTxDestination>* uniqueGrouping : uniqueGroupings)410{411ret.insert(*uniqueGrouping);412delete uniqueGrouping;413}415return ret;416}417} // namespace wallet