aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/daemon/command_parser_executor.cpp18
-rw-r--r--src/daemon/command_parser_executor.h2
-rw-r--r--src/daemon/command_server.cpp5
-rw-r--r--src/daemon/rpc_command_executor.cpp103
-rw-r--r--src/daemon/rpc_command_executor.h2
-rw-r--r--src/rpc/core_rpc_server.cpp1
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h4
7 files changed, 134 insertions, 1 deletions
diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp
index 7381dd06f..9d28cd41e 100644
--- a/src/daemon/command_parser_executor.cpp
+++ b/src/daemon/command_parser_executor.cpp
@@ -511,4 +511,22 @@ bool t_command_parser_executor::alt_chain_info(const std::vector<std::string>& a
return m_executor.alt_chain_info();
}
+bool t_command_parser_executor::print_blockchain_dynamic_stats(const std::vector<std::string>& args)
+{
+ if(args.size() != 1)
+ {
+ std::cout << "Exactly one parameter is needed" << std::endl;
+ return false;
+ }
+
+ uint64_t nblocks = 0;
+ if(!epee::string_tools::get_xtype_from_string(nblocks, args[0]) || nblocks == 0)
+ {
+ std::cout << "wrong number of blocks" << std::endl;
+ return false;
+ }
+
+ return m_executor.print_blockchain_dynamic_stats(nblocks);
+}
+
} // namespace daemonize
diff --git a/src/daemon/command_parser_executor.h b/src/daemon/command_parser_executor.h
index cc929db00..7763ebed0 100644
--- a/src/daemon/command_parser_executor.h
+++ b/src/daemon/command_parser_executor.h
@@ -121,6 +121,8 @@ public:
bool print_coinbase_tx_sum(const std::vector<std::string>& args);
bool alt_chain_info(const std::vector<std::string>& args);
+
+ bool print_blockchain_dynamic_stats(const std::vector<std::string>& args);
};
} // namespace daemonize
diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp
index 88c49d111..086478a47 100644
--- a/src/daemon/command_server.cpp
+++ b/src/daemon/command_server.cpp
@@ -230,6 +230,11 @@ t_command_server::t_command_server(
, std::bind(&t_command_parser_executor::alt_chain_info, &m_parser, p::_1)
, "Print information about alternative chains"
);
+ m_command_lookup.set_handler(
+ "bc_dyn_stats"
+ , std::bind(&t_command_parser_executor::print_blockchain_dynamic_stats, &m_parser, p::_1)
+ , "Print information about current blockchain dynamic state"
+ );
}
bool t_command_server::process_command_str(const std::string& cmd)
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index 447783d76..a4da13023 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -1406,5 +1406,108 @@ bool t_rpc_command_executor::alt_chain_info()
return true;
}
+bool t_rpc_command_executor::print_blockchain_dynamic_stats(uint64_t nblocks)
+{
+ cryptonote::COMMAND_RPC_GET_INFO::request ireq;
+ cryptonote::COMMAND_RPC_GET_INFO::response ires;
+ cryptonote::COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::request bhreq;
+ cryptonote::COMMAND_RPC_GET_BLOCK_HEADERS_RANGE::response bhres;
+ cryptonote::COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE::request fereq;
+ cryptonote::COMMAND_RPC_GET_PER_KB_FEE_ESTIMATE::response feres;
+ epee::json_rpc::error error_resp;
+
+ std::string fail_message = "Problem fetching info";
+
+ if (m_is_rpc)
+ {
+ if (!m_rpc_client->rpc_request(ireq, ires, "/getinfo", fail_message.c_str()))
+ {
+ return true;
+ }
+ if (!m_rpc_client->rpc_request(fereq, feres, "/get_fee_estimate", fail_message.c_str()))
+ {
+ return true;
+ }
+ }
+ else
+ {
+ if (!m_rpc_server->on_get_info(ireq, ires) || ires.status != CORE_RPC_STATUS_OK)
+ {
+ tools::fail_msg_writer() << fail_message.c_str();
+ return true;
+ }
+ if (!m_rpc_server->on_get_per_kb_fee_estimate(fereq, feres, error_resp) || feres.status != CORE_RPC_STATUS_OK)
+ {
+ tools::fail_msg_writer() << fail_message.c_str();
+ return true;
+ }
+ }
+
+ tools::msg_writer() << "Height: " << ires.height << ", diff " << ires.difficulty << ", cum. diff " << ires.cumulative_difficulty
+ << ", target " << ires.target << " sec" << ", dyn fee " << cryptonote::print_money(feres.fee) << "/kB";
+
+ if (nblocks > 0)
+ {
+ if (nblocks > ires.height)
+ nblocks = ires.height;
+
+ bhreq.start_height = ires.height - nblocks;
+ bhreq.end_height = ires.height - 1;
+ if (m_is_rpc)
+ {
+ if (!m_rpc_client->rpc_request(bhreq, bhres, "/getblockheadersrange", fail_message.c_str()))
+ {
+ return true;
+ }
+ }
+ else
+ {
+ if (!m_rpc_server->on_get_block_headers_range(bhreq, bhres, error_resp) || bhres.status != CORE_RPC_STATUS_OK)
+ {
+ tools::fail_msg_writer() << fail_message.c_str();
+ return true;
+ }
+ }
+
+ double avgdiff = 0;
+ double avgnumtxes = 0;
+ double avgreward = 0;
+ std::vector<uint64_t> sizes;
+ sizes.reserve(nblocks);
+ std::vector<unsigned> major_versions(256, 0), minor_versions(256, 0);
+ for (const auto &bhr: bhres.headers)
+ {
+ avgdiff += bhr.difficulty;
+ avgnumtxes += bhr.num_txes;
+ avgreward += bhr.reward;
+ sizes.push_back(bhr.block_size);
+ static_assert(sizeof(bhr.major_version) == 1, "major_version expected to be uint8_t");
+ static_assert(sizeof(bhr.minor_version) == 1, "major_version expected to be uint8_t");
+ major_versions[(unsigned)bhr.major_version]++;
+ minor_versions[(unsigned)bhr.minor_version]++;
+ }
+ avgdiff /= nblocks;
+ avgnumtxes /= nblocks;
+ avgreward /= nblocks;
+ uint64_t median_block_size = epee::misc_utils::median(sizes);
+ tools::msg_writer() << "Last " << nblocks << ": avg. diff " << (uint64_t)avgdiff << ", avg num txes " << avgnumtxes
+ << ", avg. reward " << cryptonote::print_money(avgreward) << ", median block size " << median_block_size;
+
+ unsigned int max_major = 256, max_minor = 256;
+ while (max_major > 0 && !major_versions[--max_major]);
+ while (max_minor > 0 && !minor_versions[--max_minor]);
+ std::string s = "";
+ for (unsigned n = 0; n <= max_major; ++n)
+ if (major_versions[n])
+ s += (s.empty() ? "" : ", ") + boost::lexical_cast<std::string>(major_versions[n]) + std::string(" v") + boost::lexical_cast<std::string>(n);
+ tools::msg_writer() << "Block versions: " << s;
+ s = "";
+ for (unsigned n = 0; n <= max_minor; ++n)
+ if (minor_versions[n])
+ s += (s.empty() ? "" : ", ") + boost::lexical_cast<std::string>(minor_versions[n]) + std::string(" v") + boost::lexical_cast<std::string>(n);
+ tools::msg_writer() << "Voting for: " << s;
+ }
+ return true;
+}
}// namespace daemonize
diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h
index a6c712c04..af283c1f1 100644
--- a/src/daemon/rpc_command_executor.h
+++ b/src/daemon/rpc_command_executor.h
@@ -139,6 +139,8 @@ public:
bool print_coinbase_tx_sum(uint64_t height, uint64_t count);
bool alt_chain_info();
+
+ bool print_blockchain_dynamic_stats(uint64_t nblocks);
};
} // namespace daemonize
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index ddf892cae..fc93b3a51 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -896,6 +896,7 @@ namespace cryptonote
response.difficulty = m_core.get_blockchain_storage().block_difficulty(height);
response.reward = get_block_reward(blk);
response.block_size = m_core.get_blockchain_storage().get_db().get_block_size(height);
+ response.num_txes = blk.tx_hashes.size();
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index fa86c08e4..49de94ad9 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -49,7 +49,7 @@ namespace cryptonote
// advance which version they will stop working with
// Don't go over 32767 for any of these
#define CORE_RPC_VERSION_MAJOR 1
-#define CORE_RPC_VERSION_MINOR 4
+#define CORE_RPC_VERSION_MINOR 5
#define CORE_RPC_VERSION (((CORE_RPC_VERSION_MAJOR)<<16)|(CORE_RPC_VERSION_MINOR))
struct COMMAND_RPC_GET_HEIGHT
@@ -706,6 +706,7 @@ namespace cryptonote
difficulty_type difficulty;
uint64_t reward;
uint64_t block_size;
+ uint64_t num_txes;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(major_version)
@@ -720,6 +721,7 @@ namespace cryptonote
KV_SERIALIZE(difficulty)
KV_SERIALIZE(reward)
KV_SERIALIZE(block_size)
+ KV_SERIALIZE(num_txes)
END_KV_SERIALIZE_MAP()
};