From 77d1c6b6723cfe410085208498345aa4624a217d Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 27 Mar 2016 11:00:15 +0100 Subject: simplewallet: default to trusted daemon for loopback address --- src/simplewallet/simplewallet.cpp | 42 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'src/simplewallet/simplewallet.cpp') diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 1856118f7..56c6ec8a6 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -964,6 +964,37 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m return r; } +static bool is_local_daemon(const std::string &address) +{ + // extract host + epee::net_utils::http::url_content u_c; + if (!epee::net_utils::parse_url(address, u_c)) + { + LOG_PRINT_L1("Failed to determine whether daemon is local, assuming not"); + return false; + } + if (u_c.host.empty()) + { + LOG_PRINT_L1("Failed to determine whether daemon is local, assuming not"); + return false; + } + + // resolve to IP + boost::asio::io_service io_service; + boost::asio::ip::tcp::resolver resolver(io_service); + boost::asio::ip::tcp::resolver::query query(u_c.host, ""); + boost::asio::ip::tcp::resolver::iterator i = resolver.resolve(query); + while (i != boost::asio::ip::tcp::resolver::iterator()) + { + const boost::asio::ip::tcp::endpoint &ep = *i; + if (ep.address().is_loopback()) + return true; + ++i; + } + + return false; +} + //---------------------------------------------------------------------------------------------------- bool simple_wallet::init(const boost::program_options::variables_map& vm) { @@ -999,6 +1030,17 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) if (m_daemon_address.empty()) m_daemon_address = std::string("http://") + m_daemon_host + ":" + std::to_string(m_daemon_port); + // set --trusted-daemon if local + try + { + if (is_local_daemon(m_daemon_address)) + { + LOG_PRINT_L1(tr("Daemon is local, assuming trusted")); + m_trusted_daemon = true; + } + } + catch (const std::exception &e) { } + tools::password_container pwd_container; if (!get_password(vm, true, pwd_container)) return false; -- cgit v1.2.3 From 24b3e9007a8ad0684edcee51df444b21a033e4ba Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 27 Mar 2016 12:35:36 +0100 Subject: Convey tx verification failure reasons to the RPC client This allows appropriate action to be taken, like displaying the reason to the user. Do just that in simplewallet, which should help a lot in determining why users fail to send. Also make it so a tx which is accepted but not relayed is seen as a success rather than a failure. --- src/simplewallet/simplewallet.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/simplewallet/simplewallet.cpp') diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 1856118f7..0579b1a40 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2160,6 +2160,9 @@ bool simple_wallet::transfer_main(bool new_algorithm, const std::vector &args_) catch (const tools::error::tx_rejected& e) { fail_msg_writer() << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); + std::string reason = e.reason(); + if (!reason.empty()) + fail_msg_writer() << tr("Reason: ") << reason; } catch (const tools::error::tx_sum_overflow& e) { -- cgit v1.2.3 From 3e557254c7a0828b0f2ca54aa7181c2dae1d7e4c Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 27 Mar 2016 16:26:37 +0100 Subject: wallet: make the JSON reading type safe --- src/simplewallet/simplewallet.cpp | 72 +++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 41 deletions(-) (limited to 'src/simplewallet/simplewallet.cpp') diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 04170df62..fbaea1650 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -58,6 +58,7 @@ #include "crypto/crypto.h" // for crypto::secret_key definition #include "mnemonics/electrum-words.h" #include "rapidjson/document.h" +#include "common/json_util.h" #include #if defined(WIN32) @@ -833,40 +834,27 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m return false; } - if (!json.HasMember("version")) { - fail_msg_writer() << tr("Version not found in JSON"); - return false; - } - unsigned int version = json["version"].GetUint(); + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, version, unsigned, Uint, true); const int current_version = 1; - if (version > current_version) { - fail_msg_writer() << boost::format(tr("Version %u too new, we can only grok up to %u")) % version % current_version; - return false; - } - if (!json.HasMember("filename")) { - fail_msg_writer() << tr("Filename not found in JSON"); + if (field_version > current_version) { + fail_msg_writer() << boost::format(tr("Version %u too new, we can only grok up to %u")) % field_version % current_version; return false; } - std::string filename = json["filename"].GetString(); - bool recover = false; - uint64_t scan_from_height = 0; - if (json.HasMember("scan_from_height")) { - scan_from_height = json["scan_from_height"].GetUint64(); - recover = true; - } + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, filename, std::string, String, true); - password = ""; - if (json.HasMember("password")) { - password = json["password"].GetString(); - } + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, scan_from_height, uint64_t, Uint64, false); + bool recover = field_scan_from_height_found; - std::string viewkey_string(""); + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, password, std::string, String, false); + password = field_password; + + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, viewkey, std::string, String, false); crypto::secret_key viewkey; - if (json.HasMember("viewkey")) { - viewkey_string = json["viewkey"].GetString(); + if (field_viewkey_found) + { cryptonote::blobdata viewkey_data; - if(!epee::string_tools::parse_hexstr_to_binbuff(viewkey_string, viewkey_data)) + if(!epee::string_tools::parse_hexstr_to_binbuff(field_viewkey, viewkey_data)) { fail_msg_writer() << tr("failed to parse view key secret key"); return false; @@ -874,12 +862,12 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m viewkey = *reinterpret_cast(viewkey_data.data()); } - std::string spendkey_string(""); + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, spendkey, std::string, String, false); crypto::secret_key spendkey; - if (json.HasMember("spendkey")) { - spendkey_string = json["spendkey"].GetString(); + if (field_spendkey_found) + { cryptonote::blobdata spendkey_data; - if(!epee::string_tools::parse_hexstr_to_binbuff(spendkey_string, spendkey_data)) + if(!epee::string_tools::parse_hexstr_to_binbuff(field_spendkey, spendkey_data)) { fail_msg_writer() << tr("failed to parse spend key secret key"); return false; @@ -887,30 +875,32 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m spendkey = *reinterpret_cast(spendkey_data.data()); } - std::string seed(""); + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, seed, std::string, String, false); std::string old_language; - if (json.HasMember("seed")) { - seed = json["seed"].GetString(); - if (!crypto::ElectrumWords::words_to_bytes(seed, m_recovery_key, old_language)) + if (field_seed_found) + { + if (!crypto::ElectrumWords::words_to_bytes(field_seed, m_recovery_key, old_language)) { fail_msg_writer() << tr("Electrum-style word list failed verification"); return false; } - m_electrum_seed = seed; + m_electrum_seed = field_seed; m_restore_deterministic_wallet = true; } // compatibility checks - if (seed.empty() && viewkey_string.empty()) { + if (!field_seed_found && !field_viewkey_found) + { fail_msg_writer() << tr("At least one of Electrum-style word list and private view key must be specified"); return false; } - if (!seed.empty() && (!viewkey_string.empty() || !spendkey_string.empty())) { + if (field_seed_found && (field_viewkey_found || field_spendkey_found)) + { fail_msg_writer() << tr("Both Electrum-style word list and private key(s) specified"); return false; } - m_wallet_file = filename; + m_wallet_file = field_filename; bool was_deprecated_wallet = m_restore_deterministic_wallet && ((old_language == crypto::ElectrumWords::old_language_name) || crypto::ElectrumWords::get_is_old_style_seed(m_electrum_seed)); @@ -925,7 +915,7 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m try { - if (!seed.empty()) + if (!field_seed.empty()) { m_wallet->generate(m_wallet_file, password, m_recovery_key, recover, false); } @@ -941,7 +931,7 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m return false; } - if (spendkey_string.empty()) + if (field_spendkey.empty()) { m_wallet->generate(m_wallet_file, password, address, viewkey); } @@ -957,7 +947,7 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m return false; } - m_wallet->set_refresh_from_block_height(scan_from_height); + m_wallet->set_refresh_from_block_height(field_scan_from_height); wallet_file = m_wallet_file; -- cgit v1.2.3 From ead69560800057a462ba9d6102d45c12a38089c3 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 29 Mar 2016 17:52:45 +0100 Subject: simplewallet: always gracefully exit on EOF --- src/simplewallet/simplewallet.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'src/simplewallet/simplewallet.cpp') diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 04170df62..269be285f 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -257,6 +257,8 @@ bool simple_wallet::seed(const std::vector &args/* = std::vectorget_seed_language().empty()) { std::string mnemonic_language = get_mnemonic_language(); + if (mnemonic_language.empty()) + return true; m_wallet->set_seed_language(mnemonic_language); } @@ -304,6 +306,8 @@ bool simple_wallet::seed_set_language(const std::vector &args/* = s } std::string mnemonic_language = get_mnemonic_language(); + if (mnemonic_language.empty()) + return true; m_wallet->set_seed_language(mnemonic_language); m_wallet->rewrite(m_wallet_file, pwd_container.password()); return true; @@ -698,6 +702,10 @@ bool simple_wallet::ask_wallet_create_if_needed() tr("Specify wallet file name (e.g., MyWallet). If the wallet doesn't exist, it will be created.\n" "Wallet file name: ") ); + if (std::cin.eof()) + { + return false; + } valid_path = tools::wallet2::wallet_valid_path_format(wallet_path); if (!valid_path) { @@ -1020,6 +1028,8 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) if (m_electrum_seed.empty()) { m_electrum_seed = command_line::input_line("Specify Electrum seed: "); + if (std::cin.eof()) + return false; if (m_electrum_seed.empty()) { fail_msg_writer() << tr("specify a recovery parameter with the --electrum-seed=\"words list here\""); @@ -1037,6 +1047,8 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { // parse address std::string address_string = command_line::input_line("Standard address: "); + if (std::cin.eof()) + return false; if (address_string.empty()) { fail_msg_writer() << tr("No data supplied, cancelled"); return false; @@ -1052,6 +1064,8 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) // parse view secret key std::string viewkey_string = command_line::input_line("View key: "); + if (std::cin.eof()) + return false; if (viewkey_string.empty()) { fail_msg_writer() << tr("No data supplied, cancelled"); return false; @@ -1084,6 +1098,8 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { // parse address std::string address_string = command_line::input_line("Standard address: "); + if (std::cin.eof()) + return false; if (address_string.empty()) { fail_msg_writer() << tr("No data supplied, cancelled"); return false; @@ -1099,6 +1115,8 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) // parse spend secret key std::string spendkey_string = command_line::input_line("Spend key: "); + if (std::cin.eof()) + return false; if (spendkey_string.empty()) { fail_msg_writer() << tr("No data supplied, cancelled"); return false; @@ -1113,6 +1131,8 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) // parse view secret key std::string viewkey_string = command_line::input_line("View key: "); + if (std::cin.eof()) + return false; if (viewkey_string.empty()) { fail_msg_writer() << tr("No data supplied, cancelled"); return false; @@ -1232,6 +1252,8 @@ std::string simple_wallet::get_mnemonic_language() while (language_number < 0) { language_choice = command_line::input_line(tr("Enter the number corresponding to the language of your choice: ")); + if (std::cin.eof()) + return std::string(); try { language_number = std::stoi(language_choice); @@ -1270,6 +1292,8 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string "a deprecated version of the wallet. Please use the new seed that we provide.\n"); } mnemonic_language = get_mnemonic_language(); + if (mnemonic_language.empty()) + return false; } m_wallet_file = wallet_file; @@ -1397,6 +1421,8 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa message_writer(epee::log_space::console_color_green, false) << "\n" << tr("You had been using " "a deprecated version of the wallet. Please proceed to upgrade your wallet.\n"); std::string mnemonic_language = get_mnemonic_language(); + if (mnemonic_language.empty()) + return false; m_wallet->set_seed_language(mnemonic_language); m_wallet->rewrite(m_wallet_file, password); @@ -2013,6 +2039,10 @@ bool simple_wallet::transfer_main(bool new_algorithm, const std::vector &args_) print_money(total_fee)).str(); } std::string accepted = command_line::input_line(prompt_str); + if (std::cin.eof()) + return true; if (accepted != "Y" && accepted != "y" && accepted != "Yes" && accepted != "yes") { fail_msg_writer() << tr("transaction cancelled."); -- cgit v1.2.3 From 48d0747d005c80fde3837fc4bcdb3eff26907d74 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 2 Apr 2016 13:06:39 +0100 Subject: wallet: better output selection for transfer/transfer_new This now requests the set of outputs that can be mixed first, to avoid trying non dust but unmixable outputs, which we know will fail. --- src/simplewallet/simplewallet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/simplewallet/simplewallet.cpp') diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index aa571755f..f42937606 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2133,9 +2133,9 @@ bool simple_wallet::transfer_main(bool new_algorithm, const std::vector ptx_vector; if (new_algorithm) - ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra); + ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra, m_trusted_daemon); else - ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra); + ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra, m_trusted_daemon); // if more than one tx necessary, prompt user to confirm if (m_wallet->always_confirm_transfers() || ptx_vector.size() > 1) -- cgit v1.2.3 From 1a58d202b2334617e3b877c9471cbbd4ca03a508 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 2 Apr 2016 15:22:59 +0100 Subject: simplewallet: optional address in --generate-from-json When present, it can be used to validate the keys, as well as deduce the spend key, if it is absent (watch wallet). --- src/simplewallet/simplewallet.cpp | 71 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 5 deletions(-) (limited to 'src/simplewallet/simplewallet.cpp') diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index aa571755f..6c0e7425a 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -829,6 +829,8 @@ static bool get_password(const boost::program_options::variables_map& vm, bool a //---------------------------------------------------------------------------------------------------- bool simple_wallet::generate_from_json(const boost::program_options::variables_map& vm, std::string &wallet_file, std::string &password) { + bool testnet = command_line::get_arg(vm, arg_testnet); + std::string buf; bool r = epee::file_io_utils::load_file_to_string(m_generate_from_json, buf); if (!r) { @@ -868,6 +870,11 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m return false; } viewkey = *reinterpret_cast(viewkey_data.data()); + crypto::public_key pkey; + if (!crypto::secret_key_to_public_key(viewkey, pkey)) { + fail_msg_writer() << tr("failed to verify view key secret key"); + return false; + } } GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, spendkey, std::string, String, false); @@ -881,6 +888,11 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m return false; } spendkey = *reinterpret_cast(spendkey_data.data()); + crypto::public_key pkey; + if (!crypto::secret_key_to_public_key(spendkey, pkey)) { + fail_msg_writer() << tr("failed to verify spend key secret key"); + return false; + } } GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, seed, std::string, String, false); @@ -896,6 +908,8 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m m_restore_deterministic_wallet = true; } + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, address, std::string, String, false); + // compatibility checks if (!field_seed_found && !field_viewkey_found) { @@ -908,6 +922,44 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m return false; } + // if an address was given, we check keys against it, and deduce the spend + // public key if it was not given + if (field_address_found) + { + cryptonote::account_public_address address; + bool has_payment_id; + crypto::hash8 new_payment_id; + if(!get_account_integrated_address_from_str(address, has_payment_id, new_payment_id, testnet, field_address)) + { + fail_msg_writer() << tr("invalid address"); + return false; + } + if (field_viewkey_found) + { + crypto::public_key pkey; + if (!crypto::secret_key_to_public_key(viewkey, pkey)) { + fail_msg_writer() << tr("failed to verify view key secret key"); + return false; + } + if (address.m_view_public_key != pkey) { + fail_msg_writer() << tr("view key does not match standard address"); + return false; + } + } + if (field_spendkey_found) + { + crypto::public_key pkey; + if (!crypto::secret_key_to_public_key(spendkey, pkey)) { + fail_msg_writer() << tr("failed to verify spend key secret key"); + return false; + } + if (address.m_spend_public_key != pkey) { + fail_msg_writer() << tr("spend key does not match standard address"); + return false; + } + } + } + m_wallet_file = field_filename; bool was_deprecated_wallet = m_restore_deterministic_wallet && ((old_language == crypto::ElectrumWords::old_language_name) || @@ -917,7 +969,6 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m return false; } - bool testnet = command_line::get_arg(vm, arg_testnet); m_wallet.reset(new tools::wallet2(testnet)); m_wallet->callback(this); @@ -934,17 +985,27 @@ bool simple_wallet::generate_from_json(const boost::program_options::variables_m fail_msg_writer() << tr("failed to verify view key secret key"); return false; } - if (!crypto::secret_key_to_public_key(spendkey, address.m_spend_public_key)) { - fail_msg_writer() << tr("failed to verify spend key secret key"); - return false; - } if (field_spendkey.empty()) { + // if we have an addres but no spend key, we can deduce the spend public key + // from the address + if (field_address_found) + { + cryptonote::account_public_address address2; + bool has_payment_id; + crypto::hash8 new_payment_id; + get_account_integrated_address_from_str(address2, has_payment_id, new_payment_id, testnet, field_address); + address.m_spend_public_key = address2.m_spend_public_key; + } m_wallet->generate(m_wallet_file, password, address, viewkey); } else { + if (!crypto::secret_key_to_public_key(spendkey, address.m_spend_public_key)) { + fail_msg_writer() << tr("failed to verify spend key secret key"); + return false; + } m_wallet->generate(m_wallet_file, password, address, spendkey, viewkey); } } -- cgit v1.2.3 From ed61a2ccc1bc38a8e58ecef17e5831d1e406cd0b Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 6 Apr 2016 20:00:25 +0100 Subject: simplewallet: set strict umask at start --- src/simplewallet/simplewallet.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/simplewallet/simplewallet.cpp') diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index aa571755f..3d1410f43 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2807,6 +2807,7 @@ int main(int argc, char* argv[]) std::string lang = i18n_get_language(); tools::sanitize_locale(); + tools::set_strict_default_file_permissions(true); string_tools::set_module_name_and_folder(argv[0]); -- cgit v1.2.3 From f17b2f42b28844657624e8ea41172b34f17fb2e3 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 3 Apr 2016 12:51:28 +0100 Subject: rpc: add pool/blockchain and block height results to gettransactions --- src/simplewallet/simplewallet.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/simplewallet/simplewallet.cpp') diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index aa571755f..30c958381 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2497,13 +2497,18 @@ bool simple_wallet::check_tx_key(const std::vector &args_) COMMAND_RPC_GET_TRANSACTIONS::response res; req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txid)); if (!net_utils::invoke_http_json_remote_command2(m_daemon_address + "/gettransactions", req, res, m_http_client) || - res.txs_as_hex.empty()) + (res.txs.empty() && res.txs_as_hex.empty())) { fail_msg_writer() << tr("failed to get transaction from daemon"); return true; } cryptonote::blobdata tx_data; - if (!string_tools::parse_hexstr_to_binbuff(res.txs_as_hex.front(), tx_data)) + bool ok; + if (!res.txs.empty()) + ok = string_tools::parse_hexstr_to_binbuff(res.txs.front().as_hex, tx_data); + else + ok = string_tools::parse_hexstr_to_binbuff(res.txs_as_hex.front(), tx_data); + if (!ok) { fail_msg_writer() << tr("failed to parse transaction from daemon"); return true; -- cgit v1.2.3 From c33ffc8e9420e1f530f84d44af611cd21e954e30 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 10 Apr 2016 16:56:12 +0100 Subject: simplewallet: save fixes in RPC mode ^C when in RPC mode would not save the wallet while it was still refreshing after starting up. Also, save the wallet out of the signal handler. We don't want to call complex stuff in a signal handler. --- src/simplewallet/simplewallet.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src/simplewallet/simplewallet.cpp') diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index aa571755f..8c445dc21 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2963,12 +2963,25 @@ int main(int argc, char* argv[]) } tools::wallet2 wal(testnet,restricted); + bool quit = false; + tools::signal_handler::install([&wal, &quit](int) { + quit = true; + wal.stop(); + }); try { LOG_PRINT_L0(sw::tr("Loading wallet...")); wal.load(wallet_file, password); wal.init(daemon_address); wal.refresh(); + // if we ^C during potentially length load/refresh, there's no server loop yet + if (quit) + { + LOG_PRINT_L0(sw::tr("Storing wallet...")); + wal.store(); + LOG_PRINT_GREEN(sw::tr("Stored ok"), LOG_LEVEL_0); + return 1; + } LOG_PRINT_GREEN(sw::tr("Loaded ok"), LOG_LEVEL_0); } catch (const std::exception& e) @@ -2979,10 +2992,8 @@ int main(int argc, char* argv[]) tools::wallet_rpc_server wrpc(wal); bool r = wrpc.init(vm); CHECK_AND_ASSERT_MES(r, 1, sw::tr("Failed to initialize wallet rpc server")); - tools::signal_handler::install([&wrpc, &wal](int) { wrpc.send_stop_signal(); - wal.store(); }); LOG_PRINT_L0(sw::tr("Starting wallet rpc server")); wrpc.run(); -- cgit v1.2.3