From a96d9f35945fe0784dbb077ac682cbe7d9f3e091 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Mon, 15 May 2017 14:19:57 +0800 Subject: [PATCH 01/35] basic network info added to front page https://github.com/moneroexamples/onion-monero-blockchain-explorer/issues/59 --- README.md | 23 ++++----- src/monero_headers.h | 2 + src/page.h | 98 ++++++++++++++++++++++++++++++++++++++- src/rpccalls.cpp | 66 ++++++++++++++++++++++++++ src/rpccalls.h | 6 +++ src/templates/index2.html | 13 ++++++ 6 files changed, 196 insertions(+), 12 deletions(-) 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}}
From f131bcfc9b92fcfd57d36329e474be293348949d Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Tue, 16 May 2017 07:53:21 +0800 Subject: [PATCH 02/35] info about cmake path to monero added to readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 311c8a6..d73fadf 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,9 @@ mkdir build && cd build # create the makefile cmake .. +# altearnatively can use: cmake -DMONERO_DIR=/path/to/monero_folder .. +# if monero is not in ~/monero + # compile make ``` From d6bcf94a3d2fdd7134d875f8cb9ad8e44d1ca01e Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Tue, 16 May 2017 13:29:24 +0800 Subject: [PATCH 03/35] testing monero emission thread --- main.cpp | 13 ++ src/CMakeLists.txt | 4 +- src/CurrentBlockchainStatus.cpp | 256 ++++++++++++++++++++++++++++++++ src/CurrentBlockchainStatus.h | 73 +++++++++ src/page.h | 29 +++- src/templates/index2.html | 11 +- 6 files changed, 378 insertions(+), 8 deletions(-) create mode 100644 src/CurrentBlockchainStatus.cpp create mode 100644 src/CurrentBlockchainStatus.h diff --git a/main.cpp b/main.cpp index 8c1827d..6a1d5a7 100644 --- a/main.cpp +++ b/main.cpp @@ -128,6 +128,19 @@ int main(int ac, const char* av[]) { cout << blockchain_path << endl; + if (!xmreg::CurrentBlockchainStatus::init_monero_blockchain()) + { + cerr << "Error accessing blockchain." << endl; + return EXIT_FAILURE; + } + + // launch the status monitoring thread so that it keeps track of blockchain + // info, e.g., current height. Information from this thread is used + // by tx searching threads that are launched for each user independently, + // when they log back or create new account. + xmreg::CurrentBlockchainStatus::start_monitor_blockchain_thread(); + + // create instance of our MicroCore // and make pointer to the Blockchain xmreg::MicroCore mcore; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a15dc01..d4f476c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,7 +6,7 @@ set(SOURCE_HEADERS MicroCore.h tools.h monero_headers.h - ) + CurrentBlockchainStatus.h) set(SOURCE_FILES MicroCore.cpp @@ -14,7 +14,7 @@ set(SOURCE_FILES CmdLineOptions.cpp page.h rpccalls.cpp rpccalls.h - version.h.in) + version.h.in CurrentBlockchainStatus.cpp) # make static library called libmyxrm # that we are going to link to diff --git a/src/CurrentBlockchainStatus.cpp b/src/CurrentBlockchainStatus.cpp new file mode 100644 index 0000000..ce966cd --- /dev/null +++ b/src/CurrentBlockchainStatus.cpp @@ -0,0 +1,256 @@ +// +// Created by mwo on 16/05/17. +// + +#include "CurrentBlockchainStatus.h" + +namespace xmreg +{ + +using namespace std; + + + +bool +CurrentBlockchainStatus::init_monero_blockchain() +{ + // set monero log output level + uint32_t log_level = 0; + mlog_configure(mlog_get_default_log_path(""), true); + + mcore = unique_ptr(new xmreg::MicroCore{}); + + // initialize the core using the blockchain path + if (!mcore->init(blockchain_path)) + { + cerr << "Error accessing blockchain." << endl; + return false; + } + + // get the high level Blockchain object to interact + // with the blockchain lmdb database + core_storage = &(mcore->get_core()); + + return true; +} + + +void +CurrentBlockchainStatus::start_monitor_blockchain_thread() +{ + + string emmision_saved_file = blockchain_path + output_file; + + if (boost::filesystem::exists(emmision_saved_file)) + { + if (!load_current_emission_amount()) + { + cerr << "Cant read or has incorrect format: " << emmision_saved_file << endl; + return; + } + } + + if (!is_running) + { + m_thread = std::thread{[]() + { + while (true) + { + current_height = core_storage->get_current_blockchain_height(); + + update_current_emission_amount(); + + save_current_emission_amount(); + + if (searched_blk_no < current_height - 1000) + { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + else + { + std::this_thread::sleep_for(std::chrono::seconds(60)); + } + } + }}; + + is_running = true; + } +} + + +void +CurrentBlockchainStatus::update_current_emission_amount() +{ + + cout << "updating emission rate: " << current_height << endl; + + uint64_t no_of_blocks_to_search_at_once {1000}; + + uint64_t blk_no = searched_blk_no; + + uint64_t end_block = blk_no + no_of_blocks_to_search_at_once; + + uint64_t current_blockchain_height = current_height; + + end_block = end_block > current_blockchain_height ? current_blockchain_height : end_block; + + uint64_t current_emission_amount {0}; + uint64_t current_fee_amount {0}; + + while (blk_no < end_block) + { + + block blk; + + mcore->get_block_by_height(blk_no, blk); + + uint64_t coinbase_amount = get_outs_money_amount(blk.miner_tx); + + std::list txs; + std::list missed_txs; + + uint64_t tx_fee_amount = 0; + + core_storage->get_transactions(blk.tx_hashes, txs, missed_txs); + + for(const auto& tx: txs) + { + tx_fee_amount += get_tx_fee(tx); + } + + current_emission_amount += coinbase_amount - tx_fee_amount; + current_fee_amount += tx_fee_amount; + + ++blk_no; + } + + searched_blk_no = blk_no; + total_emission_amount += current_emission_amount; + total_fee_amount += current_fee_amount; + + cout << "blk: " << blk_no + << " total_emission_amount: " << xmr_amount_to_str(uint64_t(total_emission_amount)) + << " total_fee_amount: " << xmr_amount_to_str(uint64_t(total_fee_amount)) + << endl; +} + + + +bool +CurrentBlockchainStatus::save_current_emission_amount() +{ + + string emmision_saved_file = blockchain_path + output_file; + + ofstream out(emmision_saved_file); + + if( !out ) + { + cerr << "Couldn't open file." << endl; + return false; + } + + uint64_t check_sum = uint64_t(searched_blk_no) + + uint64_t(total_emission_amount) + + uint64_t(total_fee_amount); + + string out_line = to_string(searched_blk_no) + + "," + to_string(total_emission_amount) + + "," + to_string(total_fee_amount) + + "," + to_string(check_sum); + + out << out_line << flush; + + return true; +} + + +bool +CurrentBlockchainStatus::load_current_emission_amount() +{ + string emmision_saved_file = blockchain_path + output_file; + + string last_saved_emmision = xmreg::read(emmision_saved_file); + + if (last_saved_emmision.empty()) { + cerr << "Couldn't open file." << endl; + return false; + } + + vector strs; + boost::split(strs, last_saved_emmision, boost::is_any_of(",")); + + if (strs.empty()) { + cerr << "Problem spliting string values form emission_amount." << endl; + return false; + } + + uint64_t read_check_sum{0}; + + try { + searched_blk_no = boost::lexical_cast(strs.at(0)); + total_emission_amount = boost::lexical_cast(strs.at(1)); + total_fee_amount = boost::lexical_cast(strs.at(2)); + read_check_sum = boost::lexical_cast(strs.at(3)); + } + catch (boost::bad_lexical_cast &e) { + cerr << "Cant parse to number: " << last_saved_emmision << endl; + return false; + } + + uint64_t check_sum = uint64_t(searched_blk_no) + + uint64_t(total_emission_amount) + + uint64_t(total_fee_amount); + + if (read_check_sum != check_sum) { + cerr << "read_check_sum != check_sum: " + << read_check_sum << " != " << check_sum + << endl; + + return false; + } + + return true; + +} + +vector +CurrentBlockchainStatus::get_emission_amount() +{ + + uint64_t searched_block = searched_blk_no; + uint64_t emission_amount = total_emission_amount; + uint64_t fee_amount = total_fee_amount; + + return {searched_block, emission_amount, fee_amount}; + +} + +bool +CurrentBlockchainStatus::is_thread_running() +{ + return is_running; +} + +string CurrentBlockchainStatus::blockchain_path{"/home/mwo/.bitmonero/lmdb"}; + +string CurrentBlockchainStatus::output_file {"/emission_amount.txt"}; + +string CurrentBlockchainStatus::deamon_url{"http:://127.0.0.1:18081"}; + +atomic CurrentBlockchainStatus::current_height {0}; + +atomic CurrentBlockchainStatus::total_emission_amount {0} ; + +atomic CurrentBlockchainStatus::total_fee_amount {0} ; + +atomic CurrentBlockchainStatus::searched_blk_no {0}; + +std::thread CurrentBlockchainStatus::m_thread; + +atomic CurrentBlockchainStatus::is_running {false}; + +cryptonote::Blockchain* CurrentBlockchainStatus::core_storage; +unique_ptr CurrentBlockchainStatus::mcore; + +} diff --git a/src/CurrentBlockchainStatus.h b/src/CurrentBlockchainStatus.h new file mode 100644 index 0000000..61762c6 --- /dev/null +++ b/src/CurrentBlockchainStatus.h @@ -0,0 +1,73 @@ +// +// Created by mwo on 16/05/17. +// + +#ifndef XMRBLOCKS_CURRENTBLOCKCHAINSTATUS_H +#define XMRBLOCKS_CURRENTBLOCKCHAINSTATUS_H + +#include "MicroCore.h" + +#include + +#include +#include +#include +#include +#include + +namespace xmreg +{ + +using namespace std; + +class CurrentBlockchainStatus +{ + static string blockchain_path; + + static string output_file; + + static string deamon_url; + + static atomic current_height; + + static atomic total_emission_amount; + static atomic total_fee_amount; + + static atomic searched_blk_no; + + static std::thread m_thread; + + static atomic is_running; + + // make object for accessing the blockchain here + static unique_ptr mcore; + static cryptonote::Blockchain *core_storage; + + +public: + static void + start_monitor_blockchain_thread(); + + static bool + init_monero_blockchain(); + + static void + update_current_emission_amount(); + + static bool + save_current_emission_amount(); + + static bool + load_current_emission_amount(); + + static vector + get_emission_amount(); + + static bool + is_thread_running(); + +}; + +} + +#endif //XMRBLOCKS_CURRENTBLOCKCHAINSTATUS_H diff --git a/src/page.h b/src/page.h index fe2b864..fb6a1ea 100644 --- a/src/page.h +++ b/src/page.h @@ -17,6 +17,8 @@ #include "tools.h" #include "rpccalls.h" +#include "CurrentBlockchainStatus.h" + #include "../ext/crow/http_request.h" #include "../ext/vpetrigocaches/cache.hpp" @@ -746,9 +748,9 @@ namespace xmreg } 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}")} + {"difficulty" , j_network_info["difficulty"].get()}, + {"hash_rate" , difficulty}, + {"fee_per_kb" , print_money(j_network_info["fee_per_kb"])} }; } } @@ -757,6 +759,27 @@ namespace xmreg cerr << "network_info future not ready yet, skipping." << endl; } + if (CurrentBlockchainStatus::is_thread_running()) + { + vector emission_values + = CurrentBlockchainStatus::get_emission_amount(); + + string emission_blk_no = std::to_string(emission_values.at(0) - 1); + string emission_amount = xmr_amount_to_str(emission_values.at(1), "{:0.3f}"); + string emission_fee_amount = xmr_amount_to_str(emission_values.at(2), "{:0.3f}"); + + context["emission"] = mstch::map { + {"blk_no" , emission_blk_no}, + {"amount" , emission_amount}, + {"fee_amount", emission_fee_amount} + }; + } + else + { + cerr << "emission thread not running, skipping." << endl; + } + + // get memory pool rendered template string mempool_html = mempool(false, no_of_mempool_tx_of_frontpage); diff --git a/src/templates/index2.html b/src/templates/index2.html index 94ac810..b143591 100644 --- a/src/templates/index2.html +++ b/src/templates/index2.html @@ -35,13 +35,18 @@ {{#network_info}} - -

+

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

