From fff238ec94ac6d45fc18c315d7bc590ddfaad63d Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 19 Mar 2016 21:48:36 +0000 Subject: Print stack trace upon exceptions Useful for debugging users' logs --- src/wallet/wallet2.cpp | 5 +++-- src/wallet/wallet2.h | 1 + src/wallet/wallet2_api.cpp | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/wallet') diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 2afe08cb1..ef17a770b 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -32,6 +32,7 @@ #include #include +#include "common/exception.h" #include "include_base_utils.h" using namespace epee; @@ -803,7 +804,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re // handle error from async fetching thread if (error) { - throw std::runtime_error("proxy exception in refresh thread"); + throw tools::runtime_error("proxy exception in refresh thread"); } } catch (const std::exception&) @@ -2012,7 +2013,7 @@ std::vector wallet2::create_transactions(std::vector ptx_vector; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index f798f404d..0961ad981 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -35,6 +35,7 @@ #include #include +#include "common/exception.h" #include "include_base_utils.h" #include "cryptonote_core/account.h" #include "cryptonote_core/account_boost_serialization.h" diff --git a/src/wallet/wallet2_api.cpp b/src/wallet/wallet2_api.cpp index 0644e3690..0cb253398 100644 --- a/src/wallet/wallet2_api.cpp +++ b/src/wallet/wallet2_api.cpp @@ -28,6 +28,7 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers +#include "common/exception.h" #include "wallet2_api.h" #include "wallet2.h" #include "mnemonics/electrum-words.h" -- cgit v1.2.3 From f7301c3563e7ae19b8d7c65d8bc88f3c42eefc09 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 21 Mar 2016 10:12:12 +0000 Subject: Revert "Print stack trace upon exceptions" Ain't nobody got time for link/cmake skullduggery. This reverts commit fff238ec94ac6d45fc18c315d7bc590ddfaad63d. --- src/wallet/wallet2.cpp | 5 ++--- src/wallet/wallet2.h | 1 - src/wallet/wallet2_api.cpp | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) (limited to 'src/wallet') diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index ef17a770b..2afe08cb1 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -32,7 +32,6 @@ #include #include -#include "common/exception.h" #include "include_base_utils.h" using namespace epee; @@ -804,7 +803,7 @@ void wallet2::refresh(uint64_t start_height, uint64_t & blocks_fetched, bool& re // handle error from async fetching thread if (error) { - throw tools::runtime_error("proxy exception in refresh thread"); + throw std::runtime_error("proxy exception in refresh thread"); } } catch (const std::exception&) @@ -2013,7 +2012,7 @@ std::vector wallet2::create_transactions(std::vector ptx_vector; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 0961ad981..f798f404d 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -35,7 +35,6 @@ #include #include -#include "common/exception.h" #include "include_base_utils.h" #include "cryptonote_core/account.h" #include "cryptonote_core/account_boost_serialization.h" diff --git a/src/wallet/wallet2_api.cpp b/src/wallet/wallet2_api.cpp index 0cb253398..0644e3690 100644 --- a/src/wallet/wallet2_api.cpp +++ b/src/wallet/wallet2_api.cpp @@ -28,7 +28,6 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#include "common/exception.h" #include "wallet2_api.h" #include "wallet2.h" #include "mnemonics/electrum-words.h" -- cgit v1.2.3 From a2e378b91bf5d2a54284f8e20df5080f11d25ff6 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 25 Mar 2016 00:48:11 +0000 Subject: wallet: add a --generate-from-json flag It takes a filename containing JSON data to generate a wallet. The following fields are valid: version: integer, should be 1 filename: string, path/filename for the newly created wallet scan_from_height: 64 bit unsigned integer, optional password: string, optional viewkey: string, hex representation spendkey: string, hex representation seed: string, optional, list of words separated by spaces Either seed or private keys should be given. If using private keys, the spend key may be omitted (the wallet will not be able to spend, but will see incoming transactions). If scan_from_height is given, blocks below this height will not be checked for transactions as an optimization. --- src/wallet/wallet2.cpp | 2 +- src/wallet/wallet2.h | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src/wallet') diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 2afe08cb1..1c7187cf0 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -490,7 +490,7 @@ void wallet2::process_new_blockchain_entry(const cryptonote::block& b, const cry //handle transactions from new block //optimization: seeking only for blocks that are not older then the wallet creation time plus 1 day. 1 day is for possible user incorrect time setup - if(b.timestamp + 60*60*24 > m_account.get_createtime()) + if(b.timestamp + 60*60*24 > m_account.get_createtime() && height >= m_refresh_from_block_height) { TIME_MEASURE_START(miner_tx_handle_time); process_new_transaction(b.miner_tx, height, true); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index f798f404d..e7b002925 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -88,10 +88,10 @@ namespace tools }; private: - wallet2(const wallet2&) : m_run(true), m_callback(0), m_testnet(false), m_always_confirm_transfers (false), m_store_tx_info(true), m_default_mixin(0), m_refresh_type(RefreshOptimizeCoinbase), m_auto_refresh(true) {} + wallet2(const wallet2&) : m_run(true), m_callback(0), m_testnet(false), m_always_confirm_transfers (false), m_store_tx_info(true), m_default_mixin(0), m_refresh_type(RefreshOptimizeCoinbase), m_auto_refresh(true), m_refresh_from_block_height(0) {} public: - wallet2(bool testnet = false, bool restricted = false) : m_run(true), m_callback(0), m_testnet(testnet), m_restricted(restricted), is_old_file_format(false), m_store_tx_info(true), m_default_mixin(0), m_refresh_type(RefreshOptimizeCoinbase), m_auto_refresh(true) {} + wallet2(bool testnet = false, bool restricted = false) : m_run(true), m_callback(0), m_testnet(testnet), m_restricted(restricted), is_old_file_format(false), m_store_tx_info(true), m_default_mixin(0), m_refresh_type(RefreshOptimizeCoinbase), m_auto_refresh(true), m_refresh_from_block_height(0) {} struct transfer_details { uint64_t m_block_height; @@ -226,6 +226,8 @@ namespace tools cryptonote::account_base& get_account(){return m_account;} const cryptonote::account_base& get_account()const{return m_account;} + void set_refresh_from_block_height(uint64_t height) {m_refresh_from_block_height = height;} + // upper_transaction_size_limit as defined below is set to // approximately 125% of the fixed minimum allowable penalty // free block size. TODO: fix this so that it actually takes @@ -319,6 +321,9 @@ namespace tools if(ver < 9) return; a & m_confirmed_txs; + if(ver < 11) + return; + a & m_refresh_from_block_height; } /*! @@ -430,9 +435,10 @@ namespace tools uint32_t m_default_mixin; RefreshType m_refresh_type; bool m_auto_refresh; + uint64_t m_refresh_from_block_height; }; } -BOOST_CLASS_VERSION(tools::wallet2, 10) +BOOST_CLASS_VERSION(tools::wallet2, 11) BOOST_CLASS_VERSION(tools::wallet2::payment_details, 0) BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 2) BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 1) -- cgit v1.2.3 From f26651ab8a3ed7f39a13f258880ee57f7ab85b68 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 26 Mar 2016 11:44:43 +0000 Subject: wallet: factor fee calculation --- src/wallet/wallet2.cpp | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) (limited to 'src/wallet') diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 1c7187cf0..7c54ca5e9 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -92,6 +92,13 @@ void do_prepare_file_names(const std::string& file_path, std::string& keys_file, } } +uint64_t calculate_fee(const cryptonote::blobdata &blob) +{ + uint64_t bytes = blob.size(); + uint64_t kB = (bytes + 1023) / 1024; + return kB * FEE_PER_KB; +} + } //namespace namespace tools @@ -2030,13 +2037,7 @@ std::vector wallet2::create_transactions(std::vector wallet2::create_transactions_2(std::vector available_for_fee && dsts[0].amount > 0) @@ -2686,13 +2681,7 @@ std::vector wallet2::create_dust_sweep_transactions() { transfer_dust(num_outputs_per_tx, (uint64_t)0 /* unlock_time */, 0, detail::digit_split_strategy, dust_policy, extra, tx, ptx); auto txBlob = t_serializable_object_to_blob(ptx.tx); - uint64_t txSize = txBlob.size(); - uint64_t numKB = txSize / 1024; - if (txSize % 1024) - { - numKB++; - } - needed_fee = numKB * FEE_PER_KB; + needed_fee = calculate_fee(txBlob); // reroll the tx with the actual amount minus the fee // if there's not enough for the fee, it'll throw -- cgit v1.2.3 From f9a2fd2ff55654cdbc458378d0365189ffd1c46a Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 26 Mar 2016 11:51:58 +0000 Subject: wallet: handle rare case where fee adjustment can bump to the next kB It resulted in a tx being sent with too low a fee, and thus rejected. --- src/wallet/wallet2.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/wallet') diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 7c54ca5e9..aa638143c 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2677,7 +2677,7 @@ std::vector wallet2::create_dust_sweep_transactions() // loop until fee is met without increasing tx size to next KB boundary. uint64_t needed_fee = 0; - if (1) + do { transfer_dust(num_outputs_per_tx, (uint64_t)0 /* unlock_time */, 0, detail::digit_split_strategy, dust_policy, extra, tx, ptx); auto txBlob = t_serializable_object_to_blob(ptx.tx); @@ -2687,7 +2687,8 @@ std::vector wallet2::create_dust_sweep_transactions() // if there's not enough for the fee, it'll throw transfer_dust(num_outputs_per_tx, (uint64_t)0 /* unlock_time */, needed_fee, detail::digit_split_strategy, dust_policy, extra, tx, ptx); txBlob = t_serializable_object_to_blob(ptx.tx); - } + needed_fee = calculate_fee(txBlob); + } while (ptx.fee < needed_fee); ptx_vector.push_back(ptx); -- cgit v1.2.3 From 12146daeed66fc30319c481a378c8d317b49b4db Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 26 Mar 2016 21:15:47 +0000 Subject: wallet: change sweep_dust to sweep_unmixable With the change in mixin rules for v2, the "annoying" outputs are slightly changed. There is high correlation between dust and unmixable, but no equivalence. --- src/wallet/wallet2.cpp | 104 ++++++++++++++++++++++++++++++++++----- src/wallet/wallet2.h | 7 ++- src/wallet/wallet_errors.h | 9 ++++ src/wallet/wallet_rpc_server.cpp | 2 +- 4 files changed, 106 insertions(+), 16 deletions(-) (limited to 'src/wallet') diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index aa638143c..7d308e615 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2508,7 +2508,7 @@ uint64_t wallet2::unlocked_dust_balance(const tx_dust_policy &dust_policy) const } template -void wallet2::transfer_dust(size_t num_outputs, uint64_t unlock_time, uint64_t needed_fee, T destination_split_strategy, const tx_dust_policy& dust_policy, const std::vector &extra, cryptonote::transaction& tx, pending_tx &ptx) +void wallet2::transfer_from(const std::vector &outs, size_t num_outputs, uint64_t unlock_time, uint64_t needed_fee, T destination_split_strategy, const tx_dust_policy& dust_policy, const std::vector &extra, cryptonote::transaction& tx, pending_tx &ptx) { using namespace cryptonote; @@ -2518,6 +2518,19 @@ void wallet2::transfer_dust(size_t num_outputs, uint64_t unlock_time, uint64_t n // throw if there are none uint64_t money = 0; std::list selected_transfers; +#if 1 + for (size_t n = 0; n < outs.size(); ++n) + { + const transfer_details& td = m_transfers[outs[n]]; + if (!td.m_spent) + { + selected_transfers.push_back (m_transfers.begin() + outs[n]); + money += td.amount(); + if (selected_transfers.size() >= num_outputs) + break; + } + } +#else for (transfer_container::iterator i = m_transfers.begin(); i != m_transfers.end(); ++i) { const transfer_details& td = *i; @@ -2529,6 +2542,7 @@ void wallet2::transfer_dust(size_t num_outputs, uint64_t unlock_time, uint64_t n break; } } +#endif // we don't allow no output to self, easier, but one may want to burn the dust if = fee THROW_WALLET_EXCEPTION_IF(money <= needed_fee, error::not_enough_money, money, needed_fee, needed_fee); @@ -2622,8 +2636,8 @@ bool wallet2::use_fork_rules(uint8_t version) r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client); m_daemon_rpc_mutex.unlock(); CHECK_AND_ASSERT_MES(r, false, "Failed to connect to daemon"); - CHECK_AND_ASSERT_MES(res.status != CORE_RPC_STATUS_BUSY, false, "Failed to connect to daemon"); - CHECK_AND_ASSERT_MES(res.status == CORE_RPC_STATUS_OK, false, "Failed to get hard fork status"); + CHECK_AND_ASSERT_MES(resp_t.result.status != CORE_RPC_STATUS_BUSY, false, "Failed to connect to daemon"); + CHECK_AND_ASSERT_MES(resp_t.result.status == CORE_RPC_STATUS_OK, false, "Failed to get hard fork status"); bool close_enough = res.height >= resp_t.result.earliest_height - 10; // start using the rules a bit beforehand if (close_enough) @@ -2641,20 +2655,84 @@ uint64_t wallet2::get_upper_tranaction_size_limit() return ((full_reward_zone * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; } //---------------------------------------------------------------------------------------------------- -std::vector wallet2::create_dust_sweep_transactions() +std::vector wallet2::select_available_outputs(std::function f) +{ + std::vector outputs; + size_t n = 0; + for (transfer_container::const_iterator i = m_transfers.begin(); i != m_transfers.end(); ++i, ++n) + { + if (i->m_spent) + continue; + if (!is_transfer_unlocked(*i)) + continue; + if (f(*i)) + outputs.push_back(n); + } + return outputs; +} +//---------------------------------------------------------------------------------------------------- +std::vector wallet2::get_unspent_amounts_vector() +{ + std::set set; + for (const auto &td: m_transfers) + { + if (!td.m_spent) + set.insert(td.amount()); + } + std::vector vector; + vector.reserve(set.size()); + for (const auto &i: set) + { + vector.push_back(i); + } + return vector; +} +//---------------------------------------------------------------------------------------------------- +std::vector wallet2::select_available_unmixable_outputs() +{ + // request all outputs with at least 3 instances, so we can use mixin 2 with + epee::json_rpc::request req_t = AUTO_VAL_INIT(req_t); + epee::json_rpc::response resp_t = AUTO_VAL_INIT(resp_t); + m_daemon_rpc_mutex.lock(); + req_t.jsonrpc = "2.0"; + req_t.id = epee::serialization::storage_entry(0); + req_t.method = "get_output_histogram"; + req_t.params.amounts = get_unspent_amounts_vector(); + req_t.params.min_count = 3; + req_t.params.max_count = 0; + bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client); + m_daemon_rpc_mutex.unlock(); + THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "select_available_unmixable_outputs"); + THROW_WALLET_EXCEPTION_IF(resp_t.result.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_output_histogram"); + THROW_WALLET_EXCEPTION_IF(resp_t.result.status != CORE_RPC_STATUS_OK, error::get_histogram_error, resp_t.result.status); + + std::set mixable; + for (const auto &i: resp_t.result.histogram) + { + mixable.insert(i.amount); + } + + return select_available_outputs([mixable](const transfer_details &td) { + const uint64_t amount = td.amount(); + if (mixable.find(amount) == mixable.end()) + return true; + return false; + }); +} +//---------------------------------------------------------------------------------------------------- +std::vector wallet2::create_unmixable_sweep_transactions() { // From hard fork 1, we don't consider small amounts to be dust anymore const bool hf1_rules = use_fork_rules(2); // first hard fork has version 2 tx_dust_policy dust_policy(hf1_rules ? 0 : ::config::DEFAULT_DUST_THRESHOLD); - size_t num_dust_outputs = 0; - for (transfer_container::const_iterator i = m_transfers.begin(); i != m_transfers.end(); ++i) + // may throw + std::vector unmixable_outputs = select_available_unmixable_outputs(); + size_t num_dust_outputs = unmixable_outputs.size(); + + if (num_dust_outputs == 0) { - const transfer_details& td = *i; - if (!td.m_spent && (td.amount() < dust_policy.dust_threshold || !is_valid_decomposed_amount(td.amount())) && is_transfer_unlocked(td)) - { - num_dust_outputs++; - } + return std::vector(); } // failsafe split attempt counter @@ -2679,13 +2757,13 @@ std::vector wallet2::create_dust_sweep_transactions() uint64_t needed_fee = 0; do { - transfer_dust(num_outputs_per_tx, (uint64_t)0 /* unlock_time */, 0, detail::digit_split_strategy, dust_policy, extra, tx, ptx); + transfer_from(unmixable_outputs, num_outputs_per_tx, (uint64_t)0 /* unlock_time */, 0, detail::digit_split_strategy, dust_policy, extra, tx, ptx); auto txBlob = t_serializable_object_to_blob(ptx.tx); needed_fee = calculate_fee(txBlob); // reroll the tx with the actual amount minus the fee // if there's not enough for the fee, it'll throw - transfer_dust(num_outputs_per_tx, (uint64_t)0 /* unlock_time */, needed_fee, detail::digit_split_strategy, dust_policy, extra, tx, ptx); + transfer_from(unmixable_outputs, num_outputs_per_tx, (uint64_t)0 /* unlock_time */, needed_fee, detail::digit_split_strategy, dust_policy, extra, tx, ptx); txBlob = t_serializable_object_to_blob(ptx.tx); needed_fee = calculate_fee(txBlob); } while (ptx.fee < needed_fee); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index e7b002925..2b6cdab92 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -280,7 +280,7 @@ namespace tools void transfer(const std::vector& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector& extra); void transfer(const std::vector& dsts, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector& extra, cryptonote::transaction& tx, pending_tx& ptx); template - void transfer_dust(size_t num_outputs, uint64_t unlock_time, uint64_t needed_fee, T destination_split_strategy, const tx_dust_policy& dust_policy, const std::vector& extra, cryptonote::transaction& tx, pending_tx &ptx); + void transfer_from(const std::vector &outs, size_t num_outputs, uint64_t unlock_time, uint64_t needed_fee, T destination_split_strategy, const tx_dust_policy& dust_policy, const std::vector& extra, cryptonote::transaction& tx, pending_tx &ptx); template void transfer_selected(const std::vector& dsts, const std::list selected_transfers, size_t fake_outputs_count, uint64_t unlock_time, uint64_t fee, const std::vector& extra, T destination_split_strategy, const tx_dust_policy& dust_policy, cryptonote::transaction& tx, pending_tx &ptx); @@ -289,7 +289,7 @@ namespace tools void commit_tx(std::vector& ptx_vector); std::vector create_transactions(std::vector dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee, const std::vector extra); std::vector create_transactions_2(std::vector dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee_UNUSED, const std::vector extra); - std::vector create_dust_sweep_transactions(); + std::vector create_unmixable_sweep_transactions(); bool check_connection(); void get_transfers(wallet2::transfer_container& incoming_transfers) const; void get_payments(const crypto::hash& payment_id, std::list& payments, uint64_t min_height = 0) const; @@ -402,6 +402,9 @@ namespace tools void parse_block_round(const cryptonote::blobdata &blob, cryptonote::block &bl, crypto::hash &bl_id, bool &error) const; uint64_t get_upper_tranaction_size_limit(); void check_pending_txes(); + std::vector get_unspent_amounts_vector(); + std::vector select_available_outputs(std::function f); + std::vector select_available_unmixable_outputs(); cryptonote::account_base m_account; std::string m_daemon_address; diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index 6074e0858..652b19499 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -76,6 +76,7 @@ namespace tools // daemon_busy // no_connection_to_daemon // is_key_image_spent_error + // get_histogram_error // wallet_files_doesnt_correspond // // * - class with protected ctor @@ -600,6 +601,14 @@ namespace tools } }; //---------------------------------------------------------------------------------------------------- + struct get_histogram_error : public wallet_rpc_error + { + explicit get_histogram_error(std::string&& loc, const std::string& request) + : wallet_rpc_error(std::move(loc), "failed to get output histogram", request) + { + } + }; + //---------------------------------------------------------------------------------------------------- struct wallet_files_doesnt_correspond : public wallet_logic_error { explicit wallet_files_doesnt_correspond(std::string&& loc, const std::string& keys_file, const std::string& wallet_file) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 418de327c..83e1f7535 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -347,7 +347,7 @@ namespace tools try { - std::vector ptx_vector = m_wallet.create_dust_sweep_transactions(); + std::vector ptx_vector = m_wallet.create_unmixable_sweep_transactions(); m_wallet.commit_tx(ptx_vector); -- cgit v1.2.3 From 0be6e08dd0faf5f7e3492652f00b8904e7e8216d Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 26 Mar 2016 23:22:57 +0000 Subject: wallet: do not leak owned amounts to the daemon unless --trusted-daemon This will be slower, though more private. New trusted_daemon parameter to the matching RPC call, false by default. --- src/wallet/wallet2.cpp | 9 +++++---- src/wallet/wallet2.h | 4 ++-- src/wallet/wallet_rpc_server.cpp | 2 +- src/wallet/wallet_rpc_server_commands_defs.h | 2 ++ 4 files changed, 10 insertions(+), 7 deletions(-) (limited to 'src/wallet') diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 7d308e615..3ec2265fa 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2688,7 +2688,7 @@ std::vector wallet2::get_unspent_amounts_vector() return vector; } //---------------------------------------------------------------------------------------------------- -std::vector wallet2::select_available_unmixable_outputs() +std::vector wallet2::select_available_unmixable_outputs(bool trusted_daemon) { // request all outputs with at least 3 instances, so we can use mixin 2 with epee::json_rpc::request req_t = AUTO_VAL_INIT(req_t); @@ -2697,7 +2697,8 @@ std::vector wallet2::select_available_unmixable_outputs() req_t.jsonrpc = "2.0"; req_t.id = epee::serialization::storage_entry(0); req_t.method = "get_output_histogram"; - req_t.params.amounts = get_unspent_amounts_vector(); + if (trusted_daemon) + req_t.params.amounts = get_unspent_amounts_vector(); req_t.params.min_count = 3; req_t.params.max_count = 0; bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client); @@ -2720,14 +2721,14 @@ std::vector wallet2::select_available_unmixable_outputs() }); } //---------------------------------------------------------------------------------------------------- -std::vector wallet2::create_unmixable_sweep_transactions() +std::vector wallet2::create_unmixable_sweep_transactions(bool trusted_daemon) { // From hard fork 1, we don't consider small amounts to be dust anymore const bool hf1_rules = use_fork_rules(2); // first hard fork has version 2 tx_dust_policy dust_policy(hf1_rules ? 0 : ::config::DEFAULT_DUST_THRESHOLD); // may throw - std::vector unmixable_outputs = select_available_unmixable_outputs(); + std::vector unmixable_outputs = select_available_unmixable_outputs(trusted_daemon); size_t num_dust_outputs = unmixable_outputs.size(); if (num_dust_outputs == 0) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 2b6cdab92..566be59c6 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -289,7 +289,7 @@ namespace tools void commit_tx(std::vector& ptx_vector); std::vector create_transactions(std::vector dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee, const std::vector extra); std::vector create_transactions_2(std::vector dsts, const size_t fake_outs_count, const uint64_t unlock_time, const uint64_t fee_UNUSED, const std::vector extra); - std::vector create_unmixable_sweep_transactions(); + std::vector create_unmixable_sweep_transactions(bool trusted_daemon); bool check_connection(); void get_transfers(wallet2::transfer_container& incoming_transfers) const; void get_payments(const crypto::hash& payment_id, std::list& payments, uint64_t min_height = 0) const; @@ -404,7 +404,7 @@ namespace tools void check_pending_txes(); std::vector get_unspent_amounts_vector(); std::vector select_available_outputs(std::function f); - std::vector select_available_unmixable_outputs(); + std::vector select_available_unmixable_outputs(bool trusted_daemon); cryptonote::account_base m_account; std::string m_daemon_address; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 83e1f7535..d7d99c2ae 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -347,7 +347,7 @@ namespace tools try { - std::vector ptx_vector = m_wallet.create_unmixable_sweep_transactions(); + std::vector ptx_vector = m_wallet.create_unmixable_sweep_transactions(req.trusted_daemon); m_wallet.commit_tx(ptx_vector); diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 40d6fd8f8..2c4e26406 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -178,9 +178,11 @@ namespace wallet_rpc struct request { bool get_tx_keys; + bool trusted_daemon; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(get_tx_keys) + KV_SERIALIZE(trusted_daemon) END_KV_SERIALIZE_MAP() }; -- cgit v1.2.3 From 25672d3f10e71f4db36d9497e2440f2ac26a6e01 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 26 Mar 2016 23:32:45 +0000 Subject: wallet: pass std::function by const ref, not value Because we can. --- src/wallet/wallet2.cpp | 2 +- src/wallet/wallet2.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/wallet') diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 3ec2265fa..6fd77eead 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2655,7 +2655,7 @@ uint64_t wallet2::get_upper_tranaction_size_limit() return ((full_reward_zone * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; } //---------------------------------------------------------------------------------------------------- -std::vector wallet2::select_available_outputs(std::function f) +std::vector wallet2::select_available_outputs(const std::function &f) { std::vector outputs; size_t n = 0; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 566be59c6..fc700a3de 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -403,7 +403,7 @@ namespace tools uint64_t get_upper_tranaction_size_limit(); void check_pending_txes(); std::vector get_unspent_amounts_vector(); - std::vector select_available_outputs(std::function f); + std::vector select_available_outputs(const std::function &f); std::vector select_available_unmixable_outputs(bool trusted_daemon); cryptonote::account_base m_account; -- cgit v1.2.3 From 878ab5d896c1a9cb5c50c36a0ded5da998c941d5 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 28 Mar 2016 16:46:19 +0100 Subject: wallet: fix --generate-from-keys saving as watch only --- src/wallet/wallet2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/wallet') diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 6fd77eead..363665024 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1214,7 +1214,7 @@ void wallet2::generate(const std::string& wallet_, const std::string& password, m_account_public_address = account_public_address; m_watch_only = false; - bool r = store_keys(m_keys_file, password, true); + bool r = store_keys(m_keys_file, password, false); THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file); r = file_io_utils::save_string_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_testnet)); -- cgit v1.2.3