@@ -2202,108 +2202,105 @@ void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, const
22022202 AssertLockHeld (cs_wallet);
22032203
22042204 vCoins.clear ();
2205+ CAmount nTotal = 0 ;
22052206
2207+ for (const auto & entry : mapWallet)
22062208 {
2207- CAmount nTotal = 0 ;
2209+ const uint256& wtxid = entry.first ;
2210+ const CWalletTx* pcoin = &entry.second ;
22082211
2209- for (const auto & entry : mapWallet)
2210- {
2211- const uint256& wtxid = entry.first ;
2212- const CWalletTx* pcoin = &entry.second ;
2212+ if (!CheckFinalTx (*pcoin->tx ))
2213+ continue ;
22132214
2214- if (! CheckFinalTx (* pcoin->tx ) )
2215- continue ;
2215+ if (pcoin-> IsCoinBase () && pcoin->GetBlocksToMaturity () > 0 )
2216+ continue ;
22162217
2217- if (pcoin->IsCoinBase () && pcoin->GetBlocksToMaturity () > 0 )
2218- continue ;
2218+ int nDepth = pcoin->GetDepthInMainChain ();
2219+ if (nDepth < 0 )
2220+ continue ;
22192221
2220- int nDepth = pcoin->GetDepthInMainChain ();
2221- if (nDepth < 0 )
2222- continue ;
2222+ // We should not consider coins which aren't at least in our mempool
2223+ // It's possible for these to be conflicted via ancestors which we may never be able to detect
2224+ if (nDepth == 0 && !pcoin->InMempool ())
2225+ continue ;
22232226
2224- // We should not consider coins which aren't at least in our mempool
2225- // It's possible for these to be conflicted via ancestors which we may never be able to detect
2226- if (nDepth == 0 && !pcoin->InMempool ())
2227- continue ;
2227+ bool safeTx = pcoin->IsTrusted ();
2228+
2229+ // We should not consider coins from transactions that are replacing
2230+ // other transactions.
2231+ //
2232+ // Example: There is a transaction A which is replaced by bumpfee
2233+ // transaction B. In this case, we want to prevent creation of
2234+ // a transaction B' which spends an output of B.
2235+ //
2236+ // Reason: If transaction A were initially confirmed, transactions B
2237+ // and B' would no longer be valid, so the user would have to create
2238+ // a new transaction C to replace B'. However, in the case of a
2239+ // one-block reorg, transactions B' and C might BOTH be accepted,
2240+ // when the user only wanted one of them. Specifically, there could
2241+ // be a 1-block reorg away from the chain where transactions A and C
2242+ // were accepted to another chain where B, B', and C were all
2243+ // accepted.
2244+ if (nDepth == 0 && pcoin->mapValue .count (" replaces_txid" )) {
2245+ safeTx = false ;
2246+ }
22282247
2229- bool safeTx = pcoin->IsTrusted ();
2230-
2231- // We should not consider coins from transactions that are replacing
2232- // other transactions.
2233- //
2234- // Example: There is a transaction A which is replaced by bumpfee
2235- // transaction B. In this case, we want to prevent creation of
2236- // a transaction B' which spends an output of B.
2237- //
2238- // Reason: If transaction A were initially confirmed, transactions B
2239- // and B' would no longer be valid, so the user would have to create
2240- // a new transaction C to replace B'. However, in the case of a
2241- // one-block reorg, transactions B' and C might BOTH be accepted,
2242- // when the user only wanted one of them. Specifically, there could
2243- // be a 1-block reorg away from the chain where transactions A and C
2244- // were accepted to another chain where B, B', and C were all
2245- // accepted.
2246- if (nDepth == 0 && pcoin->mapValue .count (" replaces_txid" )) {
2247- safeTx = false ;
2248- }
2248+ // Similarly, we should not consider coins from transactions that
2249+ // have been replaced. In the example above, we would want to prevent
2250+ // creation of a transaction A' spending an output of A, because if
2251+ // transaction B were initially confirmed, conflicting with A and
2252+ // A', we wouldn't want to the user to create a transaction D
2253+ // intending to replace A', but potentially resulting in a scenario
2254+ // where A, A', and D could all be accepted (instead of just B and
2255+ // D, or just A and A' like the user would want).
2256+ if (nDepth == 0 && pcoin->mapValue .count (" replaced_by_txid" )) {
2257+ safeTx = false ;
2258+ }
22492259
2250- // Similarly, we should not consider coins from transactions that
2251- // have been replaced. In the example above, we would want to prevent
2252- // creation of a transaction A' spending an output of A, because if
2253- // transaction B were initially confirmed, conflicting with A and
2254- // A', we wouldn't want to the user to create a transaction D
2255- // intending to replace A', but potentially resulting in a scenario
2256- // where A, A', and D could all be accepted (instead of just B and
2257- // D, or just A and A' like the user would want).
2258- if (nDepth == 0 && pcoin->mapValue .count (" replaced_by_txid" )) {
2259- safeTx = false ;
2260- }
2260+ if (fOnlySafe && !safeTx) {
2261+ continue ;
2262+ }
22612263
2262- if (fOnlySafe && !safeTx) {
2263- continue ;
2264- }
2264+ if (nDepth < nMinDepth || nDepth > nMaxDepth)
2265+ continue ;
22652266
2266- if (nDepth < nMinDepth || nDepth > nMaxDepth)
2267+ for (unsigned int i = 0 ; i < pcoin->tx ->vout .size (); i++) {
2268+ if (pcoin->tx ->vout [i].nValue < nMinimumAmount || pcoin->tx ->vout [i].nValue > nMaximumAmount)
22672269 continue ;
22682270
2269- for (unsigned int i = 0 ; i < pcoin->tx ->vout .size (); i++) {
2270- if (pcoin->tx ->vout [i].nValue < nMinimumAmount || pcoin->tx ->vout [i].nValue > nMaximumAmount)
2271- continue ;
2272-
2273- if (coinControl && coinControl->HasSelected () && !coinControl->fAllowOtherInputs && !coinControl->IsSelected (COutPoint (entry.first , i)))
2274- continue ;
2275-
2276- if (IsLockedCoin (entry.first , i))
2277- continue ;
2271+ if (coinControl && coinControl->HasSelected () && !coinControl->fAllowOtherInputs && !coinControl->IsSelected (COutPoint (entry.first , i)))
2272+ continue ;
22782273
2279- if (IsSpent (wtxid , i))
2280- continue ;
2274+ if (IsLockedCoin (entry. first , i))
2275+ continue ;
22812276
2282- isminetype mine = IsMine (pcoin->tx ->vout [i]);
2277+ if (IsSpent (wtxid, i))
2278+ continue ;
22832279
2284- if (mine == ISMINE_NO) {
2285- continue ;
2286- }
2280+ isminetype mine = IsMine (pcoin->tx ->vout [i]);
22872281
2288- bool fSpendableIn = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (coinControl && coinControl->fAllowWatchOnly && (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO);
2289- bool fSolvableIn = (mine & (ISMINE_SPENDABLE | ISMINE_WATCH_SOLVABLE)) != ISMINE_NO;
2282+ if (mine == ISMINE_NO) {
2283+ continue ;
2284+ }
22902285
2291- vCoins.push_back (COutput (pcoin, i, nDepth, fSpendableIn , fSolvableIn , safeTx));
2286+ bool fSpendableIn = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (coinControl && coinControl->fAllowWatchOnly && (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO);
2287+ bool fSolvableIn = (mine & (ISMINE_SPENDABLE | ISMINE_WATCH_SOLVABLE)) != ISMINE_NO;
22922288
2293- // Checks the sum amount of all UTXO's.
2294- if (nMinimumSumAmount != MAX_MONEY) {
2295- nTotal += pcoin->tx ->vout [i].nValue ;
2289+ vCoins.push_back (COutput (pcoin, i, nDepth, fSpendableIn , fSolvableIn , safeTx));
22962290
2297- if (nTotal >= nMinimumSumAmount) {
2298- return ;
2299- }
2300- }
2291+ // Checks the sum amount of all UTXO's.
2292+ if (nMinimumSumAmount != MAX_MONEY) {
2293+ nTotal += pcoin->tx ->vout [i].nValue ;
23012294
2302- // Checks the maximum number of UTXO's.
2303- if (nMaximumCount > 0 && vCoins.size () >= nMaximumCount) {
2295+ if (nTotal >= nMinimumSumAmount) {
23042296 return ;
23052297 }
23062298 }
2299+
2300+ // Checks the maximum number of UTXO's.
2301+ if (nMaximumCount > 0 && vCoins.size () >= nMaximumCount) {
2302+ return ;
2303+ }
23072304 }
23082305 }
23092306}
0 commit comments