- {{/network_info}} + {{/network_info}} + + {{#emission}} +

+ Monero emission (fees) is {{amount}} ({{fee_amount}}) as of {{blk_no}} block +

+ {{/emission}}
From 7a4a02b56317eb25c9ac705d3a6d568a3dbe11b1 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Wed, 17 May 2017 08:20:43 +0800 Subject: [PATCH 04/35] emission for testnet network added --- main.cpp | 33 +++++++++++------- src/CurrentBlockchainStatus.cpp | 60 +++++++++++++++++++++++---------- src/CurrentBlockchainStatus.h | 15 ++++++--- 3 files changed, 75 insertions(+), 33 deletions(-) diff --git a/main.cpp b/main.cpp index 6a1d5a7..2b38b74 100644 --- a/main.cpp +++ b/main.cpp @@ -128,18 +128,6 @@ int main(int ac, const char* av[]) { cout << blockchain_path << endl; - if (!xmreg::CurrentBlockchainStatus::init_monero_blockchain()) - { - cerr << "Error accessing blockchain." << endl; - return EXIT_FAILURE; - } - - // launch the status monitoring thread so that it keeps track of blockchain - // info, e.g., current height. Information from this thread is used - // by tx searching threads that are launched for each user independently, - // when they log back or create new account. - xmreg::CurrentBlockchainStatus::start_monitor_blockchain_thread(); - // create instance of our MicroCore // and make pointer to the Blockchain @@ -157,7 +145,28 @@ int main(int ac, const char* av[]) { string deamon_url {*deamon_url_opt}; if (testnet && deamon_url == "http:://127.0.0.1:18081") + { deamon_url = "http:://127.0.0.1:28081"; + } + + xmreg::CurrentBlockchainStatus::blockchain_path + = blockchain_path.string(); + xmreg::CurrentBlockchainStatus::testnet + = testnet; + xmreg::CurrentBlockchainStatus::deamon_url + = deamon_url; + + if (!xmreg::CurrentBlockchainStatus::init_monero_blockchain()) + { + cerr << "Error accessing blockchain from CurrentBlockchainStatus." << endl; + return EXIT_FAILURE; + } + + // launch the status monitoring thread so that it keeps track of blockchain + // info, e.g., current height. Information from this thread is used + // by tx searching threads that are launched for each user independently, + // when they log back or create new account. + xmreg::CurrentBlockchainStatus::start_monitor_blockchain_thread(); // create instance of page class which // contains logic for the website diff --git a/src/CurrentBlockchainStatus.cpp b/src/CurrentBlockchainStatus.cpp index ce966cd..c25ad99 100644 --- a/src/CurrentBlockchainStatus.cpp +++ b/src/CurrentBlockchainStatus.cpp @@ -39,13 +39,21 @@ void CurrentBlockchainStatus::start_monitor_blockchain_thread() { - string emmision_saved_file = blockchain_path + output_file; + string emmision_saved_file = get_output_file_path(); if (boost::filesystem::exists(emmision_saved_file)) { if (!load_current_emission_amount()) { - cerr << "Cant read or has incorrect format: " << emmision_saved_file << endl; + cerr << "Emission file cant be read, got corrupted or has incorrect format:\n " << emmision_saved_file + << "\nEmission monitoring thread is not started.\nDelete the file and" + << " restart the explorer or disable emission monitoring." + << endl; + + cerr << "Press ENTER to continue without emission monitoring or Ctr+C to exit" << endl; + + cin.get(); + return; } } @@ -62,7 +70,7 @@ CurrentBlockchainStatus::start_monitor_blockchain_thread() save_current_emission_amount(); - if (searched_blk_no < current_height - 1000) + if (searched_blk_no < current_height - blockchain_chunk_size) { std::this_thread::sleep_for(std::chrono::seconds(1)); } @@ -84,11 +92,9 @@ CurrentBlockchainStatus::update_current_emission_amount() cout << "updating emission rate: " << current_height << endl; - uint64_t no_of_blocks_to_search_at_once {1000}; - uint64_t blk_no = searched_blk_no; - uint64_t end_block = blk_no + no_of_blocks_to_search_at_once; + uint64_t end_block = blk_no + blockchain_chunk_size; uint64_t current_blockchain_height = current_height; @@ -140,7 +146,7 @@ bool CurrentBlockchainStatus::save_current_emission_amount() { - string emmision_saved_file = blockchain_path + output_file; + string emmision_saved_file = get_output_file_path(); ofstream out(emmision_saved_file); @@ -168,33 +174,39 @@ CurrentBlockchainStatus::save_current_emission_amount() bool CurrentBlockchainStatus::load_current_emission_amount() { - string emmision_saved_file = blockchain_path + output_file; + string emmision_saved_file = get_output_file_path(); string last_saved_emmision = xmreg::read(emmision_saved_file); - if (last_saved_emmision.empty()) { + if (last_saved_emmision.empty()) + { cerr << "Couldn't open file." << endl; return false; } + last_saved_emmision.erase(last_saved_emmision.find_last_not_of(" \n\r\t")+1); + vector strs; boost::split(strs, last_saved_emmision, boost::is_any_of(",")); - if (strs.empty()) { + if (strs.empty()) + { cerr << "Problem spliting string values form emission_amount." << endl; return false; } uint64_t read_check_sum{0}; - try { - searched_blk_no = boost::lexical_cast(strs.at(0)); + try + { + searched_blk_no = boost::lexical_cast(strs.at(0)); total_emission_amount = boost::lexical_cast(strs.at(1)); - total_fee_amount = boost::lexical_cast(strs.at(2)); - read_check_sum = boost::lexical_cast(strs.at(3)); + total_fee_amount = boost::lexical_cast(strs.at(2)); + read_check_sum = boost::lexical_cast(strs.at(3)); } - catch (boost::bad_lexical_cast &e) { - cerr << "Cant parse to number: " << last_saved_emmision << endl; + catch (boost::bad_lexical_cast &e) + { + cerr << "Cant parse to number date from string: " << last_saved_emmision << endl; return false; } @@ -202,7 +214,8 @@ CurrentBlockchainStatus::load_current_emission_amount() + uint64_t(total_emission_amount) + uint64_t(total_fee_amount); - if (read_check_sum != check_sum) { + if (read_check_sum != check_sum) + { cerr << "read_check_sum != check_sum: " << read_check_sum << " != " << check_sum << endl; @@ -214,6 +227,15 @@ CurrentBlockchainStatus::load_current_emission_amount() } +string +CurrentBlockchainStatus::get_output_file_path() +{ + string emmision_saved_file = blockchain_path + output_file; + + return emmision_saved_file; +} + + vector CurrentBlockchainStatus::get_emission_amount() { @@ -234,10 +256,14 @@ CurrentBlockchainStatus::is_thread_running() string CurrentBlockchainStatus::blockchain_path{"/home/mwo/.bitmonero/lmdb"}; +bool CurrentBlockchainStatus::testnet {false}; + string CurrentBlockchainStatus::output_file {"/emission_amount.txt"}; string CurrentBlockchainStatus::deamon_url{"http:://127.0.0.1:18081"}; +uint64_t CurrentBlockchainStatus::blockchain_chunk_size {10000}; + atomic CurrentBlockchainStatus::current_height {0}; atomic CurrentBlockchainStatus::total_emission_amount {0} ; diff --git a/src/CurrentBlockchainStatus.h b/src/CurrentBlockchainStatus.h index 61762c6..983c0fc 100644 --- a/src/CurrentBlockchainStatus.h +++ b/src/CurrentBlockchainStatus.h @@ -20,17 +20,23 @@ namespace xmreg using namespace std; -class CurrentBlockchainStatus +struct CurrentBlockchainStatus { + static string blockchain_path; + static bool testnet; + static string output_file; static string deamon_url; + static uint64_t blockchain_chunk_size; + static atomic current_height; static atomic total_emission_amount; + static atomic total_fee_amount; static atomic searched_blk_no; @@ -41,10 +47,9 @@ class CurrentBlockchainStatus // make object for accessing the blockchain here static unique_ptr mcore; - static cryptonote::Blockchain *core_storage; + static cryptonote::Blockchain *core_storage; -public: static void start_monitor_blockchain_thread(); @@ -63,9 +68,11 @@ public: static vector get_emission_amount(); + static string + get_output_file_path(); + static bool is_thread_running(); - }; } From 9c57d8b3a382c6c1b2d9072ba2077a40a9c072e6 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Wed, 17 May 2017 13:30:36 +0800 Subject: [PATCH 05/35] Emission atomic structure added --- CMakeLists.txt | 1 + main.cpp | 61 +++++++++++++++++++------ src/CmdLineOptions.cpp | 2 + src/CurrentBlockchainStatus.cpp | 81 ++++++++++++++------------------- src/CurrentBlockchainStatus.h | 30 +++++++++--- src/page.h | 14 +++--- 6 files changed, 112 insertions(+), 77 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 75e18f7..de22f5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,6 +113,7 @@ set(LIBRARIES unbound curl crypto + atomic ssl) if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT WIN32) diff --git a/main.cpp b/main.cpp index 2b38b74..a809719 100644 --- a/main.cpp +++ b/main.cpp @@ -26,7 +26,18 @@ struct jsonresponse: crow::response }; } +class ExitHandler +{ +public: + void exit() { exitHandler(0); } + static void exitHandler(int) { s_shouldExit = true; } + bool shouldExit() const { return s_shouldExit; } + +private: + static bool s_shouldExit; +}; +bool ExitHandler::s_shouldExit = false; int main(int ac, const char* av[]) { @@ -60,6 +71,8 @@ int main(int ac, const char* av[]) { auto enable_tx_cache_opt = opts.get_option("enable-tx-cache"); auto enable_block_cache_opt = opts.get_option("enable-block-cache"); auto show_cache_times_opt = opts.get_option("show-cache-times"); + auto enable_emission_monitor_opt = opts.get_option("enable-emission-monitor"); + bool testnet {*testnet_opt}; bool enable_pusher {*enable_pusher_opt}; @@ -71,6 +84,7 @@ int main(int ac, const char* av[]) { bool enable_json_api {*enable_json_api_opt}; bool enable_tx_cache {*enable_tx_cache_opt}; bool enable_block_cache {*enable_block_cache_opt}; + bool enable_emission_monitor {*enable_emission_monitor_opt}; bool show_cache_times {*show_cache_times_opt}; @@ -149,24 +163,41 @@ int main(int ac, const char* av[]) { deamon_url = "http:://127.0.0.1:28081"; } - xmreg::CurrentBlockchainStatus::blockchain_path - = blockchain_path.string(); - xmreg::CurrentBlockchainStatus::testnet - = testnet; - xmreg::CurrentBlockchainStatus::deamon_url - = deamon_url; - if (!xmreg::CurrentBlockchainStatus::init_monero_blockchain()) + if (enable_emission_monitor == true) { - cerr << "Error accessing blockchain from CurrentBlockchainStatus." << endl; - return EXIT_FAILURE; - } + // This starts new thread, which aim is + // to calculate, store and monitor + // current total Monero emission amount. + + // This thread stores the current emission + // which it has caluclated in + // /emission_amount.txt file, + // e.g., ~/.bitmonero/lmdb/emission_amount.txt. + // So instead of calcualting the emission + // from scrach whenever the explorer is started, + // the thread is initalized with the values + // found in emission_amount.txt file. + + xmreg::CurrentBlockchainStatus::blockchain_path + = blockchain_path.string(); + xmreg::CurrentBlockchainStatus::testnet + = testnet; + xmreg::CurrentBlockchainStatus::deamon_url + = deamon_url; + + if (!xmreg::CurrentBlockchainStatus::init_monero_blockchain()) + { + cerr << "Error accessing blockchain from CurrentBlockchainStatus." << endl; + return EXIT_FAILURE; + } - // launch the status monitoring thread so that it keeps track of blockchain - // info, e.g., current height. Information from this thread is used - // by tx searching threads that are launched for each user independently, - // when they log back or create new account. - xmreg::CurrentBlockchainStatus::start_monitor_blockchain_thread(); + // launch the status monitoring thread so that it keeps track of blockchain + // info, e.g., current height. Information from this thread is used + // by tx searching threads that are launched for each user independently, + // when they log back or create new account. + xmreg::CurrentBlockchainStatus::start_monitor_blockchain_thread(); + } // create instance of page class which // contains logic for the website diff --git a/src/CmdLineOptions.cpp b/src/CmdLineOptions.cpp index 2a2830a..e93bdec 100644 --- a/src/CmdLineOptions.cpp +++ b/src/CmdLineOptions.cpp @@ -45,6 +45,8 @@ namespace xmreg "enable caching of block details") ("enable-autorefresh-option", value()->default_value(false)->implicit_value(true), "enable users to have the index page on autorefresh") + ("enable-emission-monitor", value()->default_value(false)->implicit_value(true), + "enable Monero total emission monitoring thread") ("port,p", value()->default_value("8081"), "default port") ("testnet-url", value()->default_value(""), diff --git a/src/CurrentBlockchainStatus.cpp b/src/CurrentBlockchainStatus.cpp index c25ad99..2327e8e 100644 --- a/src/CurrentBlockchainStatus.cpp +++ b/src/CurrentBlockchainStatus.cpp @@ -38,6 +38,7 @@ CurrentBlockchainStatus::init_monero_blockchain() void CurrentBlockchainStatus::start_monitor_blockchain_thread() { + total_emission_atomic = Emission {0, 0, 0}; string emmision_saved_file = get_output_file_path(); @@ -64,13 +65,15 @@ CurrentBlockchainStatus::start_monitor_blockchain_thread() { while (true) { + Emission current_emission = total_emission_atomic; + current_height = core_storage->get_current_blockchain_height(); update_current_emission_amount(); save_current_emission_amount(); - if (searched_blk_no < current_height - blockchain_chunk_size) + if (current_emission.blk_no < current_height - blockchain_chunk_size) { std::this_thread::sleep_for(std::chrono::seconds(1)); } @@ -90,9 +93,9 @@ void CurrentBlockchainStatus::update_current_emission_amount() { - cout << "updating emission rate: " << current_height << endl; + Emission current_emission = total_emission_atomic; - uint64_t blk_no = searched_blk_no; + uint64_t blk_no = current_emission.blk_no; uint64_t end_block = blk_no + blockchain_chunk_size; @@ -100,8 +103,8 @@ CurrentBlockchainStatus::update_current_emission_amount() end_block = end_block > current_blockchain_height ? current_blockchain_height : end_block; - uint64_t current_emission_amount {0}; - uint64_t current_fee_amount {0}; + uint64_t temp_emission_amount {0}; + uint64_t temp_fee_amount {0}; while (blk_no < end_block) { @@ -124,20 +127,19 @@ CurrentBlockchainStatus::update_current_emission_amount() tx_fee_amount += get_tx_fee(tx); } - current_emission_amount += coinbase_amount - tx_fee_amount; - current_fee_amount += tx_fee_amount; + temp_emission_amount += coinbase_amount - tx_fee_amount; + temp_fee_amount += tx_fee_amount; ++blk_no; } - searched_blk_no = blk_no; - total_emission_amount += current_emission_amount; - total_fee_amount += current_fee_amount; + current_emission.coinbase += temp_emission_amount; + current_emission.fee += temp_fee_amount; + current_emission.blk_no = blk_no; + + total_emission_atomic = current_emission; - cout << "blk: " << blk_no - << " total_emission_amount: " << xmr_amount_to_str(uint64_t(total_emission_amount)) - << " total_fee_amount: " << xmr_amount_to_str(uint64_t(total_fee_amount)) - << endl; + cout << "total emission: " << string(current_emission) << endl; } @@ -156,16 +158,9 @@ CurrentBlockchainStatus::save_current_emission_amount() return false; } - uint64_t check_sum = uint64_t(searched_blk_no) - + uint64_t(total_emission_amount) - + uint64_t(total_fee_amount); - - string out_line = to_string(searched_blk_no) - + "," + to_string(total_emission_amount) - + "," + to_string(total_fee_amount) - + "," + to_string(check_sum); + Emission current_emission = total_emission_atomic; - out << out_line << flush; + out << string(current_emission) << flush; return true; } @@ -195,14 +190,16 @@ CurrentBlockchainStatus::load_current_emission_amount() return false; } - uint64_t read_check_sum{0}; + Emission emission_loaded {0, 0, 0}; + + uint64_t read_check_sum {0}; try { - searched_blk_no = boost::lexical_cast(strs.at(0)); - total_emission_amount = boost::lexical_cast(strs.at(1)); - total_fee_amount = boost::lexical_cast(strs.at(2)); - read_check_sum = boost::lexical_cast(strs.at(3)); + emission_loaded.blk_no = boost::lexical_cast(strs.at(0)); + emission_loaded.coinbase = boost::lexical_cast(strs.at(1)); + emission_loaded.fee = boost::lexical_cast(strs.at(2)); + read_check_sum = boost::lexical_cast(strs.at(3)); } catch (boost::bad_lexical_cast &e) { @@ -210,19 +207,17 @@ CurrentBlockchainStatus::load_current_emission_amount() return false; } - uint64_t check_sum = uint64_t(searched_blk_no) - + uint64_t(total_emission_amount) - + uint64_t(total_fee_amount); - - if (read_check_sum != check_sum) + if (read_check_sum != emission_loaded.checksum()) { cerr << "read_check_sum != check_sum: " - << read_check_sum << " != " << check_sum + << read_check_sum << " != " << emission_loaded.checksum() << endl; return false; } + total_emission_atomic = emission_loaded; + return true; } @@ -236,16 +231,10 @@ CurrentBlockchainStatus::get_output_file_path() } -vector -CurrentBlockchainStatus::get_emission_amount() +CurrentBlockchainStatus::Emission +CurrentBlockchainStatus::get_emission() { - - uint64_t searched_block = searched_blk_no; - uint64_t emission_amount = total_emission_amount; - uint64_t fee_amount = total_fee_amount; - - return {searched_block, emission_amount, fee_amount}; - + return total_emission_atomic.load(); } bool @@ -266,11 +255,7 @@ uint64_t CurrentBlockchainStatus::blockchain_chunk_size {10000}; atomic CurrentBlockchainStatus::current_height {0}; -atomic CurrentBlockchainStatus::total_emission_amount {0} ; - -atomic CurrentBlockchainStatus::total_fee_amount {0} ; - -atomic CurrentBlockchainStatus::searched_blk_no {0}; +atomic CurrentBlockchainStatus::total_emission_atomic; std::thread CurrentBlockchainStatus::m_thread; diff --git a/src/CurrentBlockchainStatus.h b/src/CurrentBlockchainStatus.h index 983c0fc..57e2010 100644 --- a/src/CurrentBlockchainStatus.h +++ b/src/CurrentBlockchainStatus.h @@ -23,6 +23,26 @@ using namespace std; struct CurrentBlockchainStatus { + struct Emission + { + uint64_t coinbase; + uint64_t fee; + uint64_t blk_no; + + inline uint64_t + checksum() const + { + return coinbase + fee + blk_no; + } + + operator + std::string() const + { + return to_string(blk_no) + "," + to_string(coinbase) + + "," + to_string(fee) + "," + to_string(checksum()); + } + }; + static string blockchain_path; static bool testnet; @@ -35,11 +55,7 @@ struct CurrentBlockchainStatus static atomic current_height; - static atomic total_emission_amount; - - static atomic total_fee_amount; - - static atomic searched_blk_no; + static atomic total_emission_atomic; static std::thread m_thread; @@ -65,8 +81,8 @@ struct CurrentBlockchainStatus static bool load_current_emission_amount(); - static vector - get_emission_amount(); + static Emission + get_emission(); static string get_output_file_path(); diff --git a/src/page.h b/src/page.h index fb6a1ea..374d948 100644 --- a/src/page.h +++ b/src/page.h @@ -761,17 +761,17 @@ namespace xmreg if (CurrentBlockchainStatus::is_thread_running()) { - vector emission_values - = CurrentBlockchainStatus::get_emission_amount(); + CurrentBlockchainStatus::Emission current_values + = CurrentBlockchainStatus::get_emission(); - string emission_blk_no = std::to_string(emission_values.at(0) - 1); - string emission_amount = xmr_amount_to_str(emission_values.at(1), "{:0.3f}"); - string emission_fee_amount = xmr_amount_to_str(emission_values.at(2), "{:0.3f}"); + string emission_blk_no = std::to_string(current_values.blk_no); + string emission_coinbase = xmr_amount_to_str(current_values.coinbase, "{:0.3f}"); + string emission_fee = xmr_amount_to_str(current_values.fee, "{:0.3f}"); context["emission"] = mstch::map { {"blk_no" , emission_blk_no}, - {"amount" , emission_amount}, - {"fee_amount", emission_fee_amount} + {"amount" , emission_coinbase}, + {"fee_amount", emission_fee} }; } else From c2d78c692b82eb7fd301678428bc02a8e0b699a8 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Thu, 18 May 2017 08:59:26 +0800 Subject: [PATCH 06/35] boost path used instead of strings for paths --- main.cpp | 2 +- src/CmdLineOptions.cpp | 22 +++++++++++----------- src/CurrentBlockchainStatus.cpp | 20 +++++++++----------- src/CurrentBlockchainStatus.h | 6 ++++-- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/main.cpp b/main.cpp index a809719..e216f7a 100644 --- a/main.cpp +++ b/main.cpp @@ -180,7 +180,7 @@ int main(int ac, const char* av[]) { // found in emission_amount.txt file. xmreg::CurrentBlockchainStatus::blockchain_path - = blockchain_path.string(); + = blockchain_path; xmreg::CurrentBlockchainStatus::testnet = testnet; xmreg::CurrentBlockchainStatus::deamon_url diff --git a/src/CmdLineOptions.cpp b/src/CmdLineOptions.cpp index e93bdec..1ae6493 100644 --- a/src/CmdLineOptions.cpp +++ b/src/CmdLineOptions.cpp @@ -18,7 +18,7 @@ namespace xmreg p.add("txhash", -1); options_description desc( - "xmrblocks, start Onion Monero Blockchain Explorer"); + "xmrblocks, Onion Monero Blockchain Explorer"); desc.add_options() ("help,h", value()->default_value(false)->implicit_value(true), @@ -26,7 +26,7 @@ namespace xmreg ("testnet,t", value()->default_value(false)->implicit_value(true), "use testnet blockchain") ("enable-pusher", value()->default_value(false)->implicit_value(true), - "enable pushing signed tx") + "enable signed transaction pusher") ("enable-mixin-details", value()->default_value(false)->implicit_value(true), "enable mixin details for key images, e.g., timescale, mixin of mixins, in tx context") ("enable-key-image-checker", value()->default_value(false)->implicit_value(true), @@ -34,11 +34,11 @@ namespace xmreg ("enable-output-key-checker", value()->default_value(false)->implicit_value(true), "enable outputs key file checker") ("enable-mempool-cache", value()->default_value(true), - "enable caching txs in the mempool") + "enable caching of transactions from the mempool") ("enable-json-api", value()->default_value(true), "enable JSON REST api") ("enable-tx-cache", value()->default_value(false)->implicit_value(true), - "enable caching of tx details") + "enable caching of transaction details") ("show-cache-times", value()->default_value(false)->implicit_value(true), "show times of getting data from cache vs no cache") ("enable-block-cache", value()->default_value(false)->implicit_value(true), @@ -48,21 +48,21 @@ namespace xmreg ("enable-emission-monitor", value()->default_value(false)->implicit_value(true), "enable Monero total emission monitoring thread") ("port,p", value()->default_value("8081"), - "default port") + "default explorer port") ("testnet-url", value()->default_value(""), - "you can specifiy testnet url, if you run it on mainet. link will show on front page to testnet explorer") + "you can specify testnet url, if you run it on mainnet. link will show on front page to testnet explorer") ("mainnet-url", value()->default_value(""), - "you can specifiy 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()->default_value("10"), "number of last blocks to be shown on index page") ("bc-path,b", value(), - "path to lmdb blockchain") + "path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb") ("ssl-crt-file", value(), - "A path to crt file for ssl (https) functionality") + "path to crt file for ssl (https) functionality") ("ssl-key-file", value(), - "A path to key file for ssl (https) functionality") + "path to key file for ssl (https) functionality") ("deamon-url,d", value()->default_value("http:://127.0.0.1:18081"), - "monero address string"); + "Monero deamon url"); store(command_line_parser(acc, avv) diff --git a/src/CurrentBlockchainStatus.cpp b/src/CurrentBlockchainStatus.cpp index 2327e8e..90af54c 100644 --- a/src/CurrentBlockchainStatus.cpp +++ b/src/CurrentBlockchainStatus.cpp @@ -21,7 +21,7 @@ CurrentBlockchainStatus::init_monero_blockchain() mcore = unique_ptr(new xmreg::MicroCore{}); // initialize the core using the blockchain path - if (!mcore->init(blockchain_path)) + if (!mcore->init(blockchain_path.string())) { cerr << "Error accessing blockchain." << endl; return false; @@ -40,7 +40,7 @@ CurrentBlockchainStatus::start_monitor_blockchain_thread() { total_emission_atomic = Emission {0, 0, 0}; - string emmision_saved_file = get_output_file_path(); + string emmision_saved_file = get_output_file_path().string(); if (boost::filesystem::exists(emmision_saved_file)) { @@ -148,7 +148,7 @@ bool CurrentBlockchainStatus::save_current_emission_amount() { - string emmision_saved_file = get_output_file_path(); + string emmision_saved_file = get_output_file_path().string(); ofstream out(emmision_saved_file); @@ -169,7 +169,7 @@ CurrentBlockchainStatus::save_current_emission_amount() bool CurrentBlockchainStatus::load_current_emission_amount() { - string emmision_saved_file = get_output_file_path(); + string emmision_saved_file = get_output_file_path().string(); string last_saved_emmision = xmreg::read(emmision_saved_file); @@ -222,12 +222,10 @@ CurrentBlockchainStatus::load_current_emission_amount() } -string +bf::path CurrentBlockchainStatus::get_output_file_path() { - string emmision_saved_file = blockchain_path + output_file; - - return emmision_saved_file; + return blockchain_path / output_file; } @@ -243,13 +241,13 @@ CurrentBlockchainStatus::is_thread_running() return is_running; } -string CurrentBlockchainStatus::blockchain_path{"/home/mwo/.bitmonero/lmdb"}; +bf::path CurrentBlockchainStatus::blockchain_path {"/home/mwo/.bitmonero/lmdb"}; bool CurrentBlockchainStatus::testnet {false}; -string CurrentBlockchainStatus::output_file {"/emission_amount.txt"}; +string CurrentBlockchainStatus::output_file {"emission_amount.txt"}; -string CurrentBlockchainStatus::deamon_url{"http:://127.0.0.1:18081"}; +string CurrentBlockchainStatus::deamon_url {"http:://127.0.0.1:18081"}; uint64_t CurrentBlockchainStatus::blockchain_chunk_size {10000}; diff --git a/src/CurrentBlockchainStatus.h b/src/CurrentBlockchainStatus.h index 57e2010..5c8fa3a 100644 --- a/src/CurrentBlockchainStatus.h +++ b/src/CurrentBlockchainStatus.h @@ -20,6 +20,8 @@ namespace xmreg using namespace std; +namespace bf = boost::filesystem; + struct CurrentBlockchainStatus { @@ -43,7 +45,7 @@ struct CurrentBlockchainStatus } }; - static string blockchain_path; + static bf::path blockchain_path; static bool testnet; @@ -84,7 +86,7 @@ struct CurrentBlockchainStatus static Emission get_emission(); - static string + static bf::path get_output_file_path(); static bool From 14f615441dd3d04dfa5fcfb439ba9a40ee91d0e3 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 19 May 2017 07:13:57 +0800 Subject: [PATCH 07/35] Alt blocks number added to index2.html --- src/page.h | 3 ++- src/templates/index2.html | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/page.h b/src/page.h index 374d948..09ecfd6 100644 --- a/src/page.h +++ b/src/page.h @@ -750,7 +750,8 @@ namespace xmreg context["network_info"] = mstch::map { {"difficulty" , j_network_info["difficulty"].get()}, {"hash_rate" , difficulty}, - {"fee_per_kb" , print_money(j_network_info["fee_per_kb"])} + {"fee_per_kb" , print_money(j_network_info["fee_per_kb"])}, + {"alt_blocks_no" , j_network_info["alt_blocks_count"].get()} }; } } diff --git a/src/templates/index2.html b/src/templates/index2.html index b143591..31fabe2 100644 --- a/src/templates/index2.html +++ b/src/templates/index2.html @@ -39,6 +39,7 @@ Network difficulty: {{difficulty}} | Hash rate: {{hash_rate}} | Fee per kb: {{fee_per_kb}} + | Alt blocks: {{alt_blocks_no}} {{/network_info}} From 300e26fa9ed20d829a2e1dbd4892c2b8830cb7db Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 19 May 2017 07:26:26 +0800 Subject: [PATCH 08/35] Alt blocks number added to index2.html --- src/page.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/page.h b/src/page.h index 09ecfd6..5bc79cd 100644 --- a/src/page.h +++ b/src/page.h @@ -456,6 +456,16 @@ namespace xmreg {"show_cache_times" , show_cache_times} }; +// std::list atl_blks; +// +// if (core_storage->get_alternative_blocks(atl_blks)) +// { +// for (const block& alt_blk: atl_blks) +// { +// //cout << "alt_blk: " << get_block_height(alt_blk) << endl; +// } +// } + context.emplace("txs", mstch::array()); // will keep tx to show // get reference to txs mstch map to be field below From 3fcf87bdfc867bfa019b62d58933401a9c5a9b6a Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 19 May 2017 10:22:11 +0800 Subject: [PATCH 09/35] total_emission_gap added --- src/CurrentBlockchainStatus.cpp | 125 +++++++++++++++++++++++++++----- src/CurrentBlockchainStatus.h | 16 ++++ src/page.h | 2 +- 3 files changed, 125 insertions(+), 18 deletions(-) diff --git a/src/CurrentBlockchainStatus.cpp b/src/CurrentBlockchainStatus.cpp index 90af54c..05957b2 100644 --- a/src/CurrentBlockchainStatus.cpp +++ b/src/CurrentBlockchainStatus.cpp @@ -42,6 +42,7 @@ CurrentBlockchainStatus::start_monitor_blockchain_thread() string emmision_saved_file = get_output_file_path().string(); + // read stored emission data if possible if (boost::filesystem::exists(emmision_saved_file)) { if (!load_current_emission_amount()) @@ -101,17 +102,36 @@ CurrentBlockchainStatus::update_current_emission_amount() uint64_t current_blockchain_height = current_height; - end_block = end_block > current_blockchain_height ? current_blockchain_height : end_block; + // blockchain_chunk_gap is used so that we + // never read and store few top blocks + // the emission in the top few blocks will be calcalted + // later + end_block = end_block > current_blockchain_height + ? current_blockchain_height - blockchain_chunk_gap + : end_block; - uint64_t temp_emission_amount {0}; - uint64_t temp_fee_amount {0}; + Emission emission_calculated = calculate_emission_in_blocks(blk_no, end_block); - while (blk_no < end_block) - { + current_emission.coinbase += emission_calculated.coinbase; + current_emission.fee += emission_calculated.fee; + current_emission.blk_no = emission_calculated.blk_no; + + total_emission_atomic = current_emission; + + cout << "total emission: " << string(current_emission) << endl; +} +CurrentBlockchainStatus::Emission +CurrentBlockchainStatus::calculate_emission_in_blocks( + uint64_t start_blk, uint64_t end_blk) +{ + Emission emission_calculated {0, 0, 0}; + + while (start_blk < end_blk) + { block blk; - mcore->get_block_by_height(blk_no, blk); + mcore->get_block_by_height(start_blk, blk); uint64_t coinbase_amount = get_outs_money_amount(blk.miner_tx); @@ -127,23 +147,20 @@ CurrentBlockchainStatus::update_current_emission_amount() tx_fee_amount += get_tx_fee(tx); } - temp_emission_amount += coinbase_amount - tx_fee_amount; - temp_fee_amount += tx_fee_amount; + (void) missed_txs; - ++blk_no; - } + emission_calculated.coinbase += coinbase_amount - tx_fee_amount; + emission_calculated.fee += tx_fee_amount; - current_emission.coinbase += temp_emission_amount; - current_emission.fee += temp_fee_amount; - current_emission.blk_no = blk_no; + ++start_blk; + } - total_emission_atomic = current_emission; + emission_calculated.blk_no = start_blk; - cout << "total emission: " << string(current_emission) << endl; + return emission_calculated; } - bool CurrentBlockchainStatus::save_current_emission_amount() { @@ -232,7 +249,79 @@ CurrentBlockchainStatus::get_output_file_path() CurrentBlockchainStatus::Emission CurrentBlockchainStatus::get_emission() { - return total_emission_atomic.load(); + // we store gap emission from last few blocks + // we use it together with last_block_hash, so that + // we can reuse gap emission if hash is same between + // requests. no need to always keep recalucalting + // it, if top block hash is same as last time. + static Emission total_emission_gap {0, 0, 0}; + static crypto::hash last_block_hash {null_hash}; + + + // get current emission + Emission current_emission = total_emission_atomic; + + // this emission will be few blocks behind current blockchain + // height. By default 3 blocks. So we need to calcualate here + // the emission from the top missing blocks, to have complete + // emission data. + + Emission gap_emission_calculated {0, 0, 0}; + + crypto::hash top_block_id = core_storage->get_tail_id(); + + if (last_block_hash == top_block_id) + { + // if we already calclated gap for the same few blocks + // just reuse the emission calcualted for the gap. + + //cout << "reusing total_emission_gap" << endl; + + gap_emission_calculated = total_emission_gap; + } + else + { + // if top height has change for whatever reason, e.g, new block + // was added, blockchain reoraganization happened, then + // recaulate the gap emission + + //cout << "recalculate total_emission_gap" << endl; + + uint64_t current_blockchain_height = current_height; + + uint64_t start_blk = current_emission.blk_no; + + // this should be at current hight or above + // as we calculate missing blocks only for top blockchain + // height + uint64_t end_block = start_blk + blockchain_chunk_gap; + + if (end_block >= current_blockchain_height && start_blk < current_blockchain_height) + { + // make sure we are not over the blockchain height + end_block = end_block > current_blockchain_height + ? current_blockchain_height : end_block; + + // calculated emission for missing blocks + gap_emission_calculated = calculate_emission_in_blocks(start_blk, end_block); + } + + // store calcualted gap emission for future use + total_emission_gap = gap_emission_calculated; + + // update stored top block hash + last_block_hash = top_block_id; + } + + //cout << "gap_emission_calculated: " << std::string(gap_emission_calculated) << endl; + + current_emission.coinbase += gap_emission_calculated.coinbase; + current_emission.fee += gap_emission_calculated.fee; + current_emission.blk_no = gap_emission_calculated.blk_no > 0 + ? gap_emission_calculated.blk_no + : current_emission.blk_no; + + return current_emission; } bool @@ -251,6 +340,8 @@ string CurrentBlockchainStatus::deamon_url {"http:://127.0.0.1:18081"}; uint64_t CurrentBlockchainStatus::blockchain_chunk_size {10000}; +uint64_t CurrentBlockchainStatus::blockchain_chunk_gap {3}; + atomic CurrentBlockchainStatus::current_height {0}; atomic CurrentBlockchainStatus::total_emission_atomic; diff --git a/src/CurrentBlockchainStatus.h b/src/CurrentBlockchainStatus.h index 5c8fa3a..036eb0c 100644 --- a/src/CurrentBlockchainStatus.h +++ b/src/CurrentBlockchainStatus.h @@ -53,12 +53,25 @@ struct CurrentBlockchainStatus static string deamon_url; + // how many blocks to read before thread goes to sleep static uint64_t blockchain_chunk_size; + // gap from what we store total_emission_atomic and + // current blockchain height. We dont want to store + // what is on, e.g., top block, as this can get messy + // if the block gets orphaned or blockchain reorganization + // occurs. So the top 3 blocks (default number) will always + // be calculated in flight and added to what we have so far. + static uint64_t blockchain_chunk_gap; + + // current blockchain height and + // hash of top block static atomic current_height; + static atomic total_emission_atomic; + static std::thread m_thread; static atomic is_running; @@ -77,6 +90,9 @@ struct CurrentBlockchainStatus static void update_current_emission_amount(); + static Emission + calculate_emission_in_blocks(uint64_t start_blk, uint64_t end_blk); + static bool save_current_emission_amount(); diff --git a/src/page.h b/src/page.h index 5bc79cd..1b9543c 100644 --- a/src/page.h +++ b/src/page.h @@ -775,7 +775,7 @@ namespace xmreg CurrentBlockchainStatus::Emission current_values = CurrentBlockchainStatus::get_emission(); - string emission_blk_no = std::to_string(current_values.blk_no); + string emission_blk_no = std::to_string(current_values.blk_no - 1); string emission_coinbase = xmr_amount_to_str(current_values.coinbase, "{:0.3f}"); string emission_fee = xmr_amount_to_str(current_values.fee, "{:0.3f}"); From 24cd9d83f0ba94e2997dc5f9f71b8c5c1a3af022 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 19 May 2017 12:43:43 +0800 Subject: [PATCH 10/35] get_emission() simplified --- src/CurrentBlockchainStatus.cpp | 75 +++++++++------------------------ 1 file changed, 20 insertions(+), 55 deletions(-) diff --git a/src/CurrentBlockchainStatus.cpp b/src/CurrentBlockchainStatus.cpp index 05957b2..4b13b57 100644 --- a/src/CurrentBlockchainStatus.cpp +++ b/src/CurrentBlockchainStatus.cpp @@ -249,15 +249,6 @@ CurrentBlockchainStatus::get_output_file_path() CurrentBlockchainStatus::Emission CurrentBlockchainStatus::get_emission() { - // we store gap emission from last few blocks - // we use it together with last_block_hash, so that - // we can reuse gap emission if hash is same between - // requests. no need to always keep recalucalting - // it, if top block hash is same as last time. - static Emission total_emission_gap {0, 0, 0}; - static crypto::hash last_block_hash {null_hash}; - - // get current emission Emission current_emission = total_emission_atomic; @@ -266,61 +257,35 @@ CurrentBlockchainStatus::get_emission() // the emission from the top missing blocks, to have complete // emission data. - Emission gap_emission_calculated {0, 0, 0}; - - crypto::hash top_block_id = core_storage->get_tail_id(); + uint64_t current_blockchain_height = current_height; - if (last_block_hash == top_block_id) - { - // if we already calclated gap for the same few blocks - // just reuse the emission calcualted for the gap. + uint64_t start_blk = current_emission.blk_no; - //cout << "reusing total_emission_gap" << endl; + // this should be at current hight or above + // as we calculate missing blocks only for top blockchain + // height + uint64_t end_block = start_blk + blockchain_chunk_gap; - gap_emission_calculated = total_emission_gap; - } - else + if (end_block >= current_blockchain_height + && start_blk < current_blockchain_height) { - // if top height has change for whatever reason, e.g, new block - // was added, blockchain reoraganization happened, then - // recaulate the gap emission - - //cout << "recalculate total_emission_gap" << endl; - - uint64_t current_blockchain_height = current_height; + // make sure we are not over the blockchain height + end_block = end_block > current_blockchain_height + ? current_blockchain_height : end_block; - uint64_t start_blk = current_emission.blk_no; + // calculated emission for missing blocks + Emission gap_emission_calculated + = calculate_emission_in_blocks(start_blk, end_block); - // this should be at current hight or above - // as we calculate missing blocks only for top blockchain - // height - uint64_t end_block = start_blk + blockchain_chunk_gap; + //cout << "gap_emission_calculated: " << std::string(gap_emission_calculated) << endl; - if (end_block >= current_blockchain_height && start_blk < current_blockchain_height) - { - // make sure we are not over the blockchain height - end_block = end_block > current_blockchain_height - ? current_blockchain_height : end_block; - - // calculated emission for missing blocks - gap_emission_calculated = calculate_emission_in_blocks(start_blk, end_block); - } - - // store calcualted gap emission for future use - total_emission_gap = gap_emission_calculated; - - // update stored top block hash - last_block_hash = top_block_id; + current_emission.coinbase += gap_emission_calculated.coinbase; + current_emission.fee += gap_emission_calculated.fee; + current_emission.blk_no = gap_emission_calculated.blk_no > 0 + ? gap_emission_calculated.blk_no + : current_emission.blk_no; } - //cout << "gap_emission_calculated: " << std::string(gap_emission_calculated) << endl; - - current_emission.coinbase += gap_emission_calculated.coinbase; - current_emission.fee += gap_emission_calculated.fee; - current_emission.blk_no = gap_emission_calculated.blk_no > 0 - ? gap_emission_calculated.blk_no - : current_emission.blk_no; - return current_emission; } From 93472a820d6bd281cc60e7c24761996d775c17fa Mon Sep 17 00:00:00 2001 From: alvinjoelsantos Date: Thu, 18 May 2017 18:58:30 -0400 Subject: [PATCH 11/35] Changed mixin to ring size/ring member --- src/page.h | 4 ++-- src/templates/block.html | 2 +- src/templates/checkrawtx.html | 6 +++--- src/templates/index.html | 2 +- src/templates/index2.html | 4 ++-- src/templates/mempool.html | 2 +- src/templates/my_outputs.html | 6 +++--- src/templates/partials/tx_details.html | 10 +++++----- src/templates/partials/tx_table_header.html | 2 +- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/page.h b/src/page.h index 1b9543c..44db60b 100644 --- a/src/page.h +++ b/src/page.h @@ -151,7 +151,7 @@ namespace xmreg if (!input_key_imgs.empty()) { - mixin_str = std::to_string(mixin_no - 1); + mixin_str = std::to_string(mixin_no); fee_str = fmt::format("{:0.6f}", xmr_amount); fee_short_str = fmt::format("{:0.3f}", xmr_amount); } @@ -1012,7 +1012,7 @@ namespace xmreg {"no_inputs" , no_inputs}, {"no_outputs" , no_outputs}, {"no_nonrct_inputs", num_nonrct_inputs}, - {"mixin" , mixin_no}, + {"mixin" , mixin_no+1}, {"txsize" , txsize} }); diff --git a/src/templates/block.html b/src/templates/block.html index 117a4f9..c299f91 100644 --- a/src/templates/block.html +++ b/src/templates/block.html @@ -60,7 +60,7 @@ hash outputs fee - mixin + ring size in/out size [kB] version diff --git a/src/templates/checkrawtx.html b/src/templates/checkrawtx.html index 37772b6..85c8ee3 100644 --- a/src/templates/checkrawtx.html +++ b/src/templates/checkrawtx.html @@ -36,8 +36,8 @@

- Inputs' mixins time scale (from {{min_mix_time}} till {{max_mix_time}}; - resolution: {{timescales_scale}} days{{#have_raw_tx}}; R - real mixin {{/have_raw_tx}}) + Inputs' ring size time scale (from {{min_mix_time}} till {{max_mix_time}}; + resolution: {{timescales_scale}} days{{#have_raw_tx}}; R - real ring member {{/have_raw_tx}})

    @@ -111,4 +111,4 @@

- \ No newline at end of file + diff --git a/src/templates/index.html b/src/templates/index.html index 46b0272..41bcd93 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -32,7 +32,7 @@ txs fees outputs - mixins + ring size size [kB] {{#blocks}} diff --git a/src/templates/index2.html b/src/templates/index2.html index 31fabe2..a675b57 100644 --- a/src/templates/index2.html +++ b/src/templates/index2.html @@ -76,7 +76,7 @@ fees outputs in(nonrct)/out - mixin + ring size tx size [kB] {{#txs}} @@ -115,4 +115,4 @@ and {{construction_time_non_cached}} s from non cache ({{cache_misses}} misses) -{{/show_cache_times}} \ No newline at end of file +{{/show_cache_times}} diff --git a/src/templates/mempool.html b/src/templates/mempool.html index 1f00920..b7e4c18 100644 --- a/src/templates/mempool.html +++ b/src/templates/mempool.html @@ -11,7 +11,7 @@ fee outputs in(nonrct)/out - mixin + ring size tx size [kB] {{#mempooltxs}} diff --git a/src/templates/my_outputs.html b/src/templates/my_outputs.html index f744cbf..69040a1 100644 --- a/src/templates/my_outputs.html +++ b/src/templates/my_outputs.html @@ -91,7 +91,7 @@
- Mixin {{mixin_pub_key}} might use your outputs + Ring member {{mixin_pub_key}} might use your outputs
from tx of hash: {{mix_tx_hash}}
(tx public key: {{mix_tx_pub_key}}) @@ -133,7 +133,7 @@

- Sum XMR from matched and marked by * mixin's outputs: {{sum_mixin_xmr}} + Sum XMR from matched and marked by * ring member's outputs: {{sum_mixin_xmr}}
Possible spending is: {{possible_spending}} (tx fee included) @@ -150,4 +150,4 @@ -
\ No newline at end of file +
diff --git a/src/templates/partials/tx_details.html b/src/templates/partials/tx_details.html index 91deb2d..8260d3c 100644 --- a/src/templates/partials/tx_details.html +++ b/src/templates/partials/tx_details.html @@ -125,8 +125,8 @@ {{#has_inputs}} {{#enable_mixins_details}} -

Inputs' mixins time scale (from {{min_mix_time}} till {{max_mix_time}}; - resolution: {{timescales_scale}} days{{#have_raw_tx}}; R - real mixin {{/have_raw_tx}}) +

Inputs' ring size time scale (from {{min_mix_time}} till {{max_mix_time}}; + resolution: {{timescales_scale}} days{{#have_raw_tx}}; R - real ring member {{/have_raw_tx}})

    @@ -180,12 +180,12 @@ {{#enable_mixins_details}} - + {{#have_raw_tx}} {{/have_raw_tx}} - + @@ -214,7 +214,7 @@ {{^enable_mixins_details}}
    Mixin stealth addressring membersIs it real?blkmixinring size in/out timestamp age [y:d:h:m:s]
    - + {{#have_raw_tx}} {{/have_raw_tx}} diff --git a/src/templates/partials/tx_table_header.html b/src/templates/partials/tx_table_header.html index 123d214..3de6ef2 100644 --- a/src/templates/partials/tx_table_header.html +++ b/src/templates/partials/tx_table_header.html @@ -3,7 +3,7 @@ - + From 2c133482af95b158c24405af5dfe48dc01219ec2 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 19 May 2017 17:25:27 +0800 Subject: [PATCH 12/35] Info about Monero emission added to README --- README.md | 70 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index d73fadf..0966133 100644 --- a/README.md +++ b/README.md @@ -146,10 +146,10 @@ Go to your browser: http://127.0.0.1:8081 ``` ./xmrblocks -h -xmrblocks, start Onion Monero Blockchain Explorer: +xmrblocks, Onion Monero Blockchain Explorer: -h [ --help ] [=arg(=1)] (=0) produce help message -t [ --testnet ] [=arg(=1)] (=0) use testnet blockchain - --enable-pusher [=arg(=1)] (=0) enable pushing signed tx + --enable-pusher [=arg(=1)] (=0) enable signed transaction pusher --enable-mixin-details [=arg(=1)] (=0) enable mixin details for key images, e.g., timescale, mixin of mixins, in tx @@ -158,45 +158,79 @@ xmrblocks, start Onion Monero Blockchain Explorer: enable key images file checker --enable-output-key-checker [=arg(=1)] (=0) enable outputs key file checker - --enable-mempool-cache arg (=1) enable caching txs in the mempool + --enable-mempool-cache arg (=1) enable caching of transactions from the + mempool --enable-json-api arg (=1) enable JSON REST api - --enable-tx-cache [=arg(=1)] (=0) enable caching of tx details + --enable-tx-cache [=arg(=1)] (=0) enable caching of transaction details --show-cache-times [=arg(=1)] (=0) show times of getting data from cache vs no cache --enable-block-cache [=arg(=1)] (=0) enable caching of block details --enable-autorefresh-option [=arg(=1)] (=0) enable users to have the index page on autorefresh - -p [ --port ] arg (=8081) default port - --testnet-url arg you can specifiy testnet url, if you - run it on mainet. link will show on - front page to testnet explorer - --mainnet-url arg you can specifiy mainnet url, if you - run it on testnet. link will show on - front page to mainnet explorer + --enable-emission-monitor [=arg(=1)] (=0) + enable Monero total emission monitoring + thread + -p [ --port ] arg (=8081) default explorer port + --testnet-url arg you can specify testnet url, if you run + it on mainnet. link will show on front + page to testnet explorer + --mainnet-url arg you can specify mainnet url, if you run + it on testnet. link will show on front + page to mainnet explorer --no-blocks-on-index arg (=10) number of last blocks to be shown on index page - -b [ --bc-path ] arg path to lmdb blockchain - --ssl-crt-file arg A path to crt file for ssl (https) + -b [ --bc-path ] arg path to lmdb folder of the blockchain, + e.g., ~/.bitmonero/lmdb + --ssl-crt-file arg path to crt file for ssl (https) functionality - --ssl-key-file arg A path to key file for ssl (https) + --ssl-key-file arg path to key file for ssl (https) functionality -d [ --deamon-url ] arg (=http:://127.0.0.1:18081) - monero address string + Monero deamon url ``` Example usage, defined as bash aliases. ```bash # for mainnet explorer -alias xmrblocksmainnet='~/onion-monero-blockchain-explorer/build/xmrblocks --port 8081 --no-blocks-on-index 49 --testnet-url "http://139.162.32.245:8082" --enable-block-cache=1 --enable-tx-cache=1 --enable-mempool-cache=1 --show-cache-times=1 --enable-pusher' +alias xmrblocksmainnet='~/onion-monero-blockchain-explorer/build/xmrblocks --port 8081 --no-blocks-on-index 24 --testnet-url "http://139.162.32.245:8082" --enable-pusher --enable-emission-monitor' # for testnet explorer -alias xmrblockstestnet='~/onion-monero-blockchain-explorer/build/xmrblocks -t --port 8082 --no-blocks-on-index 24 --mainnet-url "http://139.162.32.245:8081" --enable-block-cache=1 --enable-tx-cache=1 --enable-mempool-cache=1 --show-cache-times=1 --enable-pusher' +alias xmrblockstestnet='~/onion-monero-blockchain-explorer/build/xmrblocks -t --port 8082 --no-blocks-on-index 24 --mainnet-url "http://139.162.32.245:8081" --enable-pusher --enable-emission-monitor' ``` -These are explorer commands used for http://139.162.32.245:8081/ and http://139.162.32.245:8082/, respectively. +These are aliases similar to those used for http://139.162.32.245:8081/ and http://139.162.32.245:8082/, respectively. +## Enable Monero emission + +Obtaining current Monero emission amount is not straight forward. Thus, by default it is +disabled. To enable it use `--enable-emission-monitor` flag, e.g., + + +```bash +xmrblocks --enable-emission-monitor +``` + +This flag will enable emission monitoring thread. When first started, the thread + will scan entire blockchain, and calculate the emission based on each block. +Since it is a separate thread, the explorer will work as usual during this time. +Every 10000 blocks, the thread will save current emission in a file, by default, + in `~/.bitmonero/lmdb/emission_amount.txt`. This file is used so that we don't + need to rescan entire blockchain whenever the explorer is restarted. When the + explorer restarts, the thread will first check if `~/.bitmonero/lmdb/emission_amount.txt` + is present, read its values, and continue from there if possible. Subsequently, only the initial + use of the tread is time consuming. Once the thread scans the entire blockchain, it updates + the emission with new blocks as they come. + + When the emission monitor is enabled, information about current emission of coinbase and fees is + displied on the front page, e.g., : + +``` +Monero emission (fees) is 14485540.430 (52545.373) as of 1313448 block +``` + + ## Enable SSL (https) By default, the explorer does not use ssl. But it has such a functionality. From 7b9ee5732d398149baa48226ed9f003a1234ffe9 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 19 May 2017 17:50:12 +0800 Subject: [PATCH 13/35] /api/emission added --- main.cpp | 8 ++++++++ src/page.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/main.cpp b/main.cpp index e216f7a..c58dac1 100644 --- a/main.cpp +++ b/main.cpp @@ -487,6 +487,14 @@ int main(int ac, const char* av[]) { return r; }); + CROW_ROUTE(app, "/api/emission") + ([&](const crow::request &req) { + + myxmr::jsonresponse r{xmrblocks.json_emission()}; + + return r; + }); + CROW_ROUTE(app, "/api/outputs").methods("GET"_method) ([&](const crow::request &req) { diff --git a/src/page.h b/src/page.h index 44db60b..2c8d72e 100644 --- a/src/page.h +++ b/src/page.h @@ -4802,6 +4802,50 @@ namespace xmreg } + /* + * Lets use this json api convention for success and error + * https://labs.omniti.com/labs/jsend + */ + json + json_emission() + { + json j_response { + {"status", "fail"}, + {"data", json {}} + }; + + json& j_data = j_response["data"]; + + json j_info; + + // get basic network info + if (!CurrentBlockchainStatus::is_thread_running()) + { + j_data["title"] = "Emission monitoring thread not enabled."; + return j_response; + } + else + { + CurrentBlockchainStatus::Emission current_values + = CurrentBlockchainStatus::get_emission(); + + string emission_blk_no = std::to_string(current_values.blk_no - 1); + string emission_coinbase = xmr_amount_to_str(current_values.coinbase, "{:0.3f}"); + string emission_fee = xmr_amount_to_str(current_values.fee, "{:0.3f}"); + + j_data = json { + {"blk_no" , current_values.blk_no - 1}, + {"coinbase", current_values.coinbase}, + {"fee" , current_values.fee}, + }; + } + + j_response["status"] = "success"; + + return j_response; + } + + private: json @@ -5657,3 +5701,4 @@ namespace xmreg #endif //CROWXMR_PAGE_H + From 21770a518ed5ed4b9d8b27ecf2ee672d516ff11b Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Sat, 20 May 2017 10:31:52 +0800 Subject: [PATCH 14/35] api/emission example added to readme --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 0966133..33cc9d8 100644 --- a/README.md +++ b/README.md @@ -623,6 +623,25 @@ curl -w "\n" -X GET "http://139.162.32.245:8081/api/networkinfo" } ``` +#### api/emission + +```bash +curl -w "\n" -X GET "http://139.162.32.245:8081/api/emission" +``` + +```json +{ + "data": { + "blk_no": 1313969, + "coinbase": 14489473877253413000, + "fee": 52601974988641130 + }, + "status": "success" +} +``` + +Emission only works when the emission monitoring thread is enabled. + #### api/rawblock/ From c45abcba1b0522e7dbfcbe8da6dfd760cde28ec9 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Wed, 24 May 2017 11:06:03 +0800 Subject: [PATCH 15/35] std::thread changed to boost::thread and the emission refactored --- README.md | 9 ++-- main.cpp | 38 +++++++-------- src/CurrentBlockchainStatus.cpp | 85 +++++++++++++++++---------------- src/CurrentBlockchainStatus.h | 12 ++--- src/MicroCore.cpp | 1 + 5 files changed, 72 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index 0966133..291fbd8 100644 --- a/README.md +++ b/README.md @@ -212,8 +212,8 @@ disabled. To enable it use `--enable-emission-monitor` flag, e.g., xmrblocks --enable-emission-monitor ``` -This flag will enable emission monitoring thread. When first started, the thread - will scan entire blockchain, and calculate the emission based on each block. +This flag will enable emission monitoring thread. When started, the thread + will initially scan the entire blockchain, and calculate the cumulative emission based on each block. Since it is a separate thread, the explorer will work as usual during this time. Every 10000 blocks, the thread will save current emission in a file, by default, in `~/.bitmonero/lmdb/emission_amount.txt`. This file is used so that we don't @@ -221,15 +221,16 @@ Every 10000 blocks, the thread will save current emission in a file, by default, explorer restarts, the thread will first check if `~/.bitmonero/lmdb/emission_amount.txt` is present, read its values, and continue from there if possible. Subsequently, only the initial use of the tread is time consuming. Once the thread scans the entire blockchain, it updates - the emission with new blocks as they come. + the emission amount using new blocks as they come. When the emission monitor is enabled, information about current emission of coinbase and fees is - displied on the front page, e.g., : + displayed on the front page, e.g., : ``` Monero emission (fees) is 14485540.430 (52545.373) as of 1313448 block ``` +To disable the monitor, simply restart the explorer without `--enable-emission-monitor` flag. ## Enable SSL (https) diff --git a/main.cpp b/main.cpp index c58dac1..b3bee81 100644 --- a/main.cpp +++ b/main.cpp @@ -17,7 +17,8 @@ namespace myxmr { struct jsonresponse: crow::response { - jsonresponse(const nlohmann::json& _body) : crow::response {_body.dump()} + jsonresponse(const nlohmann::json& _body) + : crow::response {_body.dump()} { add_header("Access-Control-Allow-Origin", "*"); add_header("Access-Control-Allow-Headers", "Content-Type"); @@ -26,21 +27,9 @@ struct jsonresponse: crow::response }; } -class ExitHandler +int +main(int ac, const char* av[]) { -public: - void exit() { exitHandler(0); } - static void exitHandler(int) { s_shouldExit = true; } - bool shouldExit() const { return s_shouldExit; } - -private: - static bool s_shouldExit; -}; - -bool ExitHandler::s_shouldExit = false; - -int main(int ac, const char* av[]) { - // get command line options xmreg::CmdLineOptions opts {ac, av}; @@ -185,12 +174,8 @@ int main(int ac, const char* av[]) { = testnet; xmreg::CurrentBlockchainStatus::deamon_url = deamon_url; - - if (!xmreg::CurrentBlockchainStatus::init_monero_blockchain()) - { - cerr << "Error accessing blockchain from CurrentBlockchainStatus." << endl; - return EXIT_FAILURE; - } + xmreg::CurrentBlockchainStatus::set_blockchain_variables( + &mcore, core_storage); // launch the status monitoring thread so that it keeps track of blockchain // info, e.g., current height. Information from this thread is used @@ -551,5 +536,16 @@ int main(int ac, const char* av[]) { } + if (enable_emission_monitor == true) + { + // finish Emission monitoring thread in a cotrolled manner. + xmreg::CurrentBlockchainStatus::m_thread.interrupt(); + xmreg::CurrentBlockchainStatus::m_thread.join(); + + cout << "Emission monitoring thread joined." << endl; + } + + cout << "The explorer is terminating." << endl; + return EXIT_SUCCESS; } diff --git a/src/CurrentBlockchainStatus.cpp b/src/CurrentBlockchainStatus.cpp index 4b13b57..8750700 100644 --- a/src/CurrentBlockchainStatus.cpp +++ b/src/CurrentBlockchainStatus.cpp @@ -11,27 +11,12 @@ using namespace std; -bool -CurrentBlockchainStatus::init_monero_blockchain() +void +CurrentBlockchainStatus::set_blockchain_variables(MicroCore* _mcore, + Blockchain* _core_storage) { - // set monero log output level - uint32_t log_level = 0; - mlog_configure(mlog_get_default_log_path(""), true); - - mcore = unique_ptr(new xmreg::MicroCore{}); - - // initialize the core using the blockchain path - if (!mcore->init(blockchain_path.string())) - { - cerr << "Error accessing blockchain." << endl; - return false; - } - - // get the high level Blockchain object to interact - // with the blockchain lmdb database - core_storage = &(mcore->get_core()); - - return true; + mcore = _mcore; + core_storage =_core_storage; } @@ -62,31 +47,50 @@ CurrentBlockchainStatus::start_monitor_blockchain_thread() if (!is_running) { - m_thread = std::thread{[]() + m_thread = boost::thread{[]() { - while (true) + try { - Emission current_emission = total_emission_atomic; + while (true) + { + Emission current_emission = total_emission_atomic; - current_height = core_storage->get_current_blockchain_height(); + current_height = core_storage->get_current_blockchain_height(); - update_current_emission_amount(); + // scan 10000 blocks for emissiom or if we are at the top of + // the blockchain, only few top blocks + update_current_emission_amount(); - save_current_emission_amount(); + cout << "current emission: " << string(current_emission) << endl; - if (current_emission.blk_no < current_height - blockchain_chunk_size) - { - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - else - { - std::this_thread::sleep_for(std::chrono::seconds(60)); - } + save_current_emission_amount(); + + if (current_emission.blk_no < current_height - blockchain_chunk_size) + { + // while we scan the blockchain from scrach, every 10000 + // blocks take 1 second break + boost::this_thread::sleep_for(boost::chrono::seconds(1)); + } + else + { + // when we reach top of the blockchain, update + // the emission amount every minute. + boost::this_thread::sleep_for(boost::chrono::seconds(60)); + } + + } // while (true) + } + catch (boost::thread_interrupted&) + { + cout << "Emission monitoring thread interrupted." << endl; + return; } - }}; + + }}; // m_thread = boost::thread{[]() is_running = true; - } + + } // if (!is_running) } @@ -117,8 +121,6 @@ CurrentBlockchainStatus::update_current_emission_amount() current_emission.blk_no = emission_calculated.blk_no; total_emission_atomic = current_emission; - - cout << "total emission: " << string(current_emission) << endl; } CurrentBlockchainStatus::Emission @@ -311,11 +313,10 @@ atomic CurrentBlockchainStatus::current_height {0}; atomic CurrentBlockchainStatus::total_emission_atomic; -std::thread CurrentBlockchainStatus::m_thread; +boost::thread CurrentBlockchainStatus::m_thread; atomic CurrentBlockchainStatus::is_running {false}; -cryptonote::Blockchain* CurrentBlockchainStatus::core_storage; -unique_ptr CurrentBlockchainStatus::mcore; - +Blockchain* CurrentBlockchainStatus::core_storage {nullptr}; +xmreg::MicroCore* CurrentBlockchainStatus::mcore {nullptr}; } diff --git a/src/CurrentBlockchainStatus.h b/src/CurrentBlockchainStatus.h index 036eb0c..d213894 100644 --- a/src/CurrentBlockchainStatus.h +++ b/src/CurrentBlockchainStatus.h @@ -72,20 +72,20 @@ struct CurrentBlockchainStatus static atomic total_emission_atomic; - static std::thread m_thread; + static boost::thread m_thread; static atomic is_running; // make object for accessing the blockchain here - static unique_ptr mcore; - - static cryptonote::Blockchain *core_storage; + static MicroCore* mcore; + static Blockchain* core_storage; static void start_monitor_blockchain_thread(); - static bool - init_monero_blockchain(); + static void + set_blockchain_variables(MicroCore* _mcore, + Blockchain* _core_storage); static void update_current_emission_amount(); diff --git a/src/MicroCore.cpp b/src/MicroCore.cpp index a75f24a..03feee4 100644 --- a/src/MicroCore.cpp +++ b/src/MicroCore.cpp @@ -327,6 +327,7 @@ MicroCore::get_blk_timestamp(uint64_t blk_height) */ MicroCore::~MicroCore() { + m_blockchain_storage.get_db().close(); delete &m_blockchain_storage.get_db(); } From 32a56f32f1b900a3e3d46949a56da1ce8a736308 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Wed, 24 May 2017 13:40:25 +0800 Subject: [PATCH 16/35] git_branch_name added to footer --- cmake/MyUtils.cmake | 10 ++++++++++ src/page.h | 3 ++- src/templates/footer.html | 2 +- src/version.h.in | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/cmake/MyUtils.cmake b/cmake/MyUtils.cmake index 616dd88..d69fa1f 100644 --- a/cmake/MyUtils.cmake +++ b/cmake/MyUtils.cmake @@ -42,6 +42,16 @@ macro(create_git_version) OUTPUT_STRIP_TRAILING_WHITESPACE ) + # Get current branch name + execute_process( + COMMAND git rev-parse --abbrev-ref HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_BRANCH_NAME + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + + configure_file( ${CMAKE_SOURCE_DIR}/src/version.h.in ${CMAKE_BINARY_DIR}/gen/version.h diff --git a/src/page.h b/src/page.h index 2c8d72e..3493d5d 100644 --- a/src/page.h +++ b/src/page.h @@ -5680,7 +5680,8 @@ namespace xmreg static const mstch::map footer_context { {"last_git_commit_hash", string {GIT_COMMIT_HASH}}, {"last_git_commit_date", string {GIT_COMMIT_DATETIME}}, - {"monero_version_full" , string {MONERO_VERSION_FULL}}, + {"git_branch_name" , string {GIT_BRANCH_NAME}}, + {"monero_version_full" , string {MONERO_VERSION_FULL}} }; string footer_html = mstch::render(xmreg::read(TMPL_FOOTER), footer_context); diff --git a/src/templates/footer.html b/src/templates/footer.html index d4ab012..e5db414 100644 --- a/src/templates/footer.html +++ b/src/templates/footer.html @@ -1,7 +1,7 @@
    source code - | explorer version: {{last_git_commit_date}}-{{last_git_commit_hash}} + | explorer version: {{git_branch_name}}-{{last_git_commit_date}}-{{last_git_commit_hash}} | monero version: {{monero_version_full}}
    diff --git a/src/version.h.in b/src/version.h.in index ef62e86..26b5927 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -8,6 +8,7 @@ #define GIT_BRANCH "@GIT_BRANCH@" #define GIT_COMMIT_HASH "@GIT_COMMIT_HASH@" #define GIT_COMMIT_DATETIME "@GIT_COMMIT_DATETIME@" +#define GIT_BRANCH_NAME "@GIT_BRANCH_NAME@" #endif //XMRBLOCKS_VERSION_H_IN_H From eb502331468529f523c125598ecba900adc95afa Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Thu, 25 May 2017 10:36:04 +0800 Subject: [PATCH 17/35] Alternative Monero block explorers added to README --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 3cb014b..4aade9c 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,11 @@ i2p users (main Monero network) - down for now: - [http://monerotools.i2p](http://monerotools.i2p) +Alternative Monero block explorers: + +- [http://moneroblocks.info](http://moneroblocks.info/) +- [https://monerobase.com](https://monerobase.com/) +- [http://chainradar.com](http://chainradar.com/xmr/blocks) ## Onion Monero Blockchain Explorer features From 4500e640c3732c8ec3a25cffbec841ff4e465803 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Thu, 25 May 2017 13:21:17 +0800 Subject: [PATCH 18/35] Mempool data processing moved to async thread --- main.cpp | 18 ++++++++++++++++ src/CmdLineOptions.cpp | 2 ++ src/page.h | 36 +++++++++++++++++++++++--------- src/templates/css/style.css | 2 +- src/templates/mempool_error.html | 10 +++++++++ 5 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 src/templates/mempool_error.html diff --git a/main.cpp b/main.cpp index b3bee81..1c8275e 100644 --- a/main.cpp +++ b/main.cpp @@ -49,6 +49,7 @@ 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 testnet_opt = opts.get_option("testnet"); auto enable_key_image_checker_opt = opts.get_option("enable-key-image-checker"); auto enable_output_key_checker_opt = opts.get_option("enable-output-key-checker"); @@ -63,6 +64,7 @@ main(int ac, const char* av[]) auto enable_emission_monitor_opt = opts.get_option("enable-emission-monitor"); + bool testnet {*testnet_opt}; bool enable_pusher {*enable_pusher_opt}; bool enable_key_image_checker {*enable_key_image_checker_opt}; @@ -152,6 +154,21 @@ main(int ac, const char* av[]) deamon_url = "http:://127.0.0.1:28081"; } + uint64_t network_info_timeout {3000}; + + try + { + network_info_timeout = boost::lexical_cast(*network_info_timeout_opt); + } + catch (boost::bad_lexical_cast &e) + { + cout << "Cant cast " << (*network_info_timeout_opt) << " into number." + << "Using default value of " << network_info_timeout << " milliseconds." + << endl; + + } + + if (enable_emission_monitor == true) { @@ -200,6 +217,7 @@ main(int ac, const char* av[]) enable_block_cache, show_cache_times, no_blocks_on_index, + network_info_timeout, *testnet_url, *mainnet_url); diff --git a/src/CmdLineOptions.cpp b/src/CmdLineOptions.cpp index 1ae6493..3b423cf 100644 --- a/src/CmdLineOptions.cpp +++ b/src/CmdLineOptions.cpp @@ -55,6 +55,8 @@ 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("3000"), + "maximum time, in milliseconds, to wait for network and mempool data availability") ("bc-path,b", value(), "path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb") ("ssl-crt-file", value(), diff --git a/src/page.h b/src/page.h index 3493d5d..1ae0387 100644 --- a/src/page.h +++ b/src/page.h @@ -35,6 +35,7 @@ #define TMPL_INDEX TMPL_DIR "/index.html" #define TMPL_INDEX2 TMPL_DIR "/index2.html" #define TMPL_MEMPOOL TMPL_DIR "/mempool.html" +#define TMPL_MEMPOOL_ERROR TMPL_DIR "/mempool_error.html" #define TMPL_HEADER TMPL_DIR "/header.html" #define TMPL_FOOTER TMPL_DIR "/footer.html" #define TMPL_BLOCK TMPL_DIR "/block.html" @@ -261,6 +262,7 @@ namespace xmreg uint64_t no_of_mempool_tx_of_frontpage; uint64_t no_blocks_on_index; + uint64_t network_info_timeout; string testnet_url; string mainnet_url; @@ -335,6 +337,7 @@ namespace xmreg bool _enable_block_cache, bool _show_cache_times, uint64_t _no_blocks_on_index, + uint64_t _network_info_timeout, string _testnet_url, string _mainnet_url) : mcore {_mcore}, @@ -352,6 +355,7 @@ 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}, testnet_url {_testnet_url}, mainnet_url {_mainnet_url}, mempool_tx_json_cache(1000), @@ -369,6 +373,7 @@ namespace xmreg template_file["footer"] = get_footer(); template_file["index2"] = get_full_page(xmreg::read(TMPL_INDEX2)); template_file["mempool"] = xmreg::read(TMPL_MEMPOOL); + template_file["mempool_error"] = xmreg::read(TMPL_MEMPOOL_ERROR); template_file["mempool_full"] = get_full_page(template_file["mempool"]); template_file["block"] = get_full_page(xmreg::read(TMPL_BLOCK)); template_file["tx"] = get_full_page(xmreg::read(TMPL_TX)); @@ -397,6 +402,8 @@ namespace xmreg 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 @@ -420,6 +427,9 @@ namespace xmreg j_info["fee_per_kb"] = fee_estimated; + // get memory pool rendered template + j_info["mempool_html"] = mempool(false, no_of_mempool_tx_of_frontpage); + return j_info; }); @@ -734,11 +744,13 @@ namespace xmreg 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. + // wait a bit (network_info_timeout millisecond max) if not, just in case, but we dont wait more. // if its not ready by now, forget about it. + string mempool_html {"Cant get mempool_pool"}; + std::future_status ftr_status = network_info_ftr.wait_for( - std::chrono::milliseconds(200)); + std::chrono::milliseconds(network_info_timeout)); if (ftr_status == std::future_status::ready) { @@ -758,16 +770,20 @@ namespace xmreg } context["network_info"] = mstch::map { - {"difficulty" , j_network_info["difficulty"].get()}, - {"hash_rate" , difficulty}, - {"fee_per_kb" , print_money(j_network_info["fee_per_kb"])}, - {"alt_blocks_no" , j_network_info["alt_blocks_count"].get()} + {"difficulty" , j_network_info["difficulty"].get()}, + {"hash_rate" , difficulty}, + {"fee_per_kb" , print_money(j_network_info["fee_per_kb"])}, + {"alt_blocks_no" , j_network_info["alt_blocks_count"].get()} }; + + mempool_html = j_network_info["mempool_html"]; } } else { - cerr << "network_info future not ready yet, skipping." << endl; + mempool_html = template_file["mempool_error"]; + + cerr << "network_info and mempool future not ready yet, skipping." << endl; } if (CurrentBlockchainStatus::is_thread_running()) @@ -792,7 +808,7 @@ namespace xmreg // get memory pool rendered template - string mempool_html = mempool(false, no_of_mempool_tx_of_frontpage); + //string mempool_html = mempool(false, no_of_mempool_tx_of_frontpage); // append mempool_html to the index context map context["mempool_info"] = mempool_html; @@ -804,8 +820,8 @@ namespace xmreg } /** - * Render mempool data - */ + * Render mempool data + */ string mempool(bool add_header_and_footer = false, uint64_t no_of_mempool_tx = 25) { diff --git a/src/templates/css/style.css b/src/templates/css/style.css index f11dee2..ac4336b 100644 --- a/src/templates/css/style.css +++ b/src/templates/css/style.css @@ -16,7 +16,7 @@ h1, h2, h3, h4, h5, h6 { padding: 10px;*/ } -tr, li, #pages { +tr, li, #pages, .info { font-family: "Lucida Console", Monaco, monospace; font-size : 12px; height: 22px; diff --git a/src/templates/mempool_error.html b/src/templates/mempool_error.html new file mode 100644 index 0000000..8397c66 --- /dev/null +++ b/src/templates/mempool_error.html @@ -0,0 +1,10 @@ +

    + Memory pool +

    +

    +
    + + Newtork info and mempool data preparation failed. + Its processing took longer than expected and it timed out. Sorry. + +
    From e9143c523cdb8909136d6d5fadf122a9848c7ea2 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Thu, 25 May 2017 13:43:33 +0800 Subject: [PATCH 19/35] Link to mempool page added to mempool_error.hml --- src/CmdLineOptions.cpp | 2 +- src/templates/mempool_error.html | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/CmdLineOptions.cpp b/src/CmdLineOptions.cpp index 3b423cf..6818084 100644 --- a/src/CmdLineOptions.cpp +++ b/src/CmdLineOptions.cpp @@ -55,7 +55,7 @@ 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("3000"), + ("network-info-timeout", value()->default_value("5000"), "maximum time, in milliseconds, to wait for network and mempool data availability") ("bc-path,b", value(), "path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb") diff --git a/src/templates/mempool_error.html b/src/templates/mempool_error.html index 8397c66..41e5e29 100644 --- a/src/templates/mempool_error.html +++ b/src/templates/mempool_error.html @@ -4,7 +4,10 @@

    - Newtork info and mempool data preparation failed. - Its processing took longer than expected and it timed out. Sorry. +

    Newtork info and mempool data preparation for the front page failed. + Its processing took longer than expected and it timed out. + To view mempool without time constrain, + go to dedicated mempool page: memory pool +

    From 91739483ad27ef8d8d572e4dc6992caf27904397 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Thu, 25 May 2017 14:00:16 +0800 Subject: [PATCH 20/35] mempool for front page is in its own async call now. --- src/CmdLineOptions.cpp | 4 ++-- src/page.h | 39 ++++++++++++++++++++++---------- src/templates/mempool_error.html | 2 +- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/CmdLineOptions.cpp b/src/CmdLineOptions.cpp index 6818084..83cac7c 100644 --- a/src/CmdLineOptions.cpp +++ b/src/CmdLineOptions.cpp @@ -55,8 +55,8 @@ 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("5000"), - "maximum time, in milliseconds, to wait for network and mempool data availability") + ("network-info-timeout", value()->default_value("3000"), + "maximum time, in milliseconds, to wait for mempool data availability") ("bc-path,b", value(), "path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb") ("ssl-crt-file", value(), diff --git a/src/page.h b/src/page.h index 1ae0387..633818e 100644 --- a/src/page.h +++ b/src/page.h @@ -427,12 +427,17 @@ namespace xmreg j_info["fee_per_kb"] = fee_estimated; - // get memory pool rendered template - j_info["mempool_html"] = mempool(false, no_of_mempool_tx_of_frontpage); - return j_info; }); + + // get mempool for the front page also using async future + std::future mempool_ftr = std::async(std::launch::async, [&] + { + // get memory pool rendered template + return mempool(false, no_of_mempool_tx_of_frontpage); + }); + //get current server timestamp server_timestamp = std::time(nullptr); @@ -744,13 +749,11 @@ namespace xmreg context["cache_misses"] = cache_misses; // now time to check if we have our networkinfo from network_info future - // wait a bit (network_info_timeout millisecond max) if not, just in case, but we dont wait more. + // 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. - string mempool_html {"Cant get mempool_pool"}; - std::future_status ftr_status = network_info_ftr.wait_for( - std::chrono::milliseconds(network_info_timeout)); + std::chrono::milliseconds(300)); if (ftr_status == std::future_status::ready) { @@ -775,15 +778,27 @@ namespace xmreg {"fee_per_kb" , print_money(j_network_info["fee_per_kb"])}, {"alt_blocks_no" , j_network_info["alt_blocks_count"].get()} }; - - mempool_html = j_network_info["mempool_html"]; } } else { - mempool_html = template_file["mempool_error"]; + cerr << "network_info future not ready yet, skipping." << endl; + } + + string mempool_html {"Cant get mempool_pool"}; - cerr << "network_info and mempool future not ready yet, skipping." << endl; + // get mempool data for the front page, if ready. If not, then just skip. + std::future_status mempool_ftr_status = mempool_ftr.wait_for( + std::chrono::milliseconds(network_info_timeout)); + + if (mempool_ftr_status == std::future_status::ready) + { + mempool_html = mempool_ftr.get(); + } + else + { + cerr << "mempool future not ready yet, skipping." << endl; + mempool_html = template_file["mempool_error"]; } if (CurrentBlockchainStatus::is_thread_running()) @@ -791,7 +806,7 @@ namespace xmreg CurrentBlockchainStatus::Emission current_values = CurrentBlockchainStatus::get_emission(); - string emission_blk_no = std::to_string(current_values.blk_no - 1); + string emission_blk_no = std::to_string(current_values.blk_no - 1); string emission_coinbase = xmr_amount_to_str(current_values.coinbase, "{:0.3f}"); string emission_fee = xmr_amount_to_str(current_values.fee, "{:0.3f}"); diff --git a/src/templates/mempool_error.html b/src/templates/mempool_error.html index 41e5e29..531a013 100644 --- a/src/templates/mempool_error.html +++ b/src/templates/mempool_error.html @@ -4,7 +4,7 @@

    -

    Newtork info and mempool data preparation for the front page failed. +

    Mempool data preparation for the front page failed. Its processing took longer than expected and it timed out. To view mempool without time constrain, go to dedicated mempool page: memory pool From 77463c2b8b6535f6dfcfd244ec65f7f3900fd6d6 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Thu, 25 May 2017 14:20:58 +0800 Subject: [PATCH 21/35] tx_pool_size_kbytes added to api/networkinfo --- src/page.h | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/page.h b/src/page.h index 633818e..56e10df 100644 --- a/src/page.h +++ b/src/page.h @@ -402,8 +402,6 @@ namespace xmreg 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 @@ -4825,6 +4823,26 @@ namespace xmreg j_info["fee_per_kb"] = fee_estimated; + // get mempool size in kB. + std::vector mempool_txs; + + if (!rpc.get_mempool(mempool_txs)) + { + j_response["status"] = "error"; + j_response["message"] = "Cant get mempool transactions"; + return j_response; + } + + uint64_t tx_pool_size_kbytes {0}; + + for (const tx_info& tx_i: mempool_txs) + { + tx_pool_size_kbytes += tx_i.blob_size; + } + + j_info["tx_pool_size"] = mempool_txs.size(); + j_info["tx_pool_size_kbytes"] = tx_pool_size_kbytes; + j_data = j_info; j_response["status"] = "success"; From 7bdd8720c89f30a80ecd0e53d0c2feb5d16da290 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 26 May 2017 07:55:08 +0800 Subject: [PATCH 22/35] tx_pool_size_kbytes removed for now as it takes long time. --- src/page.h | 43 ++++++++++++++++---------------- src/templates/mempool_error.html | 5 +++- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/page.h b/src/page.h index 56e10df..d642632 100644 --- a/src/page.h +++ b/src/page.h @@ -774,7 +774,8 @@ namespace xmreg {"difficulty" , j_network_info["difficulty"].get()}, {"hash_rate" , difficulty}, {"fee_per_kb" , print_money(j_network_info["fee_per_kb"])}, - {"alt_blocks_no" , j_network_info["alt_blocks_count"].get()} + {"alt_blocks_no" , j_network_info["alt_blocks_count"].get()}, + {"tx_pool_size" , j_network_info["tx_pool_size"].get()}, }; } } @@ -796,7 +797,7 @@ namespace xmreg else { cerr << "mempool future not ready yet, skipping." << endl; - mempool_html = template_file["mempool_error"]; + mempool_html = mstch::render(template_file["mempool_error"], context); } if (CurrentBlockchainStatus::is_thread_running()) @@ -4823,25 +4824,25 @@ namespace xmreg j_info["fee_per_kb"] = fee_estimated; - // get mempool size in kB. - std::vector mempool_txs; - - if (!rpc.get_mempool(mempool_txs)) - { - j_response["status"] = "error"; - j_response["message"] = "Cant get mempool transactions"; - return j_response; - } - - uint64_t tx_pool_size_kbytes {0}; - - for (const tx_info& tx_i: mempool_txs) - { - tx_pool_size_kbytes += tx_i.blob_size; - } - - j_info["tx_pool_size"] = mempool_txs.size(); - j_info["tx_pool_size_kbytes"] = tx_pool_size_kbytes; +// // get mempool size in kB. +// std::vector mempool_txs; +// +// if (!rpc.get_mempool(mempool_txs)) +// { +// j_response["status"] = "error"; +// j_response["message"] = "Cant get mempool transactions"; +// return j_response; +// } +// +// uint64_t tx_pool_size_kbytes {0}; +// +// for (const tx_info& tx_i: mempool_txs) +// { +// tx_pool_size_kbytes += tx_i.blob_size; +// } +// +// j_info["tx_pool_size"] = mempool_txs.size(); +// j_info["tx_pool_size_kbytes"] = tx_pool_size_kbytes; j_data = j_info; diff --git a/src/templates/mempool_error.html b/src/templates/mempool_error.html index 531a013..0d9946b 100644 --- a/src/templates/mempool_error.html +++ b/src/templates/mempool_error.html @@ -5,9 +5,12 @@

    Mempool data preparation for the front page failed. - Its processing took longer than expected and it timed out. + Its processing {{#network_info}}({{tx_pool_size}} txs){{/network_info}} + took longer than expected and it timed out. To view mempool without time constrain, go to dedicated mempool page: memory pool

    + +
    From 7df8bccd729258a1fc46accaeebe7dad6298d488 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 26 May 2017 09:25:02 +0800 Subject: [PATCH 23/35] readme updated --- README.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 4aade9c..e979768 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Clearnet versions: - [https://xmrchain.net/](https://xmrchain.net/) - https enabled, most popular and very stable. - [https://monerohash.com/explorer/](https://monerohash.com/explorer/) - nice looking one, https enabled. - [http://explore.MoneroWorld.com](http://explore.moneroworld.com) - same as the second one. - - [https://explorer.xmr.my/](https://explorer.xmr.my/) - https enabled. + - [https://explorer.xmr.my/](https://explorer.xmr.my/) - nice looking one, https enabled. - [https://explorer.monero-otc.com/](https://explorer.monero-otc.com/) - https enabled. - [http://monerochain.com/](http://monerochain.com/) - JSON API based, multiple nodes. @@ -47,7 +47,7 @@ i2p users (main Monero network) - down for now: - [http://monerotools.i2p](http://monerotools.i2p) -Alternative Monero block explorers: +Alternative block explorers: - [http://moneroblocks.info](http://moneroblocks.info/) - [https://monerobase.com](https://monerobase.com/) @@ -71,7 +71,8 @@ The key features of the Onion Monero Blockchain Explorer are: - the only explorer showing number of amount output indices, - the only explorer supporting Monero testnet network, - the only explorer providing tx checker and pusher for online pushing of transactions, - - the only explorer able to estimate possible spendings based on address and viewkey. + - the only explorer able to estimate possible spendings based on address and viewkey, + - the only explorer that can provide total amount of all miner fees. ## Compilation on Ubuntu 16.04 @@ -221,12 +222,18 @@ This flag will enable emission monitoring thread. When started, the thread will initially scan the entire blockchain, and calculate the cumulative emission based on each block. Since it is a separate thread, the explorer will work as usual during this time. Every 10000 blocks, the thread will save current emission in a file, by default, - in `~/.bitmonero/lmdb/emission_amount.txt`. This file is used so that we don't + in `~/.bitmonero/lmdb/emission_amount.txt`. For testnet network, + it is `~/.bitmonero/testnet/lmdb/emission_amount.txt`. This file is used so that we don't need to rescan entire blockchain whenever the explorer is restarted. When the explorer restarts, the thread will first check if `~/.bitmonero/lmdb/emission_amount.txt` is present, read its values, and continue from there if possible. Subsequently, only the initial use of the tread is time consuming. Once the thread scans the entire blockchain, it updates - the emission amount using new blocks as they come. + the emission amount using new blocks as they come. Since the explorer writes this file, there can + be only one instance of it running for mainnet and testnet. Thus, for example, you cant have + two explorers for mainnet + running at the same time, as they will be trying to write and read the same file at the same time, + leading to unexpected results. Off course having one instance for mainnet and one instance for testnet + is fine, as they write to different files. When the emission monitor is enabled, information about current emission of coinbase and fees is displayed on the front page, e.g., : From 86ff44bb418a0ff1f11009bcca41e44c29769e7d Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 26 May 2017 09:48:23 +0800 Subject: [PATCH 24/35] print_coinbase_tx_sum info added to readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index e979768..b83806f 100644 --- a/README.md +++ b/README.md @@ -241,6 +241,9 @@ Every 10000 blocks, the thread will save current emission in a file, by default, ``` Monero emission (fees) is 14485540.430 (52545.373) as of 1313448 block ``` + +The values given, can be checked using Monero daemon's `print_coinbase_tx_sum` command. +For example, for the above example: `print_coinbase_tx_sum 0 1313449`. To disable the monitor, simply restart the explorer without `--enable-emission-monitor` flag. From 14542502a7102d05bbd6d9f6f96d9404d81a8e05 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 26 May 2017 09:51:41 +0800 Subject: [PATCH 25/35] remove m_blockchain_storage.get_db().close() from MicroCore to be like before. It was added for tests only. --- src/MicroCore.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MicroCore.cpp b/src/MicroCore.cpp index 03feee4..8205419 100644 --- a/src/MicroCore.cpp +++ b/src/MicroCore.cpp @@ -327,7 +327,7 @@ MicroCore::get_blk_timestamp(uint64_t blk_height) */ MicroCore::~MicroCore() { - m_blockchain_storage.get_db().close(); + //m_blockchain_storage.get_db().close(); delete &m_blockchain_storage.get_db(); } From 7d47ae69b8359015742a504f2cc1fb8aa25a2971 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Fri, 26 May 2017 09:53:24 +0800 Subject: [PATCH 26/35] network_info timeout set to 1s --- src/page.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/page.h b/src/page.h index d642632..b5f87ad 100644 --- a/src/page.h +++ b/src/page.h @@ -751,7 +751,7 @@ namespace xmreg // if its not ready by now, forget about it. std::future_status ftr_status = network_info_ftr.wait_for( - std::chrono::milliseconds(300)); + std::chrono::milliseconds(1000)); if (ftr_status == std::future_status::ready) { From 36b9bd2a5646426b2de3796754bdc631a25e4101 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Sat, 27 May 2017 07:03:48 +0800 Subject: [PATCH 27/35] network info timeout set to 2s --- src/page.h | 2 +- src/templates/index2.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/page.h b/src/page.h index b5f87ad..2ee79f8 100644 --- a/src/page.h +++ b/src/page.h @@ -751,7 +751,7 @@ namespace xmreg // if its not ready by now, forget about it. std::future_status ftr_status = network_info_ftr.wait_for( - std::chrono::milliseconds(1000)); + std::chrono::milliseconds(2000)); if (ftr_status == std::future_status::ready) { diff --git a/src/templates/index2.html b/src/templates/index2.html index a675b57..7b25aba 100644 --- a/src/templates/index2.html +++ b/src/templates/index2.html @@ -39,7 +39,7 @@ Network difficulty: {{difficulty}} | Hash rate: {{hash_rate}} | Fee per kb: {{fee_per_kb}} - | Alt blocks: {{alt_blocks_no}} + | Alternative blocks no: {{alt_blocks_no}} {{/network_info}} From 74d5b9040599d2a9a2016acc6353e705545da300 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Sun, 28 May 2017 08:55:58 +0800 Subject: [PATCH 28/35] show previous network_info if current times out --- src/page.h | 86 +++++++++++++++++++++++++++++++-------- src/templates/index2.html | 3 ++ 2 files changed, 71 insertions(+), 18 deletions(-) diff --git a/src/page.h b/src/page.h index 2ee79f8..54e28ea 100644 --- a/src/page.h +++ b/src/page.h @@ -313,6 +313,21 @@ namespace xmreg // parse their json for each request fifo_cache_t mempool_tx_json_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. @@ -365,6 +380,9 @@ 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 @@ -751,7 +769,11 @@ namespace xmreg // if its not ready by now, forget about it. std::future_status ftr_status = network_info_ftr.wait_for( - std::chrono::milliseconds(2000)); + std::chrono::milliseconds(200)); + + network_info current_network_info {0, 0, 0, 0, 0, 0}; + + bool is_network_info_current {false}; if (ftr_status == std::future_status::ready) { @@ -759,31 +781,59 @@ namespace xmreg if (!j_network_info.empty()) { - string difficulty; + 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; - 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); - } + previous_network_info = current_network_info; - context["network_info"] = mstch::map { - {"difficulty" , j_network_info["difficulty"].get()}, - {"hash_rate" , difficulty}, - {"fee_per_kb" , print_money(j_network_info["fee_per_kb"])}, - {"alt_blocks_no" , j_network_info["alt_blocks_count"].get()}, - {"tx_pool_size" , j_network_info["tx_pool_size"].get()}, - }; + is_network_info_current = true; } } else { - cerr << "network_info future not ready yet, skipping." << endl; + 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 + + string hash_rate; + + if (testnet) + { + hash_rate = std::to_string(current_network_info.hash_rate) + " H/s"; + } + else + { + hash_rate = fmt::format("{:0.3f} MH/s", current_network_info.hash_rate/1.0e6); } + pair network_info_age = get_age(local_copy_server_timestamp, + current_network_info.info_timestamp); + + // 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; + } + + 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}, + {"tx_pool_size" , current_network_info.tx_pool_size}, + {"is_current_info" , is_network_info_current}, + {"age" , network_info_age.first}, + {"age_format" , network_info_age.second}, + }; + string mempool_html {"Cant get mempool_pool"}; // get mempool data for the front page, if ready. If not, then just skip. diff --git a/src/templates/index2.html b/src/templates/index2.html index 7b25aba..af8aaed 100644 --- a/src/templates/index2.html +++ b/src/templates/index2.html @@ -40,6 +40,9 @@ | Hash rate: {{hash_rate}} | Fee per kb: {{fee_per_kb}} | Alternative blocks no: {{alt_blocks_no}} + {{^is_current_info}} + | Data from {{age}} {{age_format}} ago + {{/is_current_info}} {{/network_info}} From c9ee47ec3c1cb200def7f5cd0e247cef35aba235 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Sun, 28 May 2017 09:10:42 +0800 Subject: [PATCH 29/35] mempool and network info timeout parameters added --- README.md | 4 ++++ main.cpp | 12 ++++++++---- src/CmdLineOptions.cpp | 6 ++++-- src/page.h | 7 +++++-- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b83806f..bbc5a73 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,10 @@ xmrblocks, Onion Monero Blockchain Explorer: page to mainnet explorer --no-blocks-on-index arg (=10) number of last blocks to be shown on index page + --network-info-timeout arg (=1000) maximum time, in milliseconds, to wait + for network info availability + --mempool-info-timeout arg (=1000) maximum time, in milliseconds, to wait + for mempool data for the front page -b [ --bc-path ] arg path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb --ssl-crt-file arg path to crt file for ssl (https) diff --git a/main.cpp b/main.cpp index 1c8275e..aa48895 100644 --- a/main.cpp +++ b/main.cpp @@ -50,6 +50,7 @@ main(int ac, const char* av[]) 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 testnet_opt = opts.get_option("testnet"); auto enable_key_image_checker_opt = opts.get_option("enable-key-image-checker"); auto enable_output_key_checker_opt = opts.get_option("enable-output-key-checker"); @@ -154,16 +155,18 @@ main(int ac, const char* av[]) deamon_url = "http:://127.0.0.1:28081"; } - uint64_t network_info_timeout {3000}; - + uint64_t network_info_timeout {1000}; + uint64_t mempool_info_timeout {3000}; 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) << " into number." - << "Using default value of " << network_info_timeout << " milliseconds." + cout << "Cant cast " << (*network_info_timeout_opt) + << " or/and " << (*mempool_info_timeout_opt) <<" into numbers. Using default values." << endl; } @@ -218,6 +221,7 @@ main(int ac, const char* av[]) 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 83cac7c..082e95a 100644 --- a/src/CmdLineOptions.cpp +++ b/src/CmdLineOptions.cpp @@ -55,8 +55,10 @@ 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("3000"), - "maximum time, in milliseconds, to wait for mempool data availability") + ("network-info-timeout", value()->default_value("1000"), + "maximum time, in milliseconds, to wait for network info availability") + ("mempool-info-timeout", value()->default_value("1000"), + "maximum time, in milliseconds, to wait for mempool data for the front page") ("bc-path,b", value(), "path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb") ("ssl-crt-file", value(), diff --git a/src/page.h b/src/page.h index 54e28ea..3b45186 100644 --- a/src/page.h +++ b/src/page.h @@ -263,6 +263,7 @@ 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; string mainnet_url; @@ -353,6 +354,7 @@ namespace xmreg 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) : mcore {_mcore}, @@ -371,6 +373,7 @@ namespace xmreg 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}, mempool_tx_json_cache(1000), @@ -769,7 +772,7 @@ namespace xmreg // if its not ready by now, forget about it. std::future_status ftr_status = network_info_ftr.wait_for( - std::chrono::milliseconds(200)); + std::chrono::milliseconds(network_info_timeout)); network_info current_network_info {0, 0, 0, 0, 0, 0}; @@ -838,7 +841,7 @@ namespace xmreg // get mempool data for the front page, if ready. If not, then just skip. std::future_status mempool_ftr_status = mempool_ftr.wait_for( - std::chrono::milliseconds(network_info_timeout)); + std::chrono::milliseconds(mempool_info_timeout)); if (mempool_ftr_status == std::future_status::ready) { From 4a2c0a5d3e098291ddd0e87b8dfecfb5f55e0174 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Sun, 28 May 2017 09:13:45 +0800 Subject: [PATCH 30/35] mempool_info_timeout set to 5s as default --- README.md | 2 +- main.cpp | 2 +- src/CmdLineOptions.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bbc5a73..9f625e8 100644 --- a/README.md +++ b/README.md @@ -188,7 +188,7 @@ xmrblocks, Onion Monero Blockchain Explorer: index page --network-info-timeout arg (=1000) maximum time, in milliseconds, to wait for network info availability - --mempool-info-timeout arg (=1000) maximum time, in milliseconds, to wait + --mempool-info-timeout arg (=3000) maximum time, in milliseconds, to wait for mempool data for the front page -b [ --bc-path ] arg path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb diff --git a/main.cpp b/main.cpp index aa48895..6119525 100644 --- a/main.cpp +++ b/main.cpp @@ -156,7 +156,7 @@ main(int ac, const char* av[]) } uint64_t network_info_timeout {1000}; - uint64_t mempool_info_timeout {3000}; + uint64_t mempool_info_timeout {5000}; try { network_info_timeout = boost::lexical_cast(*network_info_timeout_opt); diff --git a/src/CmdLineOptions.cpp b/src/CmdLineOptions.cpp index 082e95a..db82f64 100644 --- a/src/CmdLineOptions.cpp +++ b/src/CmdLineOptions.cpp @@ -57,7 +57,7 @@ namespace xmreg "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("1000"), + ("mempool-info-timeout", value()->default_value("5000"), "maximum time, in milliseconds, to wait for mempool data for the front page") ("bc-path,b", value(), "path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb") From f5d9f993fd45580658415376ce9de35b78ccb8d6 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Sun, 28 May 2017 09:14:11 +0800 Subject: [PATCH 31/35] mempool_info_timeout set to 5s as default --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f625e8..c73f71d 100644 --- a/README.md +++ b/README.md @@ -188,7 +188,7 @@ xmrblocks, Onion Monero Blockchain Explorer: index page --network-info-timeout arg (=1000) maximum time, in milliseconds, to wait for network info availability - --mempool-info-timeout arg (=3000) maximum time, in milliseconds, to wait + --mempool-info-timeout arg (=5000) maximum time, in milliseconds, to wait for mempool data for the front page -b [ --bc-path ] arg path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb From 6e169cb848322bf9209f7a4d8e440cda64638762 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Thu, 1 Jun 2017 07:22:29 +0800 Subject: [PATCH 32/35] show no of txpool if not zero only --- src/templates/mempool_error.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/templates/mempool_error.html b/src/templates/mempool_error.html index 0d9946b..e06c9c3 100644 --- a/src/templates/mempool_error.html +++ b/src/templates/mempool_error.html @@ -5,7 +5,8 @@

    Mempool data preparation for the front page failed. - Its processing {{#network_info}}({{tx_pool_size}} txs){{/network_info}} + Its processing + {{#network_info}}{{#tx_pool_size}}({{tx_pool_size}} txs){{/tx_pool_size}}{{/network_info}} took longer than expected and it timed out. To view mempool without time constrain, go to dedicated mempool page: memory pool From 8fb6dfef06ca25586f5051ee9edee2bc6bea94fd Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Thu, 1 Jun 2017 07:49:23 +0800 Subject: [PATCH 33/35] show no of txpool if not zero only --- src/page.h | 17 +++++++++-------- src/templates/mempool_error.html | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/page.h b/src/page.h index 3b45186..0ff364d 100644 --- a/src/page.h +++ b/src/page.h @@ -827,14 +827,15 @@ namespace xmreg } 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}, - {"tx_pool_size" , current_network_info.tx_pool_size}, - {"is_current_info" , is_network_info_current}, - {"age" , network_info_age.first}, - {"age_format" , network_info_age.second}, + {"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}, + {"tx_pool_size" , current_network_info.tx_pool_size}, + {"is_current_info" , is_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}, }; string mempool_html {"Cant get mempool_pool"}; diff --git a/src/templates/mempool_error.html b/src/templates/mempool_error.html index e06c9c3..a003cae 100644 --- a/src/templates/mempool_error.html +++ b/src/templates/mempool_error.html @@ -6,9 +6,9 @@

    Mempool data preparation for the front page failed. Its processing - {{#network_info}}{{#tx_pool_size}}({{tx_pool_size}} txs){{/tx_pool_size}}{{/network_info}} + {{#network_info}}{{^is_pool_size_zero}}({{tx_pool_size}} txs){{/is_pool_size_zero}}{{/network_info}} took longer than expected and it timed out. - To view mempool without time constrain, + To view the mempool without time constrain, go to dedicated mempool page: memory pool

    From 8592f0fcad8b6a5e10431dc87cbe24d5f4df1437 Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Thu, 1 Jun 2017 11:19:09 +0800 Subject: [PATCH 34/35] easylogging removed as dependency --- CMakeLists.txt | 1 - README.md | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index de22f5c..c693c9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,7 +107,6 @@ set(LIBRARIES common mnemonics epee - easylogging ${Boost_LIBRARIES} pthread unbound diff --git a/README.md b/README.md index c73f71d..bdf9f29 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ git clone https://github.com/monero-project/monero cd monero/ # checkout last monero version -git checkout -b v0.10.3.1 +git checkout -b last_release v0.10.3.1 make ``` From 65c222df9a3b31d515acf749fc91cf86d58c13cf Mon Sep 17 00:00:00 2001 From: moneroexamples Date: Sun, 4 Jun 2017 05:32:24 +0800 Subject: [PATCH 35/35] fluffynet subnet explorer added to readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index bdf9f29..19c7ba7 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ Clearnet versions: - [https://explorer.xmr.my/](https://explorer.xmr.my/) - nice looking one, https enabled. - [https://explorer.monero-otc.com/](https://explorer.monero-otc.com/) - https enabled. - [http://monerochain.com/](http://monerochain.com/) - JSON API based, multiple nodes. + - [http://66.85.74.134:8081/](http://66.85.74.134:8081/) - fluffynet subnet explorer. Clearnet testnet Monero version: @@ -107,6 +108,7 @@ as follows: ```bash # go to home folder if still in ~/monero cd ~ + # download the source code git clone https://github.com/moneroexamples/onion-monero-blockchain-explorer.git
    Mixin stealth addressring membersIs it real?tx hash outputs feemixinring size in/out size [kB]