Merge pull request #4406

7964d4f8 wallet2: handle corner case in picking fake outputs (moneromooo-monero)
This commit is contained in:
Riccardo Spagni 2018-09-29 21:51:50 +02:00
parent 2a44e13658
commit ff0d7a7678
No known key found for this signature in database
GPG Key ID: 55432DF31CCD4FCD

View File

@ -6723,11 +6723,23 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
} }
// while we still need more mixins // while we still need more mixins
uint64_t num_usable_outs = num_outs;
bool allow_blackballed = false;
while (num_found < requested_outputs_count) while (num_found < requested_outputs_count)
{ {
// if we've gone through every possible output, we've gotten all we can // if we've gone through every possible output, we've gotten all we can
if (seen_indices.size() == num_outs) 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; 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, // 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 // return to the top of the loop and try again, otherwise add it to the
@ -6801,14 +6813,26 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
if (seen_indices.count(i)) if (seen_indices.count(i))
continue; 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; continue;
}
seen_indices.emplace(i); seen_indices.emplace(i);
LOG_PRINT_L2("picking " << i << " as " << type); LOG_PRINT_L2("picking " << i << " as " << type);
req.outputs.push_back({amount, i}); req.outputs.push_back({amount, i});
++num_found; ++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 // sort the subsection, to ensure the daemon doesn't know which output is ours