-
Notifications
You must be signed in to change notification settings - Fork 116
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
New print_sn_state_changes command #727
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -362,7 +362,12 @@ t_command_server::t_command_server( | |
, "print_checkpoints [+json] [start height] [end height]" | ||
, "Query the available checkpoints between the range, omit arguments to print the last 60 checkpoints" | ||
); | ||
|
||
m_command_lookup.set_handler( | ||
"print_sn_state_changes" | ||
, std::bind(&t_command_parser_executor::print_sn_state_changes, &m_parser, p::_1) | ||
, "print_sn_state_changes start height [end height]" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
start height is mandatory so <> notation There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed. |
||
, "Query the state changes between the range, omit the last argument to scan until the current block" | ||
); | ||
#if defined(LOKI_ENABLE_INTEGRATION_TEST_HOOKS) | ||
m_command_lookup.set_handler( | ||
"relay_votes_and_uptime", std::bind([rpc_server](std::vector<std::string> const &args) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -312,6 +312,42 @@ bool t_rpc_command_executor::print_checkpoints(uint64_t start_height, uint64_t e | |
return true; | ||
} | ||
|
||
bool t_rpc_command_executor::print_sn_state_changes(uint64_t start_height, uint64_t end_height) | ||
{ | ||
cryptonote::COMMAND_RPC_GET_SN_STATE_CHANGES::request req; | ||
cryptonote::COMMAND_RPC_GET_SN_STATE_CHANGES::response res; | ||
epee::json_rpc::error error_resp; | ||
|
||
req.start_height = start_height; | ||
req.end_height = end_height; | ||
|
||
if (m_is_rpc) | ||
{ | ||
if (!m_rpc_client->json_rpc_request(req, res, "get_sn_state_changes", "Failed to query blockchain checkpoints")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
return false; | ||
} | ||
else | ||
{ | ||
if (!m_rpc_server->on_get_service_nodes_state_changes(req, res, error_resp) || res.status != CORE_RPC_STATUS_OK) | ||
{ | ||
tools::fail_msg_writer() << "Failed to query sn state changes"; | ||
return false; | ||
} | ||
} | ||
|
||
std::stringstream output; | ||
|
||
output << "Service Node state Changes (blocks " << res.start_height << "-" << res.end_height << ")" << std::endl; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
End_height here should be -1 if (res.end_height == sentinel) which by default it gets set to the chain height, so the height is the block you are mining for and not a block that already exists in the blockchain. Otherwise if it's set, you are grabbing the state changes inclusive of the blocks specified so you don't need the -1. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed logic to set the end_height to current_height - 1 when the sentinel is set. |
||
output << " Recommissions:\t\t" << res.total_recommission << std::endl; | ||
output << " Unlocks:\t\t" << res.total_unlock << std::endl; | ||
output << " Decommissions:\t\t" << res.total_decommission << std::endl; | ||
output << " Deregistrations:\t" << res.total_deregister << std::endl; | ||
output << " IP change penalties:\t" << res.total_ip_change_penalty << std::endl; | ||
|
||
tools::success_msg_writer() << output.str(); | ||
return true; | ||
} | ||
|
||
bool t_rpc_command_executor::print_peer_list(bool white, bool gray, size_t limit) { | ||
cryptonote::COMMAND_RPC_GET_PEER_LIST::request req; | ||
cryptonote::COMMAND_RPC_GET_PEER_LIST::response res; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2966,5 +2966,89 @@ namespace cryptonote | |
res.checkpoints = db.get_checkpoints_range(req.start_height, req.end_height); | ||
return true; | ||
} | ||
//------------------------------------------------------------------------------------------------------------------------------ | ||
bool core_rpc_server::on_get_service_nodes_state_changes(const COMMAND_RPC_GET_SN_STATE_CHANGES::request& req, COMMAND_RPC_GET_SN_STATE_CHANGES::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx) | ||
{ | ||
using blob_t = cryptonote::blobdata; | ||
using block_pair_t = std::pair<blob_t, block>; | ||
std::vector<block_pair_t> blocks; | ||
std::vector<blob_t> txs; | ||
|
||
const auto& db = m_core.get_blockchain_storage(); | ||
const uint64_t current_height = db.get_current_blockchain_height(); | ||
|
||
uint64_t end_height; | ||
if (req.end_height == COMMAND_RPC_GET_SN_STATE_CHANGES::HEIGHT_SENTINEL_VALUE) { | ||
end_height = current_height; | ||
} else { | ||
end_height = req.end_height; | ||
} | ||
|
||
if (!db.get_blocks(req.start_height, end_height - req.start_height, blocks, txs)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should handle the case where req.start_height > end_height There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
MERROR("Could not query block at requested height: " << req.start_height); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of MERROR, fill out the error_resp argument so that it gets returned in the json response. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
return false; | ||
} | ||
|
||
res.start_height = req.start_height; | ||
res.end_height = end_height; | ||
res.total_deregister = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually don't need to initialise to 0 since the typedef epee::struct_init thingy sets default initialises things it can to 0. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good to know, thanks! Changed. |
||
res.total_decommission = 0; | ||
res.total_ip_change_penalty = 0; | ||
res.total_recommission = 0; | ||
res.total_unlock = 0; | ||
|
||
for (size_t i = 0; i < txs.size(); ++i) | ||
{ | ||
const auto& blob = txs[i]; | ||
cryptonote::transaction tx; | ||
if (!cryptonote::parse_and_validate_tx_from_blob(blob, tx)) | ||
{ | ||
MERROR("tx could not be validated from blob, possibly corrupt blockchain"); | ||
continue; | ||
} | ||
if (tx.type == cryptonote::txtype::state_change) | ||
{ | ||
const uint8_t hard_fork_version = blocks[i].second.major_version; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is probably what's causing the get_service_node_state_change to fail a lot. The txs and blocks array aren't 1:1. The txs returned from get_blocks looks to be all the transactions spanning across all the blocks requested. So you could call get_transaction_blobs yourself per block so you use the right version for each set of transactions There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah that probably explains a lot :) |
||
cryptonote::tx_extra_service_node_state_change state_change; | ||
if (!cryptonote::get_service_node_state_change_from_tx_extra(tx.extra, state_change, hard_fork_version)) | ||
{ | ||
// TODO: This seem to be triggered quite often with hf 11 blocks | ||
// LOG_ERROR("Could not get state change from tx, possibly corrupt tx, hf_version "<< std::to_string(hard_fork_version)); | ||
continue; | ||
} | ||
|
||
switch(state_change.state) { | ||
case service_nodes::new_state::deregister: | ||
res.total_deregister++; | ||
break; | ||
|
||
case service_nodes::new_state::decommission: | ||
res.total_decommission++; | ||
break; | ||
|
||
case service_nodes::new_state::recommission: | ||
res.total_recommission++; | ||
break; | ||
|
||
case service_nodes::new_state::ip_change_penalty: | ||
res.total_ip_change_penalty++; | ||
break; | ||
|
||
default: | ||
MERROR("Unhandled state in on_get_service_nodes_state_changes"); | ||
break; | ||
} | ||
} | ||
|
||
if (tx.type == cryptonote::txtype::key_image_unlock) | ||
{ | ||
res.total_unlock++; | ||
} | ||
} | ||
|
||
res.status = CORE_RPC_STATUS_OK; | ||
return true; | ||
} | ||
|
||
|
||
} // namespace cryptonote |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here as well
It'd be nice to lookup the usage from the command_handler, but out of scope. Gonna add it to the todo list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.