diff options
author | Andrew Chow <achow101-github@achow101.com> | 2022-01-18 19:03:23 -0500 |
---|---|---|
committer | Andrew Chow <achow101-github@achow101.com> | 2022-03-17 11:04:22 -0400 |
commit | d51f27d3bb0d6e3ca55bcd23ce53e4fe413a9360 (patch) | |
tree | 2be30afe1561e64d9410d8647ee01c238ff0f26f /src | |
parent | b799814bbd53736b79495072f3c9e05989a465e8 (diff) |
wallet: Store whether a COutput is from the wallet
Instead of determining whether the containing transaction is from the
wallet dynamically as needed, just pass it in to COutput and store it.
The transaction ownership isn't going to change.
Diffstat (limited to 'src')
-rw-r--r-- | src/bench/coin_selection.cpp | 2 | ||||
-rw-r--r-- | src/wallet/spend.cpp | 10 | ||||
-rw-r--r-- | src/wallet/spend.h | 8 | ||||
-rw-r--r-- | src/wallet/test/coinselector_tests.cpp | 14 |
4 files changed, 15 insertions, 19 deletions
diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp index 4cbfb05228..d22b335a8b 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<COutput> 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 887a5dae77..cc987e7e65 100644 --- a/src/wallet/spend.cpp +++ b/src/wallet/spend.cpp @@ -158,6 +158,8 @@ void AvailableCoins(const CWallet& wallet, std::vector<COutput>& 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<COutput>& 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<CTxDestination, std::vector<COutput>> 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<OutputGroup> GroupOutputs(const CWallet& wallet, const std::vector<C // Make an OutputGroup containing just this output OutputGroup group{coin_sel_params}; - group.Insert(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); // Check the OutputGroup's eligibility. Only add the eligible ones. if (positive_only && group.GetSelectionAmount() <= 0) continue; @@ -346,7 +348,7 @@ std::vector<OutputGroup> GroupOutputs(const CWallet& wallet, const std::vector<C } // Add the input_coin to group - group->Insert(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 86735fc998..e71e90eaca 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 bcfcfd186a..2293f5793c 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<COutput>& 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<OutputGroup>& GroupCoins(const std::vector<COutput>& 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; } |