Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RPC updates for ed/x25519 keys #880

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 0 additions & 83 deletions src/common/loki.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,89 +502,6 @@ loki::round (double x)
return z;
}

// adapted from Lokinet llarp/encode.hpp
// from https://en.wikipedia.org/wiki/Base32#z-base-32
static const char zbase32_alpha[] = {'y', 'b', 'n', 'd', 'r', 'f', 'g', '8',
'e', 'j', 'k', 'm', 'c', 'p', 'q', 'x',
'o', 't', '1', 'u', 'w', 'i', 's', 'z',
'a', '3', '4', '5', 'h', '7', '6', '9'};

/// adapted from i2pd
template <typename stack_t>
const char* base32z_encode(const std::vector<uint8_t>& value, stack_t &stack)
{
size_t ret = 0, pos = 1;
uint32_t bits = 8, tmp = value[0];
size_t len = value.size();
while(ret < sizeof(stack) && (bits > 0 || pos < len))
{
if(bits < 5)
{
if(pos < len)
{
tmp <<= 8;
tmp |= value[pos] & 0xFF;
pos++;
bits += 8;
}
else // last byte
{
tmp <<= (5 - bits);
bits = 5;
}
}

bits -= 5;
int ind = (tmp >> bits) & 0x1F;
if(ret < sizeof(stack))
{
stack[ret] = zbase32_alpha[ind];
ret++;
}
else
return nullptr;
}
return &stack[0];
}

constexpr uint8_t hex_to_nibble(const char & ch)
{
return ( ch >= '0' && ch <= '9') ? ch - 48 : ((ch >= 'A' && ch <= 'F' ) ? ch - 55 : ((ch >= 'a' && ch <= 'f' ) ? ch - 87 : 0));
}

constexpr uint8_t hexpair_to_byte(const char & hi, const char & lo)
{
return hex_to_nibble(hi) << 4 | hex_to_nibble(lo);
}

std::string loki::hex64_to_base32z(const std::string &src)
{
assert(src.size() <= 64); // NOTE: Developer error, update function if you need more. This is intended for 64 char snode pubkeys
// decode to binary
std::vector<uint8_t> bin;
// odd sized is invalid
if(src.size() & 1)
return "";
{
auto itr = src.begin();
while(itr != src.end())
{
const char hi = *itr;
++itr;
const char lo = *itr;
++itr;
bin.emplace_back(hexpair_to_byte(hi,lo));
}
}
// encode to base32z
char buf[64] = {0};
std::string result;
if (char const *dest = base32z_encode(bin, buf))
result = dest;

return result;
}

uint64_t loki::clamp_u64(uint64_t val, uint64_t min, uint64_t max)
{
assert(min <= max);
Expand Down
1 change: 0 additions & 1 deletion src/common/loki.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ namespace loki
{
double round (double);
double exp2 (double);
std::string hex64_to_base32z(std::string const& src);
uint64_t clamp_u64 (uint64_t min, uint64_t val, uint64_t max);

template <typename lambda_t>
Expand Down
5 changes: 0 additions & 5 deletions src/cryptonote_core/cryptonote_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2220,11 +2220,6 @@ namespace cryptonote
return get_blockchain_storage().prune_blockchain(pruning_seed);
}
//-----------------------------------------------------------------------------------------------
void core::get_all_service_nodes_public_keys(std::vector<crypto::public_key>& keys, bool active_nodes_only) const
{
m_service_node_list.get_all_service_nodes_public_keys(keys, active_nodes_only);
}
//-----------------------------------------------------------------------------------------------
std::time_t core::get_start_time() const
{
return start_time;
Expand Down
8 changes: 0 additions & 8 deletions src/cryptonote_core/cryptonote_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -830,14 +830,6 @@ namespace cryptonote
*/
std::shared_ptr<const service_node_keys> get_service_node_keys() const;

/**
* @brief Get the public key of every service node.
*
* @param keys The container in which to return the keys
* @param active_nodes_only Only return nodes that are funded and actively working (i.e. not decommissioned) on the network
*/
void get_all_service_nodes_public_keys(std::vector<crypto::public_key>& keys, bool active_nodes_only) const;

/**
* @brief attempts to submit an uptime proof to the network, if this is running in service node mode
*
Expand Down
16 changes: 0 additions & 16 deletions src/cryptonote_core/service_node_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1877,22 +1877,6 @@ namespace service_nodes
return true;
}

void service_node_list::get_all_service_nodes_public_keys(std::vector<crypto::public_key>& keys, bool require_active) const
{
keys.clear();
keys.reserve(m_state.service_nodes_infos.size());

if (require_active) {
for (const auto &key_info : m_state.service_nodes_infos)
if (key_info.second->is_active())
keys.push_back(key_info.first);
}
else {
for (const auto &key_info : m_state.service_nodes_infos)
keys.push_back(key_info.first);
}
}

static crypto::hash hash_uptime_proof(const cryptonote::NOTIFY_UPTIME_PROOF::request &proof, uint8_t hf_version)
{
// NB: quorumnet_port isn't actually used or exposed yet; including it in the HF13 proof and
Expand Down
2 changes: 0 additions & 2 deletions src/cryptonote_core/service_node_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,6 @@ namespace service_nodes
void set_quorum_history_storage(uint64_t hist_size); // 0 = none (default), 1 = unlimited, N = # of blocks
bool store();

void get_all_service_nodes_public_keys(std::vector<crypto::public_key>& keys, bool require_active) const;

/// Record public ip and storage port and add them to the service node list
cryptonote::NOTIFY_UPTIME_PROOF::request generate_uptime_proof(const service_node_keys &keys, uint32_t public_ip, uint16_t storage_port) const;
bool handle_uptime_proof (cryptonote::NOTIFY_UPTIME_PROOF::request const &proof, bool &my_uptime_proof_confirmation);
Expand Down
41 changes: 18 additions & 23 deletions src/rpc/core_rpc_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2718,6 +2718,8 @@ namespace cryptonote
if (auto keys = m_core.get_service_node_keys())
{
res.service_node_pubkey = string_tools::pod_to_hex(keys->pub);
res.service_node_pubkey_ed25519 = string_tools::pod_to_hex(keys->pub_ed25519);
res.service_node_pubkey_x25519 = string_tools::pod_to_hex(keys->pub_x25519);
res.status = CORE_RPC_STATUS_OK;
return true;
}
Expand All @@ -2727,22 +2729,6 @@ namespace cryptonote
return false;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_get_all_service_nodes_keys(const COMMAND_RPC_GET_ALL_SERVICE_NODES_KEYS::request& req, COMMAND_RPC_GET_ALL_SERVICE_NODES_KEYS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
{
std::vector<crypto::public_key> keys;
m_core.get_all_service_nodes_public_keys(keys, req.active_nodes_only);

res.keys.clear();
res.keys.resize(keys.size());
size_t i = 0;
for (const auto& key : keys)
{
std::string const hex64 = string_tools::pod_to_hex(key);
res.keys[i++] = loki::hex64_to_base32z(hex64);
}
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
template<typename response>
void core_rpc_server::fill_sn_response_entry(response &entry, const service_nodes::service_node_pubkey_info &sn_info, uint64_t current_height) {

Expand Down Expand Up @@ -2856,6 +2842,22 @@ namespace cryptonote
epee::json_rpc::error&,
const connection_context*)
{
res.status = CORE_RPC_STATUS_OK;
const uint64_t height = m_core.get_current_blockchain_height();
res.height = height - 1;
res.target_height = m_core.get_target_blockchain_height();
res.block_hash = string_tools::pod_to_hex(m_core.get_block_id_by_height(res.height));
res.hardfork = m_core.get_hard_fork_version(res.height);

if (!req.if_block_not_equal.empty()) {
res.gave_if_not_equal = true;
if (req.if_block_not_equal == res.block_hash) {
res.unchanged = true;
res.fields = req.fields;
return true;
}
}

std::vector<service_nodes::service_node_pubkey_info> sn_infos = m_core.get_service_node_list_state({});

if (req.active_only) {
Expand All @@ -2880,7 +2882,6 @@ namespace cryptonote

res.service_node_states.reserve(sn_infos.size());

const uint64_t height = m_core.get_current_blockchain_height();

for (auto &pubkey_info : sn_infos) {
COMMAND_RPC_GET_N_SERVICE_NODES::response::entry entry = {res.fields};
Expand All @@ -2890,12 +2891,6 @@ namespace cryptonote
res.service_node_states.push_back(entry);
}

res.status = CORE_RPC_STATUS_OK;
res.height = height - 1;
res.target_height = m_core.get_target_blockchain_height();
res.block_hash = string_tools::pod_to_hex(m_core.get_block_id_by_height(res.height));
res.hardfork = m_core.get_hard_fork_version(res.height);

res.fields = req.fields;
return true;
}
Expand Down
2 changes: 0 additions & 2 deletions src/rpc/core_rpc_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ namespace cryptonote
MAP_JON_RPC_WE_IF("get_service_node_key", on_get_service_node_key, COMMAND_RPC_GET_SERVICE_NODE_KEY, !m_restricted)
MAP_JON_RPC_WE("get_service_nodes", on_get_service_nodes, COMMAND_RPC_GET_SERVICE_NODES)
MAP_JON_RPC_WE("get_all_service_nodes", on_get_all_service_nodes, COMMAND_RPC_GET_SERVICE_NODES)
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_n_service_nodes", on_get_n_service_nodes, COMMAND_RPC_GET_N_SERVICE_NODES)
MAP_JON_RPC_WE("get_staking_requirement", on_get_staking_requirement, COMMAND_RPC_GET_STAKING_REQUIREMENT)
MAP_JON_RPC_WE("get_checkpoints", on_get_checkpoints, COMMAND_RPC_GET_CHECKPOINTS)
Expand Down Expand Up @@ -270,7 +269,6 @@ namespace cryptonote
bool on_get_service_node_key(const COMMAND_RPC_GET_SERVICE_NODE_KEY::request& req, COMMAND_RPC_GET_SERVICE_NODE_KEY::response& res, epee::json_rpc::error &error_resp, const connection_context *ctx = NULL);
bool on_get_service_nodes(const COMMAND_RPC_GET_SERVICE_NODES::request& req, COMMAND_RPC_GET_SERVICE_NODES::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
bool on_get_n_service_nodes(const COMMAND_RPC_GET_N_SERVICE_NODES::request& req, COMMAND_RPC_GET_N_SERVICE_NODES::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
bool on_get_all_service_nodes_keys(const COMMAND_RPC_GET_ALL_SERVICE_NODES_KEYS::request& req, COMMAND_RPC_GET_ALL_SERVICE_NODES_KEYS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx);
bool on_get_all_service_nodes(const COMMAND_RPC_GET_SERVICE_NODES::request& req, COMMAND_RPC_GET_SERVICE_NODES::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
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
Expand Down
49 changes: 19 additions & 30 deletions src/rpc/core_rpc_server_commands_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -889,30 +889,6 @@ namespace cryptonote
typedef epee::misc_utils::struct_init<response_t> response;
};

//-----------------------------------------------
LOKI_RPC_DOC_INTROSPECT
// Retrieve all Service Node Keys.
struct COMMAND_RPC_GET_ALL_SERVICE_NODES_KEYS
{
struct request_t
{
bool active_nodes_only; // Return keys for service nodes if they are funded and working on the network
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_OPT(active_nodes_only, (bool)true)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;

struct response_t
{
std::vector<std::string> keys; // Returns as base32z of the hex key, for Lokinet internal usage
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(keys)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
};

LOKI_RPC_DOC_INTROSPECT
// Stop mining on the daemon.
struct COMMAND_RPC_STOP_MINING
Expand Down Expand Up @@ -2654,7 +2630,7 @@ namespace cryptonote
};

LOKI_RPC_DOC_INTROSPECT
// Get the service node public key of the queried daemon.
// Get the service node public keys of the queried daemon.
// The daemon must be started in --service-node mode otherwise this RPC command will fail.
struct COMMAND_RPC_GET_SERVICE_NODE_KEY
{
Expand All @@ -2667,11 +2643,15 @@ namespace cryptonote

struct response_t
{
std::string service_node_pubkey; // The queried daemon's service node key.
std::string status; // Generic RPC error code. "OK" is the success value.
std::string service_node_pubkey; // The queried daemon's service node key.
std::string service_node_pubkey_ed25519; // The queried daemon's ed25519 auxiliary public key
std::string service_node_pubkey_x25519; // The queried daemon's x25519 auxiliary public key
std::string status; // Generic RPC error code. "OK" is the success value.

BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(service_node_pubkey)
KV_SERIALIZE(service_node_pubkey_ed25519)
KV_SERIALIZE(service_node_pubkey_x25519)
KV_SERIALIZE(status)
END_KV_SERIALIZE_MAP()
};
Expand Down Expand Up @@ -2846,7 +2826,7 @@ namespace cryptonote
if (this_ref.requested_fields.var || !this_ref.requested_fields.explicitly_set) KV_SERIALIZE(var)

LOKI_RPC_DOC_INTROSPECT
// Get information on a random subset of Service Nodes.
// Get information on a all (or optionally a random subset) of Service Nodes.
struct COMMAND_RPC_GET_N_SERVICE_NODES
{

Expand Down Expand Up @@ -2938,11 +2918,13 @@ namespace cryptonote
uint32_t limit;
bool active_only;
requested_fields_t fields;
std::string if_block_not_equal;
jagerman marked this conversation as resolved.
Show resolved Hide resolved

BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(limit)
KV_SERIALIZE(active_only)
KV_SERIALIZE(fields)
KV_SERIALIZE(if_block_not_equal)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
Expand Down Expand Up @@ -3026,29 +3008,36 @@ namespace cryptonote
};

requested_fields_t fields;
bool gave_if_not_equal;
jagerman marked this conversation as resolved.
Show resolved Hide resolved

std::vector<entry> service_node_states; // Array of service node registration information
uint64_t height; // Current block's height.
uint64_t target_height; // Blockchain's target height.
std::string block_hash; // Current block's hash.
bool unchanged; // Will be true (and `service_node_states` omitted) if you gave the current block hash to if_block_not_equal
uint8_t hardfork; // Current hardfork version.
std::string status; // Generic RPC error code. "OK" is the success value.

BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(service_node_states)
if (!this_ref.unchanged) {
KV_SERIALIZE(service_node_states)
}
KV_SERIALIZE(status)
if (this_ref.fields.height) {
KV_SERIALIZE(height)
}
if (this_ref.fields.target_height) {
KV_SERIALIZE(target_height)
}
if (this_ref.fields.block_hash) {
if (this_ref.fields.block_hash || (this_ref.gave_if_not_equal && !this_ref.unchanged)) {
KV_SERIALIZE(block_hash)
}
if (this_ref.fields.hardfork) {
KV_SERIALIZE(hardfork)
}
if (this_ref.gave_if_not_equal) {
KV_SERIALIZE(unchanged);
}
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
Expand Down