carrot_impl: input_count_for_max_usable_money fix
This commit is contained in:
@@ -105,19 +105,19 @@ static void stable_sort_indices_by_block_index(const epee::span<const CarrotPreS
|
|||||||
//-------------------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------------------
|
||||||
static std::pair<size_t, boost::multiprecision::int128_t> input_count_for_max_usable_money(
|
static std::pair<size_t, boost::multiprecision::int128_t> input_count_for_max_usable_money(
|
||||||
const epee::span<const CarrotPreSelectedInput> input_candidates,
|
const epee::span<const CarrotPreSelectedInput> input_candidates,
|
||||||
const std::set<size_t> selectable_inputs,
|
const std::set<size_t> &selectable_inputs,
|
||||||
const std::map<size_t, boost::multiprecision::int128_t> &required_money_by_input_count)
|
const std::map<size_t, rct::xmr_amount> &fee_by_input_count)
|
||||||
{
|
{
|
||||||
// Returns (N, X) where the X is the sum of the amounts of the greatest N <= CARROT_MAX_TX_INPUTS
|
// Returns (N, X) where the X is the sum of the amounts of the greatest N <= CARROT_MAX_TX_INPUTS
|
||||||
// inputs from selectable_inputs, maximizing X - R(N). R(N) is the required money for this
|
// inputs from selectable_inputs, maximizing X - F(N). F(N) is the fee for this transaction,
|
||||||
// transaction, including fee, for given input count N. This should correctly handle "almost-dust":
|
// given input count N. This should correctly handle "almost-dust": inputs which are less than
|
||||||
// inputs which are less than the fee, but greater than or equal to the difference of the fee
|
// the fee, but greater than or equal to the difference of the fee compared to excluding that
|
||||||
// compared to excluding that input. If this function returns N == 0, then there aren't enough
|
// input. If this function returns N == 0, then there aren't enough usable funds, i.e. no N
|
||||||
// usable funds, i.e. no N exists such that X - R(N) > 0.
|
// exists such that X - F(N) > 0.
|
||||||
|
|
||||||
size_t num_ins = 0;
|
size_t num_ins = 0;
|
||||||
boost::multiprecision::int128_t cumulative_input_sum = 0;
|
boost::multiprecision::int128_t cumulative_input_sum = 0;
|
||||||
boost::multiprecision::int128_t last_required_money = 0;
|
rct::xmr_amount last_fee = 0;
|
||||||
|
|
||||||
std::vector<size_t> selectable_inputs_vec(selectable_inputs.cbegin(), selectable_inputs.cend());
|
std::vector<size_t> selectable_inputs_vec(selectable_inputs.cbegin(), selectable_inputs.cend());
|
||||||
stable_sort_indices_by_amount(input_candidates, selectable_inputs_vec);
|
stable_sort_indices_by_amount(input_candidates, selectable_inputs_vec);
|
||||||
@@ -125,13 +125,14 @@ static std::pair<size_t, boost::multiprecision::int128_t> input_count_for_max_us
|
|||||||
// for selectable indices in descending amount...
|
// for selectable indices in descending amount...
|
||||||
for (auto it = selectable_inputs_vec.crbegin(); it != selectable_inputs_vec.crend(); ++it)
|
for (auto it = selectable_inputs_vec.crbegin(); it != selectable_inputs_vec.crend(); ++it)
|
||||||
{
|
{
|
||||||
++num_ins;
|
if (num_ins == CARROT_MAX_TX_INPUTS)
|
||||||
if (num_ins > CARROT_MAX_TX_INPUTS)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
++num_ins;
|
||||||
|
|
||||||
const rct::xmr_amount amount = input_candidates[*it].core.amount;
|
const rct::xmr_amount amount = input_candidates[*it].core.amount;
|
||||||
|
|
||||||
if (amount < required_money_by_input_count.at(num_ins) - last_required_money)
|
if (amount < fee_by_input_count.at(num_ins) - last_fee)
|
||||||
{
|
{
|
||||||
// then this input doesn't pay for itself, rollback previous state and break
|
// then this input doesn't pay for itself, rollback previous state and break
|
||||||
// since all next inputs will have same amount or less
|
// since all next inputs will have same amount or less
|
||||||
@@ -140,6 +141,7 @@ static std::pair<size_t, boost::multiprecision::int128_t> input_count_for_max_us
|
|||||||
}
|
}
|
||||||
|
|
||||||
cumulative_input_sum += amount;
|
cumulative_input_sum += amount;
|
||||||
|
last_fee = fee_by_input_count.at(num_ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {num_ins, cumulative_input_sum};
|
return {num_ins, cumulative_input_sum};
|
||||||
@@ -256,8 +258,9 @@ select_inputs_func_t make_single_transfer_input_selector(
|
|||||||
// Return early if not enough money in this selectable set...
|
// Return early if not enough money in this selectable set...
|
||||||
const auto max_usable_money = input_count_for_max_usable_money(input_candidates,
|
const auto max_usable_money = input_count_for_max_usable_money(input_candidates,
|
||||||
selectable_indices,
|
selectable_indices,
|
||||||
required_money_by_input_count);
|
fee_by_input_count);
|
||||||
const bool enough_money = max_usable_money.first > 0;
|
const bool enough_money = max_usable_money.first > 0
|
||||||
|
&& max_usable_money.second >= required_money_by_input_count.at(max_usable_money.first);
|
||||||
if (!enough_money)
|
if (!enough_money)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user