aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2018-09-19 20:20:58 +0000
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2018-09-22 15:57:47 +0000
commit7964d4f8ea9ef05a4d2dea54e1b5a55a4b2487e5 (patch)
treedad5aebd3745911f6ca9a3c28fbd1afdbcbdbb55
parentMerge pull request #4391 (diff)
downloadmonero-7964d4f8ea9ef05a4d2dea54e1b5a55a4b2487e5.tar.xz
wallet2: handle corner case in picking fake outputs
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.
-rw-r--r--src/wallet/wallet2.cpp30
1 files changed, 27 insertions, 3 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 6502463e2..6ca393cd4 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -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
@@ -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