From 26c2200af32c86d15341ffa8aebf5a91061e60e1 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 1 Jul 2020 23:10:37 +0700 Subject: [PATCH] #1756 Added results and connection reports. --- src/App.cpp | 4 +- src/Summary.cpp | 9 +- src/base/net/stratum/NetworkState.cpp | 196 +++++++++++++++++++++++--- src/base/net/stratum/NetworkState.h | 11 +- src/core/Controller.cpp | 7 + src/core/Controller.h | 1 + src/net/Network.cpp | 42 +++--- src/net/Network.h | 1 + 8 files changed, 225 insertions(+), 46 deletions(-) diff --git a/src/App.cpp b/src/App.cpp index 694a9915..1d1ec3e9 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -37,8 +37,6 @@ #include "base/kernel/Platform.h" #include "core/config/Config.h" #include "core/Controller.h" -#include "core/Miner.h" -#include "net/Network.h" #include "Summary.h" #include "version.h" @@ -107,7 +105,7 @@ void xmrig::App::onConsoleCommand(char command) close(); } else { - m_controller->miner()->execCommand(command); + m_controller->execCommand(command); } } diff --git a/src/Summary.cpp b/src/Summary.cpp index d2a723c0..a026c938 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -161,11 +161,14 @@ static void print_commands(Config *) { if (Log::isColors()) { Log::print(GREEN_BOLD(" * ") WHITE_BOLD("COMMANDS ") MAGENTA_BG(WHITE_BOLD_S "h") WHITE_BOLD("ashrate, ") - MAGENTA_BG(WHITE_BOLD_S "p") WHITE_BOLD("ause, ") - MAGENTA_BG(WHITE_BOLD_S "r") WHITE_BOLD("esume")); + MAGENTA_BG(WHITE_BOLD_S "p") WHITE_BOLD("ause, ") + MAGENTA_BG(WHITE_BOLD_S "r") WHITE_BOLD("esume, ") + WHITE_BOLD("re") MAGENTA_BG(WHITE_BOLD_S "s") WHITE_BOLD("ults, ") + MAGENTA_BG(WHITE_BOLD_S "c") WHITE_BOLD("onnection") + ); } else { - Log::print(" * COMMANDS 'h' hashrate, 'p' pause, 'r' resume"); + Log::print(" * COMMANDS 'h' hashrate, 'p' pause, 'r' resume, 's' results, 'c' connection"); } } diff --git a/src/base/net/stratum/NetworkState.cpp b/src/base/net/stratum/NetworkState.cpp index 136128ce..9e788019 100644 --- a/src/base/net/stratum/NetworkState.cpp +++ b/src/base/net/stratum/NetworkState.cpp @@ -25,6 +25,7 @@ #include "base/net/stratum/NetworkState.h" #include "3rdparty/rapidjson/document.h" +#include "base/io/log/Log.h" #include "base/kernel/interfaces/IClient.h" #include "base/kernel/interfaces/IStrategy.h" #include "base/net/stratum/Job.h" @@ -40,6 +41,80 @@ +namespace xmrig { + + +inline static void printCount(uint64_t accepted, uint64_t rejected) +{ + float percent = 100.0; + int color = 2; + + if (!accepted) { + percent = 0.0; + color = 1; + } + else if (rejected) { + percent = static_cast(accepted) / (accepted + rejected) * 100.0; + color = 3; + } + + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-17s") CSI "1;3%dm%" PRIu64 CLEAR CSI "0;3%dm (%1.1f%%)", "accepted", color, accepted, color, percent); + + if (rejected) { + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-17s") RED_BOLD("%" PRIu64), "rejected", rejected); + } +} + + +inline static void printHashes(uint64_t accepted, uint64_t hashes) +{ + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-17s") CYAN_BOLD("%" PRIu64) " avg " CYAN("%1.0f"), + "pool-side hashes", hashes, static_cast(hashes) / accepted); +} + + +inline static void printAvgTime(uint64_t time) +{ + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-17s") CSI "1;3%dm%1.1fs", "avg result time", (time < 10000 ? 3 : 2), time / 1000.0); +} + + +static void printDiff(uint64_t diff) +{ + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-17s") CYAN_BOLD("%s"), "difficulty", NetworkState::humanDiff(diff).c_str()); +} + + +inline static void printDiff(size_t i, uint64_t diff, uint64_t hashes) +{ + if (!diff) { + return; + } + + const double effort = static_cast(hashes) / diff * 100.0; + const double target = (i + 1) * 100.0; + const int color = effort > (target + 100.0) ? 1 : (effort > target ? 3 : 2); + + Log::print("%3zu | %10s | " CSI "0;3%dm%8.2f" CLEAR " |", i + 1, NetworkState::humanDiff(diff).c_str(), color, effort); +} + + +inline static void printLatency(uint32_t latency) +{ + if (!latency) { + return; + } + + const int color = latency < 100 ? 2 : (latency > 500 ? 1 : 3); + + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-17s") CSI "1;3%dm%ums", "ping time", color, latency); +} + + +} // namespace xmrig + + + xmrig::NetworkState::NetworkState(IStrategyListener *listener) : StrategyProxy(listener) { } @@ -54,7 +129,8 @@ rapidjson::Value xmrig::NetworkState::getConnection(rapidjson::Document &doc, in Value connection(kObjectType); connection.AddMember("pool", StringRef(m_pool), allocator); connection.AddMember("ip", m_ip.toJSON(), allocator); - connection.AddMember("uptime", connectionTime(), allocator); + connection.AddMember("uptime", connectionTime() / 1000, allocator); + connection.AddMember("uptime_ms", connectionTime(), allocator); connection.AddMember("ping", latency(), allocator); connection.AddMember("failures", m_failures, allocator); connection.AddMember("tls", m_tls.toJSON(), allocator); @@ -64,7 +140,8 @@ rapidjson::Value xmrig::NetworkState::getConnection(rapidjson::Document &doc, in connection.AddMember("diff", m_diff, allocator); connection.AddMember("accepted", m_accepted, allocator); connection.AddMember("rejected", m_rejected, allocator); - connection.AddMember("avg_time", avgTime(), allocator); + connection.AddMember("avg_time", avgTime() / 1000, allocator); + connection.AddMember("avg_time_ms", avgTime(), allocator); connection.AddMember("hashes_total", m_hashes, allocator); if (version == 1) { @@ -85,11 +162,14 @@ rapidjson::Value xmrig::NetworkState::getResults(rapidjson::Document &doc, int v results.AddMember("diff_current", m_diff, allocator); results.AddMember("shares_good", m_accepted, allocator); results.AddMember("shares_total", m_accepted + m_rejected, allocator); - results.AddMember("avg_time", avgTime(), allocator); + results.AddMember("avg_time", avgTime() / 1000, allocator); + results.AddMember("avg_time_ms", avgTime(), allocator); results.AddMember("hashes_total", m_hashes, allocator); Value best(kArrayType); - for (uint64_t i : topDiff) { + best.Reserve(m_topDiff.size(), allocator); + + for (uint64_t i : m_topDiff) { best.PushBack(i, allocator); } @@ -104,6 +184,84 @@ rapidjson::Value xmrig::NetworkState::getResults(rapidjson::Document &doc, int v #endif +void xmrig::NetworkState::printConnection() const +{ + if (!m_active) { + LOG_NOTICE(YELLOW_BOLD_S "no active connection"); + + return; + } + + Log::print(MAGENTA_BOLD_S " - CONNECTION"); + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-17s") CYAN_BOLD("%s ") BLACK_BOLD("(%s) ") GREEN_BOLD("%s"), + "pool address", m_pool, m_ip.data(), m_tls.isNull() ? "" : m_tls.data()); + + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-17s") WHITE_BOLD("%s"), "algorithm", m_algorithm.shortName()); + printDiff(m_diff); + printLatency(latency()); + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-17s") CYAN_BOLD("%" PRIu64 "s"), "connection time", connectionTime() / 1000); +} + + +void xmrig::NetworkState::printResults() const +{ + if (!m_hashes) { + LOG_NOTICE(YELLOW_BOLD_S "no any results yet"); + + return; + } + + Log::print(MAGENTA_BOLD_S " - RESULTS"); + + printCount(m_accepted, m_rejected); + printHashes(m_accepted, m_hashes); + printDiff(m_diff); + + if (m_active && !m_latency.empty()) { + printAvgTime(avgTime()); + } + + Log::print(MAGENTA_BOLD_S " - TOP 10"); + Log::print(WHITE_BOLD_S " # | DIFFICULTY | EFFORT %% |"); + + for (size_t i = 0; i < m_topDiff.size(); ++i) { + printDiff(i, m_topDiff[i], m_hashes); + } +} + + +const char *xmrig::NetworkState::scaleDiff(uint64_t &diff) +{ + if (diff >= 100000000000) { + diff /= 1000000000; + + return "G"; + } + + if (diff >= 100000000) { + diff /= 1000000; + + return "M"; + } + + if (diff >= 1000000) { + diff /= 1000; + + return "K"; + } + + return ""; +} + + +std::string xmrig::NetworkState::humanDiff(uint64_t diff) +{ + const char *scale = scaleDiff(diff); + + return std::to_string(diff) + scale; +} + + void xmrig::NetworkState::onActive(IStrategy *strategy, IClient *client) { snprintf(m_pool, sizeof(m_pool) - 1, "%s:%d", client->pool().host().data(), client->pool().port()); @@ -145,16 +303,6 @@ void xmrig::NetworkState::onResultAccepted(IStrategy *strategy, IClient *client, } -uint32_t xmrig::NetworkState::avgTime() const -{ - if (m_latency.empty()) { - return 0; - } - - return connectionTime() / (uint32_t)m_latency.size(); -} - - uint32_t xmrig::NetworkState::latency() const { const size_t calls = m_latency.size(); @@ -169,9 +317,19 @@ uint32_t xmrig::NetworkState::latency() const } +uint64_t xmrig::NetworkState::avgTime() const +{ + if (m_latency.empty()) { + return 0; + } + + return connectionTime() / m_latency.size(); +} + + uint64_t xmrig::NetworkState::connectionTime() const { - return m_active ? ((Chrono::steadyMSecs() - m_connectionTime) / 1000) : 0; + return m_active ? ((Chrono::steadyMSecs() - m_connectionTime)) : 0; } @@ -185,10 +343,10 @@ void xmrig::NetworkState::add(const SubmitResult &result, const char *error) m_accepted++; m_hashes += result.diff; - const size_t ln = topDiff.size() - 1; - if (result.actualDiff > topDiff[ln]) { - topDiff[ln] = result.actualDiff; - std::sort(topDiff.rbegin(), topDiff.rend()); + const size_t ln = m_topDiff.size() - 1; + if (result.actualDiff > m_topDiff[ln]) { + m_topDiff[ln] = result.actualDiff; + std::sort(m_topDiff.rbegin(), m_topDiff.rend()); } m_latency.push_back(result.elapsed > 0xFFFF ? 0xFFFF : static_cast(result.elapsed)); diff --git a/src/base/net/stratum/NetworkState.h b/src/base/net/stratum/NetworkState.h index 074dd9f9..8fa1fede 100644 --- a/src/base/net/stratum/NetworkState.h +++ b/src/base/net/stratum/NetworkState.h @@ -32,6 +32,7 @@ #include +#include #include @@ -52,6 +53,12 @@ public: rapidjson::Value getResults(rapidjson::Document &doc, int version) const; # endif + void printConnection() const; + void printResults() const; + + static const char *scaleDiff(uint64_t &diff); + static std::string humanDiff(uint64_t diff); + protected: void onActive(IStrategy *strategy, IClient *client) override; void onJob(IStrategy *strategy, IClient *client, const Job &job, const rapidjson::Value ¶ms) override; @@ -59,8 +66,8 @@ protected: void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) override; private: - uint32_t avgTime() const; uint32_t latency() const; + uint64_t avgTime() const; uint64_t connectionTime() const; void add(const SubmitResult &result, const char *error); void stop(); @@ -68,7 +75,7 @@ private: Algorithm m_algorithm; bool m_active = false; char m_pool[256]{}; - std::array topDiff { { } }; + std::array m_topDiff { { } }; std::vector m_latency; String m_fingerprint; String m_ip; diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 21570ea8..8f230e00 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -98,3 +98,10 @@ xmrig::Network *xmrig::Controller::network() const return m_network; } + + +void xmrig::Controller::execCommand(char command) +{ + miner()->execCommand(command); + network()->execCommand(command); +} diff --git a/src/core/Controller.h b/src/core/Controller.h index b2b8c9cb..94708473 100644 --- a/src/core/Controller.h +++ b/src/core/Controller.h @@ -52,6 +52,7 @@ public: Miner *miner() const; Network *network() const; + void execCommand(char command); private: Miner *m_miner = nullptr; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 3ab09680..0bb741d4 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -98,6 +98,25 @@ void xmrig::Network::connect() } +void xmrig::Network::execCommand(char command) +{ + switch (command) { + case 's': + case 'S': + m_state->printResults(); + break; + + case 'c': + case 'C': + m_state->printConnection(); + break; + + default: + break; + } +} + + void xmrig::Network::onActive(IStrategy *strategy, IClient *client) { if (m_donate && m_donate == strategy) { @@ -192,24 +211,10 @@ void xmrig::Network::onPause(IStrategy *strategy) } -static void scale_diff(uint64_t& diff, const char* &scale) -{ - if (diff >= 100000000) { - diff /= 1000000; - scale = "M"; - } - else if (diff >= 1000000) { - diff /= 1000; - scale = "K"; - } -} - - void xmrig::Network::onResultAccepted(IStrategy *, IClient *, const SubmitResult &result, const char *error) { - uint64_t diff = result.diff; - const char* scale = ""; - scale_diff(diff, scale); + uint64_t diff = result.diff; + const char *scale = NetworkState::scaleDiff(diff); if (error) { LOG_INFO("%s " RED_BOLD("rejected") " (%" PRId64 "/%" PRId64 ") diff " WHITE_BOLD("%" PRIu64 "%s") " " RED("\"%s\"") " " BLACK_BOLD("(%" PRIu64 " ms)"), @@ -247,9 +252,8 @@ void xmrig::Network::onRequest(IApiRequest &request) void xmrig::Network::setJob(IClient *client, const Job &job, bool donate) { - uint64_t diff = job.diff(); - const char* scale = ""; - scale_diff(diff, scale); + uint64_t diff = job.diff();; + const char *scale = NetworkState::scaleDiff(diff); if (job.height()) { LOG_INFO("%s " MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%" PRIu64 "%s") " algo " WHITE_BOLD("%s") " height " WHITE_BOLD("%" PRIu64), diff --git a/src/net/Network.h b/src/net/Network.h index 30b492d1..94d54657 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -58,6 +58,7 @@ public: inline IStrategy *strategy() const { return m_strategy; } void connect(); + void execCommand(char command); protected: inline void onTimer(const Timer *) override { tick(); }