#pragma once #include "thdq.hpp" #include "telemetry.hpp" #include "xmrstak/backend/iBackend.hpp" #include "xmrstak/misc/environment.hpp" #include "xmrstak/net/msgstruct.hpp" #include "xmrstak/donate-level.hpp" #include #include #include #include #include #include class jpsock; namespace xmrstak { namespace cpu { class minethd; } // namespace cpu } // namespace xmrstak class executor { public: static executor* inst() { auto& env = xmrstak::environment::inst(); if(env.pExecutor == nullptr) env.pExecutor = new executor; return env.pExecutor; }; void ex_start(bool daemon) { daemon ? ex_main() : std::thread(&executor::ex_main, this).detach(); } void get_http_report(ex_event_name ev_id, std::string& data); inline void push_event(ex_event&& ev) { oEventQ.push(std::move(ev)); } void push_timed_event(ex_event&& ev, size_t sec); private: struct timed_event { ex_event event; size_t ticks_left; timed_event(ex_event&& ev, size_t ticks) : event(std::move(ev)), ticks_left(ticks) {} }; inline void set_timestamp() { dev_timestamp = get_timestamp(); }; // In milliseconds, has to divide a second (1000ms) into an integer number constexpr static size_t iTickTime = 500; // Dev donation time period in seconds. 100 minutes by default. // We will divide up this period according to the config setting constexpr static size_t iDevDonatePeriod = 100 * 60; inline bool is_dev_time() { //Add 4 seconds to compensate for connect constexpr size_t dev_portion = double(iDevDonatePeriod) * fDevDonationLevel + 4; if(dev_portion < 15) //No point in bothering with less than 10s return false; return (get_timestamp() - dev_timestamp) % iDevDonatePeriod >= (iDevDonatePeriod - dev_portion); }; std::list lTimedEvents; std::mutex timed_event_mutex; thdq oEventQ; xmrstak::telemetry* telem; std::vector* pvThreads; size_t current_pool_id = invalid_pool_id; size_t last_usr_pool_id = invalid_pool_id; size_t dev_timestamp; std::list pools; jpsock* pick_pool_by_id(size_t pool_id); executor(); void ex_main(); void ex_clock_thd(); void pool_connect(jpsock* pool); constexpr static size_t motd_max_length = 512; bool motd_filter_console(std::string& motd); bool motd_filter_web(std::string& motd); void hashrate_report(std::string& out); void result_report(std::string& out); void connection_report(std::string& out); void http_hashrate_report(std::string& out); void http_result_report(std::string& out); void http_connection_report(std::string& out); void http_json_report(std::string& out); void http_report(ex_event_name ev); void print_report(ex_event_name ev); std::string* pHttpString = nullptr; std::promise httpReady; std::mutex httpMutex; struct sck_error_log { std::chrono::system_clock::time_point time; std::string msg; sck_error_log(std::string&& err) : msg(std::move(err)) { time = std::chrono::system_clock::now(); } }; std::vector vSocketLog; // Element zero is always the success element. // Keep in mind that this is a tally and not a log like above struct result_tally { std::chrono::system_clock::time_point time; std::string msg; size_t count; result_tally() : msg("[OK]"), count(0) { time = std::chrono::system_clock::now(); } result_tally(std::string&& err) : msg(std::move(err)), count(1) { time = std::chrono::system_clock::now(); } void increment() { count++; time = std::chrono::system_clock::now(); } bool compare(std::string& err) { if(msg == err) return true; else return false; } }; std::vector vMineResults; //More result statistics std::array iTopDiff { { } }; //Initialize to zero std::chrono::system_clock::time_point tPoolConnTime; size_t iPoolHashes = 0; uint64_t iPoolDiff = 0; // Set it to 16 bit so that we can just let it grow // Maximum realistic growth rate - 5MB / month std::vector iPoolCallTimes; //Those stats are reset if we disconnect inline void reset_stats() { iPoolCallTimes.clear(); tPoolConnTime = std::chrono::system_clock::now(); iPoolHashes = 0; } double fHighestHps = 0.0; void log_socket_error(jpsock* pool, std::string&& sError); void log_result_error(std::string&& sError); void log_result_ok(uint64_t iActualDiff); void on_sock_ready(size_t pool_id); void on_sock_error(size_t pool_id, std::string&& sError, bool silent); void on_pool_have_job(size_t pool_id, pool_job& oPoolJob); void on_miner_result(size_t pool_id, job_result& oResult); void connect_to_pools(std::list& eval_pools); bool get_live_pools(std::vector& eval_pools, bool is_dev); void eval_pool_choice(); inline size_t sec_to_ticks(size_t sec) { return sec * (1000 / iTickTime); } };