diff --git a/index.html b/index.html index b080fa93..52c00577 100644 --- a/index.html +++ b/index.html @@ -206,7 +206,20 @@ } }, { - text: ' Shutdown miner', + text: ' Reebot machine', + className: 'btn-warning', + enabled: false, + action: function () { + table.rows({selected: true}).eq(0).each(function (index) { + var row = table.row(index); + var data = row.data(); + + sendAction("REBOOT", data.client_status.client_id); + }); + } + }, + { + text: ' Stop miner', className: 'btn-danger', enabled: false, action: function () { diff --git a/src/App.cpp b/src/App.cpp index 0b549eda..b240431e 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -258,6 +258,15 @@ void App::shutdown() m_self->stop(false); } +void App::reboot() +{ + auto rebootCmd = m_self->m_options->ccRebootCmd(); + if (rebootCmd) { + system(rebootCmd); + shutdown(); + } +} + void App::onSignal(uv_signal_t* handle, int signum) { switch (signum) @@ -299,6 +308,9 @@ void App::onCommandReceived(uv_async_t* async) case ControlCommand::SHUTDOWN: App::shutdown(); break; + case ControlCommand::REBOOT: + App::reboot(); + break; case ControlCommand::PUBLISH_CONFIG:; break; } diff --git a/src/App.h b/src/App.h index cd886a83..d5286d18 100644 --- a/src/App.h +++ b/src/App.h @@ -47,6 +47,7 @@ public: static void restart(); static void shutdown(); + static void reboot(); protected: void onConsoleCommand(char command) override; diff --git a/src/Cpu.cpp b/src/Cpu.cpp index ead28fdd..56b09abc 100644 --- a/src/Cpu.cpp +++ b/src/Cpu.cpp @@ -53,10 +53,10 @@ CpuImpl::CpuImpl() } void CpuImpl::optimizeParameters(size_t& threadsCount, size_t& hashFactor, - Options::Algo algo, size_t maxCpuUsage, bool safeMode) + Options::Algo algo, PowVariant powVariant, size_t maxCpuUsage, bool safeMode) { // limits hashfactor to maximum possible value defined by compiler flag - hashFactor = std::min(hashFactor, algo == Options::ALGO_CRYPTONIGHT_HEAVY ? 3 : static_cast(MAX_NUM_HASH_BLOCKS)); + hashFactor = std::min(hashFactor, (algo == Options::ALGO_CRYPTONIGHT_HEAVY || powVariant == POW_XFH) ? 3 : static_cast(MAX_NUM_HASH_BLOCKS)); if (!safeMode && threadsCount > 0 && hashFactor > 0) { @@ -81,7 +81,7 @@ void CpuImpl::optimizeParameters(size_t& threadsCount, size_t& hashFactor, size_t maximumReasonableFactor = std::max(cache / algoBlockSize, static_cast(1ul)); size_t maximumReasonableThreadCount = std::min(maximumReasonableFactor, m_totalThreads); - size_t maximumReasonableHashFactor = std::min(maximumReasonableFactor, algo == Options::ALGO_CRYPTONIGHT_HEAVY ? 3 : static_cast(MAX_NUM_HASH_BLOCKS)); + size_t maximumReasonableHashFactor = std::min(maximumReasonableFactor, (algo == Options::ALGO_CRYPTONIGHT_HEAVY || powVariant == POW_XFH) ? 3 : static_cast(MAX_NUM_HASH_BLOCKS)); if (safeMode) { if (threadsCount > maximumReasonableThreadCount) { @@ -141,10 +141,10 @@ void Cpu::init() CpuImpl::instance().init(); } -void Cpu::optimizeParameters(size_t& threadsCount, size_t& hashFactor, Options::Algo algo, +void Cpu::optimizeParameters(size_t& threadsCount, size_t& hashFactor, Options::Algo algo, PowVariant powVariant, size_t maxCpuUsage, bool safeMode) { - CpuImpl::instance().optimizeParameters(threadsCount, hashFactor, algo, maxCpuUsage, safeMode); + CpuImpl::instance().optimizeParameters(threadsCount, hashFactor, algo, powVariant, maxCpuUsage, safeMode); } int Cpu::setThreadAffinity(size_t threadId, int64_t affinityMask) diff --git a/src/Cpu.h b/src/Cpu.h index 4f8821d8..73b03a6f 100644 --- a/src/Cpu.h +++ b/src/Cpu.h @@ -39,8 +39,8 @@ public: static void init(); - static void optimizeParameters(size_t& threadsCount, size_t& hashFactor, Options::Algo algo, - size_t maxCpuUsage, bool safeMode); + static void optimizeParameters(size_t& threadsCount, size_t& hashFactor, Options::Algo algo, PowVariant powVariant, + size_t maxCpuUsage, bool safeMode); static int setThreadAffinity(size_t threadId, int64_t affinityMask); diff --git a/src/CpuImpl.h b/src/CpuImpl.h index 56288f9a..828400b6 100644 --- a/src/CpuImpl.h +++ b/src/CpuImpl.h @@ -38,7 +38,7 @@ public: CpuImpl(); void init(); - void optimizeParameters(size_t& threadsCount, size_t& hashFactor, Options::Algo algo, + void optimizeParameters(size_t& threadsCount, size_t& hashFactor, Options::Algo algo, PowVariant powVariant, size_t maxCpuUsage, bool safeMode); int setThreadAffinity(size_t threadId, int64_t affinityMask); diff --git a/src/Options.cpp b/src/Options.cpp index e74615ae..71f36a46 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -99,7 +99,8 @@ Options:\n" --cc-worker-id=ID custom worker-id for CC Server\n\ --cc-update-interval-s=N status update interval in seconds (default: 10 min: 1)\n\ --cc-use-remote-logging enable remote logging on CC Server\n\ - --cc-upload-config-on-startup upload current miner config to CC Server on startup\n" + --cc-upload-config-on-startup upload current miner config to CC Server on startup\n\ + --cc-reboot-cmd command/bat to execute to Reboot miner\n" # endif # endif @@ -114,6 +115,10 @@ Options:\n" --cc-key-file=FILE when tls is turned on, use this to point to the right key file (default: server.key) \n\ --cc-client-log-lines-history=N maximum lines of log history kept per miner (default: 100)\n\ --cc-client-config-folder=FOLDER Folder contains the client config files\n\ + --cc-pushover-user-key pushover user for push messages\n\ + --cc-pushover-api-token your user key for pushover notifications\n\ + --cc-push-miner-offline-info api token/keytoken of the application for pushover notifications\n\ + --cc-push-periodic-mining-status send periodic mining status push\n\ --cc-custom-dashboard=FILE loads a custom dashboard and serve it to '/'\n" # endif "\ @@ -187,6 +192,11 @@ static struct option const options[] = { { "cc-use-remote-logging", 0, nullptr, 4017 }, { "cc-client-log-lines-history", 1, nullptr, 4018 }, { "cc-upload-config-on-startup", 0, nullptr, 4019 }, + { "cc-reboot-cmd", 1, nullptr, 4021 }, + { "cc-pushover-user-key", 1, nullptr, 4022 }, + { "cc-pushover-api-token", 1, nullptr, 4023 }, + { "cc-push-miner-offline-info", 0, nullptr, 4024 }, + { "cc-push-periodic-mining-status", 0, nullptr, 4025 }, { "daemonized", 0, nullptr, 4011 }, { "doublehash-thread-mask", 1, nullptr, 4013 }, { "multihash-thread-mask", 1, nullptr, 4013 }, @@ -252,6 +262,7 @@ static struct option const cc_client_options[] = { { "use-tls", 0, nullptr, 4016 }, { "use-remote-logging", 0, nullptr, 4017 }, { "upload-config-on-startup", 0, nullptr, 4019 }, + { "reboot-cmd", 1, nullptr, 4021 }, { nullptr, 0, nullptr, 0 } }; @@ -266,6 +277,10 @@ static struct option const cc_server_options[] = { { "key-file", 1, nullptr, 4015 }, { "use-tls", 0, nullptr, 4016 }, { "client-log-lines-history", 1, nullptr, 4018 }, + { "pushover-user-key", 1, nullptr, 4022 }, + { "pushover-api-token", 1, nullptr, 4023 }, + { "push-miner-offline-info", 0, nullptr, 4024 }, + { "push-periodic-mining-status", 0, nullptr, 4025 }, { nullptr, 0, nullptr, 0 } }; @@ -337,6 +352,8 @@ Options::Options(int argc, char **argv) : m_ccUseTls(false), m_ccUseRemoteLogging(true), m_ccUploadConfigOnStartup(true), + m_ccPushOfflineMiners(false), + m_ccPushPeriodicStatus(false), m_fileName(Platform::defaultConfigName()), m_apiToken(nullptr), m_apiWorkerId(nullptr), @@ -351,6 +368,9 @@ Options::Options(int argc, char **argv) : m_ccCustomDashboard(nullptr), m_ccKeyFile(nullptr), m_ccCertFile(nullptr), + m_ccRebootCmd(nullptr), + m_ccPushoverUser(nullptr), + m_ccPushoverToken(nullptr), m_algo(ALGO_CRYPTONIGHT), m_algoVariant(AV0_AUTO), m_aesni(AESNI_AUTO), @@ -609,6 +629,21 @@ bool Options::parseArg(int key, const char *arg) case 4020: /* --asm-optimization */ return parseAsmOptimization(arg); + case 4021: /* --cc-reboot-cmd */ + m_ccRebootCmd = strdup(arg); + + case 4022: /* --cc-pushover-user-key */ + m_ccPushoverUser = strdup(arg); + + case 4023: /* --cc-pushover-api-token */ + m_ccPushoverToken = strdup(arg); + + case 4024: /* --cc-push-miner-offline-info */ + return parseBoolean(key, false); + + case 4025: /* --cc-push-periodic-mining-status */ + return parseBoolean(key, false); + case 't': /* --threads */ if (strncmp(arg, "all", 3) == 0) { m_threads = Cpu::threads(); @@ -849,6 +884,14 @@ bool Options::parseBoolean(int key, bool enable) m_ccUploadConfigOnStartup = enable; break; + case 4024: /* --cc-push-miner-offline-info */ + m_ccPushOfflineMiners = enable; + break; + + case 4025: /* --cc-push-periodic-mining-status */ + m_ccPushPeriodicStatus = enable; + break; + default: break; } @@ -1151,12 +1194,12 @@ void Options::optimizeAlgorithmConfiguration() m_aesni = aesniFromCpu; } - if (m_algo == Options::ALGO_CRYPTONIGHT_HEAVY && m_hashFactor > 3) { - fprintf(stderr, "Maximum supported hashfactor for cryptonight-heavy is: 3\n"); + if ((m_algo == Options::ALGO_CRYPTONIGHT_HEAVY || m_powVariant == PowVariant::POW_XFH) && m_hashFactor > 3) { + fprintf(stderr, "Maximum supported hashfactor for cryptonight-heavy and XFH is: 3\n"); m_hashFactor = 3; } - Cpu::optimizeParameters(m_threads, m_hashFactor, m_algo, m_maxCpuUsage, m_safe); + Cpu::optimizeParameters(m_threads, m_hashFactor, m_algo, m_powVariant, m_maxCpuUsage, m_safe); } bool Options::parseCCUrl(const char* url) diff --git a/src/Options.h b/src/Options.h index 31a167fe..07fccb3c 100644 --- a/src/Options.h +++ b/src/Options.h @@ -75,6 +75,8 @@ public: inline bool ccUseTls() const { return m_ccUseTls; } inline bool ccUseRemoteLogging() const { return m_ccUseRemoteLogging; } inline bool ccUploadConfigOnStartup() const { return m_ccUploadConfigOnStartup; } + inline bool ccPushOfflineMiners() const { return m_ccPushOfflineMiners; } + inline bool ccPushPeriodicStatus() const { return m_ccPushPeriodicStatus; } inline const char *fileName() const { return m_fileName; } inline const char *apiToken() const { return m_apiToken; } inline const char *apiWorkerId() const { return m_apiWorkerId; } @@ -89,6 +91,9 @@ public: inline const char *ccCustomDashboard() const { return m_ccCustomDashboard == nullptr ? "index.html" : m_ccCustomDashboard; } inline const char *ccKeyFile() const { return m_ccKeyFile == nullptr ? "server.key" : m_ccKeyFile; } inline const char *ccCertFile() const { return m_ccCertFile == nullptr ? "server.pem" : m_ccCertFile; } + inline const char *ccRebootCmd() const { return (m_ccRebootCmd != nullptr && strlen(m_ccRebootCmd) > 0) ? m_ccRebootCmd : nullptr; } + inline const char *ccPushoverUser() const { return (m_ccPushoverUser != nullptr && strlen(m_ccPushoverUser) > 0) ? m_ccPushoverUser : nullptr; } + inline const char *ccPushoverToken() const { return (m_ccPushoverToken != nullptr && strlen(m_ccPushoverToken) > 0) ? m_ccPushoverToken : nullptr; } inline const std::vector &pools() const { return m_pools; } inline Algo algo() const { return m_algo; } inline PowVariant powVariant() const { return m_powVariant; } @@ -152,6 +157,8 @@ private: bool m_ccUseTls; bool m_ccUseRemoteLogging; bool m_ccUploadConfigOnStartup; + bool m_ccPushOfflineMiners; + bool m_ccPushPeriodicStatus; const char* m_fileName; char *m_apiToken; char *m_apiWorkerId; @@ -166,6 +173,9 @@ private: char *m_ccCustomDashboard; char *m_ccKeyFile; char *m_ccCertFile; + char *m_ccRebootCmd; + char *m_ccPushoverUser; + char *m_ccPushoverToken; Algo m_algo; AlgoVariant m_algoVariant; AesNi m_aesni; diff --git a/src/Summary.h b/src/Summary.h index 3f64fd60..f5a34900 100644 --- a/src/Summary.h +++ b/src/Summary.h @@ -29,6 +29,8 @@ class Summary { public: static void print(); + + static void print_pushinfo(); }; diff --git a/src/cc/CCClient.cpp b/src/cc/CCClient.cpp index 854ecbf0..557b3d36 100644 --- a/src/cc/CCClient.cpp +++ b/src/cc/CCClient.cpp @@ -219,9 +219,11 @@ void CCClient::publishClientStatusReport() LOG_WARN("[CC-Client] Command: PUBLISH_CONFIG received -> publish config"); publishConfig(); }else if (controlCommand.getCommand() == ControlCommand::RESTART) { - LOG_WARN("[CC-Client] Command: RESTART received -> restart"); + LOG_WARN("[CC-Client] Command: RESTART received -> trigger restart"); } else if (controlCommand.getCommand() == ControlCommand::SHUTDOWN) { - LOG_WARN("[CC-Client] Command: SHUTDOWN received -> shutdown"); + LOG_WARN("[CC-Client] Command: SHUTDOWN received -> quit"); + } else if (controlCommand.getCommand() == ControlCommand::REBOOT) { + LOG_WARN("[CC-Client] Command: REBOOT received -> trigger reboot"); } m_self->m_async->data = reinterpret_cast(controlCommand.getCommand()); diff --git a/src/cc/ClientStatus.cpp b/src/cc/ClientStatus.cpp index 9655386a..e141c746 100644 --- a/src/cc/ClientStatus.cpp +++ b/src/cc/ClientStatus.cpp @@ -356,7 +356,7 @@ uint32_t ClientStatus::getAvgTime() const return m_avgTime; } -std::time_t ClientStatus::getLastStatusUpdate() const +uint64_t ClientStatus::getLastStatusUpdate() const { return m_lastStatusUpdate; } @@ -516,7 +516,8 @@ bool ClientStatus::parseFromJson(const rapidjson::Document& document) } auto time_point = std::chrono::system_clock::now(); - m_lastStatusUpdate = std::chrono::system_clock::to_time_t(time_point); + m_lastStatusUpdate = static_cast(std::chrono::system_clock::to_time_t(time_point)); + result = true; } diff --git a/src/cc/ClientStatus.h b/src/cc/ClientStatus.h index 65eb1ed2..ea1baa5a 100644 --- a/src/cc/ClientStatus.h +++ b/src/cc/ClientStatus.h @@ -148,7 +148,7 @@ public: void setAvgTime(uint32_t avgTime); uint32_t getAvgTime() const; - std::time_t getLastStatusUpdate() const; + uint64_t getLastStatusUpdate() const; void setUptime(uint64_t uptime); uint64_t getUptime() const; @@ -203,8 +203,7 @@ private: uint64_t m_uptime; uint32_t m_avgTime; - - std::time_t m_lastStatusUpdate; + uint64_t m_lastStatusUpdate; }; #endif /* __CLIENT_STATUS_H__ */ diff --git a/src/cc/ControlCommand.cpp b/src/cc/ControlCommand.cpp index afdda3dd..d3e27bc8 100644 --- a/src/cc/ControlCommand.cpp +++ b/src/cc/ControlCommand.cpp @@ -97,5 +97,6 @@ bool ControlCommand::isOneTimeCommand() const { return m_command == ControlCommand::UPDATE_CONFIG || m_command == ControlCommand::PUBLISH_CONFIG || m_command == ControlCommand::RESTART || - m_command == ControlCommand::SHUTDOWN; + m_command == ControlCommand::SHUTDOWN || + m_command == ControlCommand::REBOOT; } diff --git a/src/cc/ControlCommand.h b/src/cc/ControlCommand.h index 246aa923..588a2ef2 100644 --- a/src/cc/ControlCommand.h +++ b/src/cc/ControlCommand.h @@ -21,13 +21,14 @@ #include #include "rapidjson/document.h" -static const char* command_str[6] = { +static const char* command_str[7] = { "START", "STOP", "UPDATE_CONFIG", "PUBLISH_CONFIG", "RESTART", - "SHUTDOWN" + "SHUTDOWN", + "REBOOT" }; class ControlCommand @@ -39,7 +40,8 @@ public: UPDATE_CONFIG, PUBLISH_CONFIG, RESTART, - SHUTDOWN + SHUTDOWN, + REBOOT }; public: diff --git a/src/cc/Service.cpp b/src/cc/Service.cpp index 9131ee31..d88fe2e6 100644 --- a/src/cc/Service.cpp +++ b/src/cc/Service.cpp @@ -26,6 +26,10 @@ #include #include #include +#include + +#include "log/Log.h" +#include <3rdparty/cpp-httplib/httplib.h> #include <3rdparty/rapidjson/document.h> #include <3rdparty/rapidjson/stringbuffer.h> #include <3rdparty/rapidjson/writer.h> @@ -33,21 +37,34 @@ #include <3rdparty/rapidjson/filereadstream.h> #include <3rdparty/rapidjson/error/en.h> #include <3rdparty/rapidjson/prettywriter.h> -#include -#include "log/Log.h" +#include "version.h" #include "Service.h" uv_mutex_t Service::m_mutex; +uv_timer_t Service::m_timer; + std::map Service::m_clientCommand; std::map Service::m_clientStatus; std::map> Service::m_clientLog; -int Service::m_currentServerTime = 0; +uint64_t Service::m_currentServerTime = 0; +uint64_t Service::m_lastOfflineCheckTime = 0; +uint64_t Service::m_lastStatusUpdateTime = 0; bool Service::start() { uv_mutex_init(&m_mutex); +#ifndef XMRIG_NO_TLS + if (Options::i()->ccPushoverToken() && Options::i()->ccPushoverUser()) + { + uv_timer_init(uv_default_loop(), &m_timer); + uv_timer_start(&m_timer, Service::onPushTimer, + static_cast(TIMER_INTERVAL), + static_cast(TIMER_INTERVAL)); + } +#endif + return true; } @@ -55,6 +72,8 @@ void Service::release() { uv_mutex_lock(&m_mutex); + uv_timer_stop(&m_timer); + m_clientCommand.clear(); m_clientStatus.clear(); m_clientLog.clear(); @@ -156,7 +175,7 @@ unsigned Service::getClientConfig(const Options* options, const std::string& cli data << clientConfig.rdbuf(); clientConfig.close(); } else { - std::ifstream defaultConfig("default_config.json"); + std::ifstream defaultConfig("default_miner_config.json"); if (defaultConfig) { data << defaultConfig.rdbuf(); defaultConfig.close(); @@ -230,7 +249,7 @@ unsigned Service::getClientStatusList(std::string& resp) } auto time_point = std::chrono::system_clock::now(); - m_currentServerTime = std::chrono::system_clock::to_time_t(time_point); + m_currentServerTime = static_cast(std::chrono::system_clock::to_time_t(time_point)); document.AddMember("current_server_time", m_currentServerTime, allocator); document.AddMember("current_version", rapidjson::StringRef(Version::string().c_str()), allocator); @@ -420,3 +439,100 @@ std::string Service::getClientConfigFileName(const Options* options, const std:: return clientConfigFileName; } + +void Service::onPushTimer(uv_timer_t* handle) +{ + auto time_point = std::chrono::system_clock::now(); + auto now = static_cast(std::chrono::system_clock::to_time_t(time_point) * 1000); + + if (Options::i()->ccPushOfflineMiners()) { + sendMinerOfflinePush(now); + m_lastOfflineCheckTime = now; + } + + if (Options::i()->ccPushPeriodicStatus()) { + if (now > (m_lastStatusUpdateTime + STATUS_UPDATE_INTERVAL)) { + sendServerStatusPush(now); + m_lastStatusUpdateTime = now; + } + } +} + +void Service::sendMinerOfflinePush(uint64_t now) +{ + for (auto clientStatus : m_clientStatus) { + uint64_t lastStatus = clientStatus.second.getLastStatusUpdate() * 1000; + uint64_t offlineThreshold = now - OFFLINE_TRESHOLD_IN_MS; + + if (lastStatus < offlineThreshold) { + offlineThreshold = now - (OFFLINE_TRESHOLD_IN_MS + (now - m_lastOfflineCheckTime)); + if (lastStatus > offlineThreshold) { + std::stringstream message; + message << "Miner: " << clientStatus.first << " just went offline!"; + + LOG_WARN("Send miner went offline push", clientStatus.first.c_str()); + triggerPush(APP_NAME " Offline Monitor", message.str()); + } + } + } +} + +void Service::sendServerStatusPush(uint64_t now) +{ + size_t onlineMiner = 0; + size_t offlineMiner = 0; + + double hashrateMedium = 0; + double hashrateLong = 0; + double avgTime = 0; + + uint64_t sharesGood = 0; + uint64_t sharesTotal = 0; + uint64_t offlineThreshold = now - OFFLINE_TRESHOLD_IN_MS; + + for (auto clientStatus : m_clientStatus) { + if (offlineThreshold < clientStatus.second.getLastStatusUpdate() * 1000) { + onlineMiner++; + } else { + offlineMiner++; + } + + hashrateMedium += clientStatus.second.getHashrateMedium(); + hashrateLong += clientStatus.second.getHashrateLong(); + + sharesGood += clientStatus.second.getSharesGood(); + sharesTotal += clientStatus.second.getSharesTotal(); + avgTime += clientStatus.second.getAvgTime(); + } + + if (!m_clientStatus.empty()) { + avgTime = avgTime / m_clientStatus.size(); + } + + std::stringstream message; + message << "Miners: " << onlineMiner << " (Online), " << offlineMiner << " (Offline)\n" + << "Shares: " << sharesGood << " (Good), " << sharesTotal - sharesGood << " (Bad)\n" + << "Hashrates: " << hashrateMedium << "h/s (1min), " << hashrateLong << "h/s (15min)\n" + << "Avg. Time: " << avgTime << "s"; + + LOG_WARN("Send Server status push"); + triggerPush(APP_NAME " Status", message.str()); +} + +void Service::triggerPush(const std::string& title, const std::string& message) +{ +#ifndef XMRIG_NO_TLS + std::shared_ptr cli = std::make_shared("api.pushover.net", 443); + + httplib::Params params; + params.emplace("token", Options::i()->ccPushoverToken()); + params.emplace("user", Options::i()->ccPushoverUser()); + params.emplace("title", title); + params.emplace("message", httplib::detail::encode_url(message)); + + auto res = cli->Post("/1/messages.json", params); + if (res) { + LOG_WARN("Push response: %s", res->body.c_str()); + } +#endif +} \ No newline at end of file diff --git a/src/cc/Service.h b/src/cc/Service.h index b4e7d610..adffcc10 100644 --- a/src/cc/Service.h +++ b/src/cc/Service.h @@ -36,6 +36,10 @@ #include "ClientStatus.h" #include "ControlCommand.h" +#define TIMER_INTERVAL 10000 +#define OFFLINE_TRESHOLD_IN_MS 60000 +#define STATUS_UPDATE_INTERVAL 3600000 + class Service { public: @@ -61,15 +65,22 @@ private: static std::string getClientConfigFileName(const Options *options, const std::string &clientId); + static void onPushTimer(uv_timer_t* handle); + static void sendServerStatusPush(uint64_t now); + static void sendMinerOfflinePush(uint64_t now); + static void triggerPush(const std::string& title, const std::string& message); + private: - static int m_currentServerTime; + static uint64_t m_currentServerTime; + static uint64_t m_lastOfflineCheckTime; + static uint64_t m_lastStatusUpdateTime; static std::map m_clientStatus; static std::map m_clientCommand; static std::map> m_clientLog; static uv_mutex_t m_mutex; - + static uv_timer_t m_timer; }; #endif /* __SERVICE_H__ */ diff --git a/src/cc/Summary.cpp b/src/cc/Summary.cpp index a1544e03..011c60e9 100644 --- a/src/cc/Summary.cpp +++ b/src/cc/Summary.cpp @@ -59,9 +59,37 @@ static void print_commands() } } +void Summary::print_pushinfo() { + if (Options::i()->ccPushoverToken() && Options::i()->ccPushoverUser()) + { +#ifndef XMRIG_NO_TLS + if (Options::i()->colors()) { + Log::i()->text("\x1B[01;32m * \x1B[01;37mPUSHSERVICE: \x1B[01;32mEnabled"); + } + else { + Log::i()->text(" * PUSHSERVICE: Enabled"); + } +#else + if (Options::i()->colors()) { + Log::i()->text("\x1B[01;32m * \x1B[01;37mPUSHSERVICE: \x1B[01;31mUnavailable requires TLS"); + } + else { + Log::i()->text(" * PUSHSERVICE: Unavailable requires TLS"); + } +#endif + } else { + if (Options::i()->colors()) { + Log::i()->text("\x1B[01;32m * \x1B[01;37mPUSHSERVICE: \x1B[01;31mDisabled"); + } + else { + Log::i()->text(" * PUSHSERVICE: Disabled"); + } + } +} void Summary::print() { print_versions(); + print_pushinfo(); print_commands(); } diff --git a/src/config.json b/src/config.json index c5b0f06f..7a744e36 100644 --- a/src/config.json +++ b/src/config.json @@ -36,6 +36,7 @@ "worker-id": null, // custom worker-id for CC Server (otherwise hostname is used) "update-interval-s": 10, // status update interval in seconds (default: 10 min: 1) "use-remote-logging" : true, // enable remote logging on CC Server - "upload-config-on-startup" : true // upload current miner config to CC Server on startup + "upload-config-on-startup" : true, // upload current miner config to CC Server on startup + "reboot-cmd" : "" // command to execute to reboot the OS } } diff --git a/src/config_cc.json b/src/config_cc.json index ea4e492a..ced0782a 100644 --- a/src/config_cc.json +++ b/src/config_cc.json @@ -13,6 +13,11 @@ "pass": "pass", // admin pass for access CC Dashboard "client-config-folder" : null, // folder which contains the client-config files (null=current) "client-log-lines-history" : 100, // maximum lines of log history kept per miner - "custom-dashboard" : "index.html" // dashboard html file + "custom-dashboard" : "index.html", // dashboard html file + // Pushnotification Howto @ https://github.com/Bendr0id/xmrigCC/wiki/Setup-Pushover + "pushover-user-key" : "", // your user key for pushover notifications + "pushover-api-token" : "", // api token/keytoken of the application for pushover notifications + "push-miner-offline-info" : true, // push notification for offline miners + "push-periodic-mining-status" : true // push periodic status notification (every hour) } } diff --git a/src/default_config.json b/src/default_miner_config.json similarity index 96% rename from src/default_config.json rename to src/default_miner_config.json index a58eb815..82c5cdfb 100644 --- a/src/default_config.json +++ b/src/default_miner_config.json @@ -36,6 +36,7 @@ "worker-id": null, // custom worker-id for CC Server (otherwise hostname is used) "update-interval-s": 10, // status update interval in seconds (default: 10 min: 1) "use-remote-logging" : true, // enable remote logging on CC Server - "upload-config-on-startup" : true // upload current miner config to CC Server on startup + "upload-config-on-startup" : true, // upload current miner config to CC Server on startup + "reboot-cmd" : "" // command to execute to reboot the OS } } \ No newline at end of file diff --git a/src/version.h b/src/version.h index 1920a632..59b40263 100644 --- a/src/version.h +++ b/src/version.h @@ -29,21 +29,21 @@ #define APP_ID "XMRigCC" #define APP_NAME "XMRigCC" #define APP_DESC "XMRigCC Command'n'Control Server" -#define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id" +#define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id" # else #define APP_ID "XMRigCC" #define APP_NAME "XMRigCC" #define APP_DESC "XMRigCC CPU miner" -#define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id" +#define APP_COPYRIGHT "Copyright (C) 2017- BenDr0id" #endif -#define APP_VERSION "1.8.4 (based on XMRig)" +#define APP_VERSION "1.8.5-beta1 (based on XMRig)" #define APP_DOMAIN "" #define APP_SITE "https://github.com/Bendr0id/xmrigCC" #define APP_KIND "cpu" #define APP_VER_MAJOR 1 #define APP_VER_MINOR 8 -#define APP_VER_BUILD 4 +#define APP_VER_BUILD 5 #define APP_VER_REV 0 #ifndef NDEBUG diff --git a/test/cpu/test_cpu.cpp b/test/cpu/test_cpu.cpp index f2cad46c..632e206e 100644 --- a/test/cpu/test_cpu.cpp +++ b/test/cpu/test_cpu.cpp @@ -32,10 +32,10 @@ void setMockedCpu(size_t numProcessors, size_t numCores, size_t numPusPerCore, s Cpu::init(); } -std::pair testOptimize(size_t numThreads, size_t hashFactor, Options::Algo algo, bool safeMode, +std::pair testOptimize(size_t numThreads, size_t hashFactor, Options::Algo algo, PowVariant powVariant, bool safeMode, size_t maxCpuUsage = 100) { - Cpu::optimizeParameters(numThreads, hashFactor, algo, maxCpuUsage, safeMode); + Cpu::optimizeParameters(numThreads, hashFactor, algo, powVariant, maxCpuUsage, safeMode); return std::pair(numThreads, hashFactor); }