Repository: bitcoin/bitcoin
File: src/wallet/coinselection.cpp (C++)

Code before:

    return waste;
}

CAmount GenerateChangeTarget(const CAmount payment_value, const CAmount change_fee, FastRandomContext& rng)
{
    if (payment_value <= CHANGE_LOWER / 2) {
        return change_fee + CHANGE_LOWER;
    } else {
        // random value between 50ksat and min (payment_value * 2, 1milsat)
        const auto upper_bound = std::min(payment_value * 2, CHANGE_UPPER);
        return change_fee + rng.randrange(upper_bound - CHANGE_LOWER) + CHANGE_LOWER;
    }
}

void SelectionResult::SetBumpFeeDiscount(const CAmount discount)
{
    // Overlapping ancestry can only lower the fees, not increase them
    assert (discount >= 0);
    bump_fee_group_discount = discount;
}


void SelectionResult::ComputeAndSetWaste(const CAmount min_viable_change, const CAmount change_cost, const CAmount change_fee)
{
    const CAmount change = GetChange(min_viable_change, change_fee);

    if (change > 0) {
        m_waste = GetSelectionWaste(change_cost, m_target, m_use_effective);
    } else {
        m_waste = GetSelectionWaste(0, m_target, m_use_effective);
    }
}

void SelectionResult::SetAlgoCompleted(bool algo_completed)
{
    m_algo_completed = algo_completed;
}

bool SelectionResult::GetAlgoCompleted() const
{
    return m_algo_completed;
}

void SelectionResult::SetSelectionsEvaluated(size_t attempts)
{
    m_selections_evaluated = attempts;
}

size_t SelectionResult::GetSelectionsEvaluated() const
{

Review comment (refactor):
In 44db79b0c48d6b1a26dba6ab01c2a296d610c06b "Refactor ComputeAndSetWaste()"

nit: Unnecessary parentheses, also usually the check of the value is after the function. Could also use brace initialization.

```suggestion
    bool makes_change{GetChange(min_viable_change, change_fee) != 0};
```

Code after:
    for (const auto& coin_ptr : m_selected_inputs) {
        const COutput& coin = *coin_ptr;
        waste += coin.GetFee() - coin.long_term_fee;
    }
    // Bump fee of whole selection may diverge from sum of individual bump fees
    waste -= bump_fee_group_discount;

    if (GetChange(min_viable_change, change_fee)) {
        // if we have a minimum viable amount after deducting fees, account for
        // cost of creating and spending change
        waste += change_cost;
    } else {
        // When we are not making change (GetChange(…) == 0), consider the excess we are throwing away to fees
        CAmount selected_effective_value = m_use_effective ? GetSelectedEffectiveValue() : GetSelectedValue();
        assert(selected_effective_value >= m_target);
        waste += selected_effective_value - m_target;
    }

    m_waste = waste;
}

void SelectionResult::SetAlgoCompleted(bool algo_completed)
{
    m_algo_completed = algo_completed;
}

bool SelectionResult::GetAlgoCompleted() const
{
    return m_algo_completed;
}

void SelectionResult::SetSelectionsEvaluated(size_t attempts)
{
    m_selections_evaluated = attempts;
}

size_t SelectionResult::GetSelectionsEvaluated() const
{
    return m_selections_evaluated;
}

CAmount SelectionResult::GetWaste() const
{
    return *Assert(m_waste);
}

CAmount SelectionResult::GetSelectedValue() const
{
    return std::accumulate(m_selected_inputs.cbegin(), m_selected_inputs.cend(), CAmount{0}, [](CAmount sum, const auto& coin) { return sum + coin->txout.nValue; });
}