Improve daemon RPC version handling

Daemon RPC version is now composed of a major and minor number,
so that incompatible changes bump the major version, while
compatible changes can still bump the minor version without
causing clients to unnecessarily complain.
This commit is contained in:
moneromooo-monero 2016-11-26 12:53:33 +00:00
parent c36cb54340
commit d6086f5b4e
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
5 changed files with 30 additions and 16 deletions

View file

@ -41,7 +41,16 @@ namespace cryptonote
#define CORE_RPC_STATUS_BUSY "BUSY" #define CORE_RPC_STATUS_BUSY "BUSY"
#define CORE_RPC_STATUS_NOT_MINING "NOT MINING" #define CORE_RPC_STATUS_NOT_MINING "NOT MINING"
#define CORE_RPC_VERSION 5 // When making *any* change here, bump minor
// If the change is incompatible, then bump major and set minor to 0
// This ensures CORE_RPC_VERSION always increases, that every change
// has its own version, and that clients can just test major to see
// whether they can talk to a given daemon without having to know in
// advance which version they will stop working with
// Don't go over 32767 for any of these
#define CORE_RPC_VERSION_MAJOR 1
#define CORE_RPC_VERSION_MINOR 0
#define CORE_RPC_VERSION (((CORE_RPC_VERSION_MAJOR)<<16)|(CORE_RPC_VERSION_MINOR))
struct COMMAND_RPC_GET_HEIGHT struct COMMAND_RPC_GET_HEIGHT
{ {

View file

@ -263,6 +263,10 @@ namespace
return "invalid"; return "invalid";
} }
std::string get_version_string(uint32_t version)
{
return boost::lexical_cast<std::string>(version >> 16) + "." + boost::lexical_cast<std::string>(version & 0xffff);
}
} }
@ -1189,8 +1193,8 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
bool simple_wallet::try_connect_to_daemon(bool silent) bool simple_wallet::try_connect_to_daemon(bool silent)
{ {
bool same_version = false; uint32_t version = 0;
if (!m_wallet->check_connection(&same_version)) if (!m_wallet->check_connection(&version))
{ {
if (!silent) if (!silent)
fail_msg_writer() << tr("wallet failed to connect to daemon: ") << m_wallet->get_daemon_address() << ". " << fail_msg_writer() << tr("wallet failed to connect to daemon: ") << m_wallet->get_daemon_address() << ". " <<
@ -1198,11 +1202,10 @@ bool simple_wallet::try_connect_to_daemon(bool silent)
"Please make sure daemon is running or restart the wallet with the correct daemon address."); "Please make sure daemon is running or restart the wallet with the correct daemon address.");
return false; return false;
} }
if (!m_allow_mismatched_daemon_version && !same_version) if (!m_allow_mismatched_daemon_version && ((version >> 16) != CORE_RPC_VERSION_MAJOR))
{ {
if (!silent) if (!silent)
fail_msg_writer() << tr("Daemon uses a different RPC version that the wallet: ") << m_wallet->get_daemon_address() << ". " << fail_msg_writer() << boost::format(tr("Daemon uses a different RPC major version (%u) than the wallet (%u): %s. Either update one of them, or use --allow-mismatched-daemon-version.")) % (version>>16) % CORE_RPC_VERSION_MAJOR % m_wallet->get_daemon_address();
tr("Either update one of them, or use --allow-mismatched-daemon-version.");
return false; return false;
} }
return true; return true;
@ -3564,7 +3567,8 @@ bool simple_wallet::get_tx_note(const std::vector<std::string> &args)
bool simple_wallet::status(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(); uint64_t local_height = m_wallet->get_blockchain_current_height();
if (!try_connect_to_daemon()) uint32_t version = 0;
if (!m_wallet->check_connection(&version))
{ {
success_msg_writer() << "Refreshed " << local_height << "/?, no daemon connected"; success_msg_writer() << "Refreshed " << local_height << "/?, no daemon connected";
return true; return true;
@ -3575,7 +3579,8 @@ bool simple_wallet::status(const std::vector<std::string> &args)
if (err.empty()) if (err.empty())
{ {
bool synced = local_height == bc_height; bool synced = local_height == bc_height;
success_msg_writer() << "Refreshed " << local_height << "/" << bc_height << ", " << (synced ? "synced" : "syncing"); success_msg_writer() << "Refreshed " << local_height << "/" << bc_height << ", " << (synced ? "synced" : "syncing")
<< ", daemon RPC v" << get_version_string(version);
} }
else else
{ {

View file

@ -906,11 +906,11 @@ bool WalletImpl::connectToDaemon()
Wallet::ConnectionStatus WalletImpl::connected() const Wallet::ConnectionStatus WalletImpl::connected() const
{ {
bool same_version = false; uint32_t version = 0;
bool is_connected = m_wallet->check_connection(&same_version); bool is_connected = m_wallet->check_connection(&version);
if (!is_connected) if (!is_connected)
return Wallet::ConnectionStatus_Disconnected; return Wallet::ConnectionStatus_Disconnected;
if (!same_version) if ((version >> 16) != CORE_RPC_VERSION_MAJOR)
return Wallet::ConnectionStatus_WrongVersion; return Wallet::ConnectionStatus_WrongVersion;
return Wallet::ConnectionStatus_Connected; return Wallet::ConnectionStatus_Connected;
} }

View file

@ -2221,7 +2221,7 @@ bool wallet2::prepare_file_names(const std::string& file_path)
return true; return true;
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
bool wallet2::check_connection(bool *same_version) bool wallet2::check_connection(uint32_t *version)
{ {
boost::lock_guard<boost::mutex> lock(m_daemon_rpc_mutex); boost::lock_guard<boost::mutex> lock(m_daemon_rpc_mutex);
@ -2239,7 +2239,7 @@ bool wallet2::check_connection(bool *same_version)
return false; return false;
} }
if (same_version) if (version)
{ {
epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_VERSION::request> req_t = AUTO_VAL_INIT(req_t); 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); epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_VERSION::response, std::string> resp_t = AUTO_VAL_INIT(resp_t);
@ -2248,9 +2248,9 @@ bool wallet2::check_connection(bool *same_version)
req_t.method = "get_version"; 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); 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) if (!r || resp_t.result.status != CORE_RPC_STATUS_OK)
*same_version = false; *version = 0;
else else
*same_version = resp_t.result.version == CORE_RPC_VERSION; *version = resp_t.result.version;
} }
return true; return true;

View file

@ -408,7 +408,7 @@ namespace tools
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, uint32_t priority, 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, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon);
std::vector<wallet2::pending_tx> create_transactions_from(const cryptonote::account_public_address &address, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon); std::vector<wallet2::pending_tx> create_transactions_from(const cryptonote::account_public_address &address, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t> extra, bool trusted_daemon);
std::vector<pending_tx> create_unmixable_sweep_transactions(bool trusted_daemon); std::vector<pending_tx> create_unmixable_sweep_transactions(bool trusted_daemon);
bool check_connection(bool *same_version = NULL); bool check_connection(uint32_t *version = NULL);
void get_transfers(wallet2::transfer_container& incoming_transfers) const; 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(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; 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;