diff --git a/CMakeLists.txt b/CMakeLists.txt index 57df6d59c..dc8a82d8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ include (src/base/base.cmake) set(HEADERS "${HEADERS_BASE}" "${HEADERS_BASE_HTTP}" - src/api/NetworkState.h + src/api/interfaces/IApiListener.h src/App.h src/common/config/CommonConfig.h src/common/config/ConfigLoader.h @@ -45,13 +45,14 @@ set(HEADERS src/Mem.h src/net/JobResult.h src/net/Network.h + src/net/NetworkState.h src/net/strategies/DonateStrategy.h src/Summary.h src/version.h src/workers/CpuThread.h - src/workers/ThreadHandle.h src/workers/Hashrate.h src/workers/MultiWorker.h + src/workers/ThreadHandle.h src/workers/Worker.h src/workers/Workers.h ) @@ -81,7 +82,6 @@ endif() set(SOURCES "${SOURCES_BASE}" "${SOURCES_BASE_HTTP}" - src/api/NetworkState.cpp src/App.cpp src/common/config/CommonConfig.cpp src/common/config/ConfigLoader.cpp @@ -93,12 +93,13 @@ set(SOURCES src/core/Controller.cpp src/Mem.cpp src/net/Network.cpp + src/net/NetworkState.cpp src/net/strategies/DonateStrategy.cpp src/Summary.cpp src/workers/CpuThread.cpp - src/workers/ThreadHandle.cpp src/workers/Hashrate.cpp src/workers/MultiWorker.cpp + src/workers/ThreadHandle.cpp src/workers/Worker.cpp src/workers/Workers.cpp src/xmrig.cpp diff --git a/src/api/Api.cpp b/src/api/Api.cpp index 013090021..c9f0fd9ab 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -28,6 +28,7 @@ #include "3rdparty/http-parser/http_parser.h" #include "api/Api.h" +#include "api/interfaces/IApiListener.h" #include "api/requests/HttpApiRequest.h" #include "base/tools/Buffer.h" #include "common/crypto/keccak.h" @@ -102,9 +103,15 @@ void xmrig::Api::onConfigChanged(Config *config, Config *previousConfig) void xmrig::Api::exec(IApiRequest &request) { - if (request.isNew()) { - request.done(HTTP_STATUS_NOT_FOUND); + for (IApiListener *listener : m_listeners) { + listener->onRequest(request); + + if (request.isDone()) { + return; + } } + + request.done(request.isNew() ? HTTP_STATUS_NOT_FOUND : HTTP_STATUS_OK); } diff --git a/src/api/Api.h b/src/api/Api.h index 04d923939..dc4e8e212 100644 --- a/src/api/Api.h +++ b/src/api/Api.h @@ -26,6 +26,9 @@ #define XMRIG_API_H +#include + + #include "base/kernel/interfaces/IControllerListener.h" @@ -35,6 +38,7 @@ namespace xmrig { class Controller; class Httpd; class HttpRequest; +class IApiListener; class IApiRequest; class String; @@ -45,8 +49,9 @@ public: Api(Controller *controller); ~Api() override; - inline const char *id() const { return m_id; } - inline const char *workerId() const { return m_workerId; } + inline const char *id() const { return m_id; } + inline const char *workerId() const { return m_workerId; } + inline void addListener(IApiListener *listener) { m_listeners.push_back(listener); } void request(const HttpRequest &req); void start(); @@ -64,6 +69,7 @@ private: char m_workerId[128]; Controller *m_controller; Httpd *m_httpd; + std::vector m_listeners; }; diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 20752f0c4..30597f46c 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -102,8 +102,6 @@ void ApiRouter::ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply & getIdentify(doc); getMiner(doc); getHashrate(doc); - getResults(doc); - getConnection(doc); return finalize(reply, doc); } @@ -120,12 +118,6 @@ void ApiRouter::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) } -void ApiRouter::tick(const xmrig::NetworkState &network) -{ - m_network = network; -} - - void ApiRouter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) { updateWorkerId(config->apiWorkerId(), previousConfig->apiWorkerId()); @@ -185,21 +177,6 @@ void ApiRouter::genId(const char *id) } -void ApiRouter::getConnection(rapidjson::Document &doc) const -{ - auto &allocator = doc.GetAllocator(); - - rapidjson::Value connection(rapidjson::kObjectType); - connection.AddMember("pool", rapidjson::StringRef(m_network.pool), allocator); - connection.AddMember("uptime", m_network.connectionTime(), allocator); - connection.AddMember("ping", m_network.latency(), allocator); - connection.AddMember("failures", m_network.failures, allocator); - connection.AddMember("error_log", rapidjson::Value(rapidjson::kArrayType), allocator); - - doc.AddMember("connection", connection, allocator); -} - - void ApiRouter::getHashrate(rapidjson::Document &doc) const { auto &allocator = doc.GetAllocator(); @@ -258,30 +235,6 @@ void ApiRouter::getMiner(rapidjson::Document &doc) const } -void ApiRouter::getResults(rapidjson::Document &doc) const -{ - auto &allocator = doc.GetAllocator(); - - rapidjson::Value results(rapidjson::kObjectType); - - results.AddMember("diff_current", m_network.diff, allocator); - results.AddMember("shares_good", m_network.accepted, allocator); - results.AddMember("shares_total", m_network.accepted + m_network.rejected, allocator); - results.AddMember("avg_time", m_network.avgTime(), allocator); - results.AddMember("hashes_total", m_network.total, allocator); - - rapidjson::Value best(rapidjson::kArrayType); - for (size_t i = 0; i < m_network.topDiff.size(); ++i) { - best.PushBack(m_network.topDiff[i], allocator); - } - - results.AddMember("best", best, allocator); - results.AddMember("error_log", rapidjson::Value(rapidjson::kArrayType), allocator); - - doc.AddMember("results", results, allocator); -} - - void ApiRouter::getThreads(rapidjson::Document &doc) const { doc.SetObject(); diff --git a/src/api/ApiRouter.h b/src/api/ApiRouter.h index 61c052018..fd9baea8a 100644 --- a/src/api/ApiRouter.h +++ b/src/api/ApiRouter.h @@ -50,26 +50,21 @@ public: void get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const; void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply); - void tick(const xmrig::NetworkState &results); - protected: void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override; private: void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const; void genId(const char *id); - void getConnection(rapidjson::Document &doc) const; void getHashrate(rapidjson::Document &doc) const; void getIdentify(rapidjson::Document &doc) const; void getMiner(rapidjson::Document &doc) const; - void getResults(rapidjson::Document &doc) const; void getThreads(rapidjson::Document &doc) const; void setWorkerId(const char *id); void updateWorkerId(const char *id, const char *previousId); char m_id[32]; char m_workerId[128]; - xmrig::NetworkState m_network; xmrig::Controller *m_controller; }; diff --git a/src/api/interfaces/IApiListener.h b/src/api/interfaces/IApiListener.h new file mode 100644 index 000000000..7897e3755 --- /dev/null +++ b/src/api/interfaces/IApiListener.h @@ -0,0 +1,45 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2018 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_IAPILISTENER_H +#define XMRIG_IAPILISTENER_H + + +namespace xmrig { + + +class IApiRequest; + + +class IApiListener +{ +public: + virtual ~IApiListener() = default; + + virtual void onRequest(IApiRequest &request) = 0; +}; + + +} /* namespace xmrig */ + + +#endif // XMRIG_IAPILISTENER_H diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 7f3f81d3f..fa0d00a4e 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -41,9 +41,16 @@ #include "core/Controller.h" #include "net/Network.h" #include "net/strategies/DonateStrategy.h" +#include "rapidjson/document.h" #include "workers/Workers.h" +#ifdef XMRIG_FEATURE_API +# include "api/Api.h" +# include "api/interfaces/IApiRequest.h" +#endif + + xmrig::Network::Network(Controller *controller) : m_donate(nullptr), m_timer(nullptr) @@ -51,6 +58,10 @@ xmrig::Network::Network(Controller *controller) : Workers::setListener(this); controller->addListener(this); +# ifdef XMRIG_FEATURE_API + controller->api()->addListener(this); +# endif + const Pools &pools = controller->config()->pools(); m_strategy = pools.createStrategy(this); @@ -152,6 +163,19 @@ 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.accept(); + + getResults(request.reply(), request.doc()); + getConnection(request.reply(), request.doc()); + } +# endif +} + + void xmrig::Network::onResultAccepted(IStrategy *, Client *, const SubmitResult &result, const char *error) { m_state.add(result, error); @@ -196,8 +220,47 @@ void xmrig::Network::tick() if (m_donate) { m_donate->tick(now); } - -# ifdef XMRIG_FEATURE_API - //Api::tick(m_state); -# endif } + + +#ifdef XMRIG_FEATURE_API +void xmrig::Network::getConnection(rapidjson::Value &reply, rapidjson::Document &doc) const +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Value connection(kObjectType); + connection.AddMember("pool", StringRef(m_state.pool), allocator); + connection.AddMember("uptime", m_state.connectionTime(), allocator); + connection.AddMember("ping", m_state.latency(), allocator); + connection.AddMember("failures", m_state.failures, allocator); + connection.AddMember("error_log", Value(kArrayType), allocator); + + reply.AddMember("connection", connection, allocator); +} + + +void xmrig::Network::getResults(rapidjson::Value &reply, rapidjson::Document &doc) const +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Value results(kObjectType); + + results.AddMember("diff_current", m_state.diff, allocator); + results.AddMember("shares_good", m_state.accepted, allocator); + results.AddMember("shares_total", m_state.accepted + m_state.rejected, allocator); + results.AddMember("avg_time", m_state.avgTime(), allocator); + results.AddMember("hashes_total", m_state.total, allocator); + + Value best(kArrayType); + for (size_t i = 0; i < m_state.topDiff.size(); ++i) { + best.PushBack(m_state.topDiff[i], allocator); + } + + results.AddMember("best", best, allocator); + results.AddMember("error_log", Value(kArrayType), allocator); + + reply.AddMember("results", results, allocator); +} +#endif diff --git a/src/net/Network.h b/src/net/Network.h index 9fa7564d2..09e7c815f 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -29,11 +29,13 @@ #include -#include "api/NetworkState.h" +#include "api/interfaces/IApiListener.h" #include "base/kernel/interfaces/IControllerListener.h" #include "base/kernel/interfaces/IStrategyListener.h" #include "base/kernel/interfaces/ITimerListener.h" #include "interfaces/IJobResultListener.h" +#include "net/NetworkState.h" +#include "rapidjson/fwd.h" namespace xmrig { @@ -43,7 +45,7 @@ class Controller; class IStrategy; -class Network : public IJobResultListener, public IStrategyListener, public IControllerListener, public ITimerListener +class Network : public IJobResultListener, public IStrategyListener, public IControllerListener, public ITimerListener, public IApiListener { public: Network(Controller *controller); @@ -61,6 +63,7 @@ protected: void onJob(IStrategy *strategy, Client *client, const Job &job) override; void onJobResult(const JobResult &result) override; void onPause(IStrategy *strategy) override; + void onRequest(IApiRequest &request) override; void onResultAccepted(IStrategy *strategy, Client *client, const SubmitResult &result, const char *error) override; private: @@ -69,6 +72,11 @@ private: void setJob(Client *client, const Job &job, bool donate); void tick(); +# ifdef XMRIG_FEATURE_API + void getConnection(rapidjson::Value &reply, rapidjson::Document &doc) const; + void getResults(rapidjson::Value &reply, rapidjson::Document &doc) const; +# endif + IStrategy *m_donate; IStrategy *m_strategy; NetworkState m_state; diff --git a/src/api/NetworkState.cpp b/src/net/NetworkState.cpp similarity index 98% rename from src/api/NetworkState.cpp rename to src/net/NetworkState.cpp index 8a541eaa5..df248602a 100644 --- a/src/api/NetworkState.cpp +++ b/src/net/NetworkState.cpp @@ -29,9 +29,9 @@ #include -#include "api/NetworkState.h" #include "base/net/stratum/SubmitResult.h" #include "base/tools/Chrono.h" +#include "net/NetworkState.h" xmrig::NetworkState::NetworkState() : diff --git a/src/api/NetworkState.h b/src/net/NetworkState.h similarity index 100% rename from src/api/NetworkState.h rename to src/net/NetworkState.h