Skip to content

Commit

Permalink
wallet2: handle corner case in picking fake outputs
Browse files Browse the repository at this point in the history
If we originally think we have enough outputs on the blockchain
to pick random fake outputs, we might end up with not enough of
them if enough are actually blackballed.
  • Loading branch information
moneromooo-monero committed Sep 22, 2018
1 parent bad2c7c commit 7964d4f
Showing 1 changed file with 27 additions and 3 deletions.
30 changes: 27 additions & 3 deletions src/wallet/wallet2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6642,11 +6642,23 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
}

// while we still need more mixins
uint64_t num_usable_outs = num_outs;
bool allow_blackballed = false;
while (num_found < requested_outputs_count)
{
// if we've gone through every possible output, we've gotten all we can
if (seen_indices.size() == num_outs)
break;
if (seen_indices.size() == num_usable_outs)
{
// there is a first pass which rejects blackballed outputs, then a second pass
// which allows them if we don't have enough non blackballed outputs to reach
// the required amount of outputs (since consensus does not care about blackballed
// outputs, we still need to reach the minimum ring size)
if (allow_blackballed)
break;
MINFO("Not enough non blackballed outputs, we'll allow blackballed ones");
allow_blackballed = true;
num_usable_outs = num_outs;
}

// get a random output index from the DB. If we've already seen it,
// return to the top of the loop and try again, otherwise add it to the
Expand Down Expand Up @@ -6720,14 +6732,26 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>

if (seen_indices.count(i))
continue;
if (is_output_blackballed(std::make_pair(amount, i))) // don't add blackballed outputs
if (!allow_blackballed && is_output_blackballed(std::make_pair(amount, i))) // don't add blackballed outputs
{
--num_usable_outs;
continue;
}
seen_indices.emplace(i);

LOG_PRINT_L2("picking " << i << " as " << type);
req.outputs.push_back({amount, i});
++num_found;
}

// if we had enough unusable outputs, we might fall off here and still
// have too few outputs, so we stuff with one to keep counts good, and
// we'll error out later
while (num_found < requested_outputs_count)
{
req.outputs.push_back({amount, 0});
++num_found;
}
}

// sort the subsection, to ensure the daemon doesn't know which output is ours
Expand Down

0 comments on commit 7964d4f

Please sign in to comment.