mirror of
https://github.com/oxen-io/oxen-core.git
synced 2023-12-14 02:22:56 +01:00
Require storage server running for uptime proofs (v.2) (#631)
* Require storage server running for uptime proofs (v.2) * use atomic time_t; reset ping on startup
This commit is contained in:
parent
ae76293487
commit
e53922faa8
|
@ -34,6 +34,7 @@
|
|||
#include <string>
|
||||
#include <boost/uuid/uuid.hpp>
|
||||
#include <stdexcept>
|
||||
#include <chrono>
|
||||
|
||||
#define CRYPTONOTE_DNS_TIMEOUT_MS 20000
|
||||
|
||||
|
@ -66,6 +67,8 @@ static_assert(STAKING_PORTIONS % 3 == 0, "Use a multiple of three, so that it di
|
|||
#define UPTIME_PROOF_FREQUENCY_IN_SECONDS (60*60)
|
||||
#define UPTIME_PROOF_MAX_TIME_IN_SECONDS (UPTIME_PROOF_FREQUENCY_IN_SECONDS * 2 + UPTIME_PROOF_BUFFER_IN_SECONDS)
|
||||
|
||||
#define STORAGE_SERVER_PING_LIFETIME UPTIME_PROOF_FREQUENCY_IN_SECONDS
|
||||
|
||||
// MONEY_SUPPLY - total number coins to be generated
|
||||
#define MONEY_SUPPLY ((uint64_t)(-1))
|
||||
#define EMISSION_SPEED_FACTOR_PER_MINUTE (20)
|
||||
|
|
|
@ -238,6 +238,10 @@ namespace cryptonote
|
|||
{
|
||||
m_checkpoints_updating.clear();
|
||||
set_cryptonote_protocol(pprotocol);
|
||||
|
||||
// Reset the storage server last ping to make
|
||||
// sure the very first uptime proof works
|
||||
this->update_storage_server_last_ping();
|
||||
}
|
||||
void core::set_cryptonote_protocol(i_cryptonote_protocol* pprotocol)
|
||||
{
|
||||
|
@ -1404,6 +1408,26 @@ namespace cryptonote
|
|||
return res;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
|
||||
bool core::check_storage_server_ping() const
|
||||
{
|
||||
time_t last_ping = m_last_storage_server_ping.load();
|
||||
const auto elapsed = std::time(nullptr) - last_ping;
|
||||
|
||||
if (elapsed > STORAGE_SERVER_PING_LIFETIME) {
|
||||
MWARNING("Have not heard from the storage server since at least: "
|
||||
<< epee::misc_utils::get_time_str(last_ping));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
void core::update_storage_server_last_ping()
|
||||
{
|
||||
m_last_storage_server_ping.store(std::time(nullptr));
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
void core::on_transaction_relayed(const cryptonote::blobdata& tx_blob)
|
||||
{
|
||||
std::vector<std::pair<crypto::hash, cryptonote::blobdata>> txs;
|
||||
|
@ -1780,8 +1804,17 @@ namespace cryptonote
|
|||
// Code snippet from Github @Jagerman
|
||||
m_check_uptime_proof_interval.do_call([&states, this](){
|
||||
uint64_t last_uptime = m_quorum_cop.get_uptime_proof(states[0].pubkey).timestamp;
|
||||
if (last_uptime <= static_cast<uint64_t>(time(nullptr) - UPTIME_PROOF_FREQUENCY_IN_SECONDS))
|
||||
if (last_uptime <= static_cast<uint64_t>(time(nullptr) - UPTIME_PROOF_FREQUENCY_IN_SECONDS)) {
|
||||
|
||||
if (!this->check_storage_server_ping()) {
|
||||
MERROR("Failed to submit uptime proof: have not heard from"
|
||||
<< " the storage server recently. "
|
||||
<< "Make sure that it is running!");
|
||||
return true;
|
||||
}
|
||||
|
||||
this->submit_uptime_proof();
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
|
|
@ -861,6 +861,18 @@ namespace cryptonote
|
|||
*/
|
||||
service_nodes::proof_info get_uptime_proof(const crypto::public_key &key) const;
|
||||
|
||||
/**
|
||||
* @brief Check if the ping last recieved from the storage server has expired
|
||||
*
|
||||
* @return true if it has not expired
|
||||
*/
|
||||
bool check_storage_server_ping() const;
|
||||
|
||||
/**
|
||||
* @brief Update the storage server ping time
|
||||
*/
|
||||
void update_storage_server_last_ping();
|
||||
|
||||
/*
|
||||
* @brief get the blockchain pruning seed
|
||||
*
|
||||
|
@ -1140,6 +1152,9 @@ namespace cryptonote
|
|||
uint32_t m_sn_public_ip;
|
||||
uint16_t m_storage_port;
|
||||
|
||||
/// Time point at which the storage server last pinged us
|
||||
std::atomic<time_t> m_last_storage_server_ping;
|
||||
|
||||
size_t block_sync_size;
|
||||
|
||||
time_t start_time;
|
||||
|
|
|
@ -2884,6 +2884,15 @@ namespace cryptonote
|
|||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_storage_server_ping(const COMMAND_RPC_STORAGE_SERVER_PING::request&,
|
||||
COMMAND_RPC_STORAGE_SERVER_PING::response&,
|
||||
epee::json_rpc::error&,
|
||||
const connection_context*)
|
||||
{
|
||||
m_core.update_storage_server_last_ping();
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_get_staking_requirement(const COMMAND_RPC_GET_STAKING_REQUIREMENT::request& req, COMMAND_RPC_GET_STAKING_REQUIREMENT::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||
{
|
||||
PERF_TIMER(on_get_staking_requirement);
|
||||
|
|
|
@ -186,6 +186,7 @@ namespace cryptonote
|
|||
MAP_JON_RPC_WE("get_all_service_nodes_keys", on_get_all_service_nodes_keys, COMMAND_RPC_GET_ALL_SERVICE_NODES_KEYS)
|
||||
MAP_JON_RPC_WE("get_staking_requirement", on_get_staking_requirement, COMMAND_RPC_GET_STAKING_REQUIREMENT)
|
||||
MAP_JON_RPC_WE_IF("perform_blockchain_test", on_perform_blockchain_test, COMMAND_RPC_PERFORM_BLOCKCHAIN_TEST, !m_restricted)
|
||||
MAP_JON_RPC_WE_IF("storage_server_ping", on_storage_server_ping, COMMAND_RPC_STORAGE_SERVER_PING, !m_restricted)
|
||||
END_JSON_RPC_MAP()
|
||||
END_URI_MAP2()
|
||||
|
||||
|
@ -273,6 +274,7 @@ namespace cryptonote
|
|||
bool on_get_staking_requirement(const COMMAND_RPC_GET_STAKING_REQUIREMENT::request& req, COMMAND_RPC_GET_STAKING_REQUIREMENT::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
/// Provide a proof that this node holds the blockchain
|
||||
bool on_perform_blockchain_test(const COMMAND_RPC_PERFORM_BLOCKCHAIN_TEST::request& req, COMMAND_RPC_PERFORM_BLOCKCHAIN_TEST::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_storage_server_ping(const COMMAND_RPC_STORAGE_SERVER_PING::request& req, COMMAND_RPC_STORAGE_SERVER_PING::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
//-----------------------
|
||||
|
||||
void on_get_checkpoints() { m_core.debug__print_checkpoints(); }
|
||||
|
|
|
@ -2826,6 +2826,21 @@ namespace cryptonote
|
|||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_STORAGE_SERVER_PING
|
||||
{
|
||||
struct request
|
||||
{
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
||||
LOKI_RPC_DOC_INTROSPECT
|
||||
// Get the required amount of Loki to become a Service Node at the queried height.
|
||||
// For stagenet and testnet values, ensure the daemon is started with the
|
||||
|
|
Loading…
Reference in a new issue