From 01efdc6a7e5fb541a779a06e0158c2c8b8f811b3 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 16 Mar 2019 11:48:05 +0000 Subject: [PATCH 1/5] wallet_rpc_server: set confirmations to 0 for pending/pool txes --- src/wallet/wallet_rpc_server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index f80263007..5c95d94bb 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -85,7 +85,7 @@ namespace //------------------------------------------------------------------------------------------------------------------------------ void set_confirmations(tools::wallet_rpc::transfer_entry &entry, uint64_t blockchain_height, uint64_t block_reward) { - if (entry.height >= blockchain_height) + if (entry.height >= blockchain_height || (entry.height == 0 && (!strcmp(entry.type.c_str(), "pending") || !strcmp(entry.type.c_str(), "pool")))) { entry.confirmations = 0; entry.suggested_confirmations_threshold = 0; From f82bc29ec2f29ebd6c08c744bcd434ce4f595b49 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 16 Mar 2019 13:17:11 +0000 Subject: [PATCH 2/5] wallet_rpc_server: always fill out subaddr_indices in get_transfers It was not filled out for in and pool types --- src/wallet/wallet_rpc_server.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 5c95d94bb..a9bb63e2b 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -302,6 +302,7 @@ namespace tools entry.note = m_wallet->get_tx_note(pd.m_tx_hash); entry.type = pd.m_coinbase ? "block" : "in"; entry.subaddr_index = pd.m_subaddr_index; + entry.subaddr_indices.push_back(pd.m_subaddr_index); entry.address = m_wallet->get_subaddress_as_str(pd.m_subaddr_index); set_confirmations(entry, m_wallet->get_blockchain_current_height(), m_wallet->get_last_block_reward()); } @@ -373,6 +374,7 @@ namespace tools entry.double_spend_seen = ppd.m_double_spend_seen; entry.type = "pool"; entry.subaddr_index = pd.m_subaddr_index; + entry.subaddr_indices.push_back(pd.m_subaddr_index); entry.address = m_wallet->get_subaddress_as_str(pd.m_subaddr_index); set_confirmations(entry, m_wallet->get_blockchain_current_height(), m_wallet->get_last_block_reward()); } From 705acbac4d2bd831517505d1a352381bdf5be000 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 16 Mar 2019 13:33:11 +0000 Subject: [PATCH 3/5] wallet2: init some variables to default values if loading old wallets --- src/wallet/wallet2.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 439873932..8b2af6eca 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3589,13 +3589,16 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_ m_multisig_derivations.clear(); m_always_confirm_transfers = false; m_print_ring_members = false; + m_store_tx_info = true; m_default_mixin = 0; m_default_priority = 0; m_auto_refresh = true; m_refresh_type = RefreshType::RefreshDefault; + m_refresh_from_block_height = 0; m_confirm_missing_payment_id = true; m_confirm_non_default_ring_size = true; m_ask_password = AskPasswordToDecrypt; + cryptonote::set_default_decimal_point(CRYPTONOTE_DISPLAY_DECIMAL_POINT); m_min_output_count = 0; m_min_output_value = 0; m_merge_destinations = false; From 67aa4adcfcd8ce06d2dbd9605df6af3d2a67e0da Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 18 Mar 2019 11:45:31 +0000 Subject: [PATCH 4/5] wallet_rpc_server: add a set_daemon RPC --- src/wallet/wallet2.cpp | 22 +++++++++---- src/wallet/wallet2.h | 6 ++++ src/wallet/wallet_rpc_server.cpp | 34 ++++++++++++++++++++ src/wallet/wallet_rpc_server.h | 2 ++ src/wallet/wallet_rpc_server_commands_defs.h | 34 ++++++++++++++++++++ 5 files changed, 91 insertions(+), 7 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 8b2af6eca..3f041105d 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1154,23 +1154,31 @@ std::unique_ptr wallet2::make_dummy(const boost::program_options::varia } //---------------------------------------------------------------------------------------------------- -bool wallet2::init(std::string daemon_address, boost::optional daemon_login, boost::asio::ip::tcp::endpoint proxy, uint64_t upper_transaction_weight_limit, bool trusted_daemon, epee::net_utils::ssl_support_t ssl_support, const std::pair &private_key_and_certificate_path, const std::list &allowed_certificates, const std::vector> &allowed_fingerprints, bool allow_any_cert) +bool wallet2::set_daemon(std::string daemon_address, boost::optional daemon_login, bool trusted_daemon, + epee::net_utils::ssl_support_t ssl_support, const std::pair &private_key_and_certificate_path, + const std::list &allowed_certificates, const std::vector> &allowed_fingerprints, + bool allow_any_cert) { - m_checkpoints.init_default_checkpoints(m_nettype); if(m_http_client.is_connected()) m_http_client.disconnect(); - m_is_initialized = true; - m_upper_transaction_weight_limit = upper_transaction_weight_limit; m_daemon_address = std::move(daemon_address); m_daemon_login = std::move(daemon_login); m_trusted_daemon = trusted_daemon; - if (proxy != boost::asio::ip::tcp::endpoint{}) - m_http_client.set_connector(net::socks::connector{std::move(proxy)}); - // When switching from light wallet to full wallet, we need to reset the height we got from lw node. + MINFO("setting daemon to " << get_daemon_address()); return m_http_client.set_server(get_daemon_address(), get_daemon_login(), ssl_support, private_key_and_certificate_path, allowed_certificates, allowed_fingerprints, allow_any_cert); } //---------------------------------------------------------------------------------------------------- +bool wallet2::init(std::string daemon_address, boost::optional daemon_login, boost::asio::ip::tcp::endpoint proxy, uint64_t upper_transaction_weight_limit, bool trusted_daemon, epee::net_utils::ssl_support_t ssl_support, const std::pair &private_key_and_certificate_path, const std::list &allowed_certificates, const std::vector> &allowed_fingerprints, bool allow_any_cert) +{ + m_checkpoints.init_default_checkpoints(m_nettype); + m_is_initialized = true; + m_upper_transaction_weight_limit = upper_transaction_weight_limit; + if (proxy != boost::asio::ip::tcp::endpoint{}) + m_http_client.set_connector(net::socks::connector{std::move(proxy)}); + return set_daemon(daemon_address, daemon_login, trusted_daemon, ssl_support, private_key_and_certificate_path, allowed_certificates, allowed_fingerprints, allow_any_cert); +} +//---------------------------------------------------------------------------------------------------- bool wallet2::is_deterministic() const { crypto::secret_key second; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 28ebd6704..2bc11d2f7 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -689,6 +689,12 @@ namespace tools const std::pair &private_key_and_certificate_path = {}, const std::list &allowed_certificates = {}, const std::vector> &allowed_fingerprints = {}, bool allow_any_cert = false); + bool set_daemon(std::string daemon_address = "http://localhost:8080", + boost::optional daemon_login = boost::none, bool trusted_daemon = true, + epee::net_utils::ssl_support_t ssl_support = epee::net_utils::ssl_support_t::e_ssl_support_autodetect, + const std::pair &private_key_and_certificate_path = {}, + const std::list &allowed_certificates = {}, const std::vector> &allowed_fingerprints = {}, + bool allow_any_cert = false); void stop() { m_run.store(false, std::memory_order_relaxed); m_message_store.stop(); } diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index a9bb63e2b..e0a77e34c 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -4033,6 +4033,40 @@ namespace tools return false; } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_set_daemon(const wallet_rpc::COMMAND_RPC_SET_DAEMON::request& req, wallet_rpc::COMMAND_RPC_SET_DAEMON::response& res, epee::json_rpc::error& er, const connection_context *ctx) + { + if (!m_wallet) return not_open(er); + if (m_restricted) + { + er.code = WALLET_RPC_ERROR_CODE_DENIED; + er.message = "Command unavailable in restricted mode."; + return false; + } + epee::net_utils::ssl_support_t ssl_support; + if (!epee::net_utils::ssl_support_from_string(ssl_support, req.ssl_support)) + { + er.code = WALLET_RPC_ERROR_CODE_NO_DAEMON_CONNECTION; + er.message = std::string("Invalid ssl support mode"); + return false; + } + std::vector> ssl_allowed_fingerprints; + ssl_allowed_fingerprints.reserve(req.ssl_allowed_fingerprints.size()); + for (const std::string &fp: req.ssl_allowed_fingerprints) + { + ssl_allowed_fingerprints.push_back({}); + std::vector &v = ssl_allowed_fingerprints.back(); + for (auto c: fp) + v.push_back(c); + } + if (!m_wallet->set_daemon(req.address, boost::none, req.trusted, ssl_support, std::make_pair(req.ssl_private_key_path, req.ssl_certificate_path), req.ssl_allowed_certificates, ssl_allowed_fingerprints, req.ssl_allow_any_cert)) + { + er.code = WALLET_RPC_ERROR_CODE_NO_DAEMON_CONNECTION; + er.message = std::string("Unable to set daemon"); + return false; + } + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_get_version(const wallet_rpc::COMMAND_RPC_GET_VERSION::request& req, wallet_rpc::COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& er, const connection_context *ctx) { res.version = WALLET_RPC_VERSION; diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 2b52275b8..fb0c48a80 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -150,6 +150,7 @@ namespace tools MAP_JON_RPC_WE("sign_multisig", on_sign_multisig, wallet_rpc::COMMAND_RPC_SIGN_MULTISIG) MAP_JON_RPC_WE("submit_multisig", on_submit_multisig, wallet_rpc::COMMAND_RPC_SUBMIT_MULTISIG) MAP_JON_RPC_WE("validate_address", on_validate_address, wallet_rpc::COMMAND_RPC_VALIDATE_ADDRESS) + MAP_JON_RPC_WE("set_daemon", on_set_daemon, wallet_rpc::COMMAND_RPC_SET_DAEMON) MAP_JON_RPC_WE("get_version", on_get_version, wallet_rpc::COMMAND_RPC_GET_VERSION) END_JSON_RPC_MAP() END_URI_MAP2() @@ -232,6 +233,7 @@ namespace tools bool on_sign_multisig(const wallet_rpc::COMMAND_RPC_SIGN_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_SIGN_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_submit_multisig(const wallet_rpc::COMMAND_RPC_SUBMIT_MULTISIG::request& req, wallet_rpc::COMMAND_RPC_SUBMIT_MULTISIG::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_validate_address(const wallet_rpc::COMMAND_RPC_VALIDATE_ADDRESS::request& req, wallet_rpc::COMMAND_RPC_VALIDATE_ADDRESS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); + bool on_set_daemon(const wallet_rpc::COMMAND_RPC_SET_DAEMON::request& req, wallet_rpc::COMMAND_RPC_SET_DAEMON::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); bool on_get_version(const wallet_rpc::COMMAND_RPC_GET_VERSION::request& req, wallet_rpc::COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL); //json rpc v2 diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index de3067a52..298f34f66 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -2437,5 +2437,39 @@ namespace wallet_rpc typedef epee::misc_utils::struct_init response; }; + struct COMMAND_RPC_SET_DAEMON + { + struct request_t + { + std::string address; + bool trusted; + std::string ssl_support; // disabled, enabled, autodetect + std::string ssl_private_key_path; + std::string ssl_certificate_path; + std::list ssl_allowed_certificates; + std::vector ssl_allowed_fingerprints; + bool ssl_allow_any_cert; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(address) + KV_SERIALIZE_OPT(trusted, false) + KV_SERIALIZE_OPT(ssl_support, (std::string)"autodetect") + KV_SERIALIZE(ssl_private_key_path) + KV_SERIALIZE(ssl_certificate_path) + KV_SERIALIZE(ssl_allowed_certificates) + KV_SERIALIZE(ssl_allowed_fingerprints) + KV_SERIALIZE_OPT(ssl_allow_any_cert, false) + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init request; + + struct response_t + { + BEGIN_KV_SERIALIZE_MAP() + END_KV_SERIALIZE_MAP() + }; + typedef epee::misc_utils::struct_init response; + }; + } } From f825055d224f9757d49dcc21c87d5d8b56d5fbc5 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 19 Mar 2019 01:07:46 +0000 Subject: [PATCH 5/5] wallet_rpc_server: error out on getting the spend key from a hot wallet --- src/wallet/wallet_rpc_server.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index e0a77e34c..95cda7f1e 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -1832,7 +1832,7 @@ namespace tools if (m_wallet->watch_only()) { er.code = WALLET_RPC_ERROR_CODE_WATCH_ONLY; - er.message = "The wallet is watch-only. Cannot display seed."; + er.message = "The wallet is watch-only. Cannot retrieve seed."; return false; } if (!m_wallet->is_deterministic()) @@ -1857,6 +1857,12 @@ namespace tools } else if(req.key_type.compare("spend_key") == 0) { + if (m_wallet->watch_only()) + { + er.code = WALLET_RPC_ERROR_CODE_WATCH_ONLY; + er.message = "The wallet is watch-only. Cannot retrieve spend key."; + return false; + } epee::wipeable_string key = epee::to_hex::wipeable_string(m_wallet->get_account().get_keys().m_spend_secret_key); res.key = std::string(key.data(), key.size()); }