diff options
Diffstat (limited to 'src/daemon')
-rw-r--r-- | src/daemon/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/daemon/command_line_args.h | 4 | ||||
-rw-r--r-- | src/daemon/command_parser_executor.cpp | 41 | ||||
-rw-r--r-- | src/daemon/command_parser_executor.h | 4 | ||||
-rw-r--r-- | src/daemon/command_server.cpp | 10 | ||||
-rw-r--r-- | src/daemon/core.h | 11 | ||||
-rw-r--r-- | src/daemon/daemon.cpp | 9 | ||||
-rw-r--r-- | src/daemon/daemon.h | 5 | ||||
-rw-r--r-- | src/daemon/executor.cpp | 8 | ||||
-rw-r--r-- | src/daemon/executor.h | 3 | ||||
-rw-r--r-- | src/daemon/main.cpp | 66 | ||||
-rw-r--r-- | src/daemon/p2p.h | 15 | ||||
-rw-r--r-- | src/daemon/protocol.h | 11 | ||||
-rw-r--r-- | src/daemon/rpc.h | 17 | ||||
-rw-r--r-- | src/daemon/rpc_command_executor.cpp | 136 | ||||
-rw-r--r-- | src/daemon/rpc_command_executor.h | 7 |
16 files changed, 263 insertions, 85 deletions
diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index 0f4baf932..1b6363f7b 100644 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -89,7 +89,6 @@ target_link_libraries(daemon cryptonote_core crypto common - otshell_utils p2p cryptonote_protocol daemonizer diff --git a/src/daemon/command_line_args.h b/src/daemon/command_line_args.h index 1fe2ddcf6..cb9fb6014 100644 --- a/src/daemon/command_line_args.h +++ b/src/daemon/command_line_args.h @@ -46,10 +46,10 @@ namespace daemon_args , "Specify log file" , "" }; - const command_line::arg_descriptor<int> arg_log_level = { + const command_line::arg_descriptor<std::string> arg_log_level = { "log-level" , "" - , LOG_LEVEL_0 + , "" }; const command_line::arg_descriptor<std::vector<std::string>> arg_command = { "daemon_command" diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index 7381dd06f..27f9d0fd7 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -29,6 +29,9 @@ #include "common/dns_utils.h" #include "daemon/command_parser_executor.h" +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "daemon" + namespace daemonize { t_command_parser_executor::t_command_parser_executor( @@ -117,24 +120,24 @@ bool t_command_parser_executor::set_log_level(const std::vector<std::string>& ar { if(args.size() != 1) { - std::cout << "use: set_log <log_level_number_0-4>" << std::endl; + std::cout << "use: set_log [<log_level_number_0-4> | <categories>]" << std::endl; return true; } uint16_t l = 0; - if(!epee::string_tools::get_xtype_from_string(l, args[0])) + if(epee::string_tools::get_xtype_from_string(l, args[0])) { - std::cout << "wrong number format, use: set_log <log_level_number_0-4>" << std::endl; - return true; + if(4 < l) + { + std::cout << "wrong number range, use: set_log <log_level_number_0-4>" << std::endl; + return true; + } + return m_executor.set_log_level(l); } - - if(LOG_LEVEL_4 < l) + else { - std::cout << "wrong number range, use: set_log <log_level_number_0-4>" << std::endl; - return true; + return m_executor.set_log_categories(args.front()); } - - return m_executor.set_log_level(l); } bool t_command_parser_executor::print_height(const std::vector<std::string>& args) @@ -511,4 +514,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..15293ade9 100644 --- a/src/daemon/command_parser_executor.h +++ b/src/daemon/command_parser_executor.h @@ -72,6 +72,8 @@ public: bool set_log_level(const std::vector<std::string>& args); + bool set_log_categories(const std::vector<std::string>& args); + bool print_height(const std::vector<std::string>& args); bool print_block(const std::vector<std::string>& args); @@ -121,6 +123,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..95fd3178c 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -30,6 +30,9 @@ #include "version.h" #include "daemon/command_server.h" +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "daemon" + namespace daemonize { namespace p = std::placeholders; @@ -133,7 +136,7 @@ t_command_server::t_command_server( m_command_lookup.set_handler( "set_log" , std::bind(&t_command_parser_executor::set_log_level, &m_parser, p::_1) - , "set_log <level> - Change current log detalization level, <level> is a number 0-4" + , "set_log <level>|<categories> - Change current loglevel, <level> is a number 0-4" ); m_command_lookup.set_handler( "diff" @@ -230,6 +233,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/core.h b/src/daemon/core.h index 2b7f0d177..23f7a9f63 100644 --- a/src/daemon/core.h +++ b/src/daemon/core.h @@ -33,6 +33,9 @@ #include "misc_log_ex.h" #include "daemon/command_line_args.h" +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "daemon" + namespace daemonize { @@ -68,12 +71,12 @@ public: bool run() { //initialize core here - LOG_PRINT_L0("Initializing core..."); + MGINFO("Initializing core..."); if (!m_core.init(m_vm_HACK)) { return false; } - LOG_PRINT_L0("Core initialized OK"); + MGINFO("Core initialized OK"); return true; } @@ -84,12 +87,12 @@ public: ~t_core() { - LOG_PRINT_L0("Deinitializing core..."); + MGINFO("Deinitializing core..."); try { m_core.deinit(); m_core.set_cryptonote_protocol(nullptr); } catch (...) { - LOG_PRINT_L0("Failed to deinitialize core..."); + MERROR("Failed to deinitialize core..."); } } }; diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 74875bfb0..287c30cb4 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -46,6 +46,9 @@ using namespace epee; #include <functional> +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "daemon" + namespace daemonize { struct t_internals { @@ -136,17 +139,17 @@ bool t_daemon::run(bool interactive) } mp_internals->rpc.stop(); - LOG_PRINT("Node stopped.", LOG_LEVEL_0); + MGINFO("Node stopped."); return true; } catch (std::exception const & ex) { - LOG_ERROR("Uncaught exception! " << ex.what()); + MFATAL("Uncaught exception! " << ex.what()); return false; } catch (...) { - LOG_ERROR("Uncaught exception!"); + MFATAL("Uncaught exception!"); return false; } } diff --git a/src/daemon/daemon.h b/src/daemon/daemon.h index 561cb4d9d..c8fae5c28 100644 --- a/src/daemon/daemon.h +++ b/src/daemon/daemon.h @@ -29,9 +29,12 @@ #pragma once #include <boost/program_options.hpp> +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "daemon" + namespace daemonize { -class t_internals; +struct t_internals; class t_daemon final { public: diff --git a/src/daemon/executor.cpp b/src/daemon/executor.cpp index 9583fd056..ac5803cfb 100644 --- a/src/daemon/executor.cpp +++ b/src/daemon/executor.cpp @@ -26,16 +26,19 @@ // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include "daemon/executor.h" - #include "misc_log_ex.h" +#include "daemon/executor.h" + #include "common/command_line.h" #include "cryptonote_config.h" #include "version.h" #include <string> +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "daemon" + namespace daemonize { std::string const t_executor::NAME = "Monero Daemon"; @@ -64,7 +67,6 @@ namespace daemonize boost::program_options::variables_map const & vm ) { - epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL); return t_daemon{vm}.run(true); } } diff --git a/src/daemon/executor.h b/src/daemon/executor.h index 37b4970f4..a6b47b93d 100644 --- a/src/daemon/executor.h +++ b/src/daemon/executor.h @@ -34,6 +34,9 @@ #include <string> #include <vector> +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "daemon" + namespace daemonize { class t_executor final diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index 0895e1bf1..e08065ccd 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -47,6 +47,9 @@ #include "common/stack_trace.h" #endif // STACK_TRACE +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "daemon" + namespace po = boost::program_options; namespace bf = boost::filesystem; @@ -54,7 +57,6 @@ int main(int argc, char const * argv[]) { try { - _note_c("dbg/main", "Begin of main()"); // TODO parse the debug options like set log level right here at start tools::sanitize_locale(); @@ -79,7 +81,6 @@ int main(int argc, char const * argv[]) bf::path default_conf = default_data_dir / std::string(CRYPTONOTE_NAME ".conf"); command_line::add_arg(visible_options, daemon_args::arg_config_file, default_conf.string()); command_line::add_arg(visible_options, command_line::arg_test_dbg_lock_sleep); - cryptonote::core::init_options(core_settings); // Settings bf::path default_log = default_data_dir / std::string(CRYPTONOTE_NAME ".log"); @@ -196,6 +197,23 @@ int main(int argc, char const * argv[]) } po::notify(vm); + // log_file_path + // default: <data_dir>/<CRYPTONOTE_NAME>.log + // if log-file argument given: + // absolute path + // relative path: relative to data_dir + bf::path log_file_path {data_dir / std::string(CRYPTONOTE_NAME ".log")}; + if (! vm["log-file"].defaulted()) + log_file_path = command_line::get_arg(vm, daemon_args::arg_log_file); + log_file_path = bf::absolute(log_file_path, relative_path_base); + mlog_configure(log_file_path.string(), true); + + // Set log level + if (!vm["log-level"].defaulted()) + { + mlog_set_log(command_line::get_arg(vm, daemon_args::arg_log_level).c_str()); + } + // If there are positional options, we're running a daemon command { auto command = command_line::get_arg(vm, daemon_args::arg_command); @@ -236,55 +254,17 @@ int main(int argc, char const * argv[]) } } - // Start with log level 0 - epee::log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0); - - // Set log level - { - int new_log_level = command_line::get_arg(vm, daemon_args::arg_log_level); - if(new_log_level < LOG_LEVEL_MIN || new_log_level > LOG_LEVEL_MAX) - { - LOG_PRINT_L0("Wrong log level value: " << new_log_level); - } - else if (epee::log_space::get_set_log_detalisation_level(false) != new_log_level) - { - epee::log_space::get_set_log_detalisation_level(true, new_log_level); - int otshell_utils_log_level = 100 - (new_log_level * 20); - gCurrentLogger.setDebugLevel(otshell_utils_log_level); - LOG_PRINT_L0("LOG_LEVEL set to " << new_log_level); - } - } - - // log_file_path - // default: <data_dir>/<CRYPTONOTE_NAME>.log - // if log-file argument given: - // absolute path - // relative path: relative to data_dir - - // Set log file - { - bf::path log_file_path {data_dir / std::string(CRYPTONOTE_NAME ".log")}; - if (! vm["log-file"].defaulted()) - log_file_path = command_line::get_arg(vm, daemon_args::arg_log_file); - log_file_path = bf::absolute(log_file_path, relative_path_base); - - epee::log_space::log_singletone::add_logger( - LOGGER_FILE - , log_file_path.filename().string().c_str() - , log_file_path.parent_path().string().c_str() - ); #ifdef STACK_TRACE - tools::set_stack_trace_log(log_file_path.filename().string()); + tools::set_stack_trace_log(log_file_path.filename().string()); #endif // STACK_TRACE - } if (command_line::has_arg(vm, daemon_args::arg_max_concurrency)) tools::set_max_concurrency(command_line::get_arg(vm, daemon_args::arg_max_concurrency)); // logging is now set up - LOG_PRINT_L0("Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"); + MGINFO("Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")"); - _note_c("dbg/main", "Moving from main() into the daemonize now."); + MINFO("Moving from main() into the daemonize now."); return daemonizer::daemonize(argc, argv, daemonize::t_executor{}, vm); } diff --git a/src/daemon/p2p.h b/src/daemon/p2p.h index 3858989ce..f29c2d822 100644 --- a/src/daemon/p2p.h +++ b/src/daemon/p2p.h @@ -34,6 +34,9 @@ #include "p2p/net_node.h" #include "daemon/protocol.h" +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "daemon" + namespace daemonize { @@ -57,12 +60,12 @@ public: : m_server{protocol.get()} { //initialize objects - LOG_PRINT_L0("Initializing p2p server..."); + MGINFO("Initializing p2p server..."); if (!m_server.init(vm)) { throw std::runtime_error("Failed to initialize p2p server."); } - LOG_PRINT_L0("P2p server initialized OK"); + MGINFO("P2p server initialized OK"); } t_node_server & get() @@ -72,9 +75,9 @@ public: void run() { - LOG_PRINT_L0("Starting p2p net loop..."); + MGINFO("Starting p2p net loop..."); m_server.run(); - LOG_PRINT_L0("p2p net loop stopped"); + MGINFO("p2p net loop stopped"); } void stop() @@ -84,11 +87,11 @@ public: ~t_p2p() { - LOG_PRINT_L0("Deinitializing p2p..."); + MGINFO("Deinitializing p2p..."); try { m_server.deinit(); } catch (...) { - LOG_PRINT_L0("Failed to deinitialize p2p..."); + MERROR("Failed to deinitialize p2p..."); } } }; diff --git a/src/daemon/protocol.h b/src/daemon/protocol.h index eb894fb81..bc2333659 100644 --- a/src/daemon/protocol.h +++ b/src/daemon/protocol.h @@ -30,6 +30,9 @@ #pragma once +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "daemon" + namespace daemonize { @@ -47,12 +50,12 @@ public: ) : m_protocol{core.get(), nullptr} { - LOG_PRINT_L0("Initializing cryptonote protocol..."); + MGINFO("Initializing cryptonote protocol..."); if (!m_protocol.init(vm)) { throw std::runtime_error("Failed to initialize cryptonote protocol."); } - LOG_PRINT_L0("Cryptonote protocol initialized OK"); + MGINFO("Cryptonote protocol initialized OK"); } t_protocol_raw & get() @@ -69,11 +72,11 @@ public: ~t_protocol() { - LOG_PRINT_L0("Stopping cryptonote protocol..."); + MGINFO("Stopping cryptonote protocol..."); try { m_protocol.deinit(); m_protocol.set_p2p_endpoint(nullptr); - LOG_PRINT_L0("Cryptonote protocol stopped successfully"); + MGINFO("Cryptonote protocol stopped successfully"); } catch (...) { LOG_ERROR("Failed to stop cryptonote protocol!"); } diff --git a/src/daemon/rpc.h b/src/daemon/rpc.h index bfd2afd84..8b0d5808d 100644 --- a/src/daemon/rpc.h +++ b/src/daemon/rpc.h @@ -32,6 +32,9 @@ #include "rpc/core_rpc_server.h" +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "daemon" + namespace daemonize { @@ -52,27 +55,27 @@ public: ) : m_server{core.get(), p2p.get()} { - LOG_PRINT_L0("Initializing core rpc server..."); + MGINFO("Initializing core rpc server..."); if (!m_server.init(vm)) { throw std::runtime_error("Failed to initialize core rpc server."); } - LOG_PRINT_GREEN("Core rpc server initialized OK on port: " << m_server.get_binded_port(), LOG_LEVEL_0); + MGINFO("Core rpc server initialized OK on port: " << m_server.get_binded_port()); } void run() { - LOG_PRINT_L0("Starting core rpc server..."); + MGINFO("Starting core rpc server..."); if (!m_server.run(2, false)) { throw std::runtime_error("Failed to start core rpc server."); } - LOG_PRINT_L0("Core rpc server started ok"); + MGINFO("Core rpc server started ok"); } void stop() { - LOG_PRINT_L0("Stopping core rpc server..."); + MGINFO("Stopping core rpc server..."); m_server.send_stop_signal(); m_server.timed_wait_server_stop(5000); } @@ -84,11 +87,11 @@ public: ~t_rpc() { - LOG_PRINT_L0("Deinitializing rpc server..."); + MGINFO("Deinitializing rpc server..."); try { m_server.deinit(); } catch (...) { - LOG_PRINT_L0("Failed to deinitialize rpc server..."); + MERROR("Failed to deinitialize rpc server..."); } } }; diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 447783d76..8558ebc17 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -38,6 +38,9 @@ #include <ctime> #include <string> +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "daemon" + namespace daemonize { namespace { @@ -517,6 +520,34 @@ bool t_rpc_command_executor::set_log_level(int8_t level) { return true; } +bool t_rpc_command_executor::set_log_categories(const std::string &categories) { + cryptonote::COMMAND_RPC_SET_LOG_CATEGORIES::request req; + cryptonote::COMMAND_RPC_SET_LOG_CATEGORIES::response res; + req.categories = categories; + + std::string fail_message = "Unsuccessful"; + + if (m_is_rpc) + { + if (!m_rpc_client->rpc_request(req, res, "/set_log_categories", fail_message.c_str())) + { + return true; + } + } + else + { + if (!m_rpc_server->on_set_log_categories(req, res) || res.status != CORE_RPC_STATUS_OK) + { + tools::fail_msg_writer() << fail_message.c_str(); + return true; + } + } + + tools::success_msg_writer() << "Log categories are now " << categories; + + return true; +} + bool t_rpc_command_executor::print_height() { cryptonote::COMMAND_RPC_GET_HEIGHT::request req; cryptonote::COMMAND_RPC_GET_HEIGHT::response res; @@ -743,6 +774,7 @@ bool t_rpc_command_executor::print_transaction_pool_long() { << "fee: " << cryptonote::print_money(tx_info.fee) << std::endl << "receive_time: " << tx_info.receive_time << " (" << get_human_time_ago(tx_info.receive_time, now) << ")" << std::endl << "relayed: " << [&](const cryptonote::tx_info &tx_info)->std::string { if (!tx_info.relayed) return "no"; return boost::lexical_cast<std::string>(tx_info.last_relayed_time) + " (" + get_human_time_ago(tx_info.last_relayed_time, now) + ")"; } (tx_info) << std::endl + << "do_not_relay: " << (tx_info.do_not_relay ? 'T' : 'F') << std::endl << "kept_by_block: " << (tx_info.kept_by_block ? 'T' : 'F') << std::endl << "max_used_block_height: " << tx_info.max_used_block_height << std::endl << "max_used_block_id: " << tx_info.max_used_block_id_hash << std::endl @@ -823,6 +855,7 @@ bool t_rpc_command_executor::print_transaction_pool_short() { << "fee: " << cryptonote::print_money(tx_info.fee) << std::endl << "receive_time: " << tx_info.receive_time << " (" << get_human_time_ago(tx_info.receive_time, now) << ")" << std::endl << "relayed: " << [&](const cryptonote::tx_info &tx_info)->std::string { if (!tx_info.relayed) return "no"; return boost::lexical_cast<std::string>(tx_info.last_relayed_time) + " (" + get_human_time_ago(tx_info.last_relayed_time, now) + ")"; } (tx_info) << std::endl + << "do_not_relay: " << (tx_info.do_not_relay ? 'T' : 'F') << std::endl << "kept_by_block: " << (tx_info.kept_by_block ? 'T' : 'F') << std::endl << "max_used_block_height: " << tx_info.max_used_block_height << std::endl << "max_used_block_id: " << tx_info.max_used_block_id_hash << std::endl @@ -1406,5 +1439,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..afcd99d32 100644 --- a/src/daemon/rpc_command_executor.h +++ b/src/daemon/rpc_command_executor.h @@ -45,6 +45,9 @@ #include "p2p/net_node.h" #include "rpc/core_rpc_server.h" +#undef MONERO_DEFAULT_LOG_CATEGORY +#define MONERO_DEFAULT_LOG_CATEGORY "daemon" + namespace daemonize { class t_rpc_command_executor final { @@ -82,6 +85,8 @@ public: bool set_log_level(int8_t level); + bool set_log_categories(const std::string &categories); + bool print_height(); bool print_block_by_hash(crypto::hash block_hash); @@ -139,6 +144,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 |