From a76e56a30dd0b3ce746b607edc9cd9f2ab41dc20 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 2 Aug 2019 21:36:38 +0700 Subject: [PATCH] Sync changes. --- src/api/Api.cpp | 31 +++++++++++++++++-- src/api/Api.h | 2 ++ src/api/interfaces/IApiListener.h | 2 ++ src/api/interfaces/IApiRequest.h | 12 +++++++- src/api/requests/ApiRequest.cpp | 3 +- src/api/requests/ApiRequest.h | 7 ++++- src/api/requests/HttpApiRequest.cpp | 11 +++++++ src/api/v1/ApiRouter.cpp | 20 ------------- src/base/io/log/Log.cpp | 17 ++++------- src/base/io/log/Log.h | 4 +++ src/base/kernel/Entry.cpp | 46 ++++++++++++++++++++++++++++- src/base/kernel/Entry.h | 3 +- src/base/net/stratum/Job.cpp | 24 +++++++++++++++ src/base/net/stratum/Job.h | 5 +++- src/base/tools/Buffer.h | 15 ++++++---- src/proxy/Login.cpp | 2 +- src/proxy/Miner.cpp | 10 +------ src/proxy/Stats.cpp | 3 +- src/proxy/StatsData.h | 45 ++++++++++------------------ 19 files changed, 173 insertions(+), 89 deletions(-) diff --git a/src/api/Api.cpp b/src/api/Api.cpp index 3222a2e..949b23e 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -53,6 +53,7 @@ xmrig::Api::Api(Base *base) : m_base(base), m_id(), m_workerId(), + m_timestamp(Chrono::currentMSecsSinceEpoch()), m_httpd(nullptr) { base->addListener(this); @@ -117,10 +118,34 @@ void xmrig::Api::exec(IApiRequest &request) { using namespace rapidjson; - if (request.method() == IApiRequest::METHOD_GET && (request.url() == "/1/summary" || request.url() == "/api.json")) { + if (request.type() == IApiRequest::REQ_SUMMARY) { + auto &allocator = request.doc().GetAllocator(); + request.accept(); - request.reply().AddMember("id", StringRef(m_id), request.doc().GetAllocator()); - request.reply().AddMember("worker_id", StringRef(m_workerId), request.doc().GetAllocator());; + request.reply().AddMember("id", StringRef(m_id), allocator); + request.reply().AddMember("worker_id", StringRef(m_workerId), allocator); + request.reply().AddMember("uptime", (Chrono::currentMSecsSinceEpoch() - m_timestamp) / 1000, allocator); + + Value features(kArrayType); +# ifdef XMRIG_FEATURE_API + features.PushBack("api", allocator); +# endif +# ifdef XMRIG_FEATURE_ASM + features.PushBack("asm", allocator); +# endif +# ifdef XMRIG_FEATURE_HTTP + features.PushBack("http", allocator); +# endif +# ifdef XMRIG_FEATURE_LIBCPUID + features.PushBack("cpuid", allocator); +# endif +# ifdef XMRIG_FEATURE_HWLOC + features.PushBack("hwloc", allocator); +# endif +# ifdef XMRIG_FEATURE_TLS + features.PushBack("tls", allocator); +# endif + request.reply().AddMember("features", features, allocator); } for (IApiListener *listener : m_listeners) { diff --git a/src/api/Api.h b/src/api/Api.h index 0c7fac5..716f88f 100644 --- a/src/api/Api.h +++ b/src/api/Api.h @@ -27,6 +27,7 @@ #include +#include #include "base/kernel/interfaces/IBaseListener.h" @@ -70,6 +71,7 @@ private: Base *m_base; char m_id[32]; char m_workerId[128]; + const uint64_t m_timestamp; Httpd *m_httpd; std::vector m_listeners; }; diff --git a/src/api/interfaces/IApiListener.h b/src/api/interfaces/IApiListener.h index 7897e37..bbf153a 100644 --- a/src/api/interfaces/IApiListener.h +++ b/src/api/interfaces/IApiListener.h @@ -35,7 +35,9 @@ class IApiListener public: virtual ~IApiListener() = default; +# ifdef XMRIG_FEATURE_API virtual void onRequest(IApiRequest &request) = 0; +# endif }; diff --git a/src/api/interfaces/IApiRequest.h b/src/api/interfaces/IApiRequest.h index 2c2f563..8e65a92 100644 --- a/src/api/interfaces/IApiRequest.h +++ b/src/api/interfaces/IApiRequest.h @@ -4,7 +4,9 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2018 XMRig + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -50,6 +52,12 @@ public: }; + enum RequestType { + REQ_UNKNOWN, + REQ_SUMMARY + }; + + virtual ~IApiRequest() = default; virtual bool isDone() const = 0; @@ -57,9 +65,11 @@ public: virtual bool isRestricted() const = 0; virtual const rapidjson::Value &json() const = 0; virtual const String &url() const = 0; + virtual int version() const = 0; virtual Method method() const = 0; virtual rapidjson::Document &doc() = 0; virtual rapidjson::Value &reply() = 0; + virtual RequestType type() const = 0; virtual Source source() const = 0; virtual void accept() = 0; virtual void done(int status) = 0; diff --git a/src/api/requests/ApiRequest.cpp b/src/api/requests/ApiRequest.cpp index c092a33..3812e41 100644 --- a/src/api/requests/ApiRequest.cpp +++ b/src/api/requests/ApiRequest.cpp @@ -28,8 +28,7 @@ xmrig::ApiRequest::ApiRequest(Source source, bool restricted) : m_restricted(restricted), - m_source(source), - m_state(STATE_NEW) + m_source(source) { } diff --git a/src/api/requests/ApiRequest.h b/src/api/requests/ApiRequest.h index 1754aa9..05716e2 100644 --- a/src/api/requests/ApiRequest.h +++ b/src/api/requests/ApiRequest.h @@ -43,10 +43,15 @@ protected: inline bool isDone() const override { return m_state == STATE_DONE; } inline bool isNew() const override { return m_state == STATE_NEW; } inline bool isRestricted() const override { return m_restricted; } + inline int version() const override { return m_version; } + inline RequestType type() const override { return m_type; } inline Source source() const override { return m_source; } inline void accept() override { m_state = STATE_ACCEPTED; } inline void done(int) override { m_state = STATE_DONE; } + int m_version = 1; + RequestType m_type = REQ_UNKNOWN; + private: enum State { STATE_NEW, @@ -56,7 +61,7 @@ private: bool m_restricted; Source m_source; - State m_state; + State m_state = STATE_NEW; }; diff --git a/src/api/requests/HttpApiRequest.cpp b/src/api/requests/HttpApiRequest.cpp index e4f2de1..b4dc181 100644 --- a/src/api/requests/HttpApiRequest.cpp +++ b/src/api/requests/HttpApiRequest.cpp @@ -35,6 +35,17 @@ xmrig::HttpApiRequest::HttpApiRequest(const HttpData &req, bool restricted) : m_res(req.id()), m_url(req.url.c_str()) { + if (method() == METHOD_GET) { + if (url() == "/1/summary" || url() == "/2/summary" || url() == "/api.json") { + m_type = REQ_SUMMARY; + } + } + + if (url().size() > 4) { + if (memcmp(url().data(), "/2/", 3) == 0) { + m_version = 2; + } + } } diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp index fa95e6d..e6a0c98 100644 --- a/src/api/v1/ApiRouter.cpp +++ b/src/api/v1/ApiRouter.cpp @@ -82,25 +82,6 @@ void xmrig::ApiRouter::onRequest(IApiRequest &request) request.accept(); getMiners(request.reply(), request.doc()); } - else if (request.url() == "/1/config") { - if (request.isRestricted()) { - return request.done(403); - } - - request.accept(); - m_base->config()->getJSON(request.doc()); - } - } - else if (request.method() == IApiRequest::METHOD_PUT || request.method() == IApiRequest::METHOD_POST) { - if (request.url() == "/1/config") { - request.accept(); - - if (!m_base->reload(request.json())) { - return request.done(400); - } - - request.done(204); - } } } @@ -134,7 +115,6 @@ void xmrig::ApiRouter::getMiner(rapidjson::Value &reply, rapidjson::Document &do reply.AddMember("algo", "invalid", allocator); reply.AddMember("mode", rapidjson::StringRef(m_base->config()->modeName()), allocator); reply.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator); - reply.AddMember("uptime", stats.uptime(), allocator); reply.AddMember("donate_level", m_base->config()->pools().donateLevel(), allocator); if (stats.hashes && stats.donateHashes) { diff --git a/src/base/io/log/Log.cpp b/src/base/io/log/Log.cpp index 22972a7..4e3bd5a 100644 --- a/src/base/io/log/Log.cpp +++ b/src/base/io/log/Log.cpp @@ -31,6 +31,7 @@ #include +#include #include #include #include @@ -69,14 +70,11 @@ public: inline LogPrivate() : m_buf() { - uv_mutex_init(&m_mutex); } inline ~LogPrivate() { - uv_mutex_destroy(&m_mutex); - for (ILogBackend *backend : m_backends) { delete backend; } @@ -91,13 +89,14 @@ public: size_t size = 0; size_t offset = 0; - lock(); + std::lock_guard lock(m_mutex); + timestamp(level, size, offset); color(level, size); const int rc = vsnprintf(m_buf + size, sizeof (m_buf) - offset - 32, fmt, args); if (rc < 0) { - return unlock(); + return; } size += std::min(static_cast(rc), sizeof (m_buf) - offset - 32); @@ -119,16 +118,10 @@ public: fputs(txt.c_str(), stdout); fflush(stdout); } - - unlock(); } private: - inline void lock() { uv_mutex_lock(&m_mutex); } - inline void unlock() { uv_mutex_unlock(&m_mutex); } - - inline void timestamp(Log::Level level, size_t &size, size_t &offset) { if (level == Log::NONE) { @@ -192,8 +185,8 @@ private: char m_buf[4096]; + std::mutex m_mutex; std::vector m_backends; - uv_mutex_t m_mutex; }; diff --git a/src/base/io/log/Log.h b/src/base/io/log/Log.h index 078a854..d8bcb44 100644 --- a/src/base/io/log/Log.h +++ b/src/base/io/log/Log.h @@ -85,6 +85,8 @@ private: #define BLUE_BG_BOLD_S CSI "44;1m" #define MAGENTA_BG_S CSI "45m" #define MAGENTA_BG_BOLD_S CSI "45;1m" +#define CYAN_BG_S CSI "46m" +#define CYAN_BG_BOLD_S CSI "46;1m" //color wrappings #define BLACK(x) BLACK_S x CLEAR @@ -108,6 +110,8 @@ private: #define BLUE_BG_BOLD(x) BLUE_BG_BOLD_S x CLEAR #define MAGENTA_BG(x) MAGENTA_BG_S x CLEAR #define MAGENTA_BG_BOLD(x) MAGENTA_BG_BOLD_S x CLEAR +#define CYAN_BG(x) CYAN_BG_S x CLEAR +#define CYAN_BG_BOLD(x) CYAN_BG_BOLD_S x CLEAR #define LOG_EMERG(x, ...) xmrig::Log::print(xmrig::Log::EMERG, x, ##__VA_ARGS__) diff --git a/src/base/kernel/Entry.cpp b/src/base/kernel/Entry.cpp index da225e4..f9e97c2 100644 --- a/src/base/kernel/Entry.cpp +++ b/src/base/kernel/Entry.cpp @@ -41,6 +41,9 @@ #include "version.h" +namespace xmrig { + + static int showVersion() { printf(APP_NAME " " APP_VERSION "\n built on " __DATE__ @@ -92,6 +95,36 @@ static int showVersion() } +#ifdef XMRIG_FEATURE_HWLOC +static int exportTopology(const Process &process) +{ + const String path = process.location(Process::ExeLocation, "topology.xml"); + + hwloc_topology_t topology; + hwloc_topology_init(&topology); + hwloc_topology_load(topology); + +# if HWLOC_API_VERSION >= 0x20000 + if (hwloc_topology_export_xml(topology, path, 0) == -1) { +# else + if (hwloc_topology_export_xml(topology, path) == -1) { +# endif + printf("failed to export hwloc topology.\n"); + } + else { + printf("hwloc topology successfully exported to \"%s\"\n", path.data()); + } + + hwloc_topology_destroy(topology); + + return 0; +} +#endif + + +} // namespace xmrig + + xmrig::Entry::Id xmrig::Entry::get(const Process &process) { const Arguments &args = process.arguments(); @@ -103,11 +136,17 @@ xmrig::Entry::Id xmrig::Entry::get(const Process &process) return Version; } +# ifdef XMRIG_FEATURE_HWLOC + if (args.hasArg("--export-topology")) { + return Topo; + } +# endif + return Default; } -int xmrig::Entry::exec(const Process &, Id id) +int xmrig::Entry::exec(const Process &process, Id id) { switch (id) { case Usage: @@ -117,6 +156,11 @@ int xmrig::Entry::exec(const Process &, Id id) case Version: return showVersion(); +# ifdef XMRIG_FEATURE_HWLOC + case Topo: + return exportTopology(process); +# endif + default: break; } diff --git a/src/base/kernel/Entry.h b/src/base/kernel/Entry.h index 0208ecd..c0bde08 100644 --- a/src/base/kernel/Entry.h +++ b/src/base/kernel/Entry.h @@ -38,7 +38,8 @@ public: enum Id { Default, Usage, - Version + Version, + Topo }; static Id get(const Process &process); diff --git a/src/base/net/stratum/Job.cpp b/src/base/net/stratum/Job.cpp index a383bbf..04bd82d 100644 --- a/src/base/net/stratum/Job.cpp +++ b/src/base/net/stratum/Job.cpp @@ -160,3 +160,27 @@ void xmrig::Job::setDiff(uint64_t diff) m_rawTarget[16] = '\0'; # endif } + + +void xmrig::Job::copy(const Job &other) +{ + m_algorithm = other.m_algorithm; + m_nicehash = other.m_nicehash; + m_size = other.m_size; + m_clientId = other.m_clientId; + m_id = other.m_id; + m_diff = other.m_diff; + m_height = other.m_height; + m_target = other.m_target; + m_index = other.m_index; + + memcpy(m_blob, other.m_blob, sizeof(m_blob)); + memcpy(m_seedHash, other.m_seedHash, sizeof(m_seedHash)); + +# ifdef XMRIG_PROXY_PROJECT + m_rawSeedHash = other.m_rawSeedHash; + + memcpy(m_rawBlob, other.m_rawBlob, sizeof(m_rawBlob)); + memcpy(m_rawTarget, other.m_rawTarget, sizeof(m_rawTarget)); +# endif +} diff --git a/src/base/net/stratum/Job.h b/src/base/net/stratum/Job.h index 06d1be7..2b256a1 100644 --- a/src/base/net/stratum/Job.h +++ b/src/base/net/stratum/Job.h @@ -90,10 +90,13 @@ public: inline bool operator==(const Job &other) const { return isEqual(other); } inline bool operator!=(const Job &other) const { return !isEqual(other); } + inline Job &operator=(const Job &other) { copy(other); return *this; } private: + void copy(const Job &other); + Algorithm m_algorithm; - bool m_nicehash = false; + bool m_nicehash = false; size_t m_size = 0; String m_clientId; String m_id; diff --git a/src/base/tools/Buffer.h b/src/base/tools/Buffer.h index 6b72035..28f92b9 100644 --- a/src/base/tools/Buffer.h +++ b/src/base/tools/Buffer.h @@ -43,17 +43,20 @@ public: ~Buffer(); - inline char *data() { return m_data; } - inline const char *data() const { return m_data; } - inline size_t size() const { return m_size; } - inline void from(const Buffer &other) { from(other.data(), other.size()); } + inline bool isEqual(const Buffer &other) const { return m_size == other.m_size && (m_size == 0 || memcmp(m_data, other.m_data, m_size) == 0); } + inline char *data() { return m_data; } + inline const char *data() const { return m_data; } + inline size_t size() const { return m_size; } + inline void from(const Buffer &other) { from(other.data(), other.size()); } void from(const char *data, size_t size); - inline Buffer &operator=(const Buffer &other) { from(other); return *this; } - inline Buffer &operator=(Buffer &&other) { move(std::move(other)); return *this; } + inline bool operator!=(const Buffer &other) const { return !isEqual(other); } + inline bool operator==(const Buffer &other) const { return isEqual(other); } + inline Buffer &operator=(Buffer &&other) { move(std::move(other)); return *this; } + inline Buffer &operator=(const Buffer &other) { from(other); return *this; } static Buffer allocUnsafe(size_t size); diff --git a/src/proxy/Login.cpp b/src/proxy/Login.cpp index e5fca15..14771d4 100644 --- a/src/proxy/Login.cpp +++ b/src/proxy/Login.cpp @@ -75,7 +75,7 @@ bool xmrig::Login::verifyAlgorithms(LoginEvent *event) // } // } - return false; + return true; } diff --git a/src/proxy/Miner.cpp b/src/proxy/Miner.cpp index 5fdb6b6..2b3073b 100644 --- a/src/proxy/Miner.cpp +++ b/src/proxy/Miner.cpp @@ -241,15 +241,7 @@ bool xmrig::Miner::parseRequest(int64_t id, const char *method, const rapidjson: return true; } - Algorithm algorithm; - if (params.HasMember("algo")) { -// const char *algo = Json::getString(params, "algo"); - -// algorithm.parseAlgorithm(algo); FIXME -// if (!algorithm.isValid()) { -// algorithm.parseXmrStakAlgorithm(algo); -// } - } + Algorithm algorithm(Json::getString(params, "algo")); SubmitEvent *event = SubmitEvent::create(this, id, Json::getString(params, "job_id"), Json::getString(params, "nonce"), Json::getString(params, "result"), algorithm); diff --git a/src/proxy/Stats.cpp b/src/proxy/Stats.cpp index b016d9a..a0b8423 100644 --- a/src/proxy/Stats.cpp +++ b/src/proxy/Stats.cpp @@ -34,7 +34,6 @@ xmrig::Stats::Stats() : m_hashrate(4) { - m_data.startTime = uv_now(uv_default_loop()); } @@ -56,7 +55,7 @@ void xmrig::Stats::tick(uint64_t ticks, const ISplitter *splitter) m_data.hashrate[2] = hashrate(3600); m_data.hashrate[3] = hashrate(3600 * 12); m_data.hashrate[4] = hashrate(3600 * 24); - m_data.hashrate[5] = hashrate(m_data.uptime()); + m_data.hashrate[5] = hashrate(static_cast(m_data.uptime())); m_data.upstreams = splitter->upstreams(); m_data.miners = Counters::miners(); diff --git a/src/proxy/StatsData.h b/src/proxy/StatsData.h index 0b3040f..acd121d 100644 --- a/src/proxy/StatsData.h +++ b/src/proxy/StatsData.h @@ -28,11 +28,11 @@ #include #include -#include #include -#include "interfaces/ISplitter.h" +#include "base/tools/Chrono.h" +#include "proxy/interfaces/ISplitter.h" namespace xmrig { @@ -41,18 +41,9 @@ namespace xmrig { class StatsData { public: - inline StatsData() : - accepted(0), - connections(0), - donateHashes(0), - expired(0), - hashes(0), - invalid(0), - maxMiners(0), - miners(0), - rejected(0), - startTime(0) + inline StatsData() { + startTime = Chrono::currentMSecsSinceEpoch(); } @@ -80,29 +71,25 @@ public: } - inline int uptime() const + inline uint64_t uptime() const { - if (startTime == 0) { - return 0; - } - - return (uv_now(uv_default_loop()) - startTime) / 1000; + return (Chrono::currentMSecsSinceEpoch() - startTime) / 1000; } double hashrate[6] { 0.0 }; std::array topDiff { { } }; std::vector latency; - uint64_t accepted; - uint64_t connections; - uint64_t donateHashes; - uint64_t expired; - uint64_t hashes; - uint64_t invalid; - uint64_t maxMiners; - uint64_t miners; - uint64_t rejected; - uint64_t startTime; + uint64_t accepted = 0; + uint64_t connections = 0; + uint64_t donateHashes = 0; + uint64_t expired = 0; + uint64_t hashes = 0; + uint64_t invalid = 0; + uint64_t maxMiners = 0; + uint64_t miners = 0; + uint64_t rejected = 0; + uint64_t startTime = 0; Upstreams upstreams; };