diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp index 4cbfb05228d..d22b335a8b6 100644 --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -58,7 +58,7 @@ static void CoinSelection(benchmark::Bench& bench) // Create coins std::vector coins; for (const auto& wtx : wtxs) { - coins.emplace_back(wallet, *wtx, /*iIn=*/ 0, /*depth=*/ 6 * 24, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, wtx->GetTxTime(), /*use_max_sig_in=*/ false); + coins.emplace_back(wallet, *wtx, /*iIn=*/ 0, /*depth=*/ 6 * 24, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, wtx->GetTxTime(), /*from_me=*/ true, /*use_max_sig_in=*/ false); } const CoinEligibilityFilter filter_standard(1, 6, 0); diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp index 887a5dae772..cc987e7e653 100644 --- a/src/wallet/spend.cpp +++ b/src/wallet/spend.cpp @@ -158,6 +158,8 @@ void AvailableCoins(const CWallet& wallet, std::vector& vCoins, const C continue; } + bool tx_from_me = CachedTxIsFromMe(wallet, wtx, ISMINE_ALL); + for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) { // Only consider selected coins if add_inputs is false if (coinControl && !coinControl->m_add_inputs && !coinControl->IsSelected(COutPoint(entry.first, i))) { @@ -191,7 +193,7 @@ void AvailableCoins(const CWallet& wallet, std::vector& vCoins, const C bool solvable = provider ? IsSolvable(*provider, wtx.tx->vout[i].scriptPubKey) : false; bool spendable = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable)); - vCoins.emplace_back(wallet, wtx, i, nDepth, spendable, solvable, safeTx, wtx.GetTxTime(), /*use_max_sig_in=*/ (coinControl && coinControl->fAllowWatchOnly)); + vCoins.emplace_back(wallet, wtx, i, nDepth, spendable, solvable, safeTx, wtx.GetTxTime(), tx_from_me, /*use_max_sig_in=*/ (coinControl && coinControl->fAllowWatchOnly)); // Checks the sum amount of all UTXO's. if (nMinimumSumAmount != MAX_MONEY) { @@ -276,7 +278,7 @@ std::map> ListCoins(const CWallet& wallet) CTxDestination address; if (ExtractDestination(FindNonChangeParentOutput(wallet, *wtx.tx, output.n).scriptPubKey, address)) { result[address].emplace_back( - wallet, wtx, output.n, depth, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ false, wtx.GetTxTime(), /*use_max_sig_in=*/ false); + wallet, wtx, output.n, depth, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ false, wtx.GetTxTime(), CachedTxIsFromMe(wallet, wtx, ISMINE_ALL), /*use_max_sig_in=*/ false); } } } @@ -301,7 +303,7 @@ std::vector GroupOutputs(const CWallet& wallet, const std::vector GroupOutputs(const CWallet& wallet, const std::vectorInsert(input_coin, output.depth, CachedTxIsFromMe(wallet, *output.tx, ISMINE_ALL), ancestors, descendants, positive_only); + group->Insert(input_coin, output.depth, output.from_me, ancestors, descendants, positive_only); } // Now we go through the entire map and pull out the OutputGroups diff --git a/src/wallet/spend.h b/src/wallet/spend.h index 86735fc998e..e71e90eaca0 100644 --- a/src/wallet/spend.h +++ b/src/wallet/spend.h @@ -51,7 +51,10 @@ public: /** The time of the transaction containing this output as determined by CWalletTx::nTimeSmart */ int64_t time; - COutput(const CWallet& wallet, const CWalletTx& wtx, int iIn, int depth, bool spendable, bool solvable, bool safe, int64_t time, bool use_max_sig_in) + /** Whether the transaction containing this output is sent from the owning wallet */ + bool from_me; + + COutput(const CWallet& wallet, const CWalletTx& wtx, int iIn, int depth, bool spendable, bool solvable, bool safe, int64_t time, bool from_me, bool use_max_sig_in) : tx(&wtx), i(iIn), depth(depth), @@ -60,7 +63,8 @@ public: solvable(solvable), use_max_sig(use_max_sig_in), safe(safe), - time(time) + time(time), + from_me(from_me) { // If known and signable by the given wallet, compute input_bytes // Failure will keep this value -1 diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp index bcfcfd186a8..2293f5793cb 100644 --- a/src/wallet/test/coinselector_tests.cpp +++ b/src/wallet/test/coinselector_tests.cpp @@ -82,23 +82,13 @@ static void add_coin(std::vector& coins, CWallet& wallet, const CAmount assert(destination_ok); tx.vout[nInput].scriptPubKey = GetScriptForDestination(dest); } - if (fIsFromMe) { - // IsFromMe() returns (GetDebit() > 0), and GetDebit() is 0 if vin.empty(), - // so stop vin being empty, and cache a non-zero Debit to fake out IsFromMe() - tx.vin.resize(1); - } uint256 txid = tx.GetHash(); LOCK(wallet.cs_wallet); auto ret = wallet.mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(txid), std::forward_as_tuple(MakeTransactionRef(std::move(tx)), TxStateInactive{})); assert(ret.second); CWalletTx& wtx = (*ret.first).second; - if (fIsFromMe) - { - wtx.m_amounts[CWalletTx::DEBIT].Set(ISMINE_SPENDABLE, 1); - wtx.m_is_cache_empty = false; - } - coins.emplace_back(wallet, wtx, nInput, nAge, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, wtx.GetTxTime(), /*use_max_sig_in=*/ false); + coins.emplace_back(wallet, wtx, nInput, nAge, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, wtx.GetTxTime(), fIsFromMe, /*use_max_sig_in=*/ false); } /** Check if SelectionResult a is equivalent to SelectionResult b. @@ -156,7 +146,7 @@ inline std::vector& GroupCoins(const std::vector& coins) static_groups.clear(); for (auto& coin : coins) { static_groups.emplace_back(); - static_groups.back().Insert(coin.GetInputCoin(), coin.depth, coin.tx->m_amounts[CWalletTx::DEBIT].m_cached[ISMINE_SPENDABLE] && coin.tx->m_amounts[CWalletTx::DEBIT].m_value[ISMINE_SPENDABLE] == 1 /* HACK: we can't figure out the is_me flag so we use the conditions defined above; perhaps set safe to false for !fIsFromMe in add_coin() */, 0, 0, false); + static_groups.back().Insert(coin.GetInputCoin(), coin.depth, coin.from_me, 0, 0, false); } return static_groups; }