wallet2: guard gamma picker against zero-output windows

This commit is contained in:
selsta
2026-07-14 19:41:36 +02:00
parent d46a05e8c8
commit 0b7967907f
2 changed files with 11 additions and 4 deletions
+1
View File
@@ -1051,6 +1051,7 @@ gamma_picker::gamma_picker(const std::vector<uint64_t> &rct_offsets, double shap
end = rct_offsets.data() + rct_offsets.size() - (std::max(1, CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE) - 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(outputs_to_consider == 0, error::wallet_internal_error, "No outputs in consideration window");
average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / static_cast<double>(outputs_to_consider); // this assumes constant target over the whole rct range
};
+10 -4
View File
@@ -261,16 +261,22 @@ TEST(select_outputs, exact_unlock_block)
TEST(select_outputs, exact_unlock_block_tiny)
{
// Create chain of length CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE where there is one output in block 0
std::vector<uint64_t> offsets(std::max(CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, 1), 0);
offsets[0] = 1;
// Create a chain of length CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE with one
// output in block 0. Since rct_offsets is cumulative, later blocks retain
// that output even though they contain no additional outputs.
std::vector<uint64_t> offsets(std::max(CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE, 1), 1);
tools::gamma_picker picker(offsets);
constexpr size_t MAX_PICK_TRIES = 10;
constexpr size_t MAX_PICK_TRIES = 1000;
bool found_the_one_output = false;
for (size_t i = 0; i < MAX_PICK_TRIES; ++i)
{
if (picker.pick() == 0)
{
found_the_one_output = true;
break;
}
}
EXPECT_TRUE(found_the_one_output);
}