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(); }