Skip to content

Commit

Permalink
Add a daemon RPC version, and make simplewallet check it
Browse files Browse the repository at this point in the history
If the version is different, simplewallet will refuse to use that
daemon, unless --allow-mismatched-daemon-version is used.
  • Loading branch information
moneromooo-monero committed Jul 10, 2016
1 parent 18dd507 commit 014f3a0
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 18 deletions.
7 changes: 7 additions & 0 deletions src/rpc/core_rpc_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,13 @@ namespace cryptonote
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_get_version(const COMMAND_RPC_GET_VERSION::request& req, COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& error_resp)
{
res.version = CORE_RPC_VERSION;
res.status = CORE_RPC_STATUS_OK;
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_fast_exit(const COMMAND_RPC_FAST_EXIT::request& req, COMMAND_RPC_FAST_EXIT::response& res)
{
cryptonote::core::set_fast_exit();
Expand Down
2 changes: 2 additions & 0 deletions src/rpc/core_rpc_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ namespace cryptonote
MAP_JON_RPC_WE_IF("getbans", on_get_bans, COMMAND_RPC_GETBANS, !m_restricted)
MAP_JON_RPC_WE_IF("flush_txpool", on_flush_txpool, COMMAND_RPC_FLUSH_TRANSACTION_POOL, !m_restricted)
MAP_JON_RPC_WE("get_output_histogram", on_get_output_histogram, COMMAND_RPC_GET_OUTPUT_HISTOGRAM)
MAP_JON_RPC_WE("get_version", on_get_version, COMMAND_RPC_GET_VERSION)
END_JSON_RPC_MAP()
END_URI_MAP2()

Expand Down Expand Up @@ -153,6 +154,7 @@ namespace cryptonote
bool on_get_bans(const COMMAND_RPC_GETBANS::request& req, COMMAND_RPC_GETBANS::response& res, epee::json_rpc::error& error_resp);
bool on_flush_txpool(const COMMAND_RPC_FLUSH_TRANSACTION_POOL::request& req, COMMAND_RPC_FLUSH_TRANSACTION_POOL::response& res, epee::json_rpc::error& error_resp);
bool on_get_output_histogram(const COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request& req, COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response& res, epee::json_rpc::error& error_resp);
bool on_get_version(const COMMAND_RPC_GET_VERSION::request& req, COMMAND_RPC_GET_VERSION::response& res, epee::json_rpc::error& error_resp);
//-----------------------

private:
Expand Down
22 changes: 22 additions & 0 deletions src/rpc/core_rpc_server_commands_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ namespace cryptonote
#define CORE_RPC_STATUS_BUSY "BUSY"
#define CORE_RPC_STATUS_NOT_MINING "NOT MINING"

#define CORE_RPC_VERSION 1

struct COMMAND_RPC_GET_HEIGHT
{
struct request
Expand Down Expand Up @@ -1102,5 +1104,25 @@ namespace cryptonote
END_KV_SERIALIZE_MAP()
};
};

struct COMMAND_RPC_GET_VERSION
{
struct request
{
BEGIN_KV_SERIALIZE_MAP()
END_KV_SERIALIZE_MAP()
};

struct response
{
std::string status;
uint32_t version;

BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(status)
KV_SERIALIZE(version)
END_KV_SERIALIZE_MAP()
};
};
}

33 changes: 25 additions & 8 deletions src/simplewallet/simplewallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ namespace
const command_line::arg_descriptor<bool> arg_testnet = {"testnet", sw::tr("For testnet. Daemon must also be launched with --testnet flag"), false};
const command_line::arg_descriptor<bool> arg_restricted = {"restricted-rpc", sw::tr("Restricts RPC to view-only commands"), false};
const command_line::arg_descriptor<bool> arg_trusted_daemon = {"trusted-daemon", sw::tr("Enable commands which rely on a trusted daemon"), false};
const command_line::arg_descriptor<bool> arg_allow_mismatched_daemon_version = {"allow-mismatched-daemon-version", sw::tr("Allow communicating with a daemon that uses a different RPC version"), false};
const command_line::arg_descriptor<uint64_t> arg_restore_height = {"restore-height", sw::tr("Restore from specific blockchain height"), 0};

