mirror of
https://github.com/monero-project/monero.git
synced 2024-12-23 12:09:54 +00:00
simplewallet: warn about correlations if print-ring-members is not set
The warning about spending more than one output with similar creation time was skipped if print-ring-members was not set, and it defaults to false, which means most people probably aren't getting this warning if they spend correlated outputs. Reported by SeventhAlpaca.
This commit is contained in:
parent
72262b348a
commit
9989cb087e
2 changed files with 18 additions and 14 deletions
|
@ -6064,11 +6064,14 @@ std::pair<std::string, std::string> simple_wallet::show_outputs_line(const std::
|
||||||
return std::make_pair(ostr.str(), ring_str);
|
return std::make_pair(ostr.str(), ring_str);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool simple_wallet::print_ring_members(const std::vector<tools::wallet2::pending_tx>& ptx_vector, std::ostream& ostr)
|
bool simple_wallet::process_ring_members(const std::vector<tools::wallet2::pending_tx>& ptx_vector, std::ostream& ostr, bool verbose)
|
||||||
{
|
{
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
if (!try_connect_to_daemon(false, &version))
|
if (!try_connect_to_daemon(false, &version))
|
||||||
|
{
|
||||||
|
fail_msg_writer() << tr("failed to connect to daemon");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
// available for RPC version 1.4 or higher
|
// available for RPC version 1.4 or higher
|
||||||
if (version < MAKE_CORE_RPC_VERSION(1, 4))
|
if (version < MAKE_CORE_RPC_VERSION(1, 4))
|
||||||
return true;
|
return true;
|
||||||
|
@ -6084,7 +6087,8 @@ bool simple_wallet::print_ring_members(const std::vector<tools::wallet2::pending
|
||||||
{
|
{
|
||||||
const cryptonote::transaction& tx = ptx_vector[n].tx;
|
const cryptonote::transaction& tx = ptx_vector[n].tx;
|
||||||
const tools::wallet2::tx_construction_data& construction_data = ptx_vector[n].construction_data;
|
const tools::wallet2::tx_construction_data& construction_data = ptx_vector[n].construction_data;
|
||||||
ostr << boost::format(tr("\nTransaction %llu/%llu: txid=%s")) % (n + 1) % ptx_vector.size() % cryptonote::get_transaction_hash(tx);
|
if (verbose)
|
||||||
|
ostr << boost::format(tr("\nTransaction %llu/%llu: txid=%s")) % (n + 1) % ptx_vector.size() % cryptonote::get_transaction_hash(tx);
|
||||||
// for each input
|
// for each input
|
||||||
std::vector<uint64_t> spent_key_height(tx.vin.size());
|
std::vector<uint64_t> spent_key_height(tx.vin.size());
|
||||||
std::vector<crypto::hash> spent_key_txid (tx.vin.size());
|
std::vector<crypto::hash> spent_key_txid (tx.vin.size());
|
||||||
|
@ -6105,7 +6109,8 @@ bool simple_wallet::print_ring_members(const std::vector<tools::wallet2::pending
|
||||||
}
|
}
|
||||||
const cryptonote::tx_source_entry& source = *sptr;
|
const cryptonote::tx_source_entry& source = *sptr;
|
||||||
|
|
||||||
ostr << boost::format(tr("\nInput %llu/%llu (%s): amount=%s")) % (i + 1) % tx.vin.size() % epee::string_tools::pod_to_hex(in_key.k_image) % print_money(source.amount);
|
if (verbose)
|
||||||
|
ostr << boost::format(tr("\nInput %llu/%llu (%s): amount=%s")) % (i + 1) % tx.vin.size() % epee::string_tools::pod_to_hex(in_key.k_image) % print_money(source.amount);
|
||||||
// convert relative offsets of ring member keys into absolute offsets (indices) associated with the amount
|
// convert relative offsets of ring member keys into absolute offsets (indices) associated with the amount
|
||||||
std::vector<uint64_t> absolute_offsets = cryptonote::relative_output_offsets_to_absolute(in_key.key_offsets);
|
std::vector<uint64_t> absolute_offsets = cryptonote::relative_output_offsets_to_absolute(in_key.key_offsets);
|
||||||
// get block heights from which those ring member keys originated
|
// get block heights from which those ring member keys originated
|
||||||
|
@ -6135,7 +6140,8 @@ bool simple_wallet::print_ring_members(const std::vector<tools::wallet2::pending
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ostr << tr("\nOriginating block heights: ");
|
if (verbose)
|
||||||
|
ostr << tr("\nOriginating block heights: ");
|
||||||
spent_key_height[i] = res.outs[source.real_output].height;
|
spent_key_height[i] = res.outs[source.real_output].height;
|
||||||
spent_key_txid [i] = res.outs[source.real_output].txid;
|
spent_key_txid [i] = res.outs[source.real_output].txid;
|
||||||
std::vector<uint64_t> heights(absolute_offsets.size(), 0);
|
std::vector<uint64_t> heights(absolute_offsets.size(), 0);
|
||||||
|
@ -6144,7 +6150,8 @@ bool simple_wallet::print_ring_members(const std::vector<tools::wallet2::pending
|
||||||
heights[j] = res.outs[j].height;
|
heights[j] = res.outs[j].height;
|
||||||
}
|
}
|
||||||
std::pair<std::string, std::string> ring_str = show_outputs_line(heights, blockchain_height, source.real_output);
|
std::pair<std::string, std::string> ring_str = show_outputs_line(heights, blockchain_height, source.real_output);
|
||||||
ostr << ring_str.first << tr("\n|") << ring_str.second << tr("|\n");
|
if (verbose)
|
||||||
|
ostr << ring_str.first << tr("\n|") << ring_str.second << tr("|\n");
|
||||||
}
|
}
|
||||||
// warn if rings contain keys originating from the same tx or temporally very close block heights
|
// warn if rings contain keys originating from the same tx or temporally very close block heights
|
||||||
bool are_keys_from_same_tx = false;
|
bool are_keys_from_same_tx = false;
|
||||||
|
@ -6163,7 +6170,7 @@ bool simple_wallet::print_ring_members(const std::vector<tools::wallet2::pending
|
||||||
ostr
|
ostr
|
||||||
<< tr("\nWarning: Some input keys being spent are from ")
|
<< tr("\nWarning: Some input keys being spent are from ")
|
||||||
<< (are_keys_from_same_tx ? tr("the same transaction") : tr("blocks that are temporally very close"))
|
<< (are_keys_from_same_tx ? tr("the same transaction") : tr("blocks that are temporally very close"))
|
||||||
<< tr(", which can break the anonymity of ring signature. Make sure this is intentional!");
|
<< tr(", which can break the anonymity of ring signatures. Make sure this is intentional!");
|
||||||
}
|
}
|
||||||
ostr << ENDL;
|
ostr << ENDL;
|
||||||
}
|
}
|
||||||
|
@ -6604,11 +6611,8 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
|
||||||
float days = locked_blocks / 720.0f;
|
float days = locked_blocks / 720.0f;
|
||||||
prompt << boost::format(tr(".\nThis transaction (including %s change) will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)")) % cryptonote::print_money(change) % ((unsigned long long)unlock_block) % days;
|
prompt << boost::format(tr(".\nThis transaction (including %s change) will unlock on block %llu, in approximately %s days (assuming 2 minutes per block)")) % cryptonote::print_money(change) % ((unsigned long long)unlock_block) % days;
|
||||||
}
|
}
|
||||||
if (m_wallet->print_ring_members())
|
if (!process_ring_members(ptx_vector, prompt, m_wallet->print_ring_members()))
|
||||||
{
|
return false;
|
||||||
if (!print_ring_members(ptx_vector, prompt))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool default_ring_size = true;
|
bool default_ring_size = true;
|
||||||
for (const auto &ptx: ptx_vector)
|
for (const auto &ptx: ptx_vector)
|
||||||
{
|
{
|
||||||
|
@ -7064,7 +7068,7 @@ bool simple_wallet::sweep_main(uint64_t below, bool locked, const std::vector<st
|
||||||
if (subaddr_indices.size() > 1)
|
if (subaddr_indices.size() > 1)
|
||||||
prompt << tr("WARNING: Outputs of multiple addresses are being used together, which might potentially compromise your privacy.\n");
|
prompt << tr("WARNING: Outputs of multiple addresses are being used together, which might potentially compromise your privacy.\n");
|
||||||
}
|
}
|
||||||
if (m_wallet->print_ring_members() && !print_ring_members(ptx_vector, prompt))
|
if (!process_ring_members(ptx_vector, prompt, m_wallet->print_ring_members()))
|
||||||
return true;
|
return true;
|
||||||
if (ptx_vector.size() > 1) {
|
if (ptx_vector.size() > 1) {
|
||||||
prompt << boost::format(tr("Sweeping %s in %llu transactions for a total fee of %s. Is this okay?")) %
|
prompt << boost::format(tr("Sweeping %s in %llu transactions for a total fee of %s. Is this okay?")) %
|
||||||
|
@ -7308,7 +7312,7 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_)
|
||||||
uint64_t total_fee = ptx_vector[0].fee;
|
uint64_t total_fee = ptx_vector[0].fee;
|
||||||
uint64_t total_sent = m_wallet->get_transfer_details(ptx_vector[0].selected_transfers.front()).amount();
|
uint64_t total_sent = m_wallet->get_transfer_details(ptx_vector[0].selected_transfers.front()).amount();
|
||||||
std::ostringstream prompt;
|
std::ostringstream prompt;
|
||||||
if (!print_ring_members(ptx_vector, prompt))
|
if (!process_ring_members(ptx_vector, prompt, m_wallet->print_ring_members()))
|
||||||
return true;
|
return true;
|
||||||
prompt << boost::format(tr("Sweeping %s for a total fee of %s. Is this okay?")) %
|
prompt << boost::format(tr("Sweeping %s for a total fee of %s. Is this okay?")) %
|
||||||
print_money(total_sent) %
|
print_money(total_sent) %
|
||||||
|
|
|
@ -270,7 +270,7 @@ namespace cryptonote
|
||||||
bool accept_loaded_tx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message = std::string());
|
bool accept_loaded_tx(const std::function<size_t()> get_num_txes, const std::function<const tools::wallet2::tx_construction_data&(size_t)> &get_tx, const std::string &extra_message = std::string());
|
||||||
bool accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs);
|
bool accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs);
|
||||||
bool accept_loaded_tx(const tools::wallet2::signed_tx_set &txs);
|
bool accept_loaded_tx(const tools::wallet2::signed_tx_set &txs);
|
||||||
bool print_ring_members(const std::vector<tools::wallet2::pending_tx>& ptx_vector, std::ostream& ostr);
|
bool process_ring_members(const std::vector<tools::wallet2::pending_tx>& ptx_vector, std::ostream& ostr, bool verbose);
|
||||||
std::string get_prompt() const;
|
std::string get_prompt() const;
|
||||||
bool print_seed(bool encrypted);
|
bool print_seed(bool encrypted);
|
||||||
void key_images_sync_intern();
|
void key_images_sync_intern();
|
||||||
|
|
Loading…
Reference in a new issue