diff --git a/README.md b/README.md index 58a7e28..311c8a6 100644 --- a/README.md +++ b/README.md @@ -564,21 +564,22 @@ curl -w "\n" -X GET "http://139.162.32.245:8081/api/networkinfo" "data": { "alt_blocks_count": 0, "block_size_limit": 600000, - "cumulative_difficulty": 2067724366624367, - "difficulty": 7530486740, - "grey_peerlist_size": 4987, - "hash_rate": 62754056, - "height": 1307537, + "cumulative_difficulty": 2091549555696348, + "difficulty": 7941560081, + "fee_per_kb": 303970000, + "grey_peerlist_size": 4991, + "hash_rate": 66179667, + "height": 1310423, "incoming_connections_count": 0, - "outgoing_connections_count": 8, - "start_time": 1494473774, + "outgoing_connections_count": 5, + "start_time": 1494822692, "status": "OK", "target": 120, - "target_height": 1307518, + "target_height": 0, "testnet": false, - "top_block_hash": "0726de5b86f431547fc64fc2c8e1c11d76843ada0561993ee540e4eee29d83c3", - "tx_count": 1210222, - "tx_pool_size": 5, + "top_block_hash": "76f9e85d62415312758bc09e0b9b48fd2b005231ad1eee435a8081e551203f82", + "tx_count": 1219048, + "tx_pool_size": 2, "white_peerlist_size": 1000 }, "status": "success" diff --git a/src/monero_headers.h b/src/monero_headers.h index c373cc2..d43573e 100644 --- a/src/monero_headers.h +++ b/src/monero_headers.h @@ -14,6 +14,8 @@ #define KEY_IMAGE_EXPORT_FILE_MAGIC "Monero key image export\002" #define OUTPUT_EXPORT_FILE_MAGIC "Monero output export\003" +#define FEE_ESTIMATE_GRACE_BLOCKS 10 // estimate fee valid for that many blocks + #include "release/version/version.h" #include "net/http_client.h" diff --git a/src/page.h b/src/page.h index 9ae021a..fe2b864 100644 --- a/src/page.h +++ b/src/page.h @@ -394,6 +394,33 @@ namespace xmreg string index2(uint64_t page_no = 0, bool refresh_page = false) { + + // we get network info, such as current hash rate + // but since this makes a rpc call to deamon, we make it as an async + // call. this way we dont have to wait with execution of the rest of the + // index2 method, until deamon gives as the required result. + std::future network_info_ftr = std::async(std::launch::async, [&] + { + json j_info; + + if (!get_monero_network_info(j_info)) + { + 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; + }); + //get current server timestamp server_timestamp = std::time(nullptr); @@ -694,6 +721,42 @@ 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 (200 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(200)); + + if (ftr_status == std::future_status::ready) + { + json j_network_info = network_info_ftr.get(); + + if (!j_network_info.empty()) + { + string difficulty; + + if (testnet) + { + difficulty = std::to_string(j_network_info["hash_rate"].get()) + " H/s"; + } + else + { + difficulty = fmt::format("{:0.3f} MH/s", j_network_info["hash_rate"].get()/1.0e6); + } + + context["network_info"] = mstch::map { + {"difficulty", j_network_info["difficulty"].get()}, + {"hash_rate" , difficulty}, + {"fee_per_kb", xmreg::xmr_amount_to_str(j_network_info["fee_per_kb"], "{:0.12f}")} + }; + } + } + else + { + cerr << "network_info future not ready yet, skipping." << endl; + } + // get memory pool rendered template string mempool_html = mempool(false, no_of_mempool_tx_of_frontpage); @@ -4677,6 +4740,7 @@ namespace xmreg json j_info; + // get basic network info if (!get_monero_network_info(j_info)) { j_response["status"] = "error"; @@ -4684,6 +4748,18 @@ namespace xmreg return j_response; } + uint64_t fee_estimated {0}; + + // get dynamic fee estimate from last 10 blocks + if (!get_dynamic_per_kb_fee_estimate(fee_estimated)) + { + j_response["status"] = "error"; + j_response["message"] = "Cant get dynamic fee esimate"; + return j_response; + } + + j_info["fee_per_kb"] = fee_estimated; + j_data = j_info; j_response["status"] = "success"; @@ -4717,6 +4793,7 @@ namespace xmreg return j_tx; } + bool find_tx(const crypto::hash& tx_hash, transaction& tx, @@ -5464,7 +5541,7 @@ namespace xmreg + template_file["footer"]; } - bool + bool get_monero_network_info(json& j_info) { COMMAND_RPC_GET_INFO::response network_info; @@ -5498,6 +5575,25 @@ namespace xmreg return true; } + bool + get_dynamic_per_kb_fee_estimate(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; + + return true; + } + string get_footer() { diff --git a/src/rpccalls.cpp b/src/rpccalls.cpp index 7fcce07..ddce8ef 100644 --- a/src/rpccalls.cpp +++ b/src/rpccalls.cpp @@ -207,4 +207,70 @@ rpccalls::get_network_info(COMMAND_RPC_GET_INFO::response& response) } +bool +rpccalls::get_dynamic_per_kb_fee_estimate( + uint64_t grace_blocks, + uint64_t& fee, + string& error_msg) +{ + epee::json_rpc::request + req_t = AUTO_VAL_INIT(req_t); + epee::json_rpc::response + resp_t = AUTO_VAL_INIT(resp_t); + + + req_t.jsonrpc = "2.0"; + req_t.id = epee::serialization::storage_entry(0); + req_t.method = "get_fee_estimate"; + req_t.params.grace_blocks = grace_blocks; + + bool r {false}; + + std::lock_guard guard(m_daemon_rpc_mutex); + + { + if (!connect_to_monero_deamon()) + { + cerr << "get_current_height: not connected to deamon" << endl; + return false; + } + + r = epee::net_utils::invoke_http_json("/json_rpc", + req_t, resp_t, + m_http_client); + } + + string err; + + + if (r) + { + if (resp_t.result.status == CORE_RPC_STATUS_BUSY) + { + err = "daemon is busy. Please try again later."; + } + else if (resp_t.result.status != CORE_RPC_STATUS_OK) + { + err = resp_t.result.status; + } + + if (!err.empty()) + { + cerr << "Error connecting to Monero deamon due to " + << err << endl; + return false; + } + } + else + { + cerr << "Error connecting to Monero deamon at " + << deamon_url << endl; + return false; + } + + fee = resp_t.result.fee; + + return true; + +} } diff --git a/src/rpccalls.h b/src/rpccalls.h index ed21ea4..f0aefbc 100644 --- a/src/rpccalls.h +++ b/src/rpccalls.h @@ -52,6 +52,12 @@ public: bool get_network_info(COMMAND_RPC_GET_INFO::response& info); + bool + get_dynamic_per_kb_fee_estimate( + uint64_t grace_blocks, + uint64_t& fee, + string& error_msg); + }; diff --git a/src/templates/index2.html b/src/templates/index2.html index 8e70134..94ac810 100644 --- a/src/templates/index2.html +++ b/src/templates/index2.html @@ -32,6 +32,18 @@ {{/testnet}} + + + {{#network_info}} + +

+ Network difficulty: {{difficulty}} + | Hash rate: {{hash_rate}} + | Fee per kb: {{fee_per_kb}} +

+ {{/network_info}} + + {{{mempool_info}}} @@ -87,6 +99,7 @@ + {{#show_cache_times}}