wallet: add SelectionResult::GetChange

This commit is contained in:
S3RK 2022-07-06 09:00:26 +02:00
parent 72cad28da0
commit 15e97a6886
2 changed files with 46 additions and 0 deletions

View file

@ -421,6 +421,11 @@ 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; });
}
CAmount SelectionResult::GetSelectedEffectiveValue() const
{
return std::accumulate(m_selected_inputs.cbegin(), m_selected_inputs.cend(), CAmount{0}, [](CAmount sum, const auto& coin) { return sum + coin.GetEffectiveValue(); });
}
void SelectionResult::Clear()
{
m_selected_inputs.clear();
@ -480,4 +485,24 @@ std::string GetAlgorithmName(const SelectionAlgorithm algo)
}
assert(false);
}
CAmount SelectionResult::GetChange(const CAmount min_viable_change, const CAmount change_fee) const
{
// change = SUM(inputs) - SUM(outputs) - fees
// 1) With SFFO we don't pay any fees
// 2) Otherwise we pay all the fees:
// - input fees are covered by GetSelectedEffectiveValue()
// - non_input_fee is included in m_target
// - change_fee
const CAmount change = m_use_effective
? GetSelectedEffectiveValue() - m_target - change_fee
: GetSelectedValue() - m_target;
if (change < min_viable_change) {
return 0;
}
return change;
}
} // namespace wallet

View file

@ -303,6 +303,8 @@ public:
/** Get the sum of the input values */
[[nodiscard]] CAmount GetSelectedValue() const;
[[nodiscard]] CAmount GetSelectedEffectiveValue() const;
void Clear();
void AddInput(const OutputGroup& group);
@ -320,6 +322,25 @@ public:
bool operator<(SelectionResult other) const;
/** Get the amount for the change output after paying needed fees.
*
* The change amount is not 100% precise due to discrepancies in fee calculation.
* The final change amount (if any) should be corrected after calculating the final tx fees.
* When there is a discrepancy, most of the time the final change would be slightly bigger than estimated.
*
* Following are the possible factors of discrepancy:
* + non-input fees always include segwit flags
* + input fee estimation always include segwit stack size
* + input fees are rounded individually and not collectively, which leads to small rounding errors
* - input counter size is always assumed to be 1vbyte
*
* @param[in] min_viable_change Minimum amount for change output, if change would be less then we forgo change
* @param[in] change_fee Fees to include change output in the tx
* @returns Amount for change output, 0 when there is no change.
*
*/
CAmount GetChange(const CAmount min_viable_change, const CAmount change_fee) const;
CAmount GetTarget() const { return m_target; }
SelectionAlgorithm GetAlgo() const { return m_algo; }