Skip to content

Commit 1a1574b

Browse files
committed
wallet: fix silent payment change output not found during scanning
The bug was caused by generating change output separately, causing `CreateSilentPaymentOutputs` to use `k = 0` for multiple outputs
1 parent 8ee0352 commit 1a1574b

File tree

2 files changed

+17
-14
lines changed

2 files changed

+17
-14
lines changed

src/wallet/spend.cpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,11 +1304,20 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
13041304
sp_dests[i] = *sp;
13051305
}
13061306
}
1307+
if (const auto* change_sp = std::get_if<V0SilentPaymentDestination>(&change_dest)) {
1308+
// Generate output for change too
1309+
sp_dests[mutableVecSend.size()] = *change_sp;
1310+
}
13071311
const auto& silent_payment_tr_spks = CreateSilentPaymentOutputs(wallet, sp_dests, result.GetInputSet(), error);
13081312
if (!silent_payment_tr_spks.has_value()) {
13091313
return util::Error{error};
13101314
}
13111315
for (const auto& [out_idx, tr_dest] : *silent_payment_tr_spks) {
1316+
if (out_idx == mutableVecSend.size()) {
1317+
change_dest = tr_dest;
1318+
continue;
1319+
}
1320+
13121321
assert(out_idx < mutableVecSend.size());
13131322
mutableVecSend[out_idx].dest = tr_dest;
13141323
}
@@ -1324,16 +1333,6 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
13241333
if (!IsValidDestination(change_dest)) {
13251334
return util::Error{error};
13261335
}
1327-
if (const auto* sp = std::get_if<V0SilentPaymentDestination>(&change_dest)) {
1328-
// Since we will be getting the final destination
1329-
// for only the change output, the index doesn't matter.
1330-
std::map<size_t, V0SilentPaymentDestination> change_sp_dest;
1331-
change_sp_dest[0] = *sp;
1332-
auto taproot_change = CreateSilentPaymentOutputs(wallet, change_sp_dest, result.GetInputSet(), error);
1333-
if (taproot_change.has_value()) {
1334-
change_dest = taproot_change->at(0);
1335-
}
1336-
}
13371336

13381337
CScript change_script = GetScriptForDestination(change_dest);
13391338
Assert(!change_script.empty());
@@ -1537,7 +1536,8 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
15371536
if (wallet.IsMine(*tx, spent_coins))
15381537
wallet.WalletLogPrintf("Detected Silent Payments self-transfer: %s", tx->GetHash().ToString());
15391538
}
1540-
return CreatedTransactionResult(tx, current_fee, change_pos, feeCalc);
1539+
LogPrintf("change_type: %s", FormatOutputType(change_type));
1540+
return CreatedTransactionResult(tx, current_fee, change_pos, change_type, feeCalc);
15411541
}
15421542

15431543
util::Result<CreatedTransactionResult> CreateTransaction(
@@ -1572,7 +1572,9 @@ util::Result<CreatedTransactionResult> CreateTransaction(
15721572
tmp_cc.m_avoid_partial_spends = true;
15731573

15741574
// Reuse the change destination from the first creation attempt to avoid skipping BIP44 indexes
1575-
if (txr_ungrouped.change_pos) {
1575+
// Do not reuse the change dest if it came from a silent payments destination
1576+
// silent payments change dest must be generated with the other silent payment outputs
1577+
if (txr_ungrouped.change_pos && txr_ungrouped.change_type != OutputType::SILENT_PAYMENTS) {
15761578
ExtractDestination(txr_ungrouped.tx->vout[*txr_ungrouped.change_pos].scriptPubKey, tmp_cc.destChange);
15771579
}
15781580

src/wallet/spend.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,10 @@ struct CreatedTransactionResult
208208
CAmount fee;
209209
FeeCalculation fee_calc;
210210
std::optional<unsigned int> change_pos;
211+
OutputType change_type;
211212

212-
CreatedTransactionResult(CTransactionRef _tx, CAmount _fee, std::optional<unsigned int> _change_pos, const FeeCalculation& _fee_calc)
213-
: tx(_tx), fee(_fee), fee_calc(_fee_calc), change_pos(_change_pos) {}
213+
CreatedTransactionResult(CTransactionRef _tx, CAmount _fee, std::optional<unsigned int> _change_pos, const OutputType change_type, const FeeCalculation& _fee_calc)
214+
: tx(_tx), fee(_fee), fee_calc(_fee_calc), change_pos(_change_pos), change_type(change_type) {}
214215
};
215216

216217
/**

0 commit comments

Comments
 (0)