From 8541f38ef15bbc3f9889e4e1dd7a1478c27609d5 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Mon, 5 Jun 2017 13:27:11 +0800 Subject: [PATCH] Move network_info to MempoolStatus thread --- main.cpp | 7 +-- src/CmdLineOptions.cpp | 4 +- src/MempoolStatus.cpp | 96 +++++++++++++++++++++++++++++ src/MempoolStatus.h | 34 +++++++++++ src/page.h | 124 +++++++++++--------------------------- src/templates/index2.html | 3 +- 6 files changed, 168 insertions(+), 100 deletions(-) diff --git a/main.cpp b/main.cpp index 211d017..484a804 100644 --- a/main.cpp +++ b/main.cpp @@ -50,7 +50,6 @@ main(int ac, const char* av[]) auto no_blocks_on_index_opt = opts.get_option("no-blocks-on-index"); auto testnet_url = opts.get_option("testnet-url"); auto mainnet_url = opts.get_option("mainnet-url"); - auto network_info_timeout_opt = opts.get_option("network-info-timeout"); auto mempool_info_timeout_opt = opts.get_option("mempool-info-timeout"); auto mempool_refresh_time_opt = opts.get_option("mempool-refresh-time"); auto testnet_opt = opts.get_option("testnet"); @@ -155,19 +154,16 @@ main(int ac, const char* av[]) deamon_url = "http:://127.0.0.1:28081"; } - uint64_t network_info_timeout {1000}; uint64_t mempool_info_timeout {5000}; try { - network_info_timeout = boost::lexical_cast(*network_info_timeout_opt); mempool_info_timeout = boost::lexical_cast(*mempool_info_timeout_opt); } catch (boost::bad_lexical_cast &e) { - cout << "Cant cast " << (*network_info_timeout_opt) - << " or/and " << (*mempool_info_timeout_opt) <<" into numbers. Using default values." + cout << "Cant cast " << (*mempool_info_timeout_opt) <<" into numbers. Using default values." << endl; } @@ -250,7 +246,6 @@ main(int ac, const char* av[]) enable_block_cache, show_cache_times, no_blocks_on_index, - network_info_timeout, mempool_info_timeout, *testnet_url, *mainnet_url); diff --git a/src/CmdLineOptions.cpp b/src/CmdLineOptions.cpp index 2f2d0e5..a392fd0 100644 --- a/src/CmdLineOptions.cpp +++ b/src/CmdLineOptions.cpp @@ -53,11 +53,9 @@ namespace xmreg "you can specify mainnet url, if you run it on testnet. link will show on front page to mainnet explorer") ("no-blocks-on-index", value()->default_value("10"), "number of last blocks to be shown on index page") - ("network-info-timeout", value()->default_value("1000"), - "maximum time, in milliseconds, to wait for network info availability") ("mempool-info-timeout", value()->default_value("5000"), "maximum time, in milliseconds, to wait for mempool data for the front page") - ("mempool-refresh-time", value()->default_value("10"), + ("mempool-refresh-time", value()->default_value("15"), "time, in seconds, for each refresh of mempool state") ("bc-path,b", value(), "path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb") diff --git a/src/MempoolStatus.cpp b/src/MempoolStatus.cpp index d3ed2cb..c9f5555 100644 --- a/src/MempoolStatus.cpp +++ b/src/MempoolStatus.cpp @@ -23,14 +23,52 @@ MempoolStatus::set_blockchain_variables(MicroCore *_mcore, void MempoolStatus::start_mempool_status_thread() { + // initialize network info as not current. + // so we know that what ever values are returned, they + // dont come from the deamon now. + network_info local_copy = current_network_info; + local_copy.current = false; + local_copy.info_timestamp = 0; + current_network_info = local_copy; + + + if (!is_running) { m_thread = boost::thread{[]() { try { + uint64_t loop_index {0}; + + // so that network status is checked every minute + uint64_t loop_index_divider = 60 / mempool_refresh_time; + loop_index_divider = loop_index_divider == 0 ? 1 : loop_index_divider; + while (true) { + + // we just query network status every minute. No sense + // to do it as frequently as getting mempool data. + if (loop_index % 4 == 0) + { + if (!MempoolStatus::read_network_info()) + { + network_info local_copy = current_network_info; + + cerr << " Cant read network info "<< endl; + + local_copy.current = false; + + current_network_info = local_copy; + } + else + { + cout << "Current network info read, "; + loop_index == 0; + } + } + if (MempoolStatus::read_mempool()) { vector current_mempool_txs = get_mempool_txs(); @@ -45,6 +83,8 @@ MempoolStatus::start_mempool_status_thread() boost::this_thread::sleep_for( boost::chrono::seconds(mempool_refresh_time)); + ++loop_index; + } // while (true) } catch (boost::thread_interrupted&) @@ -166,6 +206,61 @@ MempoolStatus::read_mempool() return true; } + +bool +MempoolStatus::read_network_info() +{ + rpccalls rpc {deamon_url}; + + COMMAND_RPC_GET_INFO::response rpc_network_info; + + if (!rpc.get_network_info(rpc_network_info)) + { + return false; + } + + uint64_t fee_estimated; + + string error_msg; + + if (!rpc.get_dynamic_per_kb_fee_estimate( + FEE_ESTIMATE_GRACE_BLOCKS, + fee_estimated, error_msg)) + { + cerr << "rpc.get_dynamic_per_kb_fee_estimate failed" << endl; + return false; + } + + (void) error_msg; + + + network_info local_copy; + + local_copy.height = rpc_network_info.height; + local_copy.target_height = rpc_network_info.target_height; + local_copy.difficulty = rpc_network_info.difficulty; + local_copy.target = rpc_network_info.target; + local_copy.hash_rate = (rpc_network_info.difficulty/rpc_network_info.target); + local_copy.tx_count = rpc_network_info.tx_count; + local_copy.tx_pool_size = rpc_network_info.tx_pool_size; + local_copy.alt_blocks_count = rpc_network_info.alt_blocks_count; + local_copy.outgoing_connections_count = rpc_network_info.outgoing_connections_count; + local_copy.incoming_connections_count = rpc_network_info.incoming_connections_count; + local_copy.white_peerlist_size = rpc_network_info.white_peerlist_size; + local_copy.testnet = rpc_network_info.testnet; + epee::string_tools::hex_to_pod(rpc_network_info.top_block_hash, local_copy.top_block_hash); + local_copy.cumulative_difficulty = rpc_network_info.cumulative_difficulty; + local_copy.block_size_limit = rpc_network_info.block_size_limit; + local_copy.start_time = rpc_network_info.start_time; + local_copy.fee_per_kb = fee_estimated; + local_copy.info_timestamp = static_cast(std::time(nullptr)); + local_copy.current = true; + + current_network_info = local_copy; + + return true; +} + vector MempoolStatus::get_mempool_txs() { @@ -188,6 +283,7 @@ boost::thread MempoolStatus::m_thread; Blockchain* MempoolStatus::core_storage {nullptr}; xmreg::MicroCore* MempoolStatus::mcore {nullptr}; vector MempoolStatus::mempool_txs; +atomic MempoolStatus::current_network_info; atomic MempoolStatus::mempool_no {0}; // no of txs atomic MempoolStatus::mempool_size {0}; // size in bytes. uint64_t MempoolStatus::mempool_refresh_time {10}; diff --git a/src/MempoolStatus.h b/src/MempoolStatus.h index 12dab9a..2cd480e 100644 --- a/src/MempoolStatus.h +++ b/src/MempoolStatus.h @@ -42,6 +42,34 @@ struct MempoolStatus string txsize; }; + + // to keep network_info in cache + // and to show previous info in case current querry for + // the current info timesout. + struct network_info + { + uint64_t height; + bool testnet; + bool current; + crypto::hash top_block_hash; + uint64_t target_height; + uint64_t difficulty; + uint64_t target; + uint64_t tx_count; + uint64_t tx_pool_size; + uint64_t alt_blocks_count; + uint64_t outgoing_connections_count; + uint64_t incoming_connections_count; + uint64_t white_peerlist_size; + uint64_t grey_peerlist_size; + uint64_t cumulative_difficulty; + uint64_t block_size_limit; + uint64_t start_time; + uint64_t hash_rate; + uint64_t fee_per_kb; + uint64_t info_timestamp; + }; + static boost::thread m_thread; static mutex mempool_mutx; @@ -66,6 +94,8 @@ struct MempoolStatus // static vector mempool_txs; + static atomic current_network_info; + static void set_blockchain_variables(MicroCore* _mcore, Blockchain* _core_storage); @@ -76,6 +106,10 @@ struct MempoolStatus static bool read_mempool(); + static bool + read_network_info(); + + static vector get_mempool_txs(); diff --git a/src/page.h b/src/page.h index 6bfe2b3..0707e39 100644 --- a/src/page.h +++ b/src/page.h @@ -263,7 +263,6 @@ namespace xmreg uint64_t no_of_mempool_tx_of_frontpage; uint64_t no_blocks_on_index; - uint64_t network_info_timeout; uint64_t mempool_info_timeout; string testnet_url; @@ -282,26 +281,10 @@ namespace xmreg using lru_cache_t = caches::fixed_sized_cache>; - // alias for easy class typing template using fifo_cache_t = caches::fixed_sized_cache>; - // to keep network_info in cache - // and to show previous info in case current querry for - // the current info timesout. - struct network_info - { - uint64_t difficulty; - uint64_t hash_rate; - uint64_t fee_per_kb; - uint64_t alt_blocks_no; - uint64_t tx_pool_size; - uint64_t info_timestamp; - }; - - atomic previous_network_info; - // cache of txs_map of txs in blocks. this is useful for // index2 page, so that we dont parse txs in each block // for each request. @@ -325,7 +308,6 @@ namespace xmreg bool _enable_block_cache, bool _show_cache_times, uint64_t _no_blocks_on_index, - uint64_t _network_info_timeout, uint64_t _mempool_info_timeout, string _testnet_url, string _mainnet_url) @@ -343,7 +325,6 @@ namespace xmreg enable_block_cache {_enable_block_cache}, show_cache_times {_show_cache_times}, no_blocks_on_index {_no_blocks_on_index}, - network_info_timeout {_network_info_timeout}, mempool_info_timeout {_mempool_info_timeout}, testnet_url {_testnet_url}, mainnet_url {_mainnet_url}, @@ -353,9 +334,6 @@ namespace xmreg no_of_mempool_tx_of_frontpage = 25; - // initialized stored network info atomic - previous_network_info = network_info {0, 0, 0, 0, 0, 0}; - // read template files for all the pages // into template_file map @@ -406,16 +384,6 @@ namespace xmreg return json{}; } - uint64_t fee_estimated {0}; - - // get dynamic fee estimate from last 10 blocks - if (!get_dynamic_per_kb_fee_estimate(fee_estimated)) - { - return json{}; - } - - j_info["fee_per_kb"] = fee_estimated; - return j_info; }); @@ -737,43 +705,12 @@ namespace xmreg context["cache_hits"] = cache_hits; context["cache_misses"] = cache_misses; - // now time to check if we have our networkinfo from network_info future - // wait a bit (300 millisecond max) if not, just in case, but we dont wait more. - // if its not ready by now, forget about it. - - std::future_status ftr_status = network_info_ftr.wait_for( - std::chrono::milliseconds(network_info_timeout)); - - network_info current_network_info {0, 0, 0, 0, 0, 0}; - bool is_network_info_current {false}; - - if (ftr_status == std::future_status::ready) - { - json j_network_info = network_info_ftr.get(); - - if (!j_network_info.empty()) - { - current_network_info.difficulty = j_network_info["difficulty"]; - current_network_info.hash_rate = j_network_info["hash_rate"]; - current_network_info.fee_per_kb = j_network_info["fee_per_kb"]; - current_network_info.tx_pool_size = j_network_info["tx_pool_size"]; - current_network_info.alt_blocks_no = j_network_info["alt_blocks_count"]; - current_network_info.info_timestamp = local_copy_server_timestamp; - - previous_network_info = current_network_info; - - is_network_info_current = true; - } - } - else - { - current_network_info = previous_network_info; - cerr << "network_info future not ready yet, use the previous_network_info." << endl; - } + // get current network info from MemoryStatus thread. + MempoolStatus::network_info current_network_info + = MempoolStatus::current_network_info; // perapre network info mstch::map for the front page - string hash_rate; if (testnet) @@ -790,19 +727,23 @@ namespace xmreg // if network info is younger than 2 minute, assume its current. No sense // showing that it is not current if its less then block time. - if (local_copy_server_timestamp - current_network_info.info_timestamp < 120) { - is_network_info_current = true; + current_network_info.current = true; } + string block_size_limit = fmt::format("{:0.2f}", + static_cast( + current_network_info.block_size_limit)/1024.0); + context["network_info"] = mstch::map { {"difficulty" , current_network_info.difficulty}, {"hash_rate" , hash_rate}, {"fee_per_kb" , print_money(current_network_info.fee_per_kb)}, - {"alt_blocks_no" , current_network_info.alt_blocks_no}, + {"alt_blocks_no" , current_network_info.alt_blocks_count}, {"tx_pool_size" , current_network_info.tx_pool_size}, - {"is_current_info" , is_network_info_current}, + {"block_size_limit" , block_size_limit}, + {"is_current_info" , current_network_info.current}, {"is_pool_size_zero" , (current_network_info.tx_pool_size == 0)}, {"age" , network_info_age.first}, {"age_format" , network_info_age.second}, @@ -5505,32 +5446,35 @@ namespace xmreg bool get_monero_network_info(json& j_info) { - COMMAND_RPC_GET_INFO::response network_info; + MempoolStatus::network_info local_copy_network_info + = MempoolStatus::current_network_info; - if (!rpc.get_network_info(network_info)) + if (local_copy_network_info.current == false) { return false; } j_info = json { - {"status" , network_info.status}, - {"height" , network_info.height}, - {"target_height" , network_info.target_height}, - {"difficulty" , network_info.difficulty}, - {"target" , network_info.target}, - {"hash_rate" , (network_info.difficulty/network_info.target)}, - {"tx_count" , network_info.tx_count}, - {"tx_pool_size" , network_info.tx_pool_size}, - {"alt_blocks_count" , network_info.alt_blocks_count}, - {"outgoing_connections_count", network_info.outgoing_connections_count}, - {"incoming_connections_count", network_info.incoming_connections_count}, - {"white_peerlist_size" , network_info.white_peerlist_size}, - {"grey_peerlist_size" , network_info.grey_peerlist_size}, - {"testnet" , network_info.testnet}, - {"top_block_hash" , network_info.top_block_hash}, - {"cumulative_difficulty" , network_info.cumulative_difficulty}, - {"block_size_limit" , network_info.block_size_limit}, - {"start_time" , network_info.start_time} + {"status" , local_copy_network_info.current}, + {"current" , local_copy_network_info.current}, + {"height" , local_copy_network_info.height}, + {"target_height" , local_copy_network_info.target_height}, + {"difficulty" , local_copy_network_info.difficulty}, + {"target" , local_copy_network_info.target}, + {"hash_rate" , local_copy_network_info.hash_rate}, + {"tx_count" , local_copy_network_info.tx_count}, + {"tx_pool_size" , local_copy_network_info.tx_pool_size}, + {"alt_blocks_count" , local_copy_network_info.alt_blocks_count}, + {"outgoing_connections_count", local_copy_network_info.outgoing_connections_count}, + {"incoming_connections_count", local_copy_network_info.incoming_connections_count}, + {"white_peerlist_size" , local_copy_network_info.white_peerlist_size}, + {"grey_peerlist_size" , local_copy_network_info.grey_peerlist_size}, + {"testnet" , local_copy_network_info.testnet}, + {"top_block_hash" , pod_to_hex(local_copy_network_info.top_block_hash)}, + {"cumulative_difficulty" , local_copy_network_info.cumulative_difficulty}, + {"block_size_limit" , local_copy_network_info.block_size_limit}, + {"start_time" , local_copy_network_info.start_time}, + {"fee_per_kb" , local_copy_network_info.fee_per_kb} }; return true; diff --git a/src/templates/index2.html b/src/templates/index2.html index af8aaed..9a836ad 100644 --- a/src/templates/index2.html +++ b/src/templates/index2.html @@ -39,7 +39,8 @@ Network difficulty: {{difficulty}} | Hash rate: {{hash_rate}} | Fee per kb: {{fee_per_kb}} - | Alternative blocks no: {{alt_blocks_no}} + | Block size limit: {{block_size_limit}} kB + | Alt blocks no: {{alt_blocks_no}} {{^is_current_info}} | Data from {{age}} {{age_format}} ago {{/is_current_info}}