diff options
Diffstat (limited to 'src/wallet/wallet2.cpp')
-rw-r--r-- | src/wallet/wallet2.cpp | 54 |
1 files changed, 47 insertions, 7 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index fae972cf8..37b60c5d7 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -37,6 +37,8 @@ #include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/trim.hpp> #include <boost/algorithm/string/split.hpp> +#include <boost/algorithm/string/join.hpp> +#include <boost/range/adaptor/transformed.hpp> #include "include_base_utils.h" using namespace epee; @@ -121,6 +123,8 @@ using namespace cryptonote; #define FIRST_REFRESH_GRANULARITY 1024 +#define GAMMA_PICK_HALF_WINDOW 5 + static const std::string MULTISIG_SIGNATURE_MAGIC = "SigMultisigPkV1"; static const std::string MULTISIG_EXTRA_INFO_MAGIC = "MultisigxV1"; @@ -5612,6 +5616,10 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin ptx.construction_data = sd; txs.push_back(ptx); + + // add tx keys only to ptx + txs.back().tx_key = tx_key; + txs.back().additional_tx_keys = additional_tx_keys; } // add key images @@ -6797,10 +6805,29 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> error::get_output_distribution, "Decreasing offsets in rct distribution: " + std::to_string(block_offset) + ": " + std::to_string(rct_offsets[block_offset]) + ", " + std::to_string(block_offset + 1) + ": " + std::to_string(rct_offsets[block_offset + 1])); - uint64_t n_rct = rct_offsets[block_offset + 1] - rct_offsets[block_offset]; + uint64_t first_block_offset = block_offset, last_block_offset = block_offset; + for (size_t half_window = 0; half_window < GAMMA_PICK_HALF_WINDOW; ++half_window) + { + // end when we have a non empty block + uint64_t cum0 = first_block_offset > 0 ? rct_offsets[first_block_offset] - rct_offsets[first_block_offset - 1] : rct_offsets[0]; + if (cum0 > 1) + break; + uint64_t cum1 = last_block_offset > 0 ? rct_offsets[last_block_offset] - rct_offsets[last_block_offset - 1] : rct_offsets[0]; + if (cum1 > 1) + break; + if (first_block_offset == 0 && last_block_offset >= rct_offsets.size() - 2) + break; + // expand up to bounds + if (first_block_offset > 0) + --first_block_offset; + if (last_block_offset < rct_offsets.size() - 1) + ++last_block_offset; + } + const uint64_t n_rct = rct_offsets[last_block_offset] - (first_block_offset == 0 ? 0 : rct_offsets[first_block_offset - 1]); if (n_rct == 0) return rct_offsets[block_offset] ? rct_offsets[block_offset] - 1 : 0; - return rct_offsets[block_offset] + crypto::rand<uint64_t>() % n_rct; + MDEBUG("Picking 1/" << n_rct << " in " << (last_block_offset - first_block_offset + 1) << " blocks centered around " << block_offset); + return rct_offsets[first_block_offset] + crypto::rand<uint64_t>() % n_rct; }; size_t num_selected_transfers = 0; @@ -6970,6 +6997,8 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> LOG_PRINT_L1("Selecting real output: " << td.m_global_output_index << " for " << print_money(amount)); } + std::unordered_map<const char*, std::set<uint64_t>> picks; + // while we still need more mixins uint64_t num_usable_outs = num_outs; bool allow_blackballed = false; @@ -6984,7 +7013,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> // 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"); + MINFO("Not enough output not marked as spent, we'll allow outputs marked as spent"); allow_blackballed = true; num_usable_outs = num_outs; } @@ -7068,11 +7097,15 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> } seen_indices.emplace(i); - LOG_PRINT_L2("picking " << i << " as " << type); + picks[type].insert(i); req.outputs.push_back({amount, i}); ++num_found; } + for (const auto &pick: picks) + MDEBUG("picking " << pick.first << " outputs: " << + boost::join(pick.second | boost::adaptors::transformed([](uint64_t out){return std::to_string(out);}), " ")); + // 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 @@ -7088,8 +7121,15 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> [](const get_outputs_out &a, const get_outputs_out &b) { return a.index < b.index; }); } - for (auto i: req.outputs) - LOG_PRINT_L1("asking for output " << i.index << " for " << print_money(i.amount)); + if (ELPP->vRegistry()->allowed(el::Level::Debug, MONERO_DEFAULT_LOG_CATEGORY)) + { + std::map<uint64_t, std::set<uint64_t>> outs; + for (const auto &i: req.outputs) + outs[i.amount].insert(i.index); + for (const auto &o: outs) + MDEBUG("asking for outputs with amount " << print_money(o.first) << ": " << + boost::join(o.second | boost::adaptors::transformed([](uint64_t out){return std::to_string(out);}), " ")); + } // get the keys for those m_daemon_rpc_mutex.lock(); @@ -10547,7 +10587,7 @@ uint64_t wallet2::import_key_images(const std::vector<std::pair<crypto::key_imag + boost::lexical_cast<std::string>(signed_key_images.size()) + ", key image " + epee::string_tools::pod_to_hex(key_image)); THROW_WALLET_EXCEPTION_IF(!crypto::check_ring_signature((const crypto::hash&)key_image, key_image, pkeys, &signature), - error::wallet_internal_error, "Signature check failed: input " + boost::lexical_cast<std::string>(n) + "/" + error::signature_check_failed, boost::lexical_cast<std::string>(n) + "/" + boost::lexical_cast<std::string>(signed_key_images.size()) + ", key image " + epee::string_tools::pod_to_hex(key_image) + ", signature " + epee::string_tools::pod_to_hex(signature) + ", pubkey " + epee::string_tools::pod_to_hex(*pkeys[0])); |