From 015847b0d0f0a93745e46a47de6753b8a8f1195d Mon Sep 17 00:00:00 2001 From: Oran Juice Date: Sun, 12 Apr 2015 10:11:21 +0530 Subject: [PATCH] Manage inability to connect to daemon correctly. --- src/simplewallet/simplewallet.cpp | 10 +------ src/wallet/wallet2.cpp | 45 ++++++++++++++++--------------- src/wallet/wallet2.h | 18 +++++-------- 3 files changed, 31 insertions(+), 42 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 1d32e930d..5c36c89c5 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -1069,13 +1069,12 @@ bool simple_wallet::show_blockchain_height(const std::vector& args) //---------------------------------------------------------------------------------------------------- bool simple_wallet::transfer(const std::vector &args_) { + // TODO: Find a way to check if daemon is connectible via 0MQ. /*if (!try_connect_to_daemon()) return true;*/ -std::cout << "1\n"; std::vector local_args = args_; -std::cout << "2\n"; size_t fake_outs_count; if(local_args.size() > 0) { if(!epee::string_tools::get_xtype_from_string(fake_outs_count, local_args[0])) @@ -1094,7 +1093,6 @@ std::cout << "2\n"; return true; } -std::cout << "3\n"; std::vector extra; if (1 == local_args.size() % 2) { @@ -1117,7 +1115,6 @@ std::cout << "3\n"; } } -std::cout << "4\n"; vector dsts; for (size_t i = 0; i < local_args.size(); i += 2) { @@ -1192,17 +1189,14 @@ std::cout << "4\n"; dsts.push_back(de); } -std::cout << "5\n"; try { // figure out what tx will be necessary auto ptx_vector = m_wallet->create_transactions(dsts, fake_outs_count, 0 /* unlock_time */, 0 /* unused fee arg*/, extra); -std::cout << "5a\n"; // if more than one tx necessary, prompt user to confirm if (ptx_vector.size() > 1) { -std::cout << "5b\n"; std::string prompt_str = "Your transaction needs to be split into "; prompt_str += std::to_string(ptx_vector.size()); prompt_str += " transactions. This will result in a transaction fee being applied to each transaction"; @@ -1218,7 +1212,6 @@ std::cout << "5b\n"; } } -std::cout << "6\n"; // actually commit the transactions while (!ptx_vector.empty()) { @@ -1236,7 +1229,6 @@ std::cout << "6\n"; } catch (const tools::error::no_connection_to_daemon&) { -std::cout << "7\n"; fail_msg_writer() << "no connection to daemon. Please, make sure daemon is running."; } catch (const tools::error::wallet_rpc_error& e) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 0d6ad02b9..5838f9ca1 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -171,19 +171,14 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_ if(!outs.empty() && tx_money_got_in_outs) { + connect_to_daemon(); + THROW_WALLET_EXCEPTION_IF(ipc_client == NULL, error::no_connection_to_daemon, "get_output_indexes"); + //good news - got money! take care about it //usually we have only one transfer for user in transaction cryptonote::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request req = AUTO_VAL_INIT(req); cryptonote::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response res = AUTO_VAL_INIT(res); crypto::hash tx_id = get_transaction_hash(tx); - //req.txid = get_transaction_hash(tx); - /*bool r = net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/get_o_indexes.bin", req, res, m_http_client, WALLET_RCP_CONNECTION_TIMEOUT); - THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_o_indexes.bin"); - THROW_WALLET_EXCEPTION_IF(res.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "get_o_indexes.bin"); - THROW_WALLET_EXCEPTION_IF(res.status != CORE_RPC_STATUS_OK, error::get_out_indices_error, res.status); - THROW_WALLET_EXCEPTION_IF(res.o_indexes.size() != tx.vout.size(), error::wallet_internal_error, - "transactions outputs size=" + std::to_string(tx.vout.size()) + - " not match with COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES response size=" + std::to_string(res.o_indexes.size()));*/ zchunk_t *tx_id_chunk = zchunk_new(tx_id.data, crypto::HASH_SIZE); int rc = wap_client_output_indexes(ipc_client, &tx_id_chunk); @@ -354,6 +349,8 @@ void wallet2::get_blocks_from_zmq_msg(zmsg_t *msg, std::list block_ids; get_short_chain_history(block_ids); @@ -373,12 +370,12 @@ void wallet2::pull_blocks(uint64_t start_height, size_t& blocks_added) delete *it; } zlist_destroy(&list); - THROW_WALLET_EXCEPTION_IF(rc < 0, error::no_connection_to_daemon, "getblocks"); + THROW_WALLET_EXCEPTION_IF(rc < 0, error::no_connection_to_daemon, "get_blocks"); uint64_t status = wap_client_status(ipc_client); - THROW_WALLET_EXCEPTION_IF(status == IPC::STATUS_CORE_BUSY, error::daemon_busy, "getblocks"); - THROW_WALLET_EXCEPTION_IF(status == IPC::STATUS_INTERNAL_ERROR, error::daemon_internal_error, "getblocks"); - THROW_WALLET_EXCEPTION_IF(status != IPC::STATUS_OK, error::get_blocks_error, "getblocks"); + THROW_WALLET_EXCEPTION_IF(status == IPC::STATUS_CORE_BUSY, error::daemon_busy, "get_blocks"); + THROW_WALLET_EXCEPTION_IF(status == IPC::STATUS_INTERNAL_ERROR, error::daemon_internal_error, "get_blocks"); + THROW_WALLET_EXCEPTION_IF(status != IPC::STATUS_OK, error::get_blocks_error, "get_blocks"); std::list blocks; zmsg_t *msg = wap_client_block_data(ipc_client); get_blocks_from_zmq_msg(msg, blocks); @@ -1127,19 +1124,14 @@ std::string wallet2::address_from_txt_record(const std::string& s) void wallet2::commit_tx(pending_tx& ptx) { using namespace cryptonote; - /*COMMAND_RPC_SEND_RAW_TX::request req; - req.tx_as_hex = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(ptx.tx)); - COMMAND_RPC_SEND_RAW_TX::response daemon_send_resp; - bool r = epee::net_utils::invoke_http_json_remote_command2(m_daemon_address + "/sendrawtransaction", req, daemon_send_resp, m_http_client, 200000); - THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "sendrawtransaction"); - THROW_WALLET_EXCEPTION_IF(daemon_send_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "sendrawtransaction"); - THROW_WALLET_EXCEPTION_IF(daemon_send_resp.status != CORE_RPC_STATUS_OK, error::tx_rejected, ptx.tx, daemon_send_resp.status);*/ + connect_to_daemon(); + THROW_WALLET_EXCEPTION_IF(ipc_client == NULL, error::no_connection_to_daemon, "send_raw_transaction"); std::string tx_as_hex_string = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(ptx.tx)); zchunk_t *tx_as_hex = zchunk_new((void*)tx_as_hex_string.c_str(), tx_as_hex_string.length()); int rc = wap_client_put(ipc_client, &tx_as_hex); uint64_t status = wap_client_status(ipc_client); - THROW_WALLET_EXCEPTION_IF(status == IPC::STATUS_CORE_BUSY, error::daemon_busy, "sendrawtransaction"); + THROW_WALLET_EXCEPTION_IF(status == IPC::STATUS_CORE_BUSY, error::daemon_busy, "send_raw_transaction"); THROW_WALLET_EXCEPTION_IF((status == IPC::STATUS_INVALID_TX) || (status == IPC::STATUS_TX_VERIFICATION_FAILED) || (status == IPC::STATUS_TX_NOT_RELAYED), error::tx_rejected, ptx.tx, status); @@ -1281,6 +1273,17 @@ void wallet2::generate_genesis(cryptonote::block& b) { } void wallet2::stop_ipc_client() { - wap_client_destroy(&ipc_client); + if (ipc_client) { + wap_client_destroy(&ipc_client); + } +} + +void wallet2::connect_to_daemon() { + if (ipc_client) { + // TODO: Instead, check if daemon is reachable. + return; + } + ipc_client = wap_client_new(); + wap_client_connect(ipc_client, "ipc://@/monero", 200, "wallet identity"); } } diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index ee4986899..a74d8cd62 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -84,11 +84,11 @@ namespace tools wallet2(const wallet2&) : m_run(true), m_callback(0), m_testnet(false) {}; public: wallet2(bool testnet = false, bool restricted = false) : m_run(true), m_callback(0), m_testnet(testnet) { - ipc_client = wap_client_new(); - wap_client_connect(ipc_client, "ipc://@/monero", 200, "wallet identity"); + connect_to_daemon(); if (!ipc_client) { std::cout << "Couldn't connect to daemon\n\n"; - // TODO: Daemon not up. + // Let ipc_client remain null. All request sending code will verify that + // it's not null and otherwise throw. } }; struct transfer_details @@ -290,6 +290,7 @@ namespace tools void add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t change_amount); void generate_genesis(cryptonote::block& b); void check_genesis(const crypto::hash& genesis_hash); //throws + void connect_to_daemon(); cryptonote::account_base m_account; std::string m_daemon_address; @@ -458,8 +459,8 @@ namespace tools COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response daemon_resp = AUTO_VAL_INIT(daemon_resp); if(fake_outputs_count) { - // COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request req = AUTO_VAL_INIT(req); - // req.outs_count = fake_outputs_count + 1;// add one to make possible (if need) to skip real output key + connect_to_daemon(); + THROW_WALLET_EXCEPTION_IF(ipc_client == NULL, error::no_connection_to_daemon, "get_random_outs"); uint64_t outs_count = fake_outputs_count + 1; std::vector amounts; BOOST_FOREACH(transfer_container::iterator it, selected_transfers) @@ -472,13 +473,6 @@ namespace tools zframe_t *amounts_frame = zframe_new(&amounts[0], amounts.size() * sizeof(uint64_t)); int rc = wap_client_random_outs(ipc_client, outs_count, &amounts_frame); - /*bool r = epee::net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/getrandom_outs.bin", req, daemon_resp, m_http_client, 200000); - THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "getrandom_outs.bin"); - THROW_WALLET_EXCEPTION_IF(daemon_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "getrandom_outs.bin"); - THROW_WALLET_EXCEPTION_IF(daemon_resp.status != CORE_RPC_STATUS_OK, error::get_random_outs_error, daemon_resp.status); - THROW_WALLET_EXCEPTION_IF(daemon_resp.outs.size() != selected_transfers.size(), error::wallet_internal_error, - "daemon returned wrong response for getrandom_outs.bin, wrong amounts count = " + - std::to_string(daemon_resp.outs.size()) + ", expected " + std::to_string(selected_transfers.size()));*/ uint64_t status = wap_client_status(ipc_client); THROW_WALLET_EXCEPTION_IF(status == IPC::STATUS_CORE_BUSY, error::daemon_busy, "getrandomouts");