From d9164c0b7bc30dd8d6bf3dbfdd442f9fde87c13d Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 19 Jul 2019 02:24:37 +0700 Subject: [PATCH] Restored "GET /1/summary" endpoint. --- src/api/Api.cpp | 10 +-- 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 | 70 +----------------- src/api/v1/ApiRouter.h | 4 +- src/backend/common/Hashrate.cpp | 15 +++- src/backend/common/Hashrate.h | 4 + src/core/Miner.cpp | 111 ++++++++++++++++++++++++++++ src/core/Miner.h | 7 +- src/net/Network.cpp | 42 ++++++----- src/net/Network.h | 9 ++- 14 files changed, 199 insertions(+), 108 deletions(-) diff --git a/src/api/Api.cpp b/src/api/Api.cpp index a1aeb4c2d..11fc2a69b 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -120,7 +120,7 @@ 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(); @@ -145,14 +145,6 @@ void xmrig::Api::exec(IApiRequest &request) features.PushBack("tls", allocator); # endif request.reply().AddMember("features", features, allocator); - - Value algorithms(kArrayType); - - for (int i = 0; i < Algorithm::MAX; ++i) { - algorithms.PushBack(StringRef(Algorithm(static_cast(i)).shortName()), allocator); - } - - request.reply().AddMember("algorithms", algorithms, allocator); } for (IApiListener *listener : m_listeners) { diff --git a/src/api/interfaces/IApiListener.h b/src/api/interfaces/IApiListener.h index 7897e3755..bbf153a69 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 2c2f56344..8e65a9215 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 c092a3340..3812e4198 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 1754aa9c6..05716e29d 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 e4f2de1e5..b4dc18107 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 2a5bd3d0e..0e1080a18 100644 --- a/src/api/v1/ApiRouter.cpp +++ b/src/api/v1/ApiRouter.cpp @@ -38,18 +38,6 @@ #include "version.h" -static inline rapidjson::Value normalize(double d) -{ - using namespace rapidjson; - - if (!std::isnormal(d)) { - return Value(kNullType); - } - - return Value(floor(d * 100.0) / 100.0); -} - - xmrig::ApiRouter::ApiRouter(Base *base) : m_base(base) { @@ -64,12 +52,7 @@ xmrig::ApiRouter::~ApiRouter() void xmrig::ApiRouter::onRequest(IApiRequest &request) { if (request.method() == IApiRequest::METHOD_GET) { - if (request.url() == "/1/summary" || request.url() == "/api.json") { - request.accept(); - getMiner(request.reply(), request.doc()); -// getHashrate(request.reply(), request.doc()); - } - else if (request.url() == "/1/threads") { + if (request.url() == "/1/threads") { request.accept(); getThreads(request.reply(), request.doc()); } @@ -96,57 +79,6 @@ void xmrig::ApiRouter::onRequest(IApiRequest &request) } -//void xmrig::ApiRouter::getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const -//{ -// using namespace rapidjson; -// auto &allocator = doc.GetAllocator(); - -// Value hashrate(kObjectType); -// Value total(kArrayType); -// Value threads(kArrayType); - -// const Hashrate *hr = WorkersLegacy::hashrate(); - -// total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator); -// total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator); -// total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator); - -// for (size_t i = 0; i < WorkersLegacy::threads(); i++) { -// Value thread(kArrayType); -// thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); -// thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); -// thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); - -// threads.PushBack(thread, allocator); -// } - -// hashrate.AddMember("total", total, allocator); -// hashrate.AddMember("highest", normalize(hr->highest()), allocator); -// hashrate.AddMember("threads", threads, allocator); -// reply.AddMember("hashrate", hashrate, allocator); -//} - - -void xmrig::ApiRouter::getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const -{ - using namespace rapidjson; - auto &allocator = doc.GetAllocator(); - - Value cpu(kObjectType); - cpu.AddMember("brand", StringRef(Cpu::info()->brand()), allocator); - cpu.AddMember("aes", Cpu::info()->hasAES(), allocator); - cpu.AddMember("x64", Cpu::info()->isX64(), allocator); - cpu.AddMember("sockets", Cpu::info()->sockets(), allocator); - - reply.AddMember("version", APP_VERSION, allocator); - reply.AddMember("kind", APP_KIND, allocator); - reply.AddMember("ua", StringRef(Platform::userAgent()), allocator); - reply.AddMember("cpu", cpu, allocator); - reply.AddMember("hugepages", false, allocator); // FIXME hugepages - reply.AddMember("donate_level", m_base->config()->pools().donateLevel(), allocator); -} - - void xmrig::ApiRouter::getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const { // using namespace rapidjson; diff --git a/src/api/v1/ApiRouter.h b/src/api/v1/ApiRouter.h index e2b9bd256..ec468d860 100644 --- a/src/api/v1/ApiRouter.h +++ b/src/api/v1/ApiRouter.h @@ -39,7 +39,7 @@ namespace xmrig { class Base; -class ApiRouter : public xmrig::IApiListener +class ApiRouter : public IApiListener { public: ApiRouter(Base *base); @@ -49,8 +49,6 @@ protected: void onRequest(IApiRequest &request) override; private: -// void getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const; - void getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const; void getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const; Base *m_base; diff --git a/src/backend/common/Hashrate.cpp b/src/backend/common/Hashrate.cpp index 6ffd45b77..a9c63733f 100644 --- a/src/backend/common/Hashrate.cpp +++ b/src/backend/common/Hashrate.cpp @@ -29,9 +29,10 @@ #include +#include "backend/common/Hashrate.h" #include "base/tools/Chrono.h" #include "base/tools/Handle.h" -#include "backend/common/Hashrate.h" +#include "rapidjson/document.h" inline static const char *format(double h, char *buf, size_t size) @@ -162,3 +163,15 @@ const char *xmrig::Hashrate::format(double h, char *buf, size_t size) { return ::format(h, buf, size); } + + +rapidjson::Value xmrig::Hashrate::normalize(double d) +{ + using namespace rapidjson; + + if (!std::isnormal(d)) { + return Value(kNullType); + } + + return Value(floor(d * 100.0) / 100.0); +} diff --git a/src/backend/common/Hashrate.h b/src/backend/common/Hashrate.h index 2187c0bed..0674c6aba 100644 --- a/src/backend/common/Hashrate.h +++ b/src/backend/common/Hashrate.h @@ -30,6 +30,9 @@ #include +#include "rapidjson/fwd.h" + + namespace xmrig { @@ -53,6 +56,7 @@ public: inline size_t threads() const { return m_threads; } static const char *format(double h, char *buf, size_t size); + static rapidjson::Value normalize(double d); private: constexpr static size_t kBucketSize = 2 << 11; diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index b64d6b95e..7114baf9e 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -28,14 +28,24 @@ #include "backend/common/Hashrate.h" +#include "backend/cpu/Cpu.h" #include "backend/cpu/CpuBackend.h" #include "base/io/log/Log.h" +#include "base/kernel/Platform.h" #include "base/net/stratum/Job.h" #include "base/tools/Timer.h" #include "core/config/Config.h" #include "core/Controller.h" #include "core/Miner.h" #include "crypto/common/Nonce.h" +#include "rapidjson/document.h" +#include "version.h" + + +#ifdef XMRIG_FEATURE_API +# include "api/Api.h" +# include "api/interfaces/IApiRequest.h" +#endif namespace xmrig { @@ -114,6 +124,90 @@ public: } +# ifdef XMRIG_FEATURE_API + void getMiner(rapidjson::Value &reply, rapidjson::Document &doc, int version) const + { + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Value cpu(kObjectType); + cpu.AddMember("brand", StringRef(Cpu::info()->brand()), allocator); + cpu.AddMember("aes", Cpu::info()->hasAES(), allocator); + cpu.AddMember("x64", Cpu::info()->isX64(), allocator); + cpu.AddMember("sockets", Cpu::info()->sockets(), allocator); + + reply.AddMember("version", APP_VERSION, allocator); + reply.AddMember("kind", APP_KIND, allocator); + reply.AddMember("ua", StringRef(Platform::userAgent()), allocator); + reply.AddMember("cpu", cpu, allocator); + + if (version == 1) { + reply.AddMember("hugepages", false, allocator); + } + + reply.AddMember("donate_level", controller->config()->pools().donateLevel(), allocator); + + Value algo(kArrayType); + + for (const Algorithm &a : algorithms) { + algo.PushBack(StringRef(a.shortName()), allocator); + } + + reply.AddMember("algorithms", algo, allocator); + } + + + void getHashrate(rapidjson::Value &reply, rapidjson::Document &doc, int version) const + { + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Value hashrate(kObjectType); + Value total(kArrayType); + Value threads(kArrayType); + + double t[3] = { 0.0 }; + + for (IBackend *backend : backends) { + const Hashrate *hr = backend->hashrate(); + if (!hr) { + continue; + } + + t[0] += hr->calc(Hashrate::ShortInterval); + t[1] += hr->calc(Hashrate::MediumInterval); + t[2] += hr->calc(Hashrate::LargeInterval); + + if (version > 1) { + continue; + } + + for (size_t i = 0; i < hr->threads(); i++) { + Value thread(kArrayType); + thread.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); + thread.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); + thread.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); + + threads.PushBack(thread, allocator); + } + } + + total.PushBack(Hashrate::normalize(t[0]), allocator); + total.PushBack(Hashrate::normalize(t[1]), allocator); + total.PushBack(Hashrate::normalize(t[2]), allocator); + + hashrate.AddMember("total", total, allocator); + hashrate.AddMember("highest", Hashrate::normalize(maxHashrate), allocator); + + if (version == 1) { + hashrate.AddMember("threads", threads, allocator); + } + + reply.AddMember("hashrate", hashrate, allocator); + } +# endif + + Algorithms algorithms; bool active = false; bool enabled = true; @@ -137,6 +231,10 @@ xmrig::Miner::Miner(Controller *controller) { controller->addListener(this); +# ifdef XMRIG_FEATURE_API + controller->api()->addListener(this); +# endif + d_ptr->timer = new Timer(this); d_ptr->backends.push_back(new CpuBackend(controller)); @@ -309,3 +407,16 @@ void xmrig::Miner::onTimer(const Timer *) d_ptr->ticks++; } + + +#ifdef XMRIG_FEATURE_API +void xmrig::Miner::onRequest(IApiRequest &request) +{ + if (request.type() == IApiRequest::REQ_SUMMARY) { + request.accept(); + + d_ptr->getMiner(request.reply(), request.doc(), request.version()); + d_ptr->getHashrate(request.reply(), request.doc(), request.version()); + } +} +#endif diff --git a/src/core/Miner.h b/src/core/Miner.h index 333f9250c..035c02058 100644 --- a/src/core/Miner.h +++ b/src/core/Miner.h @@ -29,6 +29,7 @@ #include +#include "api/interfaces/IApiListener.h" #include "base/kernel/interfaces/IBaseListener.h" #include "base/kernel/interfaces/ITimerListener.h" #include "crypto/common/Algorithm.h" @@ -43,7 +44,7 @@ class MinerPrivate; class IBackend; -class Miner : public ITimerListener, public IBaseListener +class Miner : public ITimerListener, public IBaseListener, public IApiListener { public: Miner(Controller *controller); @@ -64,6 +65,10 @@ protected: void onConfigChanged(Config *config, Config *previousConfig) override; void onTimer(const Timer *timer) override; +# ifdef XMRIG_FEATURE_API + void onRequest(IApiRequest &request) override; +# endif + private: MinerPrivate *d_ptr; }; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index eaff6748c..5ee003883 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -185,19 +185,6 @@ void xmrig::Network::onPause(IStrategy *strategy) } -void xmrig::Network::onRequest(IApiRequest &request) -{ -# ifdef XMRIG_FEATURE_API - if (request.method() == IApiRequest::METHOD_GET && (request.url() == "/1/summary" || request.url() == "/api.json")) { - request.accept(); - - getResults(request.reply(), request.doc()); - getConnection(request.reply(), request.doc()); - } -# endif -} - - void xmrig::Network::onResultAccepted(IStrategy *, IClient *, const SubmitResult &result, const char *error) { m_state.add(result, error); @@ -223,6 +210,19 @@ void xmrig::Network::onVerifyAlgorithm(IStrategy *, const IClient *, const Algor } +#ifdef XMRIG_FEATURE_API +void xmrig::Network::onRequest(IApiRequest &request) +{ + if (request.type() == IApiRequest::REQ_SUMMARY) { + request.accept(); + + getResults(request.reply(), request.doc(), request.version()); + getConnection(request.reply(), request.doc(), request.version()); + } +} +#endif + + void xmrig::Network::setJob(IClient *client, const Job &job, bool donate) { if (job.height()) { @@ -256,7 +256,7 @@ void xmrig::Network::tick() #ifdef XMRIG_FEATURE_API -void xmrig::Network::getConnection(rapidjson::Value &reply, rapidjson::Document &doc) const +void xmrig::Network::getConnection(rapidjson::Value &reply, rapidjson::Document &doc, int version) const { using namespace rapidjson; auto &allocator = doc.GetAllocator(); @@ -271,13 +271,16 @@ void xmrig::Network::getConnection(rapidjson::Value &reply, rapidjson::Document connection.AddMember("failures", m_state.failures, allocator); connection.AddMember("tls", m_state.tls().toJSON(), allocator); connection.AddMember("tls-fingerprint", m_state.fingerprint().toJSON(), allocator); - connection.AddMember("error_log", Value(kArrayType), allocator); + + if (version == 1) { + connection.AddMember("error_log", Value(kArrayType), allocator); + } reply.AddMember("connection", connection, allocator); } -void xmrig::Network::getResults(rapidjson::Value &reply, rapidjson::Document &doc) const +void xmrig::Network::getResults(rapidjson::Value &reply, rapidjson::Document &doc, int version) const { using namespace rapidjson; auto &allocator = doc.GetAllocator(); @@ -295,8 +298,11 @@ void xmrig::Network::getResults(rapidjson::Value &reply, rapidjson::Document &do best.PushBack(m_state.topDiff[i], allocator); } - results.AddMember("best", best, allocator); - results.AddMember("error_log", Value(kArrayType), allocator); + results.AddMember("best", best, allocator); + + if (version == 1) { + results.AddMember("error_log", Value(kArrayType), allocator); + } reply.AddMember("results", results, allocator); } diff --git a/src/net/Network.h b/src/net/Network.h index 689677135..ddf6d6f39 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -65,10 +65,13 @@ protected: void onJobResult(const JobResult &result) override; void onLogin(IStrategy *strategy, IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) override; void onPause(IStrategy *strategy) override; - void onRequest(IApiRequest &request) override; void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) override; void onVerifyAlgorithm(IStrategy *strategy, const IClient *client, const Algorithm &algorithm, bool *ok) override; +# ifdef XMRIG_FEATURE_API + void onRequest(IApiRequest &request) override; +# endif + private: constexpr static int kTickInterval = 1 * 1000; @@ -76,8 +79,8 @@ private: void tick(); # ifdef XMRIG_FEATURE_API - void getConnection(rapidjson::Value &reply, rapidjson::Document &doc) const; - void getResults(rapidjson::Value &reply, rapidjson::Document &doc) const; + void getConnection(rapidjson::Value &reply, rapidjson::Document &doc, int version) const; + void getResults(rapidjson::Value &reply, rapidjson::Document &doc, int version) const; # endif Controller *m_controller;