const command_line::arg_descriptor< std::vector<std::string> > arg_command = {"command", ""};
Expand Down Expand Up @@ -623,7 +624,8 @@ bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<st
}

simple_wallet::simple_wallet()
: m_daemon_port(0)
: m_allow_mismatched_daemon_version(false)
, m_daemon_port(0)
, m_refresh_progress_reporter(*this)
, m_auto_refresh_run(false)
, m_auto_refresh_refreshing(false)
Expand Down Expand Up @@ -1439,18 +1441,28 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_
m_restore_deterministic_wallet = command_line::get_arg(vm, arg_restore_deterministic_wallet);
m_non_deterministic = command_line::get_arg(vm, arg_non_deterministic);
m_trusted_daemon = command_line::get_arg(vm, arg_trusted_daemon);
m_allow_mismatched_daemon_version = command_line::get_arg(vm, arg_allow_mismatched_daemon_version);
m_restore_height = command_line::get_arg(vm, arg_restore_height);

return true;
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::try_connect_to_daemon()
bool simple_wallet::try_connect_to_daemon(bool silent)
{
if (!m_wallet->check_connection())
bool same_version = false;
if (!m_wallet->check_connection(&same_version))
{
fail_msg_writer() << tr("wallet failed to connect to daemon: ") << m_daemon_address << ". " <<
tr("Daemon either is not started or wrong port was passed. "
"Please make sure daemon is running or restart the wallet with the correct daemon address.");
if (!silent)
fail_msg_writer() << tr("wallet failed to connect to daemon: ") << m_daemon_address << ". " <<
tr("Daemon either is not started or wrong port was passed. "
"Please make sure daemon is running or restart the wallet with the correct daemon address.");
return false;
}
if (!m_allow_mismatched_daemon_version && !same_version)
{
if (!silent)
fail_msg_writer() << tr("Daemon uses a different RPC version that the wallet: ") << m_daemon_address << ". " <<
tr("Either update one of them, or use --allow-mismatched-daemon-version.");
return false;
}
return true;
Expand Down Expand Up @@ -3207,7 +3219,8 @@ void simple_wallet::wallet_refresh_thread()
try
{
uint64_t fetched_blocks;
m_wallet->refresh(0, fetched_blocks);
if (try_connect_to_daemon(true))
m_wallet->refresh(0, fetched_blocks);
}
catch(...) {}
m_auto_refresh_refreshing = false;
Expand All @@ -3219,6 +3232,9 @@ void simple_wallet::wallet_refresh_thread()
//----------------------------------------------------------------------------------------------------
bool simple_wallet::run()
{
// check and display warning, but go on anyway
try_connect_to_daemon();

std::string addr_start = m_wallet->get_account().get_public_address_str(m_wallet->testnet()).substr(0, 6);
m_auto_refresh_run = m_wallet->auto_refresh();
if (m_auto_refresh_run)
Expand Down Expand Up @@ -3348,7 +3364,7 @@ bool simple_wallet::get_tx_note(const std::vector<std::string> &args)
bool simple_wallet::status(const std::vector<std::string> &args)
{
uint64_t local_height = m_wallet->get_blockchain_current_height();
if (!m_wallet->check_connection())
if (!try_connect_to_daemon())
{
success_msg_writer() << "Refreshed " << local_height << "/?, no daemon connected";
return true;
Expand Down Expand Up @@ -3444,6 +3460,7 @@ int main(int argc, char* argv[])
command_line::add_arg(desc_params, arg_testnet);
command_line::add_arg(desc_params, arg_restricted);
command_line::add_arg(desc_params, arg_trusted_daemon);
command_line::add_arg(desc_params, arg_allow_mismatched_daemon_version);
command_line::add_arg(desc_params, arg_restore_height);
tools::wallet_rpc_server::init_options(desc_params);

Expand Down
3 changes: 2 additions & 1 deletion src/simplewallet/simplewallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ namespace cryptonote
bool set_default_fee_multiplier(const std::vector<std::string> &args);

uint64_t get_daemon_blockchain_height(std::string& err);
bool try_connect_to_daemon();
bool try_connect_to_daemon(bool silent = false);
bool ask_wallet_create_if_needed();
bool get_address_from_str(const std::string &str, cryptonote::account_public_address &address, bool &has_payment_id, crypto::hash8 &payment_id);

Expand Down Expand Up @@ -238,6 +238,7 @@ namespace cryptonote
bool m_restore_deterministic_wallet; // recover flag
bool m_non_deterministic; // old 2-random generation
bool m_trusted_daemon;
bool m_allow_mismatched_daemon_version;
uint64_t m_restore_height; // optional

std::string m_daemon_address;
Expand Down
33 changes: 25 additions & 8 deletions src/wallet/wallet2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1435,22 +1435,39 @@ bool wallet2::prepare_file_names(const std::string& file_path)
return true;
}
//----------------------------------------------------------------------------------------------------
bool wallet2::check_connection()
bool wallet2::check_connection(bool *same_version)
{
boost::lock_guard<boost::mutex> lock(m_daemon_rpc_mutex);

if(m_http_client.is_connected())
return true;
if(!m_http_client.is_connected())
{
net_utils::http::url_content u;
net_utils::parse_url(m_daemon_address, u);

net_utils::http::url_content u;
net_utils::parse_url(m_daemon_address, u);
if(!u.port)
{
u.port = m_testnet ? config::testnet::RPC_DEFAULT_PORT : config::RPC_DEFAULT_PORT;
}

if(!u.port)
if (!m_http_client.connect(u.host, std::to_string(u.port), WALLET_RCP_CONNECTION_TIMEOUT))
return false;
}

if (same_version)
{
u.port = m_testnet ? config::testnet::RPC_DEFAULT_PORT : config::RPC_DEFAULT_PORT;
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_VERSION::request> req_t = AUTO_VAL_INIT(req_t);
epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_VERSION::response, std::string> resp_t = AUTO_VAL_INIT(resp_t);
req_t.jsonrpc = "2.0";
req_t.id = epee::serialization::storage_entry(0);
req_t.method = "get_version";
bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client);
if (!r || resp_t.result.status != CORE_RPC_STATUS_OK)
*same_version = false;
else
*same_version = resp_t.result.version == CORE_RPC_VERSION;
}

return m_http_client.connect(u.host, std::to_string(u.port), WALLET_RCP_CONNECTION_TIMEOUT);
return true;
}
//----------------------------------------------------------------------------------------------------
bool wallet2::generate_chacha8_key_from_secret_keys(crypto::chacha8_key &key) const
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/wallet2.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ namespace tools
std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint64_t fee_multiplier, const std::vector<uint8_t> extra, bool trusted_daemon);
std::vector<wallet2::pending_tx> create_transactions_all(const cryptonote::account_public_address &address, const size_t fake_outs_count, const uint64_t unlock_time, uint64_t fee_multiplier, const std::vector<uint8_t> extra, bool trusted_daemon);
std::vector<pending_tx> create_unmixable_sweep_transactions(bool trusted_daemon);
bool check_connection();
bool check_connection(bool *same_version = NULL);
void get_transfers(wallet2::transfer_container& incoming_transfers) const;
void get_payments(const crypto::hash& payment_id, std::list<wallet2::payment_details>& payments, uint64_t min_height = 0) const;
void get_payments(std::list<std::pair<crypto::hash,wallet2::payment_details>>& payments, uint64_t min_height, uint64_t max_height = (uint64_t)-1) const;
Expand Down

0 comments on commit 014f3a0

Please sign in to comment.