Skip to content

Commit d51f27d

Browse files
committed
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.
1 parent b799814 commit d51f27d

File tree

4 files changed

+15
-19
lines changed

4 files changed

+15
-19
lines changed

src/bench/coin_selection.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ static void CoinSelection(benchmark::Bench& bench)
5858
// Create coins
5959
std::vector<COutput> coins;
6060
for (const auto& wtx : wtxs) {
61-
coins.emplace_back(wallet, *wtx, /*iIn=*/ 0, /*depth=*/ 6 * 24, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, wtx->GetTxTime(), /*use_max_sig_in=*/ false);
61+
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);
6262
}
6363

6464
const CoinEligibilityFilter filter_standard(1, 6, 0);

src/wallet/spend.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ void AvailableCoins(const CWallet& wallet, std::vector<COutput>& vCoins, const C
158158
continue;
159159
}
160160

161+
bool tx_from_me = CachedTxIsFromMe(wallet, wtx, ISMINE_ALL);
162+
161163
for (unsigned int i = 0; i < wtx.tx->vout.size(); i++) {
162164
// Only consider selected coins if add_inputs is false
163165
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
191193
bool solvable = provider ? IsSolvable(*provider, wtx.tx->vout[i].scriptPubKey) : false;
192194
bool spendable = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) || (((mine & ISMINE_WATCH_ONLY) != ISMINE_NO) && (coinControl && coinControl->fAllowWatchOnly && solvable));
193195

194-
vCoins.emplace_back(wallet, wtx, i, nDepth, spendable, solvable, safeTx, wtx.GetTxTime(), /*use_max_sig_in=*/ (coinControl && coinControl->fAllowWatchOnly));
196+
vCoins.emplace_back(wallet, wtx, i, nDepth, spendable, solvable, safeTx, wtx.GetTxTime(), tx_from_me, /*use_max_sig_in=*/ (coinControl && coinControl->fAllowWatchOnly));
195197

196198
// Checks the sum amount of all UTXO's.
197199
if (nMinimumSumAmount != MAX_MONEY) {
@@ -276,7 +278,7 @@ std::map<CTxDestination, std::vector<COutput>> ListCoins(const CWallet& wallet)
276278
CTxDestination address;
277279
if (ExtractDestination(FindNonChangeParentOutput(wallet, *wtx.tx, output.n).scriptPubKey, address)) {
278280
result[address].emplace_back(
279-
wallet, wtx, output.n, depth, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ false, wtx.GetTxTime(), /*use_max_sig_in=*/ false);
281+
wallet, wtx, output.n, depth, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ false, wtx.GetTxTime(), CachedTxIsFromMe(wallet, wtx, ISMINE_ALL), /*use_max_sig_in=*/ false);
280282
}
281283
}
282284
}
@@ -301,7 +303,7 @@ std::vector<OutputGroup> GroupOutputs(const CWallet& wallet, const std::vector<C
301303

302304
// Make an OutputGroup containing just this output
303305
OutputGroup group{coin_sel_params};
304-
group.Insert(input_coin, output.depth, CachedTxIsFromMe(wallet, *output.tx, ISMINE_ALL), ancestors, descendants, positive_only);
306+
group.Insert(input_coin, output.depth, output.from_me, ancestors, descendants, positive_only);
305307

306308
// Check the OutputGroup's eligibility. Only add the eligible ones.
307309
if (positive_only && group.GetSelectionAmount() <= 0) continue;
@@ -346,7 +348,7 @@ std::vector<OutputGroup> GroupOutputs(const CWallet& wallet, const std::vector<C
346348
}
347349

348350
// Add the input_coin to group
349-
group->Insert(input_coin, output.depth, CachedTxIsFromMe(wallet, *output.tx, ISMINE_ALL), ancestors, descendants, positive_only);
351+
group->Insert(input_coin, output.depth, output.from_me, ancestors, descendants, positive_only);
350352
}
351353

352354
// Now we go through the entire map and pull out the OutputGroups

src/wallet/spend.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ class COutput
5151
/** The time of the transaction containing this output as determined by CWalletTx::nTimeSmart */
5252
int64_t time;
5353

54-
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)
54+
/** Whether the transaction containing this output is sent from the owning wallet */
55+
bool from_me;
56+
57+
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)
5558
: tx(&wtx),
5659
i(iIn),
5760
depth(depth),
@@ -60,7 +63,8 @@ class COutput
6063
solvable(solvable),
6164
use_max_sig(use_max_sig_in),
6265
safe(safe),
63-
time(time)
66+
time(time),
67+
from_me(from_me)
6468
{
6569
// If known and signable by the given wallet, compute input_bytes
6670
// Failure will keep this value -1

src/wallet/test/coinselector_tests.cpp

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,23 +82,13 @@ static void add_coin(std::vector<COutput>& coins, CWallet& wallet, const CAmount
8282
assert(destination_ok);
8383
tx.vout[nInput].scriptPubKey = GetScriptForDestination(dest);
8484
}
85-
if (fIsFromMe) {
86-
// IsFromMe() returns (GetDebit() > 0), and GetDebit() is 0 if vin.empty(),
87-
// so stop vin being empty, and cache a non-zero Debit to fake out IsFromMe()
88-
tx.vin.resize(1);
89-
}
9085
uint256 txid = tx.GetHash();
9186

9287
LOCK(wallet.cs_wallet);
9388
auto ret = wallet.mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(txid), std::forward_as_tuple(MakeTransactionRef(std::move(tx)), TxStateInactive{}));
9489
assert(ret.second);
9590
CWalletTx& wtx = (*ret.first).second;
96-
if (fIsFromMe)
97-
{
98-
wtx.m_amounts[CWalletTx::DEBIT].Set(ISMINE_SPENDABLE, 1);
99-
wtx.m_is_cache_empty = false;
100-
}
101-
coins.emplace_back(wallet, wtx, nInput, nAge, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, wtx.GetTxTime(), /*use_max_sig_in=*/ false);
91+
coins.emplace_back(wallet, wtx, nInput, nAge, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, wtx.GetTxTime(), fIsFromMe, /*use_max_sig_in=*/ false);
10292
}
10393

10494
/** Check if SelectionResult a is equivalent to SelectionResult b.
@@ -156,7 +146,7 @@ inline std::vector<OutputGroup>& GroupCoins(const std::vector<COutput>& coins)
156146
static_groups.clear();
157147
for (auto& coin : coins) {
158148
static_groups.emplace_back();
159-
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);
149+
static_groups.back().Insert(coin.GetInputCoin(), coin.depth, coin.from_me, 0, 0, false);
160150
}
161151
return static_groups;
162152
}

0 commit comments

Comments
 (0)