Skip to content

Commit b4e2d4d

Browse files
committed
wallet: move "use-only coinControl inputs" below the selected inputs lookup
Otherwise, RPC commands such as `walletcreatefundedpsbt` will not support the manual selection of locked, spent and externally added coins. Full explanation is inside #25118 comments but brief summary is: `vCoins` at `SelectCoins` time could not be containing the manually selected input because, even when they were selected by the user, the current `AvailableCoins` flow skips locked and spent coins. Extra note: this is an intermediate step to unify the `fAllowOtherInputs`/`m_add_inputs` concepts. It will not be a problem anymore in the future when we finally decouple the wtx-outputs lookup process from `SelectCoins` and don't skip the user's manually selected coins in `AvailableCoins`.
1 parent 25749f1 commit b4e2d4d

File tree

1 file changed

+9
-17
lines changed

1 file changed

+9
-17
lines changed

src/wallet/spend.cpp

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -433,23 +433,6 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, const std::vec
433433

434434
OutputGroup preset_inputs(coin_selection_params);
435435

436-
// coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
437-
if (coin_control.HasSelected() && !coin_control.fAllowOtherInputs)
438-
{
439-
for (const COutput& out : vCoins) {
440-
if (!out.spendable) continue;
441-
/* Set ancestors and descendants to 0 as these don't matter for preset inputs as no actual selection is being done.
442-
* positive_only is set to false because we want to include all preset inputs, even if they are dust.
443-
*/
444-
preset_inputs.Insert(out, /*ancestors=*/ 0, /*descendants=*/ 0, /*positive_only=*/ false);
445-
}
446-
SelectionResult result(nTargetValue, SelectionAlgorithm::MANUAL);
447-
result.AddInput(preset_inputs);
448-
if (result.GetSelectedValue() < nTargetValue) return std::nullopt;
449-
result.ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
450-
return result;
451-
}
452-
453436
// calculate value from preset inputs and store them
454437
std::set<COutPoint> preset_coins;
455438

@@ -497,6 +480,15 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, const std::vec
497480
preset_inputs.Insert(output, /*ancestors=*/ 0, /*descendants=*/ 0, /*positive_only=*/ false);
498481
}
499482

483+
// coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
484+
if (coin_control.HasSelected() && !coin_control.fAllowOtherInputs) {
485+
SelectionResult result(nTargetValue, SelectionAlgorithm::MANUAL);
486+
result.AddInput(preset_inputs);
487+
if (result.GetSelectedValue() < nTargetValue) return std::nullopt;
488+
result.ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
489+
return result;
490+
}
491+
500492
// remove preset inputs from vCoins so that Coin Selection doesn't pick them.
501493
for (std::vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coin_control.HasSelected();)
502494
{

0 commit comments

Comments
 (0)