Skip to content

Commit 0be63cf

Browse files
committed
Merge pull request #8544
864a78e wallet2: check wallet compatibility with daemon's hard fork version (j-berman)
2 parents af4f97b + 864a78e commit 0be63cf

File tree

15 files changed

+249
-28
lines changed

15 files changed

+249
-28
lines changed

src/cryptonote_basic/hardfork.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,11 @@ namespace cryptonote
231231
*/
232232
uint64_t get_window_size() const { return window_size; }
233233

234+
/**
235+
* @brief returns info for all known hard forks
236+
*/
237+
const std::vector<hardfork_t>& get_hardforks() const { return heights; }
238+
234239
private:
235240

236241
uint8_t get_block_version(uint64_t height) const;

src/cryptonote_core/blockchain.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,13 @@ namespace cryptonote
899899
*/
900900
uint64_t get_earliest_ideal_height_for_version(uint8_t version) const { return m_hardfork->get_earliest_ideal_height_for_version(version); }
901901

902+
/**
903+
* @brief returns info for all known hard forks
904+
*
905+
* @return the hardforks
906+
*/
907+
const std::vector<hardfork_t>& get_hardforks() const { return m_hardfork->get_hardforks(); }
908+
902909
/**
903910
* @brief get information about hardfork voting for a version
904911
*

src/rpc/core_rpc_server.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2861,6 +2861,10 @@ namespace cryptonote
28612861

28622862
res.version = CORE_RPC_VERSION;
28632863
res.release = MONERO_VERSION_IS_RELEASE;
2864+
res.current_height = m_core.get_current_blockchain_height();
2865+
res.target_height = m_p2p.get_payload_object().is_synchronized() ? 0 : m_core.get_target_blockchain_height();
2866+
for (const auto &hf : m_core.get_blockchain_storage().get_hardforks())
2867+
res.hard_forks.push_back({hf.version, hf.height});
28642868
res.status = CORE_RPC_STATUS_OK;
28652869
return true;
28662870
}

src/rpc/core_rpc_server_commands_defs.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ namespace cryptonote
8888
// advance which version they will stop working with
8989
// Don't go over 32767 for any of these
9090
#define CORE_RPC_VERSION_MAJOR 3
91-
#define CORE_RPC_VERSION_MINOR 10
91+
#define CORE_RPC_VERSION_MINOR 11
9292
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
9393
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
9494

@@ -2123,15 +2123,34 @@ namespace cryptonote
21232123
};
21242124
typedef epee::misc_utils::struct_init<request_t> request;
21252125

2126+
struct hf_entry
2127+
{
2128+
uint8_t hf_version;
2129+
uint64_t height;
2130+
2131+
bool operator==(const hf_entry& hfe) const { return hf_version == hfe.hf_version && height == hfe.height; }
2132+
2133+
BEGIN_KV_SERIALIZE_MAP()
2134+
KV_SERIALIZE(hf_version)
2135+
KV_SERIALIZE(height)
2136+
END_KV_SERIALIZE_MAP()
2137+
};
2138+
21262139
struct response_t: public rpc_response_base
21272140
{
21282141
uint32_t version;
21292142
bool release;
2143+
uint64_t current_height;
2144+
uint64_t target_height;
2145+
std::vector<hf_entry> hard_forks;
21302146

21312147
BEGIN_KV_SERIALIZE_MAP()
21322148
KV_SERIALIZE_PARENT(rpc_response_base)
21332149
KV_SERIALIZE(version)
21342150
KV_SERIALIZE(release)
2151+
KV_SERIALIZE_OPT(current_height, (uint64_t)0)
2152+
KV_SERIALIZE_OPT(target_height, (uint64_t)0)
2153+
KV_SERIALIZE_OPT(hard_forks, std::vector<hf_entry>())
21352154
END_KV_SERIALIZE_MAP()
21362155
};
21372156
typedef epee::misc_utils::struct_init<response_t> response;

src/simplewallet/simplewallet.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@ namespace
181181
const command_line::arg_descriptor<bool> arg_restore_from_seed = {"restore-from-seed", sw::tr("alias for --restore-deterministic-wallet"), false};
182182
const command_line::arg_descriptor<bool> arg_restore_multisig_wallet = {"restore-multisig-wallet", sw::tr("Recover multisig wallet using Electrum-style mnemonic seed"), false};
183183
const command_line::arg_descriptor<bool> arg_non_deterministic = {"non-deterministic", sw::tr("Generate non-deterministic view and spend keys"), false};
184-
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};
185184
const command_line::arg_descriptor<uint64_t> arg_restore_height = {"restore-height", sw::tr("Restore from specific blockchain height"), 0};
186185
const command_line::arg_descriptor<std::string> arg_restore_date = {"restore-date", sw::tr("Restore from estimated blockchain height on specified date"), ""};
187186
const command_line::arg_descriptor<bool> arg_do_not_relay = {"do-not-relay", sw::tr("The newly created transaction will not be relayed to the monero network"), false};
@@ -3233,8 +3232,7 @@ bool simple_wallet::scan_tx(const std::vector<std::string> &args)
32333232
}
32343233

32353234
simple_wallet::simple_wallet()
3236-
: m_allow_mismatched_daemon_version(false)
3237-
, m_refresh_progress_reporter(*this)
3235+
: m_refresh_progress_reporter(*this)
32383236
, m_idle_run(true)
32393237
, m_auto_refresh_enabled(false)
32403238
, m_auto_refresh_refreshing(false)
@@ -4755,7 +4753,6 @@ bool simple_wallet::handle_command_line(const boost::program_options::variables_
47554753
m_restore_deterministic_wallet = command_line::get_arg(vm, arg_restore_deterministic_wallet) || command_line::get_arg(vm, arg_restore_from_seed);
47564754
m_restore_multisig_wallet = command_line::get_arg(vm, arg_restore_multisig_wallet);
47574755
m_non_deterministic = command_line::get_arg(vm, arg_non_deterministic);
4758-
m_allow_mismatched_daemon_version = command_line::get_arg(vm, arg_allow_mismatched_daemon_version);
47594756
m_restore_height = command_line::get_arg(vm, arg_restore_height);
47604757
m_restore_date = command_line::get_arg(vm, arg_restore_date);
47614758
m_do_not_relay = command_line::get_arg(vm, arg_do_not_relay);
@@ -4786,20 +4783,28 @@ bool simple_wallet::try_connect_to_daemon(bool silent, uint32_t* version)
47864783
uint32_t version_ = 0;
47874784
if (!version)
47884785
version = &version_;
4789-
if (!m_wallet->check_connection(version))
4786+
bool wallet_is_outdated, daemon_is_outdated = false;
4787+
if (!m_wallet->check_connection(version, NULL, 200000, &wallet_is_outdated, &daemon_is_outdated))
47904788
{
47914789
if (!silent)
47924790
{
47934791
if (m_wallet->is_offline())
47944792
fail_msg_writer() << tr("wallet failed to connect to daemon, because it is set to offline mode");
4793+
else if (wallet_is_outdated)
4794+
fail_msg_writer() << tr("wallet failed to connect to daemon, because it is not up to date. ") <<
4795+
tr("Please make sure you are running the latest wallet.");
4796+
else if (daemon_is_outdated)
4797+
fail_msg_writer() << tr("wallet failed to connect to daemon: ") << m_wallet->get_daemon_address() << ". " <<
4798+
tr("Daemon is not up to date. "
4799+
"Please make sure the daemon is running the latest version or change the daemon address using the 'set_daemon' command.");
47954800
else
47964801
fail_msg_writer() << tr("wallet failed to connect to daemon: ") << m_wallet->get_daemon_address() << ". " <<
47974802
tr("Daemon either is not started or wrong port was passed. "
47984803
"Please make sure daemon is running or change the daemon address using the 'set_daemon' command.");
47994804
}
48004805
return false;
48014806
}
4802-
if (!m_allow_mismatched_daemon_version && ((*version >> 16) != CORE_RPC_VERSION_MAJOR))
4807+
if (!m_wallet->is_mismatched_daemon_version_allowed() && ((*version >> 16) != CORE_RPC_VERSION_MAJOR))
48034808
{
48044809
if (!silent)
48054810
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();
@@ -10629,7 +10634,6 @@ int main(int argc, char* argv[])
1062910634
command_line::add_arg(desc_params, arg_restore_multisig_wallet );
1063010635
command_line::add_arg(desc_params, arg_non_deterministic );
1063110636
command_line::add_arg(desc_params, arg_electrum_seed );
10632-
command_line::add_arg(desc_params, arg_allow_mismatched_daemon_version);
1063310637
command_line::add_arg(desc_params, arg_restore_height);
1063410638
command_line::add_arg(desc_params, arg_restore_date);
1063510639
command_line::add_arg(desc_params, arg_do_not_relay);

src/simplewallet/simplewallet.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,6 @@ namespace cryptonote
429429
bool m_restore_deterministic_wallet; // recover flag
430430
bool m_restore_multisig_wallet; // recover flag
431431
bool m_non_deterministic; // old 2-random generation
432-
bool m_allow_mismatched_daemon_version;
433432
bool m_restoring; // are we restoring, by whatever method?
434433
uint64_t m_restore_height; // optional
435434
bool m_do_not_relay;

src/wallet/api/wallet.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2173,9 +2173,15 @@ bool WalletImpl::connectToDaemon()
21732173
Wallet::ConnectionStatus WalletImpl::connected() const
21742174
{
21752175
uint32_t version = 0;
2176-
m_is_connected = m_wallet->check_connection(&version, NULL, DEFAULT_CONNECTION_TIMEOUT_MILLIS);
2176+
bool wallet_is_outdated, daemon_is_outdated = false;
2177+
m_is_connected = m_wallet->check_connection(&version, NULL, DEFAULT_CONNECTION_TIMEOUT_MILLIS, &wallet_is_outdated, &daemon_is_outdated);
21772178
if (!m_is_connected)
2178-
return Wallet::ConnectionStatus_Disconnected;
2179+
{
2180+
if (!m_wallet->light_wallet() && (wallet_is_outdated || daemon_is_outdated))
2181+
return Wallet::ConnectionStatus_WrongVersion;
2182+
else
2183+
return Wallet::ConnectionStatus_Disconnected;
2184+
}
21792185
// Version check is not implemented in light wallets nodes/wallets
21802186
if (!m_wallet->light_wallet() && (version >> 16) != CORE_RPC_VERSION_MAJOR)
21812187
return Wallet::ConnectionStatus_WrongVersion;

src/wallet/node_rpc_proxy.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,28 +82,50 @@ void NodeRPCProxy::invalidate()
8282
m_rpc_payment_seed_hash = crypto::null_hash;
8383
m_rpc_payment_next_seed_hash = crypto::null_hash;
8484
m_height_time = 0;
85+
m_target_height_time = 0;
8586
m_rpc_payment_diff = 0;
8687
m_rpc_payment_credits_per_hash_found = 0;
8788
m_rpc_payment_height = 0;
8889
m_rpc_payment_cookie = 0;
90+
m_daemon_hard_forks.clear();
8991
}
9092

91-
boost::optional<std::string> NodeRPCProxy::get_rpc_version(uint32_t &rpc_version)
93+
boost::optional<std::string> NodeRPCProxy::get_rpc_version(uint32_t &rpc_version, std::vector<std::pair<uint8_t, uint64_t>> &daemon_hard_forks, uint64_t &height, uint64_t &target_height)
9294
{
9395
if (m_offline)
9496
return boost::optional<std::string>("offline");
9597
if (m_rpc_version == 0)
9698
{
99+
const time_t now = time(NULL);
97100
cryptonote::COMMAND_RPC_GET_VERSION::request req_t = AUTO_VAL_INIT(req_t);
98101
cryptonote::COMMAND_RPC_GET_VERSION::response resp_t = AUTO_VAL_INIT(resp_t);
99102
{
100103
const boost::lock_guard<boost::recursive_mutex> lock{m_daemon_rpc_mutex};
101104
bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_version", req_t, resp_t, m_http_client, rpc_timeout);
102105
RETURN_ON_RPC_RESPONSE_ERROR(r, epee::json_rpc::error{}, resp_t, "get_version");
103106
}
107+
104108
m_rpc_version = resp_t.version;
109+
m_daemon_hard_forks.clear();
110+
for (const auto &hf : resp_t.hard_forks)
111+
m_daemon_hard_forks.push_back(std::make_pair(hf.hf_version, hf.height));
112+
if (resp_t.current_height > 0 || resp_t.target_height > 0)
113+
{
114+
m_height = resp_t.current_height;
115+
m_target_height = resp_t.target_height;
116+
m_height_time = now;
117+
m_target_height_time = now;
118+
}
105119
}
120+
106121
rpc_version = m_rpc_version;
122+
daemon_hard_forks = m_daemon_hard_forks;
123+
boost::optional<std::string> result = get_height(height);
124+
if (result)
125+
return result;
126+
result = get_target_height(target_height);
127+
if (result)
128+
return result;
107129
return boost::optional<std::string>();
108130
}
109131

@@ -138,6 +160,7 @@ boost::optional<std::string> NodeRPCProxy::get_info()
138160
m_adjusted_time = resp_t.adjusted_time;
139161
m_get_info_time = now;
140162
m_height_time = now;
163+
m_target_height_time = now;
141164
}
142165
return boost::optional<std::string>();
143166
}
@@ -160,6 +183,13 @@ boost::optional<std::string> NodeRPCProxy::get_height(uint64_t &height)
160183

161184
boost::optional<std::string> NodeRPCProxy::get_target_height(uint64_t &height)
162185
{
186+
const time_t now = time(NULL);
187+
if (now < m_target_height_time + 30) // re-cache every 30 seconds
188+
{
189+
height = m_target_height;
190+
return boost::optional<std::string>();
191+
}
192+
163193
auto res = get_info();
164194
if (res)
165195
return res;

src/wallet/node_rpc_proxy.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class NodeRPCProxy
4848
void invalidate();
4949
void set_offline(bool offline) { m_offline = offline; }
5050

51-
boost::optional<std::string> get_rpc_version(uint32_t &version);
51+
boost::optional<std::string> get_rpc_version(uint32_t &rpc_version, std::vector<std::pair<uint8_t, uint64_t>> &daemon_hard_forks, uint64_t &height, uint64_t &target_height);
5252
boost::optional<std::string> get_height(uint64_t &height);
5353
void set_height(uint64_t h);
5454
boost::optional<std::string> get_target_height(uint64_t &height);
@@ -103,6 +103,8 @@ class NodeRPCProxy
103103
crypto::hash m_rpc_payment_next_seed_hash;
104104
uint32_t m_rpc_payment_cookie;
105105
time_t m_height_time;
106+
time_t m_target_height_time;
107+
std::vector<std::pair<uint8_t, uint64_t>> m_daemon_hard_forks;
106108
};
107109

108110
}

0 commit comments

Comments
 (0)