mirror of https://github.com/oxen-io/oxen-core.git
GET_QUORUM_STATE
This commit is contained in:
parent
aa0427dbdb
commit
e206fd12ed
|
@ -706,22 +706,22 @@ bool rpc_command_executor::print_blockchain_info(int64_t start_block_index, uint
|
|||
|
||||
bool rpc_command_executor::print_quorum_state(uint64_t start_height, uint64_t end_height)
|
||||
{
|
||||
GET_QUORUM_STATE::request req{};
|
||||
GET_QUORUM_STATE::response res{};
|
||||
|
||||
req.start_height = start_height;
|
||||
req.end_height = end_height;
|
||||
req.quorum_type = GET_QUORUM_STATE::ALL_QUORUMS_SENTINEL_VALUE;
|
||||
|
||||
if (!invoke<GET_QUORUM_STATE>(std::move(req), res, "Failed to retrieve quorum state"))
|
||||
auto maybe_quorums = try_running([this, start_height, end_height] {
|
||||
return invoke<GET_QUORUM_STATE>(json{
|
||||
{"start_height", start_height},
|
||||
{"end_height", end_height},
|
||||
{"quorum_type", GET_QUORUM_STATE::ALL_QUORUMS_SENTINEL_VALUE}});
|
||||
}, "Failed to retrieve quorum state");
|
||||
if (!maybe_quorums)
|
||||
return false;
|
||||
auto& quorums = *maybe_quorums;
|
||||
|
||||
std::string output;
|
||||
output.append("{\n\"quorums\": [");
|
||||
for (GET_QUORUM_STATE::quorum_for_height const &quorum : res.quorums)
|
||||
for (auto const& quorum : quorums["quorums"])
|
||||
{
|
||||
output.append("\n");
|
||||
output.append(epee::serialization::store_t_to_json(quorum));
|
||||
output.append(quorum);
|
||||
output.append(",\n");
|
||||
}
|
||||
output.append("]\n}");
|
||||
|
|
|
@ -143,7 +143,6 @@ public:
|
|||
return invoke<Response>(params)["response"];
|
||||
}
|
||||
|
||||
|
||||
bool print_checkpoints(uint64_t start_height, uint64_t end_height, bool print_json);
|
||||
|
||||
bool print_sn_state_changes(uint64_t start_height, uint64_t end_height);
|
||||
|
|
|
@ -2237,25 +2237,25 @@ namespace cryptonote::rpc {
|
|||
}
|
||||
|
||||
|
||||
GET_QUORUM_STATE::response core_rpc_server::invoke(GET_QUORUM_STATE::request&& req, rpc_context context)
|
||||
void core_rpc_server::invoke(GET_QUORUM_STATE& get_quorum_state, rpc_context context)
|
||||
{
|
||||
GET_QUORUM_STATE::response res{};
|
||||
|
||||
PERF_TIMER(on_get_quorum_state);
|
||||
|
||||
if (req.quorum_type >= tools::enum_count<service_nodes::quorum_type> &&
|
||||
req.quorum_type != GET_QUORUM_STATE::ALL_QUORUMS_SENTINEL_VALUE)
|
||||
throw rpc_error{ERROR_WRONG_PARAM,
|
||||
"Quorum type specifies an invalid value: " + std::to_string(req.quorum_type)};
|
||||
uint8_t quorum_type = get_quorum_state.request.quorum_type;
|
||||
|
||||
auto requested_type = [&req](service_nodes::quorum_type type) {
|
||||
return req.quorum_type == GET_QUORUM_STATE::ALL_QUORUMS_SENTINEL_VALUE ||
|
||||
req.quorum_type == static_cast<uint8_t>(type);
|
||||
if (quorum_type >= tools::enum_count<service_nodes::quorum_type> &&
|
||||
quorum_type != GET_QUORUM_STATE::ALL_QUORUMS_SENTINEL_VALUE)
|
||||
throw rpc_error{ERROR_WRONG_PARAM,
|
||||
"Quorum type specifies an invalid value: " + std::to_string(get_quorum_state.request.quorum_type)};
|
||||
|
||||
auto requested_type = [quorum_type](service_nodes::quorum_type type) {
|
||||
return quorum_type == GET_QUORUM_STATE::ALL_QUORUMS_SENTINEL_VALUE ||
|
||||
quorum_type == static_cast<uint8_t>(type);
|
||||
};
|
||||
|
||||
bool latest = false;
|
||||
uint64_t latest_ob = 0, latest_cp = 0, latest_bl = 0;
|
||||
uint64_t start = req.start_height, end = req.end_height;
|
||||
uint64_t start = get_quorum_state.request.start_height, end = get_quorum_state.request.end_height;
|
||||
uint64_t curr_height = m_core.get_blockchain_storage().get_current_blockchain_height();
|
||||
if (start == GET_QUORUM_STATE::HEIGHT_SENTINEL_VALUE &&
|
||||
end == GET_QUORUM_STATE::HEIGHT_SENTINEL_VALUE)
|
||||
|
@ -2297,7 +2297,7 @@ namespace cryptonote::rpc {
|
|||
bool add_curr_pulse = (latest || end > curr_height) && requested_type(service_nodes::quorum_type::pulse);
|
||||
end = std::min(curr_height, end);
|
||||
|
||||
uint64_t count = (start > end) ? start - end : end - start;
|
||||
uint64_t count = (start > end) ? start - end : end - start;
|
||||
if (!context.admin && count > GET_QUORUM_STATE::MAX_COUNT)
|
||||
throw rpc_error{ERROR_WRONG_PARAM,
|
||||
"Number of requested quorums greater than the allowed limit: "
|
||||
|
@ -2305,7 +2305,8 @@ namespace cryptonote::rpc {
|
|||
+ ", requested: " + std::to_string(count)};
|
||||
|
||||
bool at_least_one_succeeded = false;
|
||||
res.quorums.reserve(std::min((uint64_t)16, count));
|
||||
std::vector<GET_QUORUM_STATE::quorum_for_height> quorums;
|
||||
quorums.reserve(std::min((uint64_t)16, count));
|
||||
auto net = nettype();
|
||||
for (size_t height = start; height != end;)
|
||||
{
|
||||
|
@ -2314,9 +2315,9 @@ namespace cryptonote::rpc {
|
|||
auto start_quorum_iterator = static_cast<service_nodes::quorum_type>(0);
|
||||
auto end_quorum_iterator = service_nodes::max_quorum_type_for_hf(hf_version);
|
||||
|
||||
if (req.quorum_type != GET_QUORUM_STATE::ALL_QUORUMS_SENTINEL_VALUE)
|
||||
if (quorum_type != GET_QUORUM_STATE::ALL_QUORUMS_SENTINEL_VALUE)
|
||||
{
|
||||
start_quorum_iterator = static_cast<service_nodes::quorum_type>(req.quorum_type);
|
||||
start_quorum_iterator = static_cast<service_nodes::quorum_type>(quorum_type);
|
||||
end_quorum_iterator = start_quorum_iterator;
|
||||
}
|
||||
|
||||
|
@ -2332,7 +2333,7 @@ namespace cryptonote::rpc {
|
|||
}
|
||||
if (std::shared_ptr<const service_nodes::quorum> quorum = m_core.get_quorum(type, height, true /*include_old*/))
|
||||
{
|
||||
auto& entry = res.quorums.emplace_back();
|
||||
auto& entry = quorums.emplace_back();
|
||||
entry.height = height;
|
||||
entry.quorum_type = static_cast<uint8_t>(quorum_int);
|
||||
entry.quorum.validators = hexify(quorum->validators);
|
||||
|
@ -2363,7 +2364,7 @@ namespace cryptonote::rpc {
|
|||
auto quorum = generate_pulse_quorum(m_core.get_nettype(), sn_list.get_block_leader().key, hf_version, sn_list.active_service_nodes_infos(), entropy, pulse_round);
|
||||
if (verify_pulse_quorum_sizes(quorum))
|
||||
{
|
||||
auto& entry = res.quorums.emplace_back();
|
||||
auto& entry = quorums.emplace_back();
|
||||
entry.height = curr_height;
|
||||
entry.quorum_type = static_cast<uint8_t>(service_nodes::quorum_type::pulse);
|
||||
|
||||
|
@ -2378,8 +2379,9 @@ namespace cryptonote::rpc {
|
|||
if (!at_least_one_succeeded)
|
||||
throw rpc_error{ERROR_WRONG_PARAM, "Failed to query any quorums at all"};
|
||||
|
||||
res.status = STATUS_OK;
|
||||
return res;
|
||||
get_quorum_state.response["quorums"] = quorums;
|
||||
get_quorum_state.response["status"] = STATUS_OK;
|
||||
return;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
void core_rpc_server::invoke(FLUSH_CACHE& flush_cache, rpc_context context)
|
||||
|
|
|
@ -251,6 +251,7 @@ namespace cryptonote::rpc {
|
|||
void invoke(GET_BLOCK_HEADER_BY_HEIGHT& get_block_header_by_height, rpc_context context);
|
||||
void invoke(GET_BLOCK& get_block, rpc_context context);
|
||||
void invoke(GET_SERVICE_NODE_REGISTRATION_CMD_RAW& get_service_node_registration_cmd_raw, rpc_context context);
|
||||
void invoke(GET_QUORUM_STATE& get_quorum_state, rpc_context context);
|
||||
|
||||
// Deprecated Monero NIH binary endpoints:
|
||||
GET_ALT_BLOCKS_HASHES_BIN::response invoke(GET_ALT_BLOCKS_HASHES_BIN::request&& req, rpc_context context);
|
||||
|
@ -267,7 +268,6 @@ namespace cryptonote::rpc {
|
|||
// FIXME: unconverted JSON RPC endpoints:
|
||||
GET_OUTPUT_HISTOGRAM::response invoke(GET_OUTPUT_HISTOGRAM::request&& req, rpc_context context);
|
||||
GET_ALTERNATE_CHAINS::response invoke(GET_ALTERNATE_CHAINS::request&& req, rpc_context context);
|
||||
GET_QUORUM_STATE::response invoke(GET_QUORUM_STATE::request&& req, rpc_context context);
|
||||
GET_SERVICE_NODE_REGISTRATION_CMD::response invoke(GET_SERVICE_NODE_REGISTRATION_CMD::request&& req, rpc_context context);
|
||||
ONS_NAMES_TO_OWNERS::response invoke(ONS_NAMES_TO_OWNERS::request&& req, rpc_context context);
|
||||
ONS_OWNERS_TO_NAMES::response invoke(ONS_OWNERS_TO_NAMES::request&& req, rpc_context context);
|
||||
|
|
|
@ -68,6 +68,14 @@ void from_json(const nlohmann::json& j, block_header_response& h)
|
|||
j.at("service_node_winner").get_to(h.service_node_winner);
|
||||
};
|
||||
|
||||
void to_json(nlohmann::json& j, const GET_QUORUM_STATE::quorum_t& q)
|
||||
{
|
||||
j = nlohmann::json{{"validators", q.validators}, {"workers", q.workers}};
|
||||
};
|
||||
void to_json(nlohmann::json& j, const GET_QUORUM_STATE::quorum_for_height& q)
|
||||
{
|
||||
j = nlohmann::json{{"height", q.height}, {"quorum_type", q.quorum_type}, {"quorum", q.quorum}};
|
||||
};
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(STATUS)
|
||||
KV_SERIALIZE(status)
|
||||
|
@ -218,32 +226,6 @@ KV_SERIALIZE_MAP_CODE_BEGIN(GET_OUTPUT_DISTRIBUTION::response)
|
|||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_QUORUM_STATE::request)
|
||||
KV_SERIALIZE_OPT(start_height, HEIGHT_SENTINEL_VALUE)
|
||||
KV_SERIALIZE_OPT(end_height, HEIGHT_SENTINEL_VALUE)
|
||||
KV_SERIALIZE_OPT(quorum_type, ALL_QUORUMS_SENTINEL_VALUE)
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_QUORUM_STATE::quorum_t)
|
||||
KV_SERIALIZE(validators)
|
||||
KV_SERIALIZE(workers)
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_QUORUM_STATE::quorum_for_height)
|
||||
KV_SERIALIZE(height)
|
||||
KV_SERIALIZE(quorum_type)
|
||||
KV_SERIALIZE(quorum)
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_QUORUM_STATE::response)
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(quorums)
|
||||
KV_SERIALIZE_MAP_CODE_END()
|
||||
|
||||
|
||||
KV_SERIALIZE_MAP_CODE_BEGIN(GET_SERVICE_NODE_REGISTRATION_CMD::contribution_t)
|
||||
KV_SERIALIZE(address)
|
||||
KV_SERIALIZE(amount)
|
||||
|
|
|
@ -1570,8 +1570,24 @@ namespace cryptonote::rpc {
|
|||
};
|
||||
|
||||
|
||||
OXEN_RPC_DOC_INTROSPECT
|
||||
// Accesses the list of public keys of the nodes who are participating or being tested in a quorum.
|
||||
/// Accesses the list of public keys of the nodes who are participating or being tested in a quorum.
|
||||
///
|
||||
/// Inputs:
|
||||
///
|
||||
/// - \p start_height (Optional): Start height, omit both start and end height to request the latest quorum. Note that "latest" means different heights for different types of quorums as not all quorums exist at every block heights.
|
||||
/// - \p end_height (Optional): End height, omit both start and end height to request the latest quorum
|
||||
/// - \p quorum_type (Optional): Set value to request a specific quorum, 0 = Obligation, 1 = Checkpointing, 2 = Blink, 3 = Pulse, 255 = all quorums, default is all quorums. For Pulse quorums, requesting the blockchain height (or latest) returns the primary pulse quorum responsible for the next block; for heights with blocks this returns the actual quorum, which may be a backup quorum if the primary quorum did not produce in time.
|
||||
///
|
||||
/// Output values available from a public RPC endpoint:
|
||||
///
|
||||
/// - \p status General RPC status string. `"OK"` means everything looks good.
|
||||
/// - \p quorums An array of quorums associated with the requested height. Each element is structured with the following keys:
|
||||
/// - \p service_node_pubkey The public key of the Service Node, in hex (json) or binary (bt).
|
||||
/// - \p height The height the quorums are relevant for
|
||||
/// - \p quorum_type The quorum type
|
||||
/// - \p quorum Quorum of Service Nodes. Each element is structured with the following keys:
|
||||
/// - \p validators List of service node public keys in the quorum. For obligations quorums these are the testing nodes; for checkpoint and blink these are the participating nodes (there are no workers); for Pulse blink quorums these are the block signers. This is hex encoded, even for bt-encoded requests.
|
||||
/// - \p workers Public key of the quorum workers. For obligations quorums these are the nodes being tested; for Pulse quorums this is the block producer. Checkpoint and Blink quorums do not populate this field. This is hex encoded, even for bt-encoded requests.
|
||||
struct GET_QUORUM_STATE : PUBLIC
|
||||
{
|
||||
static constexpr auto names() { return NAMES("get_quorum_state"); }
|
||||
|
@ -1579,26 +1595,17 @@ namespace cryptonote::rpc {
|
|||
static constexpr size_t MAX_COUNT = 256;
|
||||
static constexpr uint64_t HEIGHT_SENTINEL_VALUE = UINT64_MAX;
|
||||
static constexpr uint8_t ALL_QUORUMS_SENTINEL_VALUE = 255;
|
||||
struct request
|
||||
struct request_parameters
|
||||
{
|
||||
uint64_t start_height; // (Optional): Start height, omit both start and end height to request the latest quorum. Note that "latest" means different heights for different types of quorums as not all quorums exist at every block heights.
|
||||
uint64_t end_height; // (Optional): End height, omit both start and end height to request the latest quorum
|
||||
uint8_t quorum_type; // (Optional): Set value to request a specific quorum, 0 = Obligation, 1 = Checkpointing, 2 = Blink, 3 = Pulse, 255 = all quorums, default is all quorums. For Pulse quorums, requesting the blockchain height (or latest) returns the primary pulse quorum responsible for the next block; for heights with blocks this returns the actual quorum, which may be a backup quorum if the primary quorum did not produce in time.
|
||||
|
||||
KV_MAP_SERIALIZABLE
|
||||
};
|
||||
} request;
|
||||
|
||||
struct quorum_t
|
||||
{
|
||||
std::vector<std::string> validators; // List of service node public keys in the quorum. For obligations quorums these are the testing nodes; for checkpoint and blink these are the participating nodes (there are no workers); for Pulse blink quorums these are the block signers.
|
||||
std::vector<std::string> workers; // Public key of the quorum workers. For obligations quorums these are the nodes being tested; for Pulse quorums this is the block producer. Checkpoint and Blink quorums do not populate this field.
|
||||
|
||||
KV_MAP_SERIALIZABLE
|
||||
|
||||
BEGIN_SERIALIZE() // NOTE: For store_t_to_json
|
||||
FIELD(validators)
|
||||
FIELD(workers)
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
struct quorum_for_height
|
||||
|
@ -1606,24 +1613,10 @@ namespace cryptonote::rpc {
|
|||
uint64_t height; // The height the quorums are relevant for
|
||||
uint8_t quorum_type; // The quorum type
|
||||
quorum_t quorum; // Quorum of Service Nodes
|
||||
|
||||
KV_MAP_SERIALIZABLE
|
||||
|
||||
BEGIN_SERIALIZE() // NOTE: For store_t_to_json
|
||||
FIELD(height)
|
||||
FIELD(quorum_type)
|
||||
FIELD(quorum)
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
std::string status; // Generic RPC error code. "OK" is the success value.
|
||||
std::vector<quorum_for_height> quorums; // An array of quorums associated with the requested height
|
||||
|
||||
KV_MAP_SERIALIZABLE
|
||||
};
|
||||
};
|
||||
inline void to_json(nlohmann::json& j, const GET_QUORUM_STATE::quorum_t& q);
|
||||
inline void to_json(nlohmann::json& j, const GET_QUORUM_STATE::quorum_for_height& q);
|
||||
|
||||
/// Returns the command that should be run to prepare a service node, includes correct parameters
|
||||
/// and service node ids formatted ready for cut and paste into daemon console.
|
||||
|
|
Loading…
Reference in New Issue