wallet2: fix infinite loop in fake out selection

The gamma picker and the caller code did not quite agree on the
number of rct outputs available for use - by one block - which
caused an infinite loop if the picker could never pick outputs
from that block but already had picked all other outputs from
previous blocks.

Also change the range to select from using code from UkoeHB.
This commit is contained in:
Crypto City 2023-03-21 09:02:38 +00:00 committed by moneromooo-monero
parent 25645e5d23
commit 132804811d
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
2 changed files with 4 additions and 3 deletions

View file

@ -1005,7 +1005,7 @@ gamma_picker::gamma_picker(const std::vector<uint64_t> &rct_offsets, double shap
const size_t blocks_to_consider = std::min<size_t>(rct_offsets.size(), blocks_in_a_year); const size_t blocks_to_consider = std::min<size_t>(rct_offsets.size(), blocks_in_a_year);
const size_t outputs_to_consider = rct_offsets.back() - (blocks_to_consider < rct_offsets.size() ? rct_offsets[rct_offsets.size() - blocks_to_consider - 1] : 0); const size_t outputs_to_consider = rct_offsets.back() - (blocks_to_consider < rct_offsets.size() ? rct_offsets[rct_offsets.size() - blocks_to_consider - 1] : 0);
begin = rct_offsets.data(); begin = rct_offsets.data();
end = rct_offsets.data() + rct_offsets.size() - CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE; end = rct_offsets.data() + rct_offsets.size() - (std::max(1, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE) - 1);
num_rct_outputs = *(end - 1); num_rct_outputs = *(end - 1);
THROW_WALLET_EXCEPTION_IF(num_rct_outputs == 0, error::wallet_internal_error, "No rct outputs"); THROW_WALLET_EXCEPTION_IF(num_rct_outputs == 0, error::wallet_internal_error, "No rct outputs");
average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / static_cast<double>(outputs_to_consider); // this assumes constant target over the whole rct range average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / static_cast<double>(outputs_to_consider); // this assumes constant target over the whole rct range
@ -8408,7 +8408,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
else else
{ {
// the base offset of the first rct output in the first unlocked block (or the one to be if there's none) // the base offset of the first rct output in the first unlocked block (or the one to be if there's none)
num_outs = rct_offsets[rct_offsets.size() - CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE]; num_outs = gamma->get_num_rct_outs();
LOG_PRINT_L1("" << num_outs << " unlocked rct outputs"); LOG_PRINT_L1("" << num_outs << " unlocked rct outputs");
THROW_WALLET_EXCEPTION_IF(num_outs == 0, error::wallet_internal_error, THROW_WALLET_EXCEPTION_IF(num_outs == 0, error::wallet_internal_error,
"histogram reports no unlocked rct outputs, not even ours"); "histogram reports no unlocked rct outputs, not even ours");
@ -8692,7 +8692,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
} }
bool use_histogram = amount != 0; bool use_histogram = amount != 0;
if (!use_histogram) if (!use_histogram)
num_outs = rct_offsets[rct_offsets.size() - CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE]; num_outs = gamma->get_num_rct_outs();
// make sure the real outputs we asked for are really included, along // make sure the real outputs we asked for are really included, along
// with the correct key and mask: this guards against an active attack // with the correct key and mask: this guards against an active attack

View file

@ -101,6 +101,7 @@ namespace tools
uint64_t pick(); uint64_t pick();
gamma_picker(const std::vector<uint64_t> &rct_offsets); gamma_picker(const std::vector<uint64_t> &rct_offsets);
gamma_picker(const std::vector<uint64_t> &rct_offsets, double shape, double scale); gamma_picker(const std::vector<uint64_t> &rct_offsets, double shape, double scale);
uint64_t get_num_rct_outs() const { return num_rct_outputs; }
private: private:
struct gamma_engine struct gamma_engine