Move network_info to MempoolStatus thread

This commit is contained in:
moneroexamples 2017-06-05 13:27:11 +08:00
parent bea1665ac9
commit 8541f38ef1
6 changed files with 168 additions and 100 deletions

View File

@ -50,7 +50,6 @@ main(int ac, const char* av[])
auto no_blocks_on_index_opt = opts.get_option<string>("no-blocks-on-index"); auto no_blocks_on_index_opt = opts.get_option<string>("no-blocks-on-index");
auto testnet_url = opts.get_option<string>("testnet-url"); auto testnet_url = opts.get_option<string>("testnet-url");
auto mainnet_url = opts.get_option<string>("mainnet-url"); auto mainnet_url = opts.get_option<string>("mainnet-url");
auto network_info_timeout_opt = opts.get_option<string>("network-info-timeout");
auto mempool_info_timeout_opt = opts.get_option<string>("mempool-info-timeout"); auto mempool_info_timeout_opt = opts.get_option<string>("mempool-info-timeout");
auto mempool_refresh_time_opt = opts.get_option<string>("mempool-refresh-time"); auto mempool_refresh_time_opt = opts.get_option<string>("mempool-refresh-time");
auto testnet_opt = opts.get_option<bool>("testnet"); auto testnet_opt = opts.get_option<bool>("testnet");
@ -155,19 +154,16 @@ main(int ac, const char* av[])
deamon_url = "http:://127.0.0.1:28081"; deamon_url = "http:://127.0.0.1:28081";
} }
uint64_t network_info_timeout {1000};
uint64_t mempool_info_timeout {5000}; uint64_t mempool_info_timeout {5000};
try try
{ {
network_info_timeout = boost::lexical_cast<uint64_t>(*network_info_timeout_opt);
mempool_info_timeout = boost::lexical_cast<uint64_t>(*mempool_info_timeout_opt); mempool_info_timeout = boost::lexical_cast<uint64_t>(*mempool_info_timeout_opt);
} }
catch (boost::bad_lexical_cast &e) catch (boost::bad_lexical_cast &e)
{ {
cout << "Cant cast " << (*network_info_timeout_opt) cout << "Cant cast " << (*mempool_info_timeout_opt) <<" into numbers. Using default values."
<< " or/and " << (*mempool_info_timeout_opt) <<" into numbers. Using default values."
<< endl; << endl;
} }
@ -250,7 +246,6 @@ main(int ac, const char* av[])
enable_block_cache, enable_block_cache,
show_cache_times, show_cache_times,
no_blocks_on_index, no_blocks_on_index,
network_info_timeout,
mempool_info_timeout, mempool_info_timeout,
*testnet_url, *testnet_url,
*mainnet_url); *mainnet_url);

View File

@ -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") "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<string>()->default_value("10"), ("no-blocks-on-index", value<string>()->default_value("10"),
"number of last blocks to be shown on index page") "number of last blocks to be shown on index page")
("network-info-timeout", value<string>()->default_value("1000"),
"maximum time, in milliseconds, to wait for network info availability")
("mempool-info-timeout", value<string>()->default_value("5000"), ("mempool-info-timeout", value<string>()->default_value("5000"),
"maximum time, in milliseconds, to wait for mempool data for the front page") "maximum time, in milliseconds, to wait for mempool data for the front page")
("mempool-refresh-time", value<string>()->default_value("10"), ("mempool-refresh-time", value<string>()->default_value("15"),
"time, in seconds, for each refresh of mempool state") "time, in seconds, for each refresh of mempool state")
("bc-path,b", value<string>(), ("bc-path,b", value<string>(),
"path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb") "path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb")

View File

@ -23,14 +23,52 @@ MempoolStatus::set_blockchain_variables(MicroCore *_mcore,
void void
MempoolStatus::start_mempool_status_thread() 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) if (!is_running)
{ {
m_thread = boost::thread{[]() m_thread = boost::thread{[]()
{ {
try 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) 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()) if (MempoolStatus::read_mempool())
{ {
vector<mempool_tx> current_mempool_txs = get_mempool_txs(); vector<mempool_tx> current_mempool_txs = get_mempool_txs();
@ -45,6 +83,8 @@ MempoolStatus::start_mempool_status_thread()
boost::this_thread::sleep_for( boost::this_thread::sleep_for(
boost::chrono::seconds(mempool_refresh_time)); boost::chrono::seconds(mempool_refresh_time));
++loop_index;
} // while (true) } // while (true)
} }
catch (boost::thread_interrupted&) catch (boost::thread_interrupted&)
@ -166,6 +206,61 @@ MempoolStatus::read_mempool()
return true; 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<uint64_t>(std::time(nullptr));
local_copy.current = true;
current_network_info = local_copy;
return true;
}
vector<MempoolStatus::mempool_tx> vector<MempoolStatus::mempool_tx>
MempoolStatus::get_mempool_txs() MempoolStatus::get_mempool_txs()
{ {
@ -188,6 +283,7 @@ boost::thread MempoolStatus::m_thread;
Blockchain* MempoolStatus::core_storage {nullptr}; Blockchain* MempoolStatus::core_storage {nullptr};
xmreg::MicroCore* MempoolStatus::mcore {nullptr}; xmreg::MicroCore* MempoolStatus::mcore {nullptr};
vector<MempoolStatus::mempool_tx> MempoolStatus::mempool_txs; vector<MempoolStatus::mempool_tx> MempoolStatus::mempool_txs;
atomic<MempoolStatus::network_info> MempoolStatus::current_network_info;
atomic<uint64_t> MempoolStatus::mempool_no {0}; // no of txs atomic<uint64_t> MempoolStatus::mempool_no {0}; // no of txs
atomic<uint64_t> MempoolStatus::mempool_size {0}; // size in bytes. atomic<uint64_t> MempoolStatus::mempool_size {0}; // size in bytes.
uint64_t MempoolStatus::mempool_refresh_time {10}; uint64_t MempoolStatus::mempool_refresh_time {10};

View File

@ -42,6 +42,34 @@ struct MempoolStatus
string txsize; 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 boost::thread m_thread;
static mutex mempool_mutx; static mutex mempool_mutx;
@ -66,6 +94,8 @@ struct MempoolStatus
// <recieved_time, transaction> // <recieved_time, transaction>
static vector<mempool_tx> mempool_txs; static vector<mempool_tx> mempool_txs;
static atomic<network_info> current_network_info;
static void static void
set_blockchain_variables(MicroCore* _mcore, set_blockchain_variables(MicroCore* _mcore,
Blockchain* _core_storage); Blockchain* _core_storage);
@ -76,6 +106,10 @@ struct MempoolStatus
static bool static bool
read_mempool(); read_mempool();
static bool
read_network_info();
static vector<mempool_tx> static vector<mempool_tx>
get_mempool_txs(); get_mempool_txs();

View File

@ -263,7 +263,6 @@ namespace xmreg
uint64_t no_of_mempool_tx_of_frontpage; uint64_t no_of_mempool_tx_of_frontpage;
uint64_t no_blocks_on_index; uint64_t no_blocks_on_index;
uint64_t network_info_timeout;
uint64_t mempool_info_timeout; uint64_t mempool_info_timeout;
string testnet_url; string testnet_url;
@ -282,26 +281,10 @@ namespace xmreg
using lru_cache_t = caches::fixed_sized_cache<Key, Value, caches::LRUCachePolicy<Key>>; using lru_cache_t = caches::fixed_sized_cache<Key, Value, caches::LRUCachePolicy<Key>>;
// alias for easy class typing // alias for easy class typing
template <typename Key, typename Value> template <typename Key, typename Value>
using fifo_cache_t = caches::fixed_sized_cache<Key, Value, caches::FIFOCachePolicy<Key>>; using fifo_cache_t = caches::fixed_sized_cache<Key, Value, caches::FIFOCachePolicy<Key>>;
// 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<network_info> previous_network_info;
// cache of txs_map of txs in blocks. this is useful for // cache of txs_map of txs in blocks. this is useful for
// index2 page, so that we dont parse txs in each block // index2 page, so that we dont parse txs in each block
// for each request. // for each request.
@ -325,7 +308,6 @@ namespace xmreg
bool _enable_block_cache, bool _enable_block_cache,
bool _show_cache_times, bool _show_cache_times,
uint64_t _no_blocks_on_index, uint64_t _no_blocks_on_index,
uint64_t _network_info_timeout,
uint64_t _mempool_info_timeout, uint64_t _mempool_info_timeout,
string _testnet_url, string _testnet_url,
string _mainnet_url) string _mainnet_url)
@ -343,7 +325,6 @@ namespace xmreg
enable_block_cache {_enable_block_cache}, enable_block_cache {_enable_block_cache},
show_cache_times {_show_cache_times}, show_cache_times {_show_cache_times},
no_blocks_on_index {_no_blocks_on_index}, no_blocks_on_index {_no_blocks_on_index},
network_info_timeout {_network_info_timeout},
mempool_info_timeout {_mempool_info_timeout}, mempool_info_timeout {_mempool_info_timeout},
testnet_url {_testnet_url}, testnet_url {_testnet_url},
mainnet_url {_mainnet_url}, mainnet_url {_mainnet_url},
@ -353,9 +334,6 @@ namespace xmreg
no_of_mempool_tx_of_frontpage = 25; 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 // read template files for all the pages
// into template_file map // into template_file map
@ -406,16 +384,6 @@ namespace xmreg
return json{}; 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; return j_info;
}); });
@ -737,43 +705,12 @@ namespace xmreg
context["cache_hits"] = cache_hits; context["cache_hits"] = cache_hits;
context["cache_misses"] = cache_misses; 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( // get current network info from MemoryStatus thread.
std::chrono::milliseconds(network_info_timeout)); MempoolStatus::network_info current_network_info
= MempoolStatus::current_network_info;
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;
}
// perapre network info mstch::map for the front page // perapre network info mstch::map for the front page
string hash_rate; string hash_rate;
if (testnet) if (testnet)
@ -790,19 +727,23 @@ namespace xmreg
// if network info is younger than 2 minute, assume its current. No sense // 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. // showing that it is not current if its less then block time.
if (local_copy_server_timestamp - current_network_info.info_timestamp < 120) 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<double>(
current_network_info.block_size_limit)/1024.0);
context["network_info"] = mstch::map { context["network_info"] = mstch::map {
{"difficulty" , current_network_info.difficulty}, {"difficulty" , current_network_info.difficulty},
{"hash_rate" , hash_rate}, {"hash_rate" , hash_rate},
{"fee_per_kb" , print_money(current_network_info.fee_per_kb)}, {"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}, {"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)}, {"is_pool_size_zero" , (current_network_info.tx_pool_size == 0)},
{"age" , network_info_age.first}, {"age" , network_info_age.first},
{"age_format" , network_info_age.second}, {"age_format" , network_info_age.second},
@ -5505,32 +5446,35 @@ namespace xmreg
bool bool
get_monero_network_info(json& j_info) 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; return false;
} }
j_info = json { j_info = json {
{"status" , network_info.status}, {"status" , local_copy_network_info.current},
{"height" , network_info.height}, {"current" , local_copy_network_info.current},
{"target_height" , network_info.target_height}, {"height" , local_copy_network_info.height},
{"difficulty" , network_info.difficulty}, {"target_height" , local_copy_network_info.target_height},
{"target" , network_info.target}, {"difficulty" , local_copy_network_info.difficulty},
{"hash_rate" , (network_info.difficulty/network_info.target)}, {"target" , local_copy_network_info.target},
{"tx_count" , network_info.tx_count}, {"hash_rate" , local_copy_network_info.hash_rate},
{"tx_pool_size" , network_info.tx_pool_size}, {"tx_count" , local_copy_network_info.tx_count},
{"alt_blocks_count" , network_info.alt_blocks_count}, {"tx_pool_size" , local_copy_network_info.tx_pool_size},
{"outgoing_connections_count", network_info.outgoing_connections_count}, {"alt_blocks_count" , local_copy_network_info.alt_blocks_count},
{"incoming_connections_count", network_info.incoming_connections_count}, {"outgoing_connections_count", local_copy_network_info.outgoing_connections_count},
{"white_peerlist_size" , network_info.white_peerlist_size}, {"incoming_connections_count", local_copy_network_info.incoming_connections_count},
{"grey_peerlist_size" , network_info.grey_peerlist_size}, {"white_peerlist_size" , local_copy_network_info.white_peerlist_size},
{"testnet" , network_info.testnet}, {"grey_peerlist_size" , local_copy_network_info.grey_peerlist_size},
{"top_block_hash" , network_info.top_block_hash}, {"testnet" , local_copy_network_info.testnet},
{"cumulative_difficulty" , network_info.cumulative_difficulty}, {"top_block_hash" , pod_to_hex(local_copy_network_info.top_block_hash)},
{"block_size_limit" , network_info.block_size_limit}, {"cumulative_difficulty" , local_copy_network_info.cumulative_difficulty},
{"start_time" , network_info.start_time} {"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; return true;

View File

@ -39,7 +39,8 @@
Network difficulty: {{difficulty}} Network difficulty: {{difficulty}}
| Hash rate: {{hash_rate}} | Hash rate: {{hash_rate}}
| Fee per kb: {{fee_per_kb}} | 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}} {{^is_current_info}}
| Data from {{age}} {{age_format}} ago | Data from {{age}} {{age_format}} ago
{{/is_current_info}} {{/is_current_info}}