From fa2a0b9b7911ec02c18bde7fbd875f031f449b5b Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 5 Apr 2019 22:14:01 +0700 Subject: [PATCH] New config subsystem --- CMakeLists.txt | 13 +- src/api/Api.cpp | 19 +- src/api/Api.h | 10 +- src/api/Httpd.cpp | 14 +- src/api/Httpd.h | 10 +- src/api/v1/ApiRouter.cpp | 16 +- src/api/v1/ApiRouter.h | 6 +- src/base/base.cmake | 13 +- src/base/io/Json.cpp | 46 ++ src/base/io/Json.h | 26 ++ src/base/io/JsonChain.cpp | 201 +++++++++ src/base/io/JsonChain.h | 74 +++ src/base/io/Json_win.cpp | 2 +- src/base/kernel/Base.cpp | 283 ++++++++++++ .../ConfigWatcher.cpp => base/kernel/Base.h} | 68 +-- src/base/kernel/config/BaseConfig.cpp | 195 ++++++++ .../kernel/config/BaseConfig.h} | 54 +-- src/base/kernel/config/BaseTransform.cpp | 255 +++++++++++ src/base/kernel/config/BaseTransform.h | 123 +++++ ...{IControllerListener.h => IBaseListener.h} | 10 +- .../kernel}/interfaces/IConfig.h | 23 +- .../kernel/interfaces/IConfigTransform.h} | 29 +- .../kernel/interfaces/IJsonReader.h} | 45 +- src/base/net/stratum/Pools.cpp | 33 +- src/base/net/stratum/Pools.h | 14 - src/common/config/CommonConfig.cpp | 426 ------------------ src/common/config/ConfigLoader.cpp | 262 ----------- src/common/crypto/Algorithm.cpp | 2 +- src/core/Controller.cpp | 167 +------ src/core/Controller.h | 28 +- src/core/config/Config.cpp | 196 +++----- src/core/config/Config.h | 25 +- src/core/config/ConfigTransform.cpp | 106 +++++ src/core/config/ConfigTransform.h | 51 +++ ...onfigLoader_default.h => Config_default.h} | 9 +- ...figLoader_platform.h => Config_platform.h} | 24 +- src/net/Network.h | 4 +- 37 files changed, 1628 insertions(+), 1254 deletions(-) create mode 100644 src/base/io/JsonChain.cpp create mode 100644 src/base/io/JsonChain.h create mode 100644 src/base/kernel/Base.cpp rename src/{common/config/ConfigWatcher.cpp => base/kernel/Base.h} (62%) create mode 100644 src/base/kernel/config/BaseConfig.cpp rename src/{common/config/CommonConfig.h => base/kernel/config/BaseConfig.h} (71%) create mode 100644 src/base/kernel/config/BaseTransform.cpp create mode 100644 src/base/kernel/config/BaseTransform.h rename src/base/kernel/interfaces/{IControllerListener.h => IBaseListener.h} (88%) rename src/{common => base/kernel}/interfaces/IConfig.h (85%) rename src/{common/config/ConfigWatcher.h => base/kernel/interfaces/IConfigTransform.h} (72%) rename src/{common/config/ConfigLoader.h => base/kernel/interfaces/IJsonReader.h} (53%) delete mode 100644 src/common/config/CommonConfig.cpp delete mode 100644 src/common/config/ConfigLoader.cpp create mode 100644 src/core/config/ConfigTransform.cpp create mode 100644 src/core/config/ConfigTransform.h rename src/core/config/{ConfigLoader_default.h => Config_default.h} (94%) rename src/core/config/{ConfigLoader_platform.h => Config_platform.h} (88%) diff --git a/CMakeLists.txt b/CMakeLists.txt index c95132587..550de4802 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,20 +24,17 @@ set(HEADERS "${HEADERS_BASE_HTTP}" src/api/interfaces/IApiListener.h src/App.h - src/common/config/CommonConfig.h - src/common/config/ConfigLoader.h - src/common/config/ConfigWatcher.h src/common/cpu/Cpu.h src/common/crypto/Algorithm.h src/common/crypto/keccak.h - src/common/interfaces/IConfig.h src/common/interfaces/ICpuInfo.h src/common/Platform.h src/common/utils/mm_malloc.h src/common/xmrig.h src/core/config/Config.h - src/core/config/ConfigLoader_default.h - src/core/config/ConfigLoader_platform.h + src/core/config/ConfigTransform.h + src/core/config/Config_default.h + src/core/config/Config_platform.h src/core/config/usage.h src/core/Controller.h src/interfaces/IJobResultListener.h @@ -84,13 +81,11 @@ set(SOURCES "${SOURCES_BASE}" "${SOURCES_BASE_HTTP}" src/App.cpp - src/common/config/CommonConfig.cpp - src/common/config/ConfigLoader.cpp - src/common/config/ConfigWatcher.cpp src/common/crypto/Algorithm.cpp src/common/crypto/keccak.cpp src/common/Platform.cpp src/core/config/Config.cpp + src/core/config/ConfigTransform.cpp src/core/Controller.cpp src/Mem.cpp src/net/Network.cpp diff --git a/src/api/Api.cpp b/src/api/Api.cpp index fc82ac9c4..1b7210f60 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -36,6 +36,7 @@ #include "api/interfaces/IApiListener.h" #include "api/requests/HttpApiRequest.h" #include "api/v1/ApiRouter.h" +#include "base/kernel/Base.h" #include "base/tools/Buffer.h" #include "common/crypto/keccak.h" #include "core/config/Config.h" @@ -48,17 +49,17 @@ #endif -xmrig::Api::Api(Controller *controller) : +xmrig::Api::Api(Base *base) : + m_base(base), m_id(), m_workerId(), - m_controller(controller), m_httpd(nullptr) { - controller->addListener(this); + base->addListener(this); - genId(m_controller->config()->apiId()); + genId(base->config()->apiId()); - m_v1 = new ApiRouter(controller); + m_v1 = new ApiRouter(base); addListener(m_v1); } @@ -75,7 +76,7 @@ xmrig::Api::~Api() void xmrig::Api::request(const HttpRequest &req) { - HttpApiRequest request(req, m_controller->config()->http().isRestricted()); + HttpApiRequest request(req, m_base->config()->http().isRestricted()); exec(request); } @@ -83,10 +84,10 @@ void xmrig::Api::request(const HttpRequest &req) void xmrig::Api::start() { - genWorkerId(m_controller->config()->apiWorkerId()); + genWorkerId(m_base->config()->apiWorkerId()); # ifdef XMRIG_FEATURE_HTTP - m_httpd = new Httpd(m_controller); + m_httpd = new Httpd(m_base); m_httpd->start(); # endif } @@ -155,7 +156,7 @@ void xmrig::Api::genId(const String &id) uint8_t hash[200]; const size_t addrSize = sizeof(interfaces[i].phys_addr); const size_t inSize = strlen(APP_KIND) + addrSize + sizeof(uint16_t); - const uint16_t port = static_cast(m_controller->config()->http().port()); + const uint16_t port = static_cast(m_base->config()->http().port()); uint8_t *input = new uint8_t[inSize](); memcpy(input, &port, sizeof(uint16_t)); diff --git a/src/api/Api.h b/src/api/Api.h index d76e3105e..9d3919016 100644 --- a/src/api/Api.h +++ b/src/api/Api.h @@ -29,14 +29,14 @@ #include -#include "base/kernel/interfaces/IControllerListener.h" +#include "base/kernel/interfaces/IBaseListener.h" namespace xmrig { class ApiRouter; -class Controller; +class Base; class Httpd; class HttpRequest; class IApiListener; @@ -44,10 +44,10 @@ class IApiRequest; class String; -class Api : public IControllerListener +class Api : public IBaseListener { public: - Api(Controller *controller); + Api(Base *base); ~Api() override; inline const char *id() const { return m_id; } @@ -67,9 +67,9 @@ private: void genWorkerId(const String &id); ApiRouter *m_v1; + Base *m_base; char m_id[32]; char m_workerId[128]; - Controller *m_controller; Httpd *m_httpd; std::vector m_listeners; }; diff --git a/src/api/Httpd.cpp b/src/api/Httpd.cpp index 726f75e00..0aba60728 100644 --- a/src/api/Httpd.cpp +++ b/src/api/Httpd.cpp @@ -48,13 +48,13 @@ static size_t faviconSize = 0; } // namespace xmrig -xmrig::Httpd::Httpd(Controller *controller) : - m_controller(controller), +xmrig::Httpd::Httpd(Base *base) : + m_base(base), m_http(nullptr), m_server(nullptr), m_port(0) { - controller->addListener(this); + base->addListener(this); } @@ -65,7 +65,7 @@ xmrig::Httpd::~Httpd() bool xmrig::Httpd::start() { - const Http &config = m_controller->config()->http(); + const Http &config = m_base->config()->http(); if (!config.isEnabled()) { return true; @@ -157,7 +157,7 @@ void xmrig::Httpd::onHttpRequest(const HttpRequest &req) } if (req.method != HTTP_GET) { - if (m_controller->config()->http().isRestricted()) { + if (m_base->config()->http().isRestricted()) { return HttpApiResponse(req.id(), HTTP_STATUS_FORBIDDEN).end(); } @@ -166,13 +166,13 @@ void xmrig::Httpd::onHttpRequest(const HttpRequest &req) } } - m_controller->api()->request(req); + m_base->api()->request(req); } int xmrig::Httpd::auth(const HttpRequest &req) const { - const Http &config = m_controller->config()->http(); + const Http &config = m_base->config()->http(); if (!req.headers.count(kAuthorization)) { return config.isAuthRequired() ? HTTP_STATUS_UNAUTHORIZED : HTTP_STATUS_OK; diff --git a/src/api/Httpd.h b/src/api/Httpd.h index 99ee2e88a..ae6cbfc8d 100644 --- a/src/api/Httpd.h +++ b/src/api/Httpd.h @@ -29,22 +29,22 @@ #include -#include "base/kernel/interfaces/IControllerListener.h" +#include "base/kernel/interfaces/IBaseListener.h" #include "base/kernel/interfaces/IHttpListener.h" namespace xmrig { -class Controller; +class Base; class HttpServer; class TcpServer; -class Httpd : public IControllerListener, public IHttpListener +class Httpd : public IBaseListener, public IHttpListener { public: - Httpd(Controller *controller); + Httpd(Base *base); ~Httpd() override; bool start(); @@ -57,7 +57,7 @@ protected: private: int auth(const HttpRequest &req) const; - Controller *m_controller; + Base *m_base; HttpServer *m_http; TcpServer *m_server; uint16_t m_port; diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp index cef4b7fce..1f3641c37 100644 --- a/src/api/v1/ApiRouter.cpp +++ b/src/api/v1/ApiRouter.cpp @@ -29,10 +29,10 @@ #include "api/interfaces/IApiRequest.h" #include "api/v1/ApiRouter.h" +#include "base/kernel/Base.h" #include "common/cpu/Cpu.h" #include "common/Platform.h" #include "core/config/Config.h" -#include "core/Controller.h" #include "interfaces/IThread.h" #include "rapidjson/document.h" #include "version.h" @@ -50,8 +50,8 @@ static inline double normalize(double d) } -xmrig::ApiRouter::ApiRouter(xmrig::Controller *controller) : - m_controller(controller) +xmrig::ApiRouter::ApiRouter(Base *base) : + m_base(base) { } @@ -79,14 +79,14 @@ void xmrig::ApiRouter::onRequest(IApiRequest &request) } request.accept(); - m_controller->config()->getJSON(request.doc()); + 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_controller->config()->reload(request.json())) { + if (!m_base->reload(request.json())) { return request.done(400); } @@ -142,9 +142,9 @@ void xmrig::ApiRouter::getMiner(rapidjson::Value &reply, rapidjson::Document &do reply.AddMember("kind", APP_KIND, allocator); reply.AddMember("ua", StringRef(Platform::userAgent()), allocator); reply.AddMember("cpu", cpu, allocator); - reply.AddMember("algo", StringRef(m_controller->config()->algorithm().name()), allocator); + reply.AddMember("algo", StringRef(m_base->config()->algorithm().shortName()), allocator); reply.AddMember("hugepages", Workers::hugePages() > 0, allocator); - reply.AddMember("donate_level", m_controller->config()->pools().donateLevel(), allocator); + reply.AddMember("donate_level", m_base->config()->pools().donateLevel(), allocator); } @@ -156,7 +156,7 @@ void xmrig::ApiRouter::getThreads(rapidjson::Value &reply, rapidjson::Document & Workers::threadsSummary(doc); - const std::vector &threads = m_controller->config()->threads(); + const std::vector &threads = m_base->config()->threads(); Value list(kArrayType); size_t i = 0; diff --git a/src/api/v1/ApiRouter.h b/src/api/v1/ApiRouter.h index 9bb992447..bdbbaea48 100644 --- a/src/api/v1/ApiRouter.h +++ b/src/api/v1/ApiRouter.h @@ -36,13 +36,13 @@ class Hashrate; namespace xmrig { -class Controller; +class Base; class ApiRouter : public xmrig::IApiListener { public: - ApiRouter(Controller *controller); + ApiRouter(Base *base); ~ApiRouter() override; protected: @@ -53,7 +53,7 @@ private: void getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const; void getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const; - Controller *m_controller; + Base *m_base; }; diff --git a/src/base/base.cmake b/src/base/base.cmake index 688f3ef82..04016f016 100644 --- a/src/base/base.cmake +++ b/src/base/base.cmake @@ -1,15 +1,21 @@ set(HEADERS_BASE src/base/io/Console.h src/base/io/Json.h + src/base/io/JsonChain.h src/base/io/log/backends/ConsoleLog.h src/base/io/log/backends/FileLog.h src/base/io/log/Log.h src/base/io/Watcher.h + src/base/kernel/Base.h + src/base/kernel/config/BaseConfig.h + src/base/kernel/config/BaseTransform.h src/base/kernel/Entry.h + src/base/kernel/interfaces/IBaseListener.h src/base/kernel/interfaces/IClientListener.h + src/base/kernel/interfaces/IConfig.h src/base/kernel/interfaces/IConfigListener.h + src/base/kernel/interfaces/IConfigTransform.h src/base/kernel/interfaces/IConsoleListener.h - src/base/kernel/interfaces/IControllerListener.h src/base/kernel/interfaces/IDnsListener.h src/base/kernel/interfaces/ILineListener.h src/base/kernel/interfaces/ILogBackend.h @@ -44,11 +50,15 @@ set(HEADERS_BASE set(SOURCES_BASE src/base/io/Console.cpp src/base/io/Json.cpp + src/base/io/JsonChain.cpp src/base/io/log/backends/ConsoleLog.cpp src/base/io/log/backends/FileLog.cpp src/base/io/log/Log.cpp src/base/io/Watcher.cpp + src/base/kernel/config/BaseConfig.cpp + src/base/kernel/config/BaseTransform.cpp src/base/kernel/Entry.cpp + src/base/kernel/Base.cpp src/base/kernel/Process.cpp src/base/kernel/Signals.cpp src/base/net/dns/Dns.cpp @@ -87,6 +97,7 @@ if (WITH_HTTPD) set(HEADERS_BASE_HTTP src/3rdparty/http-parser/http_parser.h src/base/kernel/interfaces/IHttpListener.h + src/base/kernel/interfaces/IJsonReader.h src/base/kernel/interfaces/ITcpServerListener.h src/base/net/http/HttpApiResponse.h src/base/net/http/HttpContext.h diff --git a/src/base/io/Json.cpp b/src/base/io/Json.cpp index b95994e4e..916464531 100644 --- a/src/base/io/Json.cpp +++ b/src/base/io/Json.cpp @@ -27,6 +27,13 @@ #include "rapidjson/document.h" +namespace xmrig { + +static const rapidjson::Value kNullValue; + +} + + bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool defaultValue) { auto i = obj.FindMember(key); @@ -49,6 +56,39 @@ const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key, } +const rapidjson::Value &xmrig::Json::getArray(const rapidjson::Value &obj, const char *key) +{ + auto i = obj.FindMember(key); + if (i != obj.MemberEnd() && i->value.IsArray()) { + return i->value; + } + + return kNullValue; +} + + +const rapidjson::Value &xmrig::Json::getObject(const rapidjson::Value &obj, const char *key) +{ + auto i = obj.FindMember(key); + if (i != obj.MemberEnd() && i->value.IsObject()) { + return i->value; + } + + return kNullValue; +} + + +const rapidjson::Value &xmrig::Json::getValue(const rapidjson::Value &obj, const char *key) +{ + auto i = obj.FindMember(key); + if (i != obj.MemberEnd()) { + return i->value; + } + + return kNullValue; +} + + int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaultValue) { auto i = obj.FindMember(key); @@ -91,3 +131,9 @@ unsigned xmrig::Json::getUint(const rapidjson::Value &obj, const char *key, unsi return defaultValue; } + + +bool xmrig::JsonReader::isEmpty() const +{ + return !m_obj.IsObject() || m_obj.ObjectEmpty(); +} diff --git a/src/base/io/Json.h b/src/base/io/Json.h index 28dcf9a37..80fe5dc26 100644 --- a/src/base/io/Json.h +++ b/src/base/io/Json.h @@ -26,6 +26,7 @@ #define XMRIG_JSON_H +#include "base/kernel/interfaces/IJsonReader.h" #include "rapidjson/fwd.h" @@ -37,6 +38,9 @@ class Json public: static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false); static const char *getString(const rapidjson::Value &obj, const char *key, const char *defaultValue = nullptr); + static const rapidjson::Value &getArray(const rapidjson::Value &obj, const char *key); + static const rapidjson::Value &getObject(const rapidjson::Value &obj, const char *key); + static const rapidjson::Value &getValue(const rapidjson::Value &obj, const char *key); static int getInt(const rapidjson::Value &obj, const char *key, int defaultValue = 0); static int64_t getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue = 0); static uint64_t getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue = 0); @@ -47,6 +51,28 @@ public: }; +class JsonReader : public IJsonReader +{ +public: + inline JsonReader(const rapidjson::Value &obj) : m_obj(obj) {} + + inline bool getBool(const char *key, bool defaultValue = false) const override { return Json::getBool(m_obj, key, defaultValue); } + inline const char *getString(const char *key, const char *defaultValue = nullptr) const override { return Json::getString(m_obj, key, defaultValue); } + inline const rapidjson::Value &getArray(const char *key) const override { return Json::getArray(m_obj, key); } + inline const rapidjson::Value &getObject(const char *key) const override { return Json::getObject(m_obj, key); } + inline const rapidjson::Value &getValue(const char *key) const override { return Json::getValue(m_obj, key); } + inline int getInt(const char *key, int defaultValue = 0) const override { return Json::getInt(m_obj, key, defaultValue); } + inline int64_t getInt64(const char *key, int64_t defaultValue = 0) const override { return Json::getInt64(m_obj, key, defaultValue); } + inline uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const override { return Json::getUint64(m_obj, key, defaultValue); } + inline unsigned getUint(const char *key, unsigned defaultValue = 0) const override { return Json::getUint(m_obj, key, defaultValue); } + + bool isEmpty() const override; + +private: + const rapidjson::Value &m_obj; +}; + + } /* namespace xmrig */ diff --git a/src/base/io/JsonChain.cpp b/src/base/io/JsonChain.cpp new file mode 100644 index 000000000..d65427ccd --- /dev/null +++ b/src/base/io/JsonChain.cpp @@ -0,0 +1,201 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * 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 + * 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 . + */ + + +#include "base/io/Json.h" +#include "base/io/JsonChain.h" +#include "base/io/log/Log.h" +#include "rapidjson/error/en.h" + + +namespace xmrig { + +static const rapidjson::Value kNullValue; + +} + + +xmrig::JsonChain::JsonChain() +{ +} + + +bool xmrig::JsonChain::add(rapidjson::Document &&doc) +{ + if (doc.HasParseError() || !doc.IsObject() || doc.ObjectEmpty()) { + return false; + } + + m_chain.push_back(std::move(doc)); + + return true; +} + + +bool xmrig::JsonChain::addFile(const char *fileName) +{ + using namespace rapidjson; + Document doc; + if (Json::get(fileName, doc)) { + m_fileName = fileName; + + return add(std::move(doc)); + } + + if (doc.HasParseError()) { + LOG_ERR("%s: \"%s\"", fileName, doc.GetErrorOffset(), GetParseError_En(doc.GetParseError())); + } + else { + LOG_ERR("unable to open \"%s\".", fileName); + } + + return false; +} + + +bool xmrig::JsonChain::addRaw(const char *json) +{ + using namespace rapidjson; + Document doc; + doc.Parse(json); + + return add(std::move(doc)); +} + + +bool xmrig::JsonChain::getBool(const char *key, bool defaultValue) const +{ + for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) { + auto i = it->FindMember(key); + if (i != it->MemberEnd() && i->value.IsBool()) { + return i->value.GetBool(); + } + } + + return defaultValue; +} + + +const char *xmrig::JsonChain::getString(const char *key, const char *defaultValue) const +{ + for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) { + auto i = it->FindMember(key); + if (i != it->MemberEnd() && i->value.IsString()) { + return i->value.GetString(); + } + } + + return defaultValue; +} + + +const rapidjson::Value &xmrig::JsonChain::getArray(const char *key) const +{ + for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) { + auto i = it->FindMember(key); + if (i != it->MemberEnd() && i->value.IsArray()) { + return i->value; + } + } + + return kNullValue; +} + + +const rapidjson::Value &xmrig::JsonChain::getObject(const char *key) const +{ + for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) { + auto i = it->FindMember(key); + if (i != it->MemberEnd() && i->value.IsObject()) { + return i->value; + } + } + + return kNullValue; +} + + +const rapidjson::Value &xmrig::JsonChain::getValue(const char *key) const +{ + for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) { + auto i = it->FindMember(key); + if (i != it->MemberEnd()) { + return i->value; + } + } + + return kNullValue; +} + + +int xmrig::JsonChain::getInt(const char *key, int defaultValue) const +{ + for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) { + auto i = it->FindMember(key); + if (i != it->MemberEnd() && i->value.IsInt()) { + return i->value.GetInt(); + } + } + + return defaultValue; +} + + +int64_t xmrig::JsonChain::getInt64(const char *key, int64_t defaultValue) const +{ + for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) { + auto i = it->FindMember(key); + if (i != it->MemberEnd() && i->value.IsInt64()) { + return i->value.GetInt64(); + } + } + + return defaultValue; +} + + +uint64_t xmrig::JsonChain::getUint64(const char *key, uint64_t defaultValue) const +{ + for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) { + auto i = it->FindMember(key); + if (i != it->MemberEnd() && i->value.IsUint64()) { + return i->value.GetUint64(); + } + } + + return defaultValue; +} + + +unsigned xmrig::JsonChain::getUint(const char *key, unsigned defaultValue) const +{ + for (auto it = m_chain.rbegin(); it != m_chain.rend(); ++it) { + auto i = it->FindMember(key); + if (i != it->MemberEnd() && i->value.IsUint()) { + return i->value.GetUint(); + } + } + + return defaultValue; +} diff --git a/src/base/io/JsonChain.h b/src/base/io/JsonChain.h new file mode 100644 index 000000000..dab01218d --- /dev/null +++ b/src/base/io/JsonChain.h @@ -0,0 +1,74 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * 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 + * 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_JSONCHAIN_H +#define XMRIG_JSONCHAIN_H + + +#include + + +#include "base/kernel/interfaces/IJsonReader.h" +#include "base/tools/String.h" +#include "rapidjson/document.h" + + +namespace xmrig { + + +class JsonChain : public IJsonReader +{ +public: + JsonChain(); + + bool add(rapidjson::Document &&doc); + bool addFile(const char *fileName); + bool addRaw(const char *json); + + inline const String &fileName() const { return m_fileName; } + inline size_t size() const { return m_chain.size(); } + +protected: + inline bool isEmpty() const override { return m_chain.empty(); } + + bool getBool(const char *key, bool defaultValue = false) const override; + const char *getString(const char *key, const char *defaultValue = nullptr) const override; + const rapidjson::Value &getArray(const char *key) const override; + const rapidjson::Value &getObject(const char *key) const override; + const rapidjson::Value &getValue(const char *key) const override; + int getInt(const char *key, int defaultValue = 0) const override; + int64_t getInt64(const char *key, int64_t defaultValue = 0) const override; + uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const override; + unsigned getUint(const char *key, unsigned defaultValue = 0) const override; + +private: + std::vector m_chain; + String m_fileName; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_JSONCHAIN_H */ diff --git a/src/base/io/Json_win.cpp b/src/base/io/Json_win.cpp index 4a1c52664..58ee26b79 100644 --- a/src/base/io/Json_win.cpp +++ b/src/base/io/Json_win.cpp @@ -102,7 +102,7 @@ bool xmrig::Json::save(const char *fileName, const rapidjson::Document &doc) return false; } # elif defined(__GNUC__) - const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_TRUNC); + const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_CREAT | _O_TRUNC); if (fd == -1) { return false; } diff --git a/src/base/kernel/Base.cpp b/src/base/kernel/Base.cpp new file mode 100644 index 000000000..841524417 --- /dev/null +++ b/src/base/kernel/Base.cpp @@ -0,0 +1,283 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * 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 + * 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 . + */ + + +#include +#include + + +#include "base/io/Json.h" +#include "base/io/JsonChain.h" +#include "base/io/log/backends/ConsoleLog.h" +#include "base/io/log/backends/FileLog.h" +#include "base/io/log/Log.h" +#include "base/io/Watcher.h" +#include "base/kernel/Base.h" +#include "base/kernel/interfaces/IBaseListener.h" +#include "base/kernel/Process.h" +#include "common/Platform.h" +#include "core/config/Config_default.h" +#include "core/config/Config.h" +#include "core/config/ConfigTransform.h" + + +#ifdef HAVE_SYSLOG_H +# include "base/io/log/backends/SysLog.h" +#endif + + +#ifdef XMRIG_FEATURE_API +# include "api/Api.h" +#endif + + +class xmrig::BasePrivate +{ +public: + inline BasePrivate(Process *process) : + api(nullptr), + config(nullptr), + process(process), + watcher(nullptr) + {} + + + inline ~BasePrivate() + { +# ifdef XMRIG_FEATURE_API + delete api; +# endif + + delete config; + delete watcher; + } + + + inline bool read(const JsonChain &chain, std::unique_ptr &config) + { + config = std::unique_ptr(new Config()); + + return config->read(chain, chain.fileName()); + } + + + inline Config *load() + { + JsonChain chain; + ConfigTransform transform; + std::unique_ptr config; + + transform.load(chain, process, transform); + + if (read(chain, config)) { + return config.release(); + } + + chain.addFile(process->location(Process::ExeLocation, "config.json")); + + if (read(chain, config)) { + return config.release(); + } + +# ifdef XMRIG_FEATURE_EMBEDDED_CONFIG + chain.addRaw(default_config); + + if (read(chain, config)) { + return config.release(); + } +# endif + + return nullptr; + } + + + inline void replace(Config *newConfig) + { + Config *previousConfig = config; + config = newConfig; + + for (IBaseListener *listener : listeners) { + listener->onConfigChanged(config, previousConfig); + } + + delete previousConfig; + } + + + Api *api; + Config *config; + Process *process; + std::vector listeners; + Watcher *watcher; +}; + + +xmrig::Base::Base(Process *process) + : d_ptr(new BasePrivate(process)) +{ +} + + +xmrig::Base::~Base() +{ + delete d_ptr; +} + + +bool xmrig::Base::isReady() const +{ + return d_ptr->config != nullptr; +} + + +int xmrig::Base::init() +{ + d_ptr->config = d_ptr->load(); + + if (!d_ptr->config) { + LOG_EMERG("No valid configuration found. Exiting."); + + return 1; + } + +# ifdef XMRIG_FEATURE_API + d_ptr->api = new Api(this); +# endif + + Platform::init(config()->userAgent()); + Platform::setProcessPriority(config()->priority()); + + if (!config()->isBackground()) { + Log::add(new ConsoleLog()); + } + + if (config()->logFile()) { + Log::add(new FileLog(config()->logFile())); + } + +# ifdef HAVE_SYSLOG_H + if (config()->isSyslog()) { + Log::add(new SysLog()); + } +# endif + + return 0; +} + + +void xmrig::Base::start() +{ +# ifdef XMRIG_FEATURE_API + api()->start(); +# endif + + if (config()->isShouldSave()) { + config()->save(); + } + + if (config()->isWatch()) { + d_ptr->watcher = new Watcher(config()->fileName(), this); + } +} + + +void xmrig::Base::stop() +{ +# ifdef XMRIG_FEATURE_API + api()->stop(); +# endif + + delete d_ptr->watcher; + d_ptr->watcher = nullptr; +} + + +xmrig::Api *xmrig::Base::api() const +{ + assert(d_ptr->api != nullptr); + + return d_ptr->api; +} + + +bool xmrig::Base::reload(const rapidjson::Value &json) +{ + JsonReader reader(json); + if (reader.isEmpty()) { + return false; + } + + Config *config = new Config(); + if (!config->read(reader, d_ptr->config->fileName())) { + delete config; + + return false; + } + + const bool saved = config->save(); + + if (config->isWatch() && d_ptr->watcher && saved) { + delete config; + + return true; + } + + d_ptr->replace(config); + + return true; +} + + +xmrig::Config *xmrig::Base::config() const +{ + assert(d_ptr->config != nullptr); + + return d_ptr->config; +} + + +void xmrig::Base::addListener(IBaseListener *listener) +{ + d_ptr->listeners.push_back(listener); +} + + +void xmrig::Base::onFileChanged(const String &fileName) +{ + LOG_WARN("\"%s\" was changed, reloading configuration", fileName.data()); + + JsonChain chain; + chain.addFile(fileName); + + Config *config = new Config(); + + if (!config->read(chain, chain.fileName())) { + LOG_ERR("reloading failed"); + + delete config; + return; + } + + d_ptr->replace(config); +} diff --git a/src/common/config/ConfigWatcher.cpp b/src/base/kernel/Base.h similarity index 62% rename from src/common/config/ConfigWatcher.cpp rename to src/base/kernel/Base.h index 1c70547ec..592d3a372 100644 --- a/src/common/config/ConfigWatcher.cpp +++ b/src/base/kernel/Base.h @@ -22,42 +22,50 @@ * along with this program. If not, see . */ +#ifndef XMRIG_BASE_H +#define XMRIG_BASE_H + -#include "base/io/log/Log.h" -#include "base/io/Watcher.h" #include "base/kernel/interfaces/IConfigListener.h" -#include "common/config/ConfigLoader.h" -#include "common/config/ConfigWatcher.h" -#include "core/config/Config.h" +#include "base/kernel/interfaces/IWatcherListener.h" +#include "rapidjson/fwd.h" -xmrig::ConfigWatcher::ConfigWatcher(const String &path, IConfigListener *listener) : - m_listener(listener) +namespace xmrig { + + +class Api; +class Config; +class BasePrivate; +class IBaseListener; +class Process; + + +class Base : public IWatcherListener { - m_watcher = new Watcher(path, this); -} +public: + Base(Process *process); + ~Base() override; + + virtual bool isReady() const; + virtual int init(); + virtual void start(); + virtual void stop(); + + Api *api() const; + bool reload(const rapidjson::Value &json); + Config *config() const; + void addListener(IBaseListener *listener); + +protected: + void onFileChanged(const String &fileName) override; + +private: + BasePrivate *d_ptr; +}; -xmrig::ConfigWatcher::~ConfigWatcher() -{ - delete m_watcher; -} +} /* namespace xmrig */ - -void xmrig::ConfigWatcher::onFileChanged(const String &fileName) -{ - LOG_WARN("\"%s\" was changed, reloading configuration", fileName.data()); - - IConfig *config = Config::create(); - ConfigLoader::loadFromFile(config, fileName); - - if (!config->finalize()) { - LOG_ERR("reloading failed"); - - delete config; - return; - } - - m_listener->onNewConfig(config); -} +#endif /* XMRIG_BASE_H */ diff --git a/src/base/kernel/config/BaseConfig.cpp b/src/base/kernel/config/BaseConfig.cpp new file mode 100644 index 000000000..7284c263d --- /dev/null +++ b/src/base/kernel/config/BaseConfig.cpp @@ -0,0 +1,195 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * 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 + * 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 . + */ + + +#include +#include +#include +#include +#include + + +#ifdef XMRIG_FEATURE_TLS +# include +#endif + + +#ifdef XMRIG_AMD_PROJECT +# if defined(__APPLE__) +# include +# else +# include "3rdparty/CL/cl.h" +# endif +#endif + + +#ifdef XMRIG_NVIDIA_PROJECT +# include "nvidia/cryptonight.h" +#endif + + +#include "base/io/Json.h" +#include "base/io/log/Log.h" +#include "base/kernel/config/BaseConfig.h" +#include "base/kernel/interfaces/IJsonReader.h" +#include "donate.h" +#include "rapidjson/document.h" +#include "rapidjson/filewritestream.h" +#include "rapidjson/prettywriter.h" +#include "version.h" + + +xmrig::BaseConfig::BaseConfig() : + m_algorithm(CRYPTONIGHT, VARIANT_AUTO), + m_autoSave(true), + m_background(false), + m_dryRun(false), + m_syslog(false), + m_upgrade(false), + m_watch(true) +{ +} + + +void xmrig::BaseConfig::printVersions() +{ + char buf[256] = { 0 }; + +# if defined(__clang__) + snprintf(buf, sizeof buf, "clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__); +# elif defined(__GNUC__) + snprintf(buf, sizeof buf, "gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); +# elif defined(_MSC_VER) + snprintf(buf, sizeof buf, "MSVC/%d", MSVC_VERSION); +# endif + + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s"), "ABOUT", APP_NAME, APP_VERSION, buf); + +# if defined(XMRIG_AMD_PROJECT) +# if CL_VERSION_2_0 + const char *ocl = "2.0"; +# elif CL_VERSION_1_2 + const char *ocl = "1.2"; +# elif CL_VERSION_1_1 + const char *ocl = "1.1"; +# elif CL_VERSION_1_0 + const char *ocl = "1.0"; +# else + const char *ocl = "0.0"; +# endif + int length = snprintf(buf, sizeof buf, "OpenCL/%s ", ocl); +# elif defined(XMRIG_NVIDIA_PROJECT) + const int cudaVersion = cuda_get_runtime_version(); + int length = snprintf(buf, sizeof buf, "CUDA/%d.%d ", cudaVersion / 1000, cudaVersion % 100); +# else + memset(buf, 0, 16); + +# if defined(XMRIG_FEATURE_HTTP) || defined(XMRIG_FEATURE_TLS) + int length = 0; +# endif +# endif + +# if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT) + { + constexpr const char *v = OPENSSL_VERSION_TEXT + 8; + length += snprintf(buf + length, (sizeof buf) - length, "OpenSSL/%.*s ", static_cast(strchr(v, ' ') - v), v); + } +# endif + + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13slibuv/%s %s"), "LIBS", uv_version_string(), buf); +} + + +bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName) +{ + m_fileName = fileName; + + if (reader.isEmpty()) { + return false; + } + + m_autoSave = reader.getBool("autosave", m_autoSave); + m_background = reader.getBool("background", m_background); + m_dryRun = reader.getBool("dry-run", m_dryRun); + m_syslog = reader.getBool("syslog", m_syslog); + m_watch = reader.getBool("watch", m_watch); + m_logFile = reader.getString("log-file"); + m_userAgent = reader.getString("user-agent"); + + setPrintTime(reader.getUint("print-time", 60)); + + const rapidjson::Value &api = reader.getObject("api"); + if (api.IsObject()) { + m_apiId = Json::getString(api, "id"); + m_apiWorkerId = Json::getString(api, "worker-id"); + } + +# ifdef XMRIG_DEPRECATED + if (api.IsObject() && api.HasMember("port")) { + m_upgrade = true; + m_http.load(api); + m_http.setEnabled(Json::getUint(api, "port") > 0); + m_http.setHost("0.0.0.0"); + } + else { + m_http.load(reader.getObject("http")); + } +# else + m_http.load(chain.getObject("http")); +# endif + + m_algorithm.parseAlgorithm(reader.getString("algo")); + + m_pools.load(reader.getArray("pools")); + m_pools.setDonateLevel(reader.getInt("donate-level", kDefaultDonateLevel)); + m_pools.setProxyDonate(reader.getInt("donate-over-proxy", Pools::PROXY_DONATE_AUTO)); + m_pools.setRetries(reader.getInt("retries")); + m_pools.setRetryPause(reader.getInt("retry-pause")); + + if (!m_algorithm.isValid()) { + return false; + } + + m_pools.adjust(m_algorithm); + + return m_pools.active() > 0; +} + + +bool xmrig::BaseConfig::save() +{ + if (m_fileName.isNull()) { + return false; + } + + rapidjson::Document doc; + getJSON(doc); + + if (Json::save(m_fileName, doc)) { + LOG_NOTICE("configuration saved to: \"%s\"", m_fileName.data()); + return true; + } + + return false; +} diff --git a/src/common/config/CommonConfig.h b/src/base/kernel/config/BaseConfig.h similarity index 71% rename from src/common/config/CommonConfig.h rename to src/base/kernel/config/BaseConfig.h index 55f36d0d5..f0c52536e 100644 --- a/src/common/config/CommonConfig.h +++ b/src/base/kernel/config/BaseConfig.h @@ -22,60 +22,54 @@ * along with this program. If not, see . */ -#ifndef XMRIG_COMMONCONFIG_H -#define XMRIG_COMMONCONFIG_H +#ifndef XMRIG_BASECONFIG_H +#define XMRIG_BASECONFIG_H +#include "base/kernel/interfaces/IConfig.h" #include "base/net/http/Http.h" #include "base/net/stratum/Pools.h" -#include "common/interfaces/IConfig.h" #include "common/xmrig.h" +struct option; + + namespace xmrig { -class CommonConfig : public IConfig +class IJsonReader; + + +class BaseConfig : public IConfig { public: - CommonConfig(); + BaseConfig(); inline bool isAutoSave() const { return m_autoSave; } inline bool isBackground() const { return m_background; } inline bool isDryRun() const { return m_dryRun; } inline bool isSyslog() const { return m_syslog; } - inline const String &apiId() const { return m_apiId; } - inline const String &apiWorkerId() const { return m_apiWorkerId; } inline const char *logFile() const { return m_logFile.data(); } inline const char *userAgent() const { return m_userAgent.data(); } inline const Http &http() const { return m_http; } inline const Pools &pools() const { return m_pools; } - inline int printTime() const { return m_printTime; } + inline const String &apiId() const { return m_apiId; } + inline const String &apiWorkerId() const { return m_apiWorkerId; } + inline uint32_t printTime() const { return m_printTime; } - inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); } - inline const Algorithm &algorithm() const override { return m_algorithm; } - inline const String &fileName() const override { return m_fileName; } + inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); } + inline const Algorithm &algorithm() const override { return m_algorithm; } + inline const String &fileName() const override { return m_fileName; } + inline void setFileName(const char *fileName) override { m_fileName = fileName; } + bool read(const IJsonReader &reader, const char *fileName) override; bool save() override; void printVersions(); protected: - enum State { - NoneState, - ReadyState, - ErrorState - }; - - bool finalize() override; - bool parseBoolean(int key, bool enable) override; - bool parseString(int key, const char *arg) override; - bool parseUint64(int key, uint64_t arg) override; - void parseJSON(const rapidjson::Value &json) override; - void setFileName(const char *fileName) override; - Algorithm m_algorithm; - bool m_adjusted; bool m_autoSave; bool m_background; bool m_dryRun; @@ -83,20 +77,20 @@ protected: bool m_upgrade; bool m_watch; Http m_http; - int m_printTime; Pools m_pools; - State m_state; String m_apiId; String m_apiWorkerId; String m_fileName; String m_logFile; String m_userAgent; + uint32_t m_printTime; private: - bool parseInt(int key, int arg); + inline void setPrintTime(uint32_t printTime) { if (printTime <= 3600) { m_printTime = printTime; } } }; -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_COMMONCONFIG_H */ + +#endif /* XMRIG_BASECONFIG_H */ diff --git a/src/base/kernel/config/BaseTransform.cpp b/src/base/kernel/config/BaseTransform.cpp new file mode 100644 index 000000000..c676330e0 --- /dev/null +++ b/src/base/kernel/config/BaseTransform.cpp @@ -0,0 +1,255 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * 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 + * 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 . + */ + + +#ifdef _MSC_VER +# include "getopt/getopt.h" +#else +# include +#endif + + +#include "base/kernel/config/BaseTransform.h" +#include "base/kernel/Process.h" +#include "base/io/log/Log.h" +#include "base/kernel/interfaces/IConfig.h" +#include "base/io/JsonChain.h" +#include "core/config/Config_platform.h" + + +namespace xmrig +{ + +static const char *kApi = "api"; +static const char *kHttp = "http"; +static const char *kPools = "pools"; + +} + + +xmrig::BaseTransform::BaseTransform() +{ +} + + +void xmrig::BaseTransform::load(JsonChain &chain, Process *process, IConfigTransform &transform) +{ + using namespace rapidjson; + + int key; + int argc = process->arguments().argc(); + char **argv = process->arguments().argv(); + + Document doc(kObjectType); + + while (1) { + key = getopt_long(argc, argv, short_options, options, nullptr); + if (key < 0) { + break; + } + + if (key == IConfig::ConfigKey) { + chain.add(std::move(doc)); + chain.addFile(optarg); + + doc = Document(kObjectType); + } + else { + transform.transform(doc, key, optarg); + } + } + + if (optind < argc) { + LOG_WARN("%s: unsupported non-option argument '%s'", argv[0], argv[optind]); + } + + chain.add(std::move(doc)); +} + + +void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const char *arg) +{ + switch (key) { + case IConfig::AlgorithmKey: /* --algo */ + return set(doc, "algo", arg); + + case IConfig::UserpassKey: /* --userpass */ + return add(doc, kPools, "userpass", arg); + + case IConfig::UrlKey: /* --url */ + return add(doc, kPools, "url", arg, true); + + case IConfig::UserKey: /* --user */ + return add(doc, kPools, "user", arg); + + case IConfig::PasswordKey: /* --pass */ + return add(doc, kPools, "pass", arg); + + case IConfig::RigIdKey: /* --rig-id */ + return add(doc, kPools, "rig-id", arg); + + case IConfig::FingerprintKey: /* --tls-fingerprint */ + return add(doc, kPools, "tls-fingerprint", arg); + + case IConfig::VariantKey: /* --variant */ + return add(doc, kPools, "variant", arg); + + case IConfig::LogFileKey: /* --log-file */ + return set(doc, "log-file", arg); + +# ifdef XMRIG_DEPRECATED + case IConfig::ApiAccessTokenKey: /* --api-access-token */ + fputs("option \"--api-access-token\" deprecated, use \"--http-access-token\" instead.\n", stderr); + fflush(stdout); + return set(doc, kHttp, "access-token", arg); +# endif + + case IConfig::HttpAccessTokenKey: /* --http-access-token */ + return set(doc, kHttp, "access-token", arg); + + case IConfig::HttpHostKey: /* --http-host */ + return set(doc, kHttp, "host", arg); + + case IConfig::ApiWorkerIdKey: /* --api-worker-id */ + return set(doc, kApi, "worker-id", arg); + + case IConfig::ApiIdKey: /* --api-id */ + return set(doc, kApi, "id", arg); + + case IConfig::UserAgentKey: /* --user-agent */ + return set(doc, "user-agent", arg); + + case IConfig::RetriesKey: /* --retries */ + case IConfig::RetryPauseKey: /* --retry-pause */ + case IConfig::PrintTimeKey: /* --print-time */ + case IConfig::HttpPort: /* --http-port */ + case IConfig::DonateLevelKey: /* --donate-level */ +# ifdef XMRIG_DEPRECATED + case IConfig::ApiPort: /* --api-port */ +# endif + return transformUint64(doc, key, static_cast(strtol(arg, nullptr, 10))); + + case IConfig::BackgroundKey: /* --background */ + case IConfig::SyslogKey: /* --syslog */ + case IConfig::KeepAliveKey: /* --keepalive */ + case IConfig::NicehashKey: /* --nicehash */ + case IConfig::TlsKey: /* --tls */ + case IConfig::DryRunKey: /* --dry-run */ + case IConfig::HttpEnabledKey: /* --http-enabled */ + return transformBoolean(doc, key, true); + + case IConfig::ColorKey: /* --no-color */ + case IConfig::HttpRestrictedKey: /* --http-no-restricted */ +# ifdef XMRIG_DEPRECATED + case IConfig::ApiRestrictedKey: /* --api-no-restricted */ + case IConfig::ApiIPv6Key: /* --api-ipv6 */ +# endif + return transformBoolean(doc, key, false); + + default: + break; + } +} + + +void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, bool enable) +{ + switch (key) { + case IConfig::BackgroundKey: /* --background */ + return set(doc, "background", enable); + + case IConfig::SyslogKey: /* --syslog */ + return set(doc, "syslog", enable); + + case IConfig::KeepAliveKey: /* --keepalive */ + return add(doc, kPools, "keepalive", enable); + + case IConfig::TlsKey: /* --tls */ + return add(doc, kPools, "tls", enable); + +# ifndef XMRIG_PROXY_PROJECT + case IConfig::NicehashKey: /* --nicehash */ + return add(doc, kPools, "nicehash", enable); +# endif + + case IConfig::ColorKey: /* --no-color */ + return set(doc, "colors", enable); + +# ifdef XMRIG_DEPRECATED + case IConfig::ApiIPv6Key: /* --api-ipv6 */ + break; + + case IConfig::ApiRestrictedKey: /* --api-no-restricted */ + fputs("option \"--api-no-restricted\" deprecated, use \"--http-no-restricted\" instead.\n", stderr); + fflush(stdout); + return set(doc, kHttp, "restricted", enable); +# endif + + case IConfig::HttpRestrictedKey: /* --http-no-restricted */ + return set(doc, kHttp, "restricted", enable); + + case IConfig::HttpEnabledKey: /* --http-enabled */ + return set(doc, kHttp, "enabled", enable); + + case IConfig::DryRunKey: /* --dry-run */ + return set(doc, "dry-run", enable); + + default: + break; + } +} + + +void xmrig::BaseTransform::transformUint64(rapidjson::Document &doc, int key, uint64_t arg) +{ + switch (key) { + case IConfig::RetriesKey: /* --retries */ + return set(doc, "retries", arg); + + case IConfig::RetryPauseKey: /* --retry-pause */ + return set(doc, "retry-pause", arg); + + case IConfig::DonateLevelKey: /* --donate-level */ + return set(doc, "donate-level", arg); + + case IConfig::ProxyDonateKey: /* --donate-over-proxy */ + return set(doc, "donate-over-proxy", arg); + +# ifdef XMRIG_DEPRECATED + case IConfig::ApiPort: /* --api-port */ + fputs("option \"--api-port\" deprecated, use \"--http-port\" instead.\n", stderr); + fflush(stdout); + return set(doc, kHttp, "port", arg); +# endif + + case IConfig::HttpPort: /* --http-port */ + return set(doc, kHttp, "port", arg); + + case IConfig::PrintTimeKey: /* --print-time */ + return set(doc, "print-time", arg); + + default: + break; + } +} diff --git a/src/base/kernel/config/BaseTransform.h b/src/base/kernel/config/BaseTransform.h new file mode 100644 index 000000000..3952e22bd --- /dev/null +++ b/src/base/kernel/config/BaseTransform.h @@ -0,0 +1,123 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * 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 + * 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_BASETRANSFORM_H +#define XMRIG_BASETRANSFORM_H + + +#include "base/kernel/interfaces/IConfigTransform.h" +#include "rapidjson/document.h" + + +struct option; + + +namespace xmrig { + + +class IConfigTransform; +class JsonChain; +class Process; + + +class BaseTransform : public IConfigTransform +{ +public: + BaseTransform(); + + static void load(JsonChain &chain, Process *process, IConfigTransform &transform); + +protected: + void transform(rapidjson::Document &doc, int key, const char *arg) override; + + + template + inline void set(rapidjson::Document &doc, const char *key, T value) { set(doc, doc, key, value); } + + + template + inline void set(rapidjson::Document &doc, const char *objKey, const char *key, T value) + { + if (!doc.HasMember(objKey)) { + doc.AddMember(rapidjson::StringRef(objKey), rapidjson::kObjectType, doc.GetAllocator()); + } + + set(doc, doc[objKey], key, value); + } + + + template + inline void add(rapidjson::Document &doc, const char *arrayKey, const char *key, T value, bool force = false) + { + auto &allocator = doc.GetAllocator(); + + if (!doc.HasMember(arrayKey)) { + doc.AddMember(rapidjson::StringRef(arrayKey), rapidjson::kArrayType, allocator); + } + + rapidjson::Value &array = doc[arrayKey]; + if (force || array.Size() == 0) { + array.PushBack(rapidjson::kObjectType, allocator); + } + + set(doc, array[array.Size() - 1], key, value); + } + + + template + inline void set(rapidjson::Document &doc, rapidjson::Value &obj, const char *key, T value) + { + if (obj.HasMember(key)) { + obj[key] = value; + } + else { + obj.AddMember(rapidjson::StringRef(key), value, doc.GetAllocator()); + } + } + + +private: + void transformBoolean(rapidjson::Document &doc, int key, bool enable); + void transformUint64(rapidjson::Document &doc, int key, uint64_t arg); +}; + + +template<> +inline void BaseTransform::set(rapidjson::Document &doc, rapidjson::Value &obj, const char *key, const char *value) +{ + auto &allocator = doc.GetAllocator(); + + if (obj.HasMember(key)) { + obj[key] = rapidjson::Value(value, allocator); + } + else { + obj.AddMember(rapidjson::StringRef(key), rapidjson::Value(value, allocator), allocator); + } +} + + +} // namespace xmrig + + +#endif /* XMRIG_BASETRANSFORM_H */ diff --git a/src/base/kernel/interfaces/IControllerListener.h b/src/base/kernel/interfaces/IBaseListener.h similarity index 88% rename from src/base/kernel/interfaces/IControllerListener.h rename to src/base/kernel/interfaces/IBaseListener.h index c61574083..1f2123690 100644 --- a/src/base/kernel/interfaces/IControllerListener.h +++ b/src/base/kernel/interfaces/IBaseListener.h @@ -22,8 +22,8 @@ * along with this program. If not, see . */ -#ifndef XMRIG_ICONTROLLERLISTENER_H -#define XMRIG_ICONTROLLERLISTENER_H +#ifndef XMRIG_IBASELISTENER_H +#define XMRIG_IBASELISTENER_H namespace xmrig { @@ -32,10 +32,10 @@ namespace xmrig { class Config; -class IControllerListener +class IBaseListener { public: - virtual ~IControllerListener() = default; + virtual ~IBaseListener() = default; virtual void onConfigChanged(Config *config, Config *previousConfig) = 0; }; @@ -44,4 +44,4 @@ public: } /* namespace xmrig */ -#endif // XMRIG_ICONTROLLERLISTENER_H +#endif // XMRIG_IBASELISTENER_H diff --git a/src/common/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h similarity index 85% rename from src/common/interfaces/IConfig.h rename to src/base/kernel/interfaces/IConfig.h index 071b34786..446281290 100644 --- a/src/common/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -33,6 +33,7 @@ namespace xmrig { +class IJsonReader; class String; @@ -66,10 +67,8 @@ public: UserpassKey = 'O', VariantKey = 1010, VerboseKey = 1100, - WatchKey = 1105, TlsKey = 1013, FingerprintKey = 1014, - AutoSaveKey = 1016, ProxyDonateKey = 1017, # ifdef XMRIG_DEPRECATED @@ -92,7 +91,7 @@ public: MaxCPUUsageKey = 1004, SafeKey = 1005, ThreadsKey = 't', - HardwareAESKey = 1011, +// HardwareAESKey = 1011, AssemblyKey = 1015, // xmrig amd @@ -141,17 +140,13 @@ public: virtual ~IConfig() = default; - virtual bool finalize() = 0; - virtual bool isWatch() const = 0; - virtual bool parseBoolean(int key, bool enable) = 0; - virtual bool parseString(int key, const char *arg) = 0; - virtual bool parseUint64(int key, uint64_t arg) = 0; - virtual bool save() = 0; - virtual const Algorithm &algorithm() const = 0; - virtual const String &fileName() const = 0; - virtual void getJSON(rapidjson::Document &doc) const = 0; - virtual void parseJSON(const rapidjson::Value &json) = 0; - virtual void setFileName(const char *fileName) = 0; + virtual bool isWatch() const = 0; + virtual bool read(const IJsonReader &reader, const char *fileName) = 0; + virtual bool save() = 0; + virtual const Algorithm &algorithm() const = 0; + virtual const String &fileName() const = 0; + virtual void getJSON(rapidjson::Document &doc) const = 0; + virtual void setFileName(const char *fileName) = 0; }; diff --git a/src/common/config/ConfigWatcher.h b/src/base/kernel/interfaces/IConfigTransform.h similarity index 72% rename from src/common/config/ConfigWatcher.h rename to src/base/kernel/interfaces/IConfigTransform.h index 77b41cf5f..37ceaba1e 100644 --- a/src/common/config/ConfigWatcher.h +++ b/src/base/kernel/interfaces/IConfigTransform.h @@ -22,40 +22,31 @@ * along with this program. If not, see . */ -#ifndef XMRIG_CONFIGWATCHER_H -#define XMRIG_CONFIGWATCHER_H +#ifndef XMRIG_ICONFIGTRANSFORM_H +#define XMRIG_ICONFIGTRANSFORM_H -#include "base/kernel/interfaces/IWatcherListener.h" -#include "base/tools/String.h" +#include "common/crypto/Algorithm.h" #include "rapidjson/fwd.h" -struct option; - - namespace xmrig { -class IConfigListener; -class Watcher; +class IJsonReader; +class String; -class ConfigWatcher : public IWatcherListener +class IConfigTransform { public: - ConfigWatcher(const String &path, IConfigListener *listener); - ~ConfigWatcher() override; + virtual ~IConfigTransform() = default; -protected: - void onFileChanged(const String &fileName) override; - -private: - IConfigListener *m_listener; - Watcher *m_watcher; + virtual void transform(rapidjson::Document &doc, int key, const char *arg) = 0; }; } /* namespace xmrig */ -#endif /* __CONFIGWATCHER_H__ */ + +#endif // XMRIG_ICONFIGTRANSFORM_H diff --git a/src/common/config/ConfigLoader.h b/src/base/kernel/interfaces/IJsonReader.h similarity index 53% rename from src/common/config/ConfigLoader.h rename to src/base/kernel/interfaces/IJsonReader.h index f03de711e..c0fe09cb5 100644 --- a/src/common/config/ConfigLoader.h +++ b/src/base/kernel/interfaces/IJsonReader.h @@ -22,50 +22,35 @@ * along with this program. If not, see . */ -#ifndef XMRIG_CONFIGLOADER_H -#define XMRIG_CONFIGLOADER_H - - -#include +#ifndef XMRIG_IJSONREADER_H +#define XMRIG_IJSONREADER_H #include "rapidjson/fwd.h" -struct option; - - namespace xmrig { -class ConfigWatcher; -class IConfigListener; -class IConfig; -class Process; - - -class ConfigLoader +class IJsonReader { public: - static bool loadFromFile(IConfig *config, const char *fileName); - static bool loadFromJSON(IConfig *config, const char *json); - static bool loadFromJSON(IConfig *config, const rapidjson::Value &json); - static bool reload(IConfig *oldConfig, const rapidjson::Value &json); - static bool watch(IConfig *config); - static IConfig *load(Process *process, IConfigListener *listener); - static void release(); + virtual ~IJsonReader() = default; -private: - static bool getJSON(const char *fileName, rapidjson::Document &doc); - static bool parseArg(IConfig *config, int key, const char *arg); - static void parseJSON(IConfig *config, const struct option *option, const rapidjson::Value &object); - - static ConfigWatcher *m_watcher; - static IConfigListener *m_listener; + virtual bool getBool(const char *key, bool defaultValue = false) const = 0; + virtual bool isEmpty() const = 0; + virtual const char *getString(const char *key, const char *defaultValue = nullptr) const = 0; + virtual const rapidjson::Value &getArray(const char *key) const = 0; + virtual const rapidjson::Value &getObject(const char *key) const = 0; + virtual const rapidjson::Value &getValue(const char *key) const = 0; + virtual int getInt(const char *key, int defaultValue = 0) const = 0; + virtual int64_t getInt64(const char *key, int64_t defaultValue = 0) const = 0; + virtual uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const = 0; + virtual unsigned getUint(const char *key, unsigned defaultValue = 0) const = 0; }; } /* namespace xmrig */ -#endif /* XMRIG_CONFIGLOADER_H */ +#endif // XMRIG_IJSONREADER_H diff --git a/src/base/net/stratum/Pools.cpp b/src/base/net/stratum/Pools.cpp index 63102c009..638ba5ea7 100644 --- a/src/base/net/stratum/Pools.cpp +++ b/src/base/net/stratum/Pools.cpp @@ -44,16 +44,6 @@ xmrig::Pools::Pools() : } -xmrig::Pool &xmrig::Pools::current() -{ - if (m_data.empty()) { - m_data.push_back(Pool()); - } - - return m_data.back(); -} - - bool xmrig::Pools::isEqual(const Pools &other) const { if (m_data.size() != other.m_data.size() || m_retries != other.m_retries || m_retryPause != other.m_retryPause) { @@ -64,25 +54,6 @@ bool xmrig::Pools::isEqual(const Pools &other) const } -bool xmrig::Pools::setUrl(const char *url) -{ - if (m_data.empty() || m_data.back().isValid()) { - Pool pool(url); - - if (pool.isValid()) { - m_data.push_back(std::move(pool)); - return true; - } - - return false; - } - - current().parse(url); - - return m_data.back().isValid(); -} - - xmrig::IStrategy *xmrig::Pools::createStrategy(IStrategyListener *listener) const { if (active() == 1) { @@ -144,6 +115,10 @@ void xmrig::Pools::load(const rapidjson::Value &pools) { m_data.clear(); + if (!pools.IsArray()) { + return; + } + for (const rapidjson::Value &value : pools.GetArray()) { if (!value.IsObject()) { continue; diff --git a/src/base/net/stratum/Pools.h b/src/base/net/stratum/Pools.h index f563f243f..6a63f166b 100644 --- a/src/base/net/stratum/Pools.h +++ b/src/base/net/stratum/Pools.h @@ -50,28 +50,16 @@ public: Pools(); - inline bool setUserpass(const char *userpass) { return current().setUserpass(userpass); } inline const std::vector &data() const { return m_data; } inline int donateLevel() const { return m_donateLevel; } inline int retries() const { return m_retries; } inline int retryPause() const { return m_retryPause; } inline ProxyDonate proxyDonate() const { return m_proxyDonate; } - inline void setFingerprint(const char *fingerprint) { current().setFingerprint(fingerprint); } - inline void setKeepAlive(bool enable) { current().setKeepAlive(enable); } - inline void setKeepAlive(int keepAlive) { current().setKeepAlive(keepAlive); } - inline void setNicehash(bool enable) { current().setNicehash(enable); } - inline void setPassword(const char *password) { current().setPassword(password); } - inline void setRigId(const char *rigId) { current().setRigId(rigId); } - inline void setTLS(bool enable) { current().setTLS(enable); } - inline void setUser(const char *user) { current().setUser(user); } - inline void setVariant(const char *variant) { current().algorithm().parseVariant(variant); } - inline void setVariant(int variant) { current().algorithm().parseVariant(variant); } inline bool operator!=(const Pools &other) const { return !isEqual(other); } inline bool operator==(const Pools &other) const { return isEqual(other); } bool isEqual(const Pools &other) const; - bool setUrl(const char *url); IStrategy *createStrategy(IStrategyListener *listener) const; rapidjson::Value toJSON(rapidjson::Document &doc) const; size_t active() const; @@ -84,8 +72,6 @@ public: void setRetryPause(int retryPause); private: - Pool ¤t(); - int m_donateLevel; int m_retries; int m_retryPause; diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp deleted file mode 100644 index b0b716c1f..000000000 --- a/src/common/config/CommonConfig.cpp +++ /dev/null @@ -1,426 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * 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 - * 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 . - */ - - -#include -#include -#include -#include -#include - - -#ifdef XMRIG_FEATURE_TLS -# include -#endif - - -#ifdef XMRIG_AMD_PROJECT -# if defined(__APPLE__) -# include -# else -# include "3rdparty/CL/cl.h" -# endif -#endif - - -#ifdef XMRIG_NVIDIA_PROJECT -# include "nvidia/cryptonight.h" -#endif - - -#include "base/io/Json.h" -#include "base/io/log/Log.h" -#include "common/config/CommonConfig.h" -#include "rapidjson/document.h" -#include "rapidjson/filewritestream.h" -#include "rapidjson/prettywriter.h" -#include "version.h" - - -xmrig::CommonConfig::CommonConfig() : - m_algorithm(CRYPTONIGHT, VARIANT_AUTO), - m_adjusted(false), - m_autoSave(true), - m_background(false), - m_dryRun(false), - m_syslog(false), - m_upgrade(false), - m_watch(true), - m_printTime(60), - m_state(NoneState) -{ -} - - -void xmrig::CommonConfig::printVersions() -{ - char buf[256] = { 0 }; - -# if defined(__clang__) - snprintf(buf, sizeof buf, "clang/%d.%d.%d", __clang_major__, __clang_minor__, __clang_patchlevel__); -# elif defined(__GNUC__) - snprintf(buf, sizeof buf, "gcc/%d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); -# elif defined(_MSC_VER) - snprintf(buf, sizeof buf, "MSVC/%d", MSVC_VERSION); -# endif - - Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%s/%s") WHITE_BOLD(" %s"), "ABOUT", APP_NAME, APP_VERSION, buf); - -# if defined(XMRIG_AMD_PROJECT) -# if CL_VERSION_2_0 - const char *ocl = "2.0"; -# elif CL_VERSION_1_2 - const char *ocl = "1.2"; -# elif CL_VERSION_1_1 - const char *ocl = "1.1"; -# elif CL_VERSION_1_0 - const char *ocl = "1.0"; -# else - const char *ocl = "0.0"; -# endif - int length = snprintf(buf, sizeof buf, "OpenCL/%s ", ocl); -# elif defined(XMRIG_NVIDIA_PROJECT) - const int cudaVersion = cuda_get_runtime_version(); - int length = snprintf(buf, sizeof buf, "CUDA/%d.%d ", cudaVersion / 1000, cudaVersion % 100); -# else - memset(buf, 0, 16); - -# if defined(XMRIG_FEATURE_HTTP) || defined(XMRIG_FEATURE_TLS) - int length = 0; -# endif -# endif - -# if defined(XMRIG_FEATURE_TLS) && defined(OPENSSL_VERSION_TEXT) - { - constexpr const char *v = OPENSSL_VERSION_TEXT + 8; - length += snprintf(buf + length, (sizeof buf) - length, "OpenSSL/%.*s ", static_cast(strchr(v, ' ') - v), v); - } -# endif - - Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13slibuv/%s %s"), "LIBS", uv_version_string(), buf); -} - - -bool xmrig::CommonConfig::save() -{ - if (m_fileName.isNull()) { - return false; - } - - rapidjson::Document doc; - getJSON(doc); - - if (Json::save(m_fileName, doc)) { - LOG_NOTICE("configuration saved to: \"%s\"", m_fileName.data()); - return true; - } - - return false; -} - - -bool xmrig::CommonConfig::finalize() -{ - if (m_state == ReadyState) { - return true; - } - - if (m_state == ErrorState) { - return false; - } - - if (!m_algorithm.isValid()) { - return false; - } - - m_pools.adjust(m_algorithm); - - if (!m_pools.active()) { - m_state = ErrorState; - return false; - } - - m_state = ReadyState; - return true; -} - - -bool xmrig::CommonConfig::parseBoolean(int key, bool enable) -{ - switch (key) { - case BackgroundKey: /* --background */ - m_background = enable; - break; - - case SyslogKey: /* --syslog */ - m_syslog = enable; - break; - - case KeepAliveKey: /* --keepalive */ - m_pools.setKeepAlive(enable); - break; - - case TlsKey: /* --tls */ - m_pools.setTLS(enable); - break; - -# ifndef XMRIG_PROXY_PROJECT - case NicehashKey: /* --nicehash */ - m_pools.setNicehash(enable); - break; -# endif - - case ColorKey: /* --no-color */ - Log::colors = enable; - break; - - case WatchKey: /* watch */ - m_watch = enable; - break; - -# ifdef XMRIG_DEPRECATED - case ApiIPv6Key: /* --api-ipv6 */ - break; - - case ApiRestrictedKey: /* --api-no-restricted */ - fputs("option \"--api-no-restricted\" deprecated, use \"--http-no-restricted\" instead.\n", stderr); - fflush(stdout); - m_http.setRestricted(enable); - break; -# endif - - case HttpRestrictedKey: /* --http-no-restricted */ - m_http.setRestricted(enable); - break; - - case HttpEnabledKey: /* --http-enabled */ - m_http.setEnabled(enable); - break; - - case DryRunKey: /* --dry-run */ - m_dryRun = enable; - break; - - case AutoSaveKey: - m_autoSave = enable; - break; - - default: - break; - } - - return true; -} - - -bool xmrig::CommonConfig::parseString(int key, const char *arg) -{ - switch (key) { - case AlgorithmKey: /* --algo */ - m_algorithm.parseAlgorithm(arg); - break; - - case UserpassKey: /* --userpass */ - return m_pools.setUserpass(arg); - - case UrlKey: /* --url */ - return m_pools.setUrl(arg); - - case UserKey: /* --user */ - m_pools.setUser(arg); - break; - - case PasswordKey: /* --pass */ - m_pools.setPassword(arg); - break; - - case RigIdKey: /* --rig-id */ - m_pools.setRigId(arg); - break; - - case FingerprintKey: /* --tls-fingerprint */ - m_pools.setFingerprint(arg); - break; - - case VariantKey: /* --variant */ - m_pools.setVariant(arg); - break; - - case LogFileKey: /* --log-file */ - m_logFile = arg; - break; - -# ifdef XMRIG_DEPRECATED - case ApiAccessTokenKey: /* --api-access-token */ - fputs("option \"--api-access-token\" deprecated, use \"--http-access-token\" instead.\n", stderr); - fflush(stdout); - m_http.setToken(arg); - break; -# endif - - case HttpAccessTokenKey: /* --http-access-token */ - m_http.setToken(arg); - break; - - case HttpHostKey: /* --http-host */ - m_http.setHost(arg); - break; - - case ApiWorkerIdKey: /* --api-worker-id */ - m_apiWorkerId = arg; - break; - - case ApiIdKey: /* --api-id */ - m_apiId = arg; - break; - - case UserAgentKey: /* --user-agent */ - m_userAgent = arg; - break; - - case RetriesKey: /* --retries */ - case RetryPauseKey: /* --retry-pause */ - case PrintTimeKey: /* --print-time */ - case HttpPort: /* --http-port */ -# ifdef XMRIG_DEPRECATED - case ApiPort: /* --api-port */ -# endif - return parseUint64(key, static_cast(strtol(arg, nullptr, 10))); - - case BackgroundKey: /* --background */ - case SyslogKey: /* --syslog */ - case KeepAliveKey: /* --keepalive */ - case NicehashKey: /* --nicehash */ - case TlsKey: /* --tls */ - case DryRunKey: /* --dry-run */ - case HttpEnabledKey: /* --http-enabled */ - return parseBoolean(key, true); - - case ColorKey: /* --no-color */ - case WatchKey: /* --no-watch */ - case HttpRestrictedKey: /* --http-no-restricted */ -# ifdef XMRIG_DEPRECATED - case ApiRestrictedKey: /* --api-no-restricted */ - case ApiIPv6Key: /* --api-ipv6 */ -# endif - return parseBoolean(key, false); - - case DonateLevelKey: /* --donate-level */ - return parseUint64(key, static_cast(strtol(arg, nullptr, 10))); - - default: - break; - } - - return true; -} - - -bool xmrig::CommonConfig::parseUint64(int key, uint64_t arg) -{ - return parseInt(key, static_cast(arg)); -} - - -void xmrig::CommonConfig::parseJSON(const rapidjson::Value &json) -{ - const rapidjson::Value &pools = json["pools"]; - if (pools.IsArray()) { - m_pools.load(pools); - } - -# ifdef XMRIG_DEPRECATED - const rapidjson::Value &api = json["api"]; - if (api.IsObject() && api.HasMember("port")) { - m_upgrade = true; - m_http.load(api); - m_http.setEnabled(Json::getUint(api, "port") > 0); - m_http.setHost("0.0.0.0"); - } - else { - m_http.load(json["http"]); - } -# else - m_http.load(doc["http"]); -# endif -} - - -void xmrig::CommonConfig::setFileName(const char *fileName) -{ - m_fileName = fileName; -} - - -bool xmrig::CommonConfig::parseInt(int key, int arg) -{ - switch (key) { - case RetriesKey: /* --retries */ - m_pools.setRetries(arg); - break; - - case RetryPauseKey: /* --retry-pause */ - m_pools.setRetryPause(arg); - break; - - case KeepAliveKey: /* --keepalive */ - m_pools.setKeepAlive(arg); - break; - - case VariantKey: /* --variant */ - m_pools.setVariant(arg); - break; - - case DonateLevelKey: /* --donate-level */ - m_pools.setDonateLevel(arg); - break; - - case ProxyDonateKey: /* --donate-over-proxy */ - m_pools.setProxyDonate(arg); - break; - -# ifdef XMRIG_DEPRECATED - case ApiPort: /* --api-port */ - fputs("option \"--api-port\" deprecated, use \"--http-port\" instead.\n", stderr); - fflush(stdout); - m_http.setPort(arg); - break; -# endif - - case HttpPort: /* --http-port */ - m_http.setPort(arg); - break; - - case PrintTimeKey: /* --print-time */ - if (arg >= 0 && arg <= 3600) { - m_printTime = arg; - } - break; - - default: - break; - } - - return true; -} diff --git a/src/common/config/ConfigLoader.cpp b/src/common/config/ConfigLoader.cpp deleted file mode 100644 index 2b7f50cec..000000000 --- a/src/common/config/ConfigLoader.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * 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 - * 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 . - */ - - -#include -#include -#include -#include - - -#include "base/io/Json.h" -#include "base/kernel/interfaces/IConfigListener.h" -#include "base/kernel/Process.h" -#include "common/config/ConfigLoader.h" -#include "common/config/ConfigWatcher.h" -#include "common/interfaces/IConfig.h" -#include "common/Platform.h" -#include "core/config/Config.h" -#include "core/config/ConfigLoader_platform.h" -#include "rapidjson/document.h" -#include "rapidjson/error/en.h" -#include "rapidjson/fwd.h" - - -#ifdef XMRIG_FEATURE_EMBEDDED_CONFIG -# include "core/config/ConfigLoader_default.h" -#endif - - -namespace xmrig { - -ConfigWatcher *ConfigLoader::m_watcher = nullptr; -IConfigListener *ConfigLoader::m_listener = nullptr; - -} // namespace xmrig - - -#ifndef ARRAY_SIZE -# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -#endif - - -bool xmrig::ConfigLoader::loadFromFile(xmrig::IConfig *config, const char *fileName) -{ - rapidjson::Document doc; - if (!getJSON(fileName, doc)) { - return false; - } - - config->setFileName(fileName); - - return loadFromJSON(config, doc); -} - - -bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const char *json) -{ - using namespace rapidjson; - Document doc; - doc.Parse(json); - - if (doc.HasParseError() || !doc.IsObject()) { - return false; - } - - return loadFromJSON(config, doc); -} - - -bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const rapidjson::Value &json) -{ - for (size_t i = 0; i < ARRAY_SIZE(config_options); i++) { - parseJSON(config, &config_options[i], json); - } - - const rapidjson::Value &api = json["api"]; - if (api.IsObject()) { - for (size_t i = 0; i < ARRAY_SIZE(api_options); i++) { - parseJSON(config, &api_options[i], api); - } - } - - config->parseJSON(json); - - return config->finalize(); -} - - -bool xmrig::ConfigLoader::reload(xmrig::IConfig *oldConfig, const rapidjson::Value &json) -{ - IConfig *config = Config::create(); - if (!loadFromJSON(config, json)) { - delete config; - - return false; - } - - config->setFileName(oldConfig->fileName()); - const bool saved = config->save(); - - if (config->isWatch() && m_watcher && saved) { - delete config; - - return true; - } - - m_listener->onNewConfig(config); - return true; -} - - -bool xmrig::ConfigLoader::watch(IConfig *config) -{ - if (!config->isWatch()) { - return false; - } - - assert(m_watcher == nullptr); - - m_watcher = new ConfigWatcher(config->fileName(), m_listener); - return true; -} - - -xmrig::IConfig *xmrig::ConfigLoader::load(Process *process, IConfigListener *listener) -{ - m_listener = listener; - - IConfig *config = Config::create(); - int key; - int argc = process->arguments().argc(); - char **argv = process->arguments().argv(); - - while (1) { - key = getopt_long(argc, argv, short_options, options, nullptr); - if (key < 0) { - break; - } - - if (!parseArg(config, key, optarg)) { - delete config; - return nullptr; - } - } - - if (optind < argc) { - fprintf(stderr, "%s: unsupported non-option argument '%s'\n", argv[0], argv[optind]); - delete config; - return nullptr; - } - - if (!config->finalize()) { - delete config; - - config = Config::create(); - loadFromFile(config, process->location(Process::ExeLocation, "config.json")); - } - -# ifdef XMRIG_FEATURE_EMBEDDED_CONFIG - if (!config->finalize()) { - delete config; - - config = Config::create(); - loadFromJSON(config, default_config); - } -# endif - - if (!config->finalize()) { - if (!config->algorithm().isValid()) { - fprintf(stderr, "No valid algorithm specified. Exiting.\n"); - } - else { - fprintf(stderr, "No valid configuration found. Exiting.\n"); - } - - delete config; - return nullptr; - } - - return config; -} - - -void xmrig::ConfigLoader::release() -{ - delete m_watcher; - - m_watcher = nullptr; -} - - -bool xmrig::ConfigLoader::getJSON(const char *fileName, rapidjson::Document &doc) -{ - if (Json::get(fileName, doc)) { - return true; - } - - if (doc.HasParseError()) { - printf("%s: \"%s\"\n", fileName, doc.GetErrorOffset(), rapidjson::GetParseError_En(doc.GetParseError())); - } - else { - fprintf(stderr, "unable to open \"%s\".\n", fileName); - } - - return false; -} - - -bool xmrig::ConfigLoader::parseArg(xmrig::IConfig *config, int key, const char *arg) -{ - if (key == IConfig::ConfigKey) { - return loadFromFile(config, arg); - } - - return config->parseString(key, arg); -} - - -void xmrig::ConfigLoader::parseJSON(xmrig::IConfig *config, const struct option *option, const rapidjson::Value &object) -{ - if (!option->name || !object.HasMember(option->name)) { - return; - } - - const rapidjson::Value &value = object[option->name]; - - if (option->has_arg) { - if (value.IsString()) { - config->parseString(option->val, value.GetString()); - } - else if (value.IsInt64()) { - config->parseUint64(option->val, value.GetUint64()); - } - else if (value.IsBool()) { - config->parseBoolean(option->val, value.IsTrue()); - } - } - else if (value.IsBool()) { - config->parseBoolean(option->val, value.IsTrue()); - } -} diff --git a/src/common/crypto/Algorithm.cpp b/src/common/crypto/Algorithm.cpp index f14d034de..d9d3ead96 100644 --- a/src/common/crypto/Algorithm.cpp +++ b/src/common/crypto/Algorithm.cpp @@ -176,7 +176,7 @@ void xmrig::Algorithm::parseAlgorithm(const char *algo) m_algo = INVALID_ALGO; m_variant = VARIANT_AUTO; - assert(algo != nullptr); +// assert(algo != nullptr); if (algo == nullptr || strlen(algo) < 1) { return; } diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 32507e907..493b3e11e 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -26,89 +26,28 @@ #include -#include "base/io/log/backends/ConsoleLog.h" -#include "base/io/log/backends/FileLog.h" -#include "base/io/log/Log.h" -#include "base/kernel/interfaces/IControllerListener.h" -#include "common/config/ConfigLoader.h" #include "common/cpu/Cpu.h" #include "common/Platform.h" -#include "core/config/Config.h" #include "core/Controller.h" #include "net/Network.h" -#ifdef HAVE_SYSLOG_H -# include "base/io/log/backends/SysLog.h" -#endif - - -#ifdef XMRIG_FEATURE_API -# include "api/Api.h" -#endif - - -class xmrig::ControllerPrivate -{ -public: - inline ControllerPrivate(Process *process) : - api(nullptr), - config(nullptr), - network(nullptr), - process(process) - {} - - - inline ~ControllerPrivate() - { -# ifdef XMRIG_FEATURE_API - delete api; -# endif - - delete network; - delete config; - } - - - Api *api; - Config *config; - Network *network; - Process *process; - std::vector listeners; -}; - - -xmrig::Controller::Controller(Process *process) - : d_ptr(new ControllerPrivate(process)) +xmrig::Controller::Controller(Process *process) : + Base(process), + m_network(nullptr) { } xmrig::Controller::~Controller() { - delete d_ptr; -} - - -xmrig::Api *xmrig::Controller::api() const -{ - assert(d_ptr->api != nullptr); - - return d_ptr->api; + delete m_network; } bool xmrig::Controller::isReady() const { - return d_ptr->config && d_ptr->network; -} - - -xmrig::Config *xmrig::Controller::config() const -{ - assert(d_ptr->config != nullptr); - - return d_ptr->config; + return Base::isReady() && m_network; } @@ -116,98 +55,36 @@ int xmrig::Controller::init() { Cpu::init(); - d_ptr->config = Config::load(d_ptr->process, this); - if (!d_ptr->config) { - return 1; + const int rc = Base::init(); + if (rc != 0) { + return rc; } -# ifdef XMRIG_FEATURE_API - d_ptr->api = new Api(this); -# endif - - Platform::init(config()->userAgent()); - Platform::setProcessPriority(d_ptr->config->priority()); - - if (!config()->isBackground()) { - Log::add(new ConsoleLog()); - } - - if (config()->logFile()) { - Log::add(new FileLog(config()->logFile())); - } - -# ifdef HAVE_SYSLOG_H - if (config()->isSyslog()) { - Log::add(new SysLog()); - } -# endif - - d_ptr->network = new Network(this); + m_network = new Network(this); return 0; } -xmrig::Network *xmrig::Controller::network() const -{ - assert(d_ptr->network != nullptr); - - return d_ptr->network; -} - - -void xmrig::Controller::addListener(IControllerListener *listener) -{ - d_ptr->listeners.push_back(listener); -} - - -void xmrig::Controller::save() -{ - if (!config()) { - return; - } - - if (d_ptr->config->isShouldSave()) { - d_ptr->config->save(); - } - - ConfigLoader::watch(d_ptr->config); -} - - -void xmrig::Controller::onNewConfig(IConfig *config) -{ - Config *previousConfig = d_ptr->config; - d_ptr->config = static_cast(config); - - for (IControllerListener *listener : d_ptr->listeners) { - listener->onConfigChanged(d_ptr->config, previousConfig); - } - - delete previousConfig; -} - - void xmrig::Controller::start() { + Base::start(); + network()->connect(); - -# ifdef XMRIG_FEATURE_API - api()->start(); -# endif - - save(); } void xmrig::Controller::stop() { -# ifdef XMRIG_FEATURE_API - api()->stop(); -# endif + Base::stop(); - ConfigLoader::release(); - - delete d_ptr->network; - d_ptr->network = nullptr; + delete m_network; + m_network = nullptr; +} + + +xmrig::Network *xmrig::Controller::network() const +{ + assert(m_network != nullptr); + + return m_network; } diff --git a/src/core/Controller.h b/src/core/Controller.h index c1ca3da3b..10e12147e 100644 --- a/src/core/Controller.h +++ b/src/core/Controller.h @@ -26,45 +26,35 @@ #define XMRIG_CONTROLLER_H -#include "base/kernel/interfaces/IConfigListener.h" +#include "base/kernel/Base.h" namespace xmrig { -class Api; -class Config; -class ControllerPrivate; -class IControllerListener; class Network; class Process; -class Controller : public IConfigListener +class Controller : public Base { public: Controller(Process *process); ~Controller() override; - Api *api() const; - bool isReady() const; - Config *config() const; - int init(); - Network *network() const; - void addListener(IControllerListener *listener); - void save(); - void start(); - void stop(); + bool isReady() const override; + int init() override; + void start() override; + void stop() override; -protected: - void onNewConfig(IConfig *config) override; + Network *network() const; private: - ControllerPrivate *d_ptr; + Network *m_network; }; -} /* namespace xmrig */ +} // namespace xmrig #endif /* XMRIG_CONTROLLER_H */ diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index 2b706d74c..1249b8ba4 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -28,7 +28,7 @@ #include "base/io/log/Log.h" -#include "common/config/ConfigLoader.h" +#include "base/kernel/interfaces/IJsonReader.h" #include "common/cpu/Cpu.h" #include "core/config/Config.h" #include "crypto/Asm.h" @@ -42,7 +42,7 @@ static char affinity_tmp[20] = { 0 }; -xmrig::Config::Config() : xmrig::CommonConfig(), +xmrig::Config::Config() : m_aesMode(AES_AUTO), m_algoVariant(AV_AUTO), m_assembly(ASM_AUTO), @@ -55,9 +55,23 @@ xmrig::Config::Config() : xmrig::CommonConfig(), } -bool xmrig::Config::reload(const rapidjson::Value &json) +bool xmrig::Config::read(const IJsonReader &reader, const char *fileName) { - return xmrig::ConfigLoader::reload(this, json); + if (!BaseConfig::read(reader, fileName)) { + return false; + } + + m_hugePages = reader.getBool("huge-pages", true); + m_safe = reader.getBool("safe"); + + setAesMode(reader.getValue("hw-aes")); + setAlgoVariant(reader.getInt("av")); + setAssembly(reader.getValue("asm")); + setMaxCpuUsage(reader.getInt("max-cpu-usage", 100)); + setPriority(reader.getInt("cpu-priority", -1)); + setThreads(reader.getValue("threads")); + + return finalize(); } @@ -126,22 +140,8 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const } -xmrig::Config *xmrig::Config::load(Process *process, IConfigListener *listener) -{ - return static_cast(ConfigLoader::load(process, listener)); -} - - bool xmrig::Config::finalize() { - if (m_state != NoneState) { - return CommonConfig::finalize(); - } - - if (!CommonConfig::finalize()) { - return false; - } - if (!m_threads.cpu.empty()) { m_threads.mode = Advanced; const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; @@ -153,7 +153,7 @@ bool xmrig::Config::finalize() return true; } - const AlgoVariant av = getAlgoVariant(); + const AlgoVariant av = getAlgoVariant(); m_threads.mode = m_threads.count ? Simple : Automatic; const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024; @@ -173,117 +173,54 @@ bool xmrig::Config::finalize() } m_shouldSave = m_threads.mode == Automatic; - return true; -} - - -bool xmrig::Config::parseBoolean(int key, bool enable) -{ - if (!CommonConfig::parseBoolean(key, enable)) { - return false; - } - - switch (key) { - case SafeKey: /* --safe */ - m_safe = enable; - break; - - case HugePagesKey: /* --no-huge-pages */ - m_hugePages = enable; - break; - - case HardwareAESKey: /* hw-aes config only */ - m_aesMode = enable ? AES_HW : AES_SOFT; - break; - -# ifndef XMRIG_NO_ASM - case AssemblyKey: - m_assembly = Asm::parse(enable); - break; -# endif - - default: - break; - } return true; } -bool xmrig::Config::parseString(int key, const char *arg) +void xmrig::Config::setAesMode(const rapidjson::Value &aesMode) { - if (!CommonConfig::parseString(key, arg)) { - return false; + if (aesMode.IsBool()) { + m_aesMode = aesMode.GetBool() ? AES_HW : AES_SOFT; } - - switch (key) { - case AVKey: /* --av */ - case MaxCPUUsageKey: /* --max-cpu-usage */ - case CPUPriorityKey: /* --cpu-priority */ - return parseUint64(key, strtol(arg, nullptr, 10)); - - case SafeKey: /* --safe */ - return parseBoolean(key, true); - - case HugePagesKey: /* --no-huge-pages */ - return parseBoolean(key, false); - - case ThreadsKey: /* --threads */ - if (strncmp(arg, "all", 3) == 0) { - m_threads.count = Cpu::info()->threads(); - return true; - } - - return parseUint64(key, strtol(arg, nullptr, 10)); - - case CPUAffinityKey: /* --cpu-affinity */ - { - const char *p = strstr(arg, "0x"); - return parseUint64(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10)); - } - -# ifndef XMRIG_NO_ASM - case AssemblyKey: /* --asm */ - m_assembly = Asm::parse(arg); - break; -# endif - - default: - break; - } - - return true; } -bool xmrig::Config::parseUint64(int key, uint64_t arg) +void xmrig::Config::setAlgoVariant(int av) { - if (!CommonConfig::parseUint64(key, arg)) { - return false; + if (av >= AV_AUTO && av < AV_MAX) { + m_algoVariant = static_cast(av); } - - switch (key) { - case CPUAffinityKey: /* --cpu-affinity */ - if (arg) { - m_threads.mask = static_cast(arg); - } - break; - - default: - return parseInt(key, static_cast(arg)); - } - - return true; } -void xmrig::Config::parseJSON(const rapidjson::Value &json) +void xmrig::Config::setAssembly(const rapidjson::Value &assembly) { - CommonConfig::parseJSON(json); + m_assembly = Asm::parse(assembly); +} - const rapidjson::Value &threads = json["threads"]; +void xmrig::Config::setMaxCpuUsage(int max) +{ + if (max > 0 && max <= 100) { + m_maxCpuUsage = max; + } +} + + +void xmrig::Config::setPriority(int priority) +{ + if (priority >= 0 && priority <= 5) { + m_priority = priority; + } +} + + +void xmrig::Config::setThreads(const rapidjson::Value &threads) +{ if (threads.IsArray()) { + m_threads.cpu.clear(); + for (const rapidjson::Value &value : threads.GetArray()) { if (!value.IsObject()) { continue; @@ -298,41 +235,12 @@ void xmrig::Config::parseJSON(const rapidjson::Value &json) } } } -} - - -bool xmrig::Config::parseInt(int key, int arg) -{ - switch (key) { - case ThreadsKey: /* --threads */ - if (arg >= 0 && arg < 1024) { - m_threads.count = arg; + else if (threads.IsUint()) { + const unsigned count = threads.GetUint(); + if (count < 1024) { + m_threads.count = count; } - break; - - case AVKey: /* --av */ - if (arg >= AV_AUTO && arg < AV_MAX) { - m_algoVariant = static_cast(arg); - } - break; - - case MaxCPUUsageKey: /* --max-cpu-usage */ - if (m_maxCpuUsage > 0 && arg <= 100) { - m_maxCpuUsage = arg; - } - break; - - case CPUPriorityKey: /* --cpu-priority */ - if (arg >= 0 && arg <= 5) { - m_priority = arg; - } - break; - - default: - break; } - - return true; } diff --git a/src/core/config/Config.h b/src/core/config/Config.h index 2a8ca11d1..19c70cf13 100644 --- a/src/core/config/Config.h +++ b/src/core/config/Config.h @@ -29,7 +29,7 @@ #include -#include "common/config/CommonConfig.h" +#include "base/kernel/config/BaseConfig.h" #include "common/xmrig.h" #include "rapidjson/fwd.h" #include "workers/CpuThread.h" @@ -55,7 +55,7 @@ class Process; * api/worker-id * pools/ */ -class Config : public CommonConfig +class Config : public BaseConfig { public: enum ThreadsMode { @@ -67,8 +67,7 @@ public: Config(); - bool reload(const rapidjson::Value &json); - + bool read(const IJsonReader &reader, const char *fileName) override; void getJSON(rapidjson::Document &doc) const override; inline AesMode aesMode() const { return m_aesMode; } @@ -80,20 +79,16 @@ public: inline int priority() const { return m_priority; } inline int threadsCount() const { return static_cast(m_threads.list.size()); } inline int64_t affinity() const { return m_threads.mask; } - inline static IConfig *create() { return new Config(); } inline ThreadsMode threadsMode() const { return m_threads.mode; } - static Config *load(Process *process, IConfigListener *listener); - -protected: - bool finalize() override; - bool parseBoolean(int key, bool enable) override; - bool parseString(int key, const char *arg) override; - bool parseUint64(int key, uint64_t arg) override; - void parseJSON(const rapidjson::Value &json) override; - private: - bool parseInt(int key, int arg); + bool finalize(); + void setAesMode(const rapidjson::Value &aesMode); + void setAlgoVariant(int av); + void setAssembly(const rapidjson::Value &assembly); + void setMaxCpuUsage(int max); + void setPriority(int priority); + void setThreads(const rapidjson::Value &threads); AlgoVariant getAlgoVariant() const; # ifndef XMRIG_NO_AEON diff --git a/src/core/config/ConfigTransform.cpp b/src/core/config/ConfigTransform.cpp new file mode 100644 index 000000000..7c9afc174 --- /dev/null +++ b/src/core/config/ConfigTransform.cpp @@ -0,0 +1,106 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * 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 + * 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 . + */ + + +#include "core/config/ConfigTransform.h" +#include "base/kernel/interfaces/IConfig.h" + + +xmrig::ConfigTransform::ConfigTransform() +{ + +} + + +void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const char *arg) +{ + BaseTransform::transform(doc, key, arg); + + switch (key) { + case IConfig::AVKey: /* --av */ + case IConfig::MaxCPUUsageKey: /* --max-cpu-usage */ + case IConfig::CPUPriorityKey: /* --cpu-priority */ + case IConfig::ThreadsKey: /* --threads */ + return transformUint64(doc, key, static_cast(strtol(arg, nullptr, 10))); + + case IConfig::SafeKey: /* --safe */ + return transformBoolean(doc, key, true); + + case IConfig::HugePagesKey: /* --no-huge-pages */ + return transformBoolean(doc, key, false); + + case IConfig::CPUAffinityKey: /* --cpu-affinity */ + { + const char *p = strstr(arg, "0x"); + return transformUint64(doc, key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10)); + } + +# ifndef XMRIG_NO_ASM + case IConfig::AssemblyKey: /* --asm */ + return set(doc, "asm", arg); +# endif + + default: + break; + } +} + + +void xmrig::ConfigTransform::transformBoolean(rapidjson::Document &doc, int key, bool enable) +{ + switch (key) { + case IConfig::SafeKey: /* --safe */ + return set(doc, "safe", enable); + + case IConfig::HugePagesKey: /* --no-huge-pages */ + return set(doc, "huge-pages", enable); + + default: + break; + } +} + + +void xmrig::ConfigTransform::transformUint64(rapidjson::Document &doc, int key, uint64_t arg) +{ + switch (key) { + case IConfig::CPUAffinityKey: /* --cpu-affinity */ + return set(doc, "cpu-affinity", static_cast(arg)); + + case IConfig::ThreadsKey: /* --threads */ + return set(doc, "threads", arg); + + case IConfig::AVKey: /* --av */ + return set(doc, "av", arg); + + case IConfig::MaxCPUUsageKey: /* --max-cpu-usage */ + return set(doc, "max-cpu-usage", arg); + + case IConfig::CPUPriorityKey: /* --cpu-priority */ + return set(doc, "cpu-priority", arg); + + default: + break; + } +} diff --git a/src/core/config/ConfigTransform.h b/src/core/config/ConfigTransform.h new file mode 100644 index 000000000..2d291d8f2 --- /dev/null +++ b/src/core/config/ConfigTransform.h @@ -0,0 +1,51 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * 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_CONFIGTRANSFORM_H +#define XMRIG_CONFIGTRANSFORM_H + + +#include "base/kernel/config/BaseTransform.h" + + +namespace xmrig { + + +class ConfigTransform : public BaseTransform +{ +public: + ConfigTransform(); + +protected: + void transform(rapidjson::Document &doc, int key, const char *arg) override; + +private: + void transformBoolean(rapidjson::Document &doc, int key, bool enable); + void transformUint64(rapidjson::Document &doc, int key, uint64_t arg); +}; + + +} // namespace xmrig + + +#endif /* XMRIG_CONFIGTRANSFORM_H */ diff --git a/src/core/config/ConfigLoader_default.h b/src/core/config/Config_default.h similarity index 94% rename from src/core/config/ConfigLoader_default.h rename to src/core/config/Config_default.h index 9ef81fd21..3462ad199 100644 --- a/src/core/config/ConfigLoader_default.h +++ b/src/core/config/Config_default.h @@ -22,8 +22,8 @@ * along with this program. If not, see . */ -#ifndef XMRIG_CONFIGLOADER_DEFAULT_H -#define XMRIG_CONFIGLOADER_DEFAULT_H +#ifndef XMRIG_CONFIG_DEFAULT_H +#define XMRIG_CONFIG_DEFAULT_H namespace xmrig { @@ -85,6 +85,7 @@ R"===( #endif -} /* namespace xmrig */ +} // namespace xmrig -#endif /* XMRIG_CONFIGLOADER_DEFAULT_H */ + +#endif /* XMRIG_CONFIG_DEFAULT_H */ diff --git a/src/core/config/ConfigLoader_platform.h b/src/core/config/Config_platform.h similarity index 88% rename from src/core/config/ConfigLoader_platform.h rename to src/core/config/Config_platform.h index 5026888dd..8ece4105b 100644 --- a/src/core/config/ConfigLoader_platform.h +++ b/src/core/config/Config_platform.h @@ -22,8 +22,8 @@ * along with this program. If not, see . */ -#ifndef XMRIG_CONFIGLOADER_PLATFORM_H -#define XMRIG_CONFIGLOADER_PLATFORM_H +#ifndef XMRIG_CONFIG_PLATFORM_H +#define XMRIG_CONFIG_PLATFORM_H #ifdef _MSC_VER @@ -33,17 +33,17 @@ #endif -#include "common/interfaces/IConfig.h" +#include "base/kernel/interfaces/IConfig.h" #include "version.h" namespace xmrig { -static char const short_options[] = "a:c:kBp:Px:r:R:s:t:T:o:u:O:v:l:S"; +static const char short_options[] = "a:c:kBp:Px:r:R:s:t:T:o:u:O:v:l:S"; -static struct option const options[] = { +static const option options[] = { { "algo", 1, nullptr, IConfig::AlgorithmKey }, { "api-worker-id", 1, nullptr, IConfig::ApiWorkerIdKey }, { "api-id", 1, nullptr, IConfig::ApiIdKey }, @@ -65,7 +65,6 @@ static struct option const options[] = { { "max-cpu-usage", 1, nullptr, IConfig::MaxCPUUsageKey }, { "nicehash", 0, nullptr, IConfig::NicehashKey }, { "no-color", 0, nullptr, IConfig::ColorKey }, - { "no-watch", 0, nullptr, IConfig::WatchKey }, { "no-huge-pages", 0, nullptr, IConfig::HugePagesKey }, { "variant", 1, nullptr, IConfig::VariantKey }, { "pass", 1, nullptr, IConfig::PasswordKey }, @@ -115,21 +114,12 @@ static struct option const config_options[] = { { "syslog", 0, nullptr, IConfig::SyslogKey }, { "threads", 1, nullptr, IConfig::ThreadsKey }, { "user-agent", 1, nullptr, IConfig::UserAgentKey }, - { "watch", 0, nullptr, IConfig::WatchKey }, - { "hw-aes", 0, nullptr, IConfig::HardwareAESKey }, { "asm", 1, nullptr, IConfig::AssemblyKey }, - { "autosave", 0, nullptr, IConfig::AutoSaveKey }, { nullptr, 0, nullptr, 0 } }; -static struct option const api_options[] = { - { "worker-id", 1, nullptr, IConfig::ApiWorkerIdKey }, - { "id", 1, nullptr, IConfig::ApiIdKey }, - { nullptr, 0, nullptr, 0 } -}; +} // namespace xmrig -} /* namespace xmrig */ - -#endif /* XMRIG_CONFIGLOADER_PLATFORM_H */ +#endif /* XMRIG_CONFIG_PLATFORM_H */ diff --git a/src/net/Network.h b/src/net/Network.h index 09e7c815f..1b8f49347 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -30,7 +30,7 @@ #include "api/interfaces/IApiListener.h" -#include "base/kernel/interfaces/IControllerListener.h" +#include "base/kernel/interfaces/IBaseListener.h" #include "base/kernel/interfaces/IStrategyListener.h" #include "base/kernel/interfaces/ITimerListener.h" #include "interfaces/IJobResultListener.h" @@ -45,7 +45,7 @@ class Controller; class IStrategy; -class Network : public IJobResultListener, public IStrategyListener, public IControllerListener, public ITimerListener, public IApiListener +class Network : public IJobResultListener, public IStrategyListener, public IBaseListener, public ITimerListener, public IApiListener { public: Network(Controller *controller);