wallet: account for preselected inputs in target

When we have preselected inputs the coin selection search target is reduced
by the sum of (effective) values. This causes incorrect m_target value.

Create separate instance of SelectionResult for all the preselected inputs and
set the target equal to the sum of (effective) values. Target for preselected
SelectionResult is equal to the delta for the search target. To get the final
SelectionResult with accurate m_target we merge both SelectionResult instances.
This commit is contained in:
S3RK 2022-07-06 08:15:20 +02:00
parent f8e796348b
commit e3210a7225

View File

@ -607,12 +607,15 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& a
Shuffle(available_coins.other.begin(), available_coins.other.end(), coin_selection_params.rng_fast);
}
SelectionResult preselected(preset_inputs.GetSelectionAmount(), SelectionAlgorithm::MANUAL);
preselected.AddInput(preset_inputs);
// Coin Selection attempts to select inputs from a pool of eligible UTXOs to fund the
// transaction at a target feerate. If an attempt fails, more attempts may be made using a more
// permissive CoinEligibilityFilter.
std::optional<SelectionResult> res = [&] {
// Pre-selected inputs already cover the target amount.
if (value_to_select <= 0) return std::make_optional(SelectionResult(nTargetValue, SelectionAlgorithm::MANUAL));
if (value_to_select <= 0) return std::make_optional(SelectionResult(value_to_select, SelectionAlgorithm::MANUAL));
// If possible, fund the transaction with confirmed UTXOs only. Prefer at least six
// confirmations on outputs received from other wallets and only spend confirmed change.
@ -666,7 +669,7 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& a
if (!res) return std::nullopt;
// Add preset inputs to result
res->AddInput(preset_inputs);
res->Merge(preselected);
if (res->GetAlgo() == SelectionAlgorithm::MANUAL) {
res->ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
}