mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-07-14 20:24:47 +02:00
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`.
This commit is contained in:
@ -433,23 +433,6 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, const std::vec
|
|||||||
|
|
||||||
OutputGroup preset_inputs(coin_selection_params);
|
OutputGroup preset_inputs(coin_selection_params);
|
||||||
|
|
||||||
// coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
|
|
||||||
if (coin_control.HasSelected() && !coin_control.fAllowOtherInputs)
|
|
||||||
{
|
|
||||||
for (const COutput& out : vCoins) {
|
|
||||||
if (!out.spendable) continue;
|
|
||||||
/* Set ancestors and descendants to 0 as these don't matter for preset inputs as no actual selection is being done.
|
|
||||||
* positive_only is set to false because we want to include all preset inputs, even if they are dust.
|
|
||||||
*/
|
|
||||||
preset_inputs.Insert(out, /*ancestors=*/ 0, /*descendants=*/ 0, /*positive_only=*/ false);
|
|
||||||
}
|
|
||||||
SelectionResult result(nTargetValue, SelectionAlgorithm::MANUAL);
|
|
||||||
result.AddInput(preset_inputs);
|
|
||||||
if (result.GetSelectedValue() < nTargetValue) return std::nullopt;
|
|
||||||
result.ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate value from preset inputs and store them
|
// calculate value from preset inputs and store them
|
||||||
std::set<COutPoint> preset_coins;
|
std::set<COutPoint> preset_coins;
|
||||||
|
|
||||||
@ -497,6 +480,15 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, const std::vec
|
|||||||
preset_inputs.Insert(output, /*ancestors=*/ 0, /*descendants=*/ 0, /*positive_only=*/ false);
|
preset_inputs.Insert(output, /*ancestors=*/ 0, /*descendants=*/ 0, /*positive_only=*/ false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
|
||||||
|
if (coin_control.HasSelected() && !coin_control.fAllowOtherInputs) {
|
||||||
|
SelectionResult result(nTargetValue, SelectionAlgorithm::MANUAL);
|
||||||
|
result.AddInput(preset_inputs);
|
||||||
|
if (result.GetSelectedValue() < nTargetValue) return std::nullopt;
|
||||||
|
result.ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// remove preset inputs from vCoins so that Coin Selection doesn't pick them.
|
// remove preset inputs from vCoins so that Coin Selection doesn't pick them.
|
||||||
for (std::vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coin_control.HasSelected();)
|
for (std::vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coin_control.HasSelected();)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user