aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2022-01-18 19:03:23 -0500
committerAndrew Chow <achow101-github@achow101.com>2022-03-17 11:04:22 -0400
commitd51f27d3bb0d6e3ca55bcd23ce53e4fe413a9360 (patch)
tree2be30afe1561e64d9410d8647ee01c238ff0f26f /src/wallet
parentb799814bbd53736b79495072f3c9e05989a465e8 (diff)
downloadbitcoin-d51f27d3bb0d6e3ca55bcd23ce53e4fe413a9360.tar.xz
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/wallet')
-rw-r--r--src/wallet/spend.cpp10
-rw-r--r--src/wallet/spend.h8
-rw-r--r--src/wallet/test/coinselector_tests.cpp14
3 files changed, 14 insertions, 18 deletions
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;
}