aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/rpc_command_executor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/rpc_command_executor.cpp')
-rw-r--r--src/daemon/rpc_command_executor.cpp204
1 files changed, 128 insertions, 76 deletions
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index cca0f75f9..309e5c8dd 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -46,6 +46,19 @@
namespace daemonize {
namespace {
+ const char *get_address_type_name(epee::net_utils::address_type address_type)
+ {
+ switch (address_type)
+ {
+ default:
+ case epee::net_utils::address_type::invalid: return "invalid";
+ case epee::net_utils::address_type::ipv4: return "IPv4";
+ case epee::net_utils::address_type::ipv6: return "IPv6";
+ case epee::net_utils::address_type::i2p: return "I2P";
+ case epee::net_utils::address_type::tor: return "Tor";
+ }
+ }
+
void print_peer(std::string const & prefix, cryptonote::peer const & peer)
{
time_t now;
@@ -54,8 +67,8 @@ namespace {
std::string id_str;
std::string port_str;
- std::string elapsed = epee::misc_utils::get_time_interval_string(now - last_seen);
- std::string ip_str = epee::string_tools::get_ip_string_from_int32(peer.ip);
+ std::string elapsed = peer.last_seen == 0 ? "never" : epee::misc_utils::get_time_interval_string(now - last_seen);
+ std::string ip_str = peer.ip != 0 ? epee::string_tools::get_ip_string_from_int32(peer.ip) : std::string("[") + peer.host + "]";
std::stringstream peer_id_str;
peer_id_str << std::hex << std::setw(16) << peer.id;
peer_id_str >> id_str;
@@ -338,6 +351,7 @@ bool t_rpc_command_executor::show_difficulty() {
tools::success_msg_writer() << "BH: " << res.height
<< ", TH: " << res.top_block_hash
<< ", DIFF: " << res.difficulty
+ << ", CUM_DIFF: " << res.cumulative_difficulty
<< ", HR: " << res.difficulty / res.target << " H/s";
return true;
@@ -589,6 +603,7 @@ bool t_rpc_command_executor::print_connections() {
}
tools::msg_writer() << std::setw(30) << std::left << "Remote Host"
+ << std::setw(8) << "Type"
<< std::setw(6) << "SSL"
<< std::setw(20) << "Peer id"
<< std::setw(20) << "Support Flags"
@@ -609,6 +624,7 @@ bool t_rpc_command_executor::print_connections() {
tools::msg_writer()
//<< std::setw(30) << std::left << in_out
<< std::setw(30) << std::left << address
+ << std::setw(8) << (get_address_type_name((epee::net_utils::address_type)info.address_type))
<< std::setw(6) << (info.ssl ? "yes" : "no")
<< std::setw(20) << epee::string_tools::pad_string(info.peer_id, 16, '0', true)
<< std::setw(20) << info.support_flags
@@ -1466,13 +1482,14 @@ bool t_rpc_command_executor::get_limit_down()
return true;
}
-bool t_rpc_command_executor::out_peers(uint64_t limit)
+bool t_rpc_command_executor::out_peers(bool set, uint32_t limit)
{
cryptonote::COMMAND_RPC_OUT_PEERS::request req;
cryptonote::COMMAND_RPC_OUT_PEERS::response res;
epee::json_rpc::error error_resp;
+ req.set = set;
req.out_peers = limit;
std::string fail_message = "Unsuccessful";
@@ -1493,18 +1510,20 @@ bool t_rpc_command_executor::out_peers(uint64_t limit)
}
}
- tools::msg_writer() << "Max number of out peers set to " << limit << std::endl;
+ const std::string s = res.out_peers == (uint32_t)-1 ? "unlimited" : std::to_string(res.out_peers);
+ tools::msg_writer() << "Max number of out peers set to " << s << std::endl;
return true;
}
-bool t_rpc_command_executor::in_peers(uint64_t limit)
+bool t_rpc_command_executor::in_peers(bool set, uint32_t limit)
{
cryptonote::COMMAND_RPC_IN_PEERS::request req;
cryptonote::COMMAND_RPC_IN_PEERS::response res;
epee::json_rpc::error error_resp;
+ req.set = set;
req.in_peers = limit;
std::string fail_message = "Unsuccessful";
@@ -1525,61 +1544,9 @@ bool t_rpc_command_executor::in_peers(uint64_t limit)
}
}
- tools::msg_writer() << "Max number of in peers set to " << limit << std::endl;
-
- return true;
-}
-
-bool t_rpc_command_executor::start_save_graph()
-{
- cryptonote::COMMAND_RPC_START_SAVE_GRAPH::request req;
- cryptonote::COMMAND_RPC_START_SAVE_GRAPH::response res;
- std::string fail_message = "Unsuccessful";
-
- if (m_is_rpc)
- {
- if (!m_rpc_client->rpc_request(req, res, "/start_save_graph", fail_message.c_str()))
- {
- return true;
- }
- }
-
- else
- {
- if (!m_rpc_server->on_start_save_graph(req, res) || res.status != CORE_RPC_STATUS_OK)
- {
- tools::fail_msg_writer() << make_error(fail_message, res.status);
- return true;
- }
- }
-
- tools::success_msg_writer() << "Saving graph is now on";
- return true;
-}
+ const std::string s = res.in_peers == (uint32_t)-1 ? "unlimited" : std::to_string(res.in_peers);
+ tools::msg_writer() << "Max number of in peers set to " << s << std::endl;
-bool t_rpc_command_executor::stop_save_graph()
-{
- cryptonote::COMMAND_RPC_STOP_SAVE_GRAPH::request req;
- cryptonote::COMMAND_RPC_STOP_SAVE_GRAPH::response res;
- std::string fail_message = "Unsuccessful";
-
- if (m_is_rpc)
- {
- if (!m_rpc_client->rpc_request(req, res, "/stop_save_graph", fail_message.c_str()))
- {
- return true;
- }
- }
-
- else
- {
- if (!m_rpc_server->on_stop_save_graph(req, res) || res.status != CORE_RPC_STATUS_OK)
- {
- tools::fail_msg_writer() << make_error(fail_message, res.status);
- return true;
- }
- }
- tools::success_msg_writer() << "Saving graph is now off";
return true;
}
@@ -1641,14 +1608,14 @@ bool t_rpc_command_executor::print_bans()
for (auto i = res.bans.begin(); i != res.bans.end(); ++i)
{
- tools::msg_writer() << epee::string_tools::get_ip_string_from_int32(i->ip) << " banned for " << i->seconds << " seconds";
+ tools::msg_writer() << i->host << " banned for " << i->seconds << " seconds";
}
return true;
}
-bool t_rpc_command_executor::ban(const std::string &ip, time_t seconds)
+bool t_rpc_command_executor::ban(const std::string &address, time_t seconds)
{
cryptonote::COMMAND_RPC_SETBANS::request req;
cryptonote::COMMAND_RPC_SETBANS::response res;
@@ -1656,11 +1623,8 @@ bool t_rpc_command_executor::ban(const std::string &ip, time_t seconds)
epee::json_rpc::error error_resp;
cryptonote::COMMAND_RPC_SETBANS::ban ban;
- if (!epee::string_tools::get_ip_int32_from_string(ban.ip, ip))
- {
- tools::fail_msg_writer() << "Invalid IP";
- return true;
- }
+ ban.host = address;
+ ban.ip = 0;
ban.ban = true;
ban.seconds = seconds;
req.bans.push_back(ban);
@@ -1684,7 +1648,7 @@ bool t_rpc_command_executor::ban(const std::string &ip, time_t seconds)
return true;
}
-bool t_rpc_command_executor::unban(const std::string &ip)
+bool t_rpc_command_executor::unban(const std::string &address)
{
cryptonote::COMMAND_RPC_SETBANS::request req;
cryptonote::COMMAND_RPC_SETBANS::response res;
@@ -1692,11 +1656,8 @@ bool t_rpc_command_executor::unban(const std::string &ip)
epee::json_rpc::error error_resp;
cryptonote::COMMAND_RPC_SETBANS::ban ban;
- if (!epee::string_tools::get_ip_int32_from_string(ban.ip, ip))
- {
- tools::fail_msg_writer() << "Invalid IP";
- return true;
- }
+ ban.host = address;
+ ban.ip = 0;
ban.ban = false;
ban.seconds = 0;
req.bans.push_back(ban);
@@ -1720,6 +1681,39 @@ bool t_rpc_command_executor::unban(const std::string &ip)
return true;
}
+bool t_rpc_command_executor::banned(const std::string &address)
+{
+ cryptonote::COMMAND_RPC_BANNED::request req;
+ cryptonote::COMMAND_RPC_BANNED::response res;
+ std::string fail_message = "Unsuccessful";
+ epee::json_rpc::error error_resp;
+
+ req.address = address;
+
+ if (m_is_rpc)
+ {
+ if (!m_rpc_client->json_rpc_request(req, res, "banned", fail_message.c_str()))
+ {
+ return true;
+ }
+ }
+ else
+ {
+ if (!m_rpc_server->on_banned(req, res, error_resp) || res.status != CORE_RPC_STATUS_OK)
+ {
+ tools::fail_msg_writer() << make_error(fail_message, res.status);
+ return true;
+ }
+ }
+
+ if (res.banned)
+ tools::msg_writer() << address << " is banned for " << res.seconds << " seconds";
+ else
+ tools::msg_writer() << address << " is not banned";
+
+ return true;
+}
+
bool t_rpc_command_executor::flush_txpool(const std::string &txid)
{
cryptonote::COMMAND_RPC_FLUSH_TRANSACTION_POOL::request req;
@@ -1824,7 +1818,7 @@ bool t_rpc_command_executor::print_coinbase_tx_sum(uint64_t height, uint64_t cou
return true;
}
-bool t_rpc_command_executor::alt_chain_info(const std::string &tip)
+bool t_rpc_command_executor::alt_chain_info(const std::string &tip, size_t above, uint64_t last_blocks)
{
cryptonote::COMMAND_RPC_GET_INFO::request ireq;
cryptonote::COMMAND_RPC_GET_INFO::response ires;
@@ -1861,16 +1855,31 @@ bool t_rpc_command_executor::alt_chain_info(const std::string &tip)
if (tip.empty())
{
- tools::msg_writer() << boost::lexical_cast<std::string>(res.chains.size()) << " alternate chains found:";
- for (const auto &chain: res.chains)
+ auto chains = res.chains;
+ std::sort(chains.begin(), chains.end(), [](const cryptonote::COMMAND_RPC_GET_ALTERNATE_CHAINS::chain_info &info0, cryptonote::COMMAND_RPC_GET_ALTERNATE_CHAINS::chain_info &info1){ return info0.height < info1.height; });
+ std::vector<size_t> display;
+ for (size_t i = 0; i < chains.size(); ++i)
{
- uint64_t start_height = (chain.height - chain.length + 1);
+ const auto &chain = chains[i];
+ if (chain.length <= above)
+ continue;
+ const uint64_t start_height = (chain.height - chain.length + 1);
+ if (last_blocks > 0 && ires.height - 1 - start_height >= last_blocks)
+ continue;
+ display.push_back(i);
+ }
+ tools::msg_writer() << boost::lexical_cast<std::string>(display.size()) << " alternate chains found:";
+ for (const size_t idx: display)
+ {
+ const auto &chain = chains[idx];
+ const uint64_t start_height = (chain.height - chain.length + 1);
tools::msg_writer() << chain.length << " blocks long, from height " << start_height << " (" << (ires.height - start_height - 1)
<< " deep), diff " << chain.difficulty << ": " << chain.block_hash;
}
}
else
{
+ const uint64_t now = time(NULL);
const auto i = std::find_if(res.chains.begin(), res.chains.end(), [&tip](cryptonote::COMMAND_RPC_GET_ALTERNATE_CHAINS::chain_info &info){ return info.block_hash == tip; });
if (i != res.chains.end())
{
@@ -1882,6 +1891,49 @@ bool t_rpc_command_executor::alt_chain_info(const std::string &tip)
for (const std::string &block_id: chain.block_hashes)
tools::msg_writer() << " " << block_id;
tools::msg_writer() << "Chain parent on main chain: " << chain.main_chain_parent_block;
+ cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::request bhreq;
+ cryptonote::COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::response bhres;
+ bhreq.hashes = chain.block_hashes;
+ bhreq.hashes.push_back(chain.main_chain_parent_block);
+ bhreq.fill_pow_hash = false;
+ if (m_is_rpc)
+ {
+ if (!m_rpc_client->json_rpc_request(bhreq, bhres, "getblockheaderbyhash", fail_message.c_str()))
+ {
+ return true;
+ }
+ }
+ else
+ {
+ if (!m_rpc_server->on_get_block_header_by_hash(bhreq, bhres, error_resp))
+ {
+ tools::fail_msg_writer() << make_error(fail_message, res.status);
+ return true;
+ }
+ }
+ if (bhres.block_headers.size() != chain.length + 1)
+ {
+ tools::fail_msg_writer() << "Failed to get block header info for alt chain";
+ return true;
+ }
+ uint64_t t0 = bhres.block_headers.front().timestamp, t1 = t0;
+ for (const cryptonote::block_header_response &block_header: bhres.block_headers)
+ {
+ t0 = std::min<uint64_t>(t0, block_header.timestamp);
+ t1 = std::max<uint64_t>(t1, block_header.timestamp);
+ }
+ const uint64_t dt = t1 - t0;
+ const uint64_t age = std::max(dt, t0 < now ? now - t0 : 0);
+ tools::msg_writer() << "Age: " << tools::get_human_readable_timespan(age);
+ if (chain.length > 1)
+ {
+ tools::msg_writer() << "Time span: " << tools::get_human_readable_timespan(dt);
+ cryptonote::difficulty_type start_difficulty = bhres.block_headers.back().difficulty;
+ if (start_difficulty > 0)
+ tools::msg_writer() << "Approximated " << 100.f * DIFFICULTY_TARGET_V2 * chain.length / dt << "% of network hash rate";
+ else
+ tools::fail_msg_writer() << "Bad cmumulative difficulty reported by dameon";
+ }
}
else
tools::fail_msg_writer() << "Block hash " << tip << " is not the tip of any known alternate chain";