Merge branch 'feature-json-centric-config' into evo

This commit is contained in:
XMRig 2019-04-06 18:34:38 +07:00
commit db456a3e63
38 changed files with 1608 additions and 1268 deletions

View file

@ -24,20 +24,17 @@ set(HEADERS
"${HEADERS_BASE_HTTP}" "${HEADERS_BASE_HTTP}"
src/api/interfaces/IApiListener.h src/api/interfaces/IApiListener.h
src/App.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/cpu/Cpu.h
src/common/crypto/Algorithm.h src/common/crypto/Algorithm.h
src/common/crypto/keccak.h src/common/crypto/keccak.h
src/common/interfaces/IConfig.h
src/common/interfaces/ICpuInfo.h src/common/interfaces/ICpuInfo.h
src/common/Platform.h src/common/Platform.h
src/common/utils/mm_malloc.h src/common/utils/mm_malloc.h
src/common/xmrig.h src/common/xmrig.h
src/core/config/Config_default.h
src/core/config/Config_platform.h
src/core/config/Config.h src/core/config/Config.h
src/core/config/ConfigLoader_default.h src/core/config/ConfigTransform.h
src/core/config/ConfigLoader_platform.h
src/core/config/usage.h src/core/config/usage.h
src/core/Controller.h src/core/Controller.h
src/interfaces/IJobResultListener.h src/interfaces/IJobResultListener.h
@ -84,13 +81,11 @@ set(SOURCES
"${SOURCES_BASE}" "${SOURCES_BASE}"
"${SOURCES_BASE_HTTP}" "${SOURCES_BASE_HTTP}"
src/App.cpp 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/Algorithm.cpp
src/common/crypto/keccak.cpp src/common/crypto/keccak.cpp
src/common/Platform.cpp src/common/Platform.cpp
src/core/config/Config.cpp src/core/config/Config.cpp
src/core/config/ConfigTransform.cpp
src/core/Controller.cpp src/core/Controller.cpp
src/Mem.cpp src/Mem.cpp
src/net/Network.cpp src/net/Network.cpp

View file

@ -36,6 +36,7 @@
#include "api/interfaces/IApiListener.h" #include "api/interfaces/IApiListener.h"
#include "api/requests/HttpApiRequest.h" #include "api/requests/HttpApiRequest.h"
#include "api/v1/ApiRouter.h" #include "api/v1/ApiRouter.h"
#include "base/kernel/Base.h"
#include "base/tools/Buffer.h" #include "base/tools/Buffer.h"
#include "common/crypto/keccak.h" #include "common/crypto/keccak.h"
#include "core/config/Config.h" #include "core/config/Config.h"
@ -48,17 +49,17 @@
#endif #endif
xmrig::Api::Api(Controller *controller) : xmrig::Api::Api(Base *base) :
m_base(base),
m_id(), m_id(),
m_workerId(), m_workerId(),
m_controller(controller),
m_httpd(nullptr) 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); addListener(m_v1);
} }
@ -75,7 +76,7 @@ xmrig::Api::~Api()
void xmrig::Api::request(const HttpRequest &req) 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); exec(request);
} }
@ -83,10 +84,10 @@ void xmrig::Api::request(const HttpRequest &req)
void xmrig::Api::start() void xmrig::Api::start()
{ {
genWorkerId(m_controller->config()->apiWorkerId()); genWorkerId(m_base->config()->apiWorkerId());
# ifdef XMRIG_FEATURE_HTTP # ifdef XMRIG_FEATURE_HTTP
m_httpd = new Httpd(m_controller); m_httpd = new Httpd(m_base);
m_httpd->start(); m_httpd->start();
# endif # endif
} }
@ -155,7 +156,7 @@ void xmrig::Api::genId(const String &id)
uint8_t hash[200]; uint8_t hash[200];
const size_t addrSize = sizeof(interfaces[i].phys_addr); const size_t addrSize = sizeof(interfaces[i].phys_addr);
const size_t inSize = strlen(APP_KIND) + addrSize + sizeof(uint16_t); const size_t inSize = strlen(APP_KIND) + addrSize + sizeof(uint16_t);
const uint16_t port = static_cast<uint16_t>(m_controller->config()->http().port()); const uint16_t port = static_cast<uint16_t>(m_base->config()->http().port());
uint8_t *input = new uint8_t[inSize](); uint8_t *input = new uint8_t[inSize]();
memcpy(input, &port, sizeof(uint16_t)); memcpy(input, &port, sizeof(uint16_t));

View file

@ -29,14 +29,14 @@
#include <vector> #include <vector>
#include "base/kernel/interfaces/IControllerListener.h" #include "base/kernel/interfaces/IBaseListener.h"
namespace xmrig { namespace xmrig {
class ApiRouter; class ApiRouter;
class Controller; class Base;
class Httpd; class Httpd;
class HttpRequest; class HttpRequest;
class IApiListener; class IApiListener;
@ -44,10 +44,10 @@ class IApiRequest;
class String; class String;
class Api : public IControllerListener class Api : public IBaseListener
{ {
public: public:
Api(Controller *controller); Api(Base *base);
~Api() override; ~Api() override;
inline const char *id() const { return m_id; } inline const char *id() const { return m_id; }
@ -67,9 +67,9 @@ private:
void genWorkerId(const String &id); void genWorkerId(const String &id);
ApiRouter *m_v1; ApiRouter *m_v1;
Base *m_base;
char m_id[32]; char m_id[32];
char m_workerId[128]; char m_workerId[128];
Controller *m_controller;
Httpd *m_httpd; Httpd *m_httpd;
std::vector<IApiListener *> m_listeners; std::vector<IApiListener *> m_listeners;
}; };

View file

@ -48,13 +48,13 @@ static size_t faviconSize = 0;
} // namespace xmrig } // namespace xmrig
xmrig::Httpd::Httpd(Controller *controller) : xmrig::Httpd::Httpd(Base *base) :
m_controller(controller), m_base(base),
m_http(nullptr), m_http(nullptr),
m_server(nullptr), m_server(nullptr),
m_port(0) m_port(0)
{ {
controller->addListener(this); base->addListener(this);
} }
@ -65,7 +65,7 @@ xmrig::Httpd::~Httpd()
bool xmrig::Httpd::start() bool xmrig::Httpd::start()
{ {
const Http &config = m_controller->config()->http(); const Http &config = m_base->config()->http();
if (!config.isEnabled()) { if (!config.isEnabled()) {
return true; return true;
@ -157,7 +157,7 @@ void xmrig::Httpd::onHttpRequest(const HttpRequest &req)
} }
if (req.method != HTTP_GET) { 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(); 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 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)) { if (!req.headers.count(kAuthorization)) {
return config.isAuthRequired() ? HTTP_STATUS_UNAUTHORIZED : HTTP_STATUS_OK; return config.isAuthRequired() ? HTTP_STATUS_UNAUTHORIZED : HTTP_STATUS_OK;

View file

@ -29,22 +29,22 @@
#include <stdint.h> #include <stdint.h>
#include "base/kernel/interfaces/IControllerListener.h" #include "base/kernel/interfaces/IBaseListener.h"
#include "base/kernel/interfaces/IHttpListener.h" #include "base/kernel/interfaces/IHttpListener.h"
namespace xmrig { namespace xmrig {
class Controller; class Base;
class HttpServer; class HttpServer;
class TcpServer; class TcpServer;
class Httpd : public IControllerListener, public IHttpListener class Httpd : public IBaseListener, public IHttpListener
{ {
public: public:
Httpd(Controller *controller); Httpd(Base *base);
~Httpd() override; ~Httpd() override;
bool start(); bool start();
@ -57,7 +57,7 @@ protected:
private: private:
int auth(const HttpRequest &req) const; int auth(const HttpRequest &req) const;
Controller *m_controller; Base *m_base;
HttpServer *m_http; HttpServer *m_http;
TcpServer *m_server; TcpServer *m_server;
uint16_t m_port; uint16_t m_port;

View file

@ -29,10 +29,10 @@
#include "api/interfaces/IApiRequest.h" #include "api/interfaces/IApiRequest.h"
#include "api/v1/ApiRouter.h" #include "api/v1/ApiRouter.h"
#include "base/kernel/Base.h"
#include "common/cpu/Cpu.h" #include "common/cpu/Cpu.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "core/config/Config.h" #include "core/config/Config.h"
#include "core/Controller.h"
#include "interfaces/IThread.h" #include "interfaces/IThread.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "version.h" #include "version.h"
@ -50,8 +50,8 @@ static inline double normalize(double d)
} }
xmrig::ApiRouter::ApiRouter(xmrig::Controller *controller) : xmrig::ApiRouter::ApiRouter(Base *base) :
m_controller(controller) m_base(base)
{ {
} }
@ -79,14 +79,14 @@ void xmrig::ApiRouter::onRequest(IApiRequest &request)
} }
request.accept(); 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) { else if (request.method() == IApiRequest::METHOD_PUT || request.method() == IApiRequest::METHOD_POST) {
if (request.url() == "/1/config") { if (request.url() == "/1/config") {
request.accept(); request.accept();
if (!m_controller->config()->reload(request.json())) { if (!m_base->reload(request.json())) {
return request.done(400); 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("kind", APP_KIND, allocator);
reply.AddMember("ua", StringRef(Platform::userAgent()), allocator); reply.AddMember("ua", StringRef(Platform::userAgent()), allocator);
reply.AddMember("cpu", cpu, 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("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); Workers::threadsSummary(doc);
const std::vector<xmrig::IThread *> &threads = m_controller->config()->threads(); const std::vector<IThread *> &threads = m_base->config()->threads();
Value list(kArrayType); Value list(kArrayType);
size_t i = 0; size_t i = 0;

View file

@ -36,13 +36,13 @@ class Hashrate;
namespace xmrig { namespace xmrig {
class Controller; class Base;
class ApiRouter : public xmrig::IApiListener class ApiRouter : public xmrig::IApiListener
{ {
public: public:
ApiRouter(Controller *controller); ApiRouter(Base *base);
~ApiRouter() override; ~ApiRouter() override;
protected: protected:
@ -53,7 +53,7 @@ private:
void getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const; void getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const;
void getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const; void getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const;
Controller *m_controller; Base *m_base;
}; };

View file

@ -1,15 +1,21 @@
set(HEADERS_BASE set(HEADERS_BASE
src/base/io/Console.h src/base/io/Console.h
src/base/io/Json.h src/base/io/Json.h
src/base/io/JsonChain.h
src/base/io/log/backends/ConsoleLog.h src/base/io/log/backends/ConsoleLog.h
src/base/io/log/backends/FileLog.h src/base/io/log/backends/FileLog.h
src/base/io/log/Log.h src/base/io/log/Log.h
src/base/io/Watcher.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/Entry.h
src/base/kernel/interfaces/IBaseListener.h
src/base/kernel/interfaces/IClientListener.h src/base/kernel/interfaces/IClientListener.h
src/base/kernel/interfaces/IConfig.h
src/base/kernel/interfaces/IConfigListener.h src/base/kernel/interfaces/IConfigListener.h
src/base/kernel/interfaces/IConfigTransform.h
src/base/kernel/interfaces/IConsoleListener.h src/base/kernel/interfaces/IConsoleListener.h
src/base/kernel/interfaces/IControllerListener.h
src/base/kernel/interfaces/IDnsListener.h src/base/kernel/interfaces/IDnsListener.h
src/base/kernel/interfaces/ILineListener.h src/base/kernel/interfaces/ILineListener.h
src/base/kernel/interfaces/ILogBackend.h src/base/kernel/interfaces/ILogBackend.h
@ -44,11 +50,15 @@ set(HEADERS_BASE
set(SOURCES_BASE set(SOURCES_BASE
src/base/io/Console.cpp src/base/io/Console.cpp
src/base/io/Json.cpp src/base/io/Json.cpp
src/base/io/JsonChain.cpp
src/base/io/log/backends/ConsoleLog.cpp src/base/io/log/backends/ConsoleLog.cpp
src/base/io/log/backends/FileLog.cpp src/base/io/log/backends/FileLog.cpp
src/base/io/log/Log.cpp src/base/io/log/Log.cpp
src/base/io/Watcher.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/Entry.cpp
src/base/kernel/Base.cpp
src/base/kernel/Process.cpp src/base/kernel/Process.cpp
src/base/kernel/Signals.cpp src/base/kernel/Signals.cpp
src/base/net/dns/Dns.cpp src/base/net/dns/Dns.cpp
@ -87,6 +97,7 @@ if (WITH_HTTPD)
set(HEADERS_BASE_HTTP set(HEADERS_BASE_HTTP
src/3rdparty/http-parser/http_parser.h src/3rdparty/http-parser/http_parser.h
src/base/kernel/interfaces/IHttpListener.h src/base/kernel/interfaces/IHttpListener.h
src/base/kernel/interfaces/IJsonReader.h
src/base/kernel/interfaces/ITcpServerListener.h src/base/kernel/interfaces/ITcpServerListener.h
src/base/net/http/HttpApiResponse.h src/base/net/http/HttpApiResponse.h
src/base/net/http/HttpContext.h src/base/net/http/HttpContext.h

View file

@ -27,6 +27,13 @@
#include "rapidjson/document.h" #include "rapidjson/document.h"
namespace xmrig {
static const rapidjson::Value kNullValue;
}
bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool defaultValue) bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool defaultValue)
{ {
auto i = obj.FindMember(key); 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) int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaultValue)
{ {
auto i = obj.FindMember(key); auto i = obj.FindMember(key);
@ -91,3 +131,9 @@ unsigned xmrig::Json::getUint(const rapidjson::Value &obj, const char *key, unsi
return defaultValue; return defaultValue;
} }
bool xmrig::JsonReader::isEmpty() const
{
return !m_obj.IsObject() || m_obj.ObjectEmpty();
}

View file

@ -26,6 +26,7 @@
#define XMRIG_JSON_H #define XMRIG_JSON_H
#include "base/kernel/interfaces/IJsonReader.h"
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"
@ -37,6 +38,9 @@ class Json
public: public:
static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false); 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 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 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 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); 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 */ } /* namespace xmrig */

213
src/base/io/JsonChain.cpp Normal file
View file

@ -0,0 +1,213 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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<offset:%zu>: \"%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<kParseCommentsFlag | kParseTrailingCommasFlag>(json);
return add(std::move(doc));
}
void xmrig::JsonChain::dump(const char *fileName)
{
rapidjson::Document doc(rapidjson::kArrayType);
for (rapidjson::Document &value : m_chain) {
doc.PushBack(value, doc.GetAllocator());
}
Json::save(fileName, 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;
}

76
src/base/io/JsonChain.h Normal file
View file

@ -0,0 +1,76 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_JSONCHAIN_H
#define XMRIG_JSONCHAIN_H
#include <vector>
#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);
void dump(const char *fileName);
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<rapidjson::Document> m_chain;
String m_fileName;
};
} /* namespace xmrig */
#endif /* XMRIG_JSONCHAIN_H */

View file

@ -102,7 +102,7 @@ bool xmrig::Json::save(const char *fileName, const rapidjson::Document &doc)
return false; return false;
} }
# elif defined(__GNUC__) # 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) { if (fd == -1) {
return false; return false;
} }

View file

@ -40,6 +40,7 @@
#include "base/io/log/Log.h" #include "base/io/log/Log.h"
#include "base/kernel/interfaces/ILogBackend.h" #include "base/kernel/interfaces/ILogBackend.h"
#include "base/tools/Chrono.h"
namespace xmrig { namespace xmrig {
@ -134,7 +135,8 @@ private:
return; return;
} }
time_t now = time(nullptr); const uint64_t ms = Chrono::currentMSecsSinceEpoch();
time_t now = ms / 1000;
tm stime; tm stime;
# ifdef _WIN32 # ifdef _WIN32
@ -143,13 +145,14 @@ private:
localtime_r(&now, &stime); localtime_r(&now, &stime);
# endif # endif
const int rc = snprintf(m_buf, sizeof(m_buf) - 1, "[%d-%02d-%02d %02d:%02d:%02d] ", const int rc = snprintf(m_buf, sizeof(m_buf) - 1, "[%d-%02d-%02d %02d:%02d:%02d" BLACK_BOLD(".%03d") "] ",
stime.tm_year + 1900, stime.tm_year + 1900,
stime.tm_mon + 1, stime.tm_mon + 1,
stime.tm_mday, stime.tm_mday,
stime.tm_hour, stime.tm_hour,
stime.tm_min, stime.tm_min,
stime.tm_sec stime.tm_sec,
static_cast<int>(ms % 1000)
); );
if (rc > 0) { if (rc > 0) {

290
src/base/kernel/Base.cpp Normal file
View file

@ -0,0 +1,290 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <memory>
#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.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
#ifdef XMRIG_FEATURE_EMBEDDED_CONFIG
# include "core/config/Config_default.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)
{
config = std::unique_ptr<Config>(new Config());
return config->read(chain, chain.fileName());
}
inline Config *load()
{
JsonChain chain;
ConfigTransform transform;
std::unique_ptr<Config> 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<IBaseListener *> 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());
# ifndef XMRIG_PROXY_PROJECT
Platform::setProcessPriority(config()->priority());
# endif
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);
}

View file

@ -22,42 +22,50 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#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 "base/kernel/interfaces/IConfigListener.h"
#include "common/config/ConfigLoader.h" #include "base/kernel/interfaces/IWatcherListener.h"
#include "common/config/ConfigWatcher.h" #include "rapidjson/fwd.h"
#include "core/config/Config.h"
xmrig::ConfigWatcher::ConfigWatcher(const String &path, IConfigListener *listener) : namespace xmrig {
m_listener(listener)
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() } /* namespace xmrig */
{
delete m_watcher;
}
#endif /* XMRIG_BASE_H */
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);
}

View file

@ -0,0 +1,196 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
#ifdef XMRIG_FEATURE_TLS
# include <openssl/opensslv.h>
#endif
#ifdef XMRIG_AMD_PROJECT
# if defined(__APPLE__)
# include <OpenCL/cl.h>
# 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<int>(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);
Log::colors = reader.getBool("colors", Log::colors);
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;
}

View file

@ -22,60 +22,54 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef XMRIG_COMMONCONFIG_H #ifndef XMRIG_BASECONFIG_H
#define XMRIG_COMMONCONFIG_H #define XMRIG_BASECONFIG_H
#include "base/kernel/interfaces/IConfig.h"
#include "base/net/http/Http.h" #include "base/net/http/Http.h"
#include "base/net/stratum/Pools.h" #include "base/net/stratum/Pools.h"
#include "common/interfaces/IConfig.h"
#include "common/xmrig.h" #include "common/xmrig.h"
struct option;
namespace xmrig { namespace xmrig {
class CommonConfig : public IConfig class IJsonReader;
class BaseConfig : public IConfig
{ {
public: public:
CommonConfig(); BaseConfig();
inline bool isAutoSave() const { return m_autoSave; } inline bool isAutoSave() const { return m_autoSave; }
inline bool isBackground() const { return m_background; } inline bool isBackground() const { return m_background; }
inline bool isDryRun() const { return m_dryRun; } inline bool isDryRun() const { return m_dryRun; }
inline bool isSyslog() const { return m_syslog; } 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 *logFile() const { return m_logFile.data(); }
inline const char *userAgent() const { return m_userAgent.data(); } inline const char *userAgent() const { return m_userAgent.data(); }
inline const Http &http() const { return m_http; } inline const Http &http() const { return m_http; }
inline const Pools &pools() const { return m_pools; } 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 bool isWatch() const override { return m_watch && !m_fileName.isNull(); }
inline const Algorithm &algorithm() const override { return m_algorithm; } inline const Algorithm &algorithm() const override { return m_algorithm; }
inline const String &fileName() const override { return m_fileName; } 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; bool save() override;
void printVersions(); void printVersions();
protected: 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; Algorithm m_algorithm;
bool m_adjusted;
bool m_autoSave; bool m_autoSave;
bool m_background; bool m_background;
bool m_dryRun; bool m_dryRun;
@ -83,20 +77,20 @@ protected:
bool m_upgrade; bool m_upgrade;
bool m_watch; bool m_watch;
Http m_http; Http m_http;
int m_printTime;
Pools m_pools; Pools m_pools;
State m_state;
String m_apiId; String m_apiId;
String m_apiWorkerId; String m_apiWorkerId;
String m_fileName; String m_fileName;
String m_logFile; String m_logFile;
String m_userAgent; String m_userAgent;
uint32_t m_printTime;
private: 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 */

View file

@ -0,0 +1,255 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifdef _MSC_VER
# include "getopt/getopt.h"
#else
# include <getopt.h>
#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<uint64_t>(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<bool>(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;
}
}

View file

@ -0,0 +1,123 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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<typename T>
inline void set(rapidjson::Document &doc, const char *key, T value) { set<T>(doc, doc, key, value); }
template<typename T>
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<T>(doc, doc[objKey], key, value);
}
template<typename T>
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<T>(doc, array[array.Size() - 1], key, value);
}
template<typename T>
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 */

View file

@ -22,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef XMRIG_ICONTROLLERLISTENER_H #ifndef XMRIG_IBASELISTENER_H
#define XMRIG_ICONTROLLERLISTENER_H #define XMRIG_IBASELISTENER_H
namespace xmrig { namespace xmrig {
@ -32,10 +32,10 @@ namespace xmrig {
class Config; class Config;
class IControllerListener class IBaseListener
{ {
public: public:
virtual ~IControllerListener() = default; virtual ~IBaseListener() = default;
virtual void onConfigChanged(Config *config, Config *previousConfig) = 0; virtual void onConfigChanged(Config *config, Config *previousConfig) = 0;
}; };
@ -44,4 +44,4 @@ public:
} /* namespace xmrig */ } /* namespace xmrig */
#endif // XMRIG_ICONTROLLERLISTENER_H #endif // XMRIG_IBASELISTENER_H

View file

@ -33,6 +33,7 @@
namespace xmrig { namespace xmrig {
class IJsonReader;
class String; class String;
@ -66,10 +67,8 @@ public:
UserpassKey = 'O', UserpassKey = 'O',
VariantKey = 1010, VariantKey = 1010,
VerboseKey = 1100, VerboseKey = 1100,
WatchKey = 1105,
TlsKey = 1013, TlsKey = 1013,
FingerprintKey = 1014, FingerprintKey = 1014,
AutoSaveKey = 1016,
ProxyDonateKey = 1017, ProxyDonateKey = 1017,
# ifdef XMRIG_DEPRECATED # ifdef XMRIG_DEPRECATED
@ -92,7 +91,7 @@ public:
MaxCPUUsageKey = 1004, MaxCPUUsageKey = 1004,
SafeKey = 1005, SafeKey = 1005,
ThreadsKey = 't', ThreadsKey = 't',
HardwareAESKey = 1011, // HardwareAESKey = 1011,
AssemblyKey = 1015, AssemblyKey = 1015,
// xmrig amd // xmrig amd
@ -111,7 +110,6 @@ public:
// xmrig-proxy // xmrig-proxy
AccessLogFileKey = 'A', AccessLogFileKey = 'A',
BindKey = 'b', BindKey = 'b',
CoinKey = 1104,
CustomDiffKey = 1102, CustomDiffKey = 1102,
DebugKey = 1101, DebugKey = 1101,
ModeKey = 'm', ModeKey = 'm',
@ -141,16 +139,12 @@ public:
virtual ~IConfig() = default; virtual ~IConfig() = default;
virtual bool finalize() = 0;
virtual bool isWatch() const = 0; virtual bool isWatch() const = 0;
virtual bool parseBoolean(int key, bool enable) = 0; virtual bool read(const IJsonReader &reader, const char *fileName) = 0;
virtual bool parseString(int key, const char *arg) = 0;
virtual bool parseUint64(int key, uint64_t arg) = 0;
virtual bool save() = 0; virtual bool save() = 0;
virtual const Algorithm &algorithm() const = 0; virtual const Algorithm &algorithm() const = 0;
virtual const String &fileName() const = 0; virtual const String &fileName() const = 0;
virtual void getJSON(rapidjson::Document &doc) 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 void setFileName(const char *fileName) = 0;
}; };

View file

@ -22,40 +22,31 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef XMRIG_CONFIGWATCHER_H #ifndef XMRIG_ICONFIGTRANSFORM_H
#define XMRIG_CONFIGWATCHER_H #define XMRIG_ICONFIGTRANSFORM_H
#include "base/kernel/interfaces/IWatcherListener.h" #include "common/crypto/Algorithm.h"
#include "base/tools/String.h"
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"
struct option;
namespace xmrig { namespace xmrig {
class IConfigListener; class IJsonReader;
class Watcher; class String;
class ConfigWatcher : public IWatcherListener class IConfigTransform
{ {
public: public:
ConfigWatcher(const String &path, IConfigListener *listener); virtual ~IConfigTransform() = default;
~ConfigWatcher() override;
protected: virtual void transform(rapidjson::Document &doc, int key, const char *arg) = 0;
void onFileChanged(const String &fileName) override;
private:
IConfigListener *m_listener;
Watcher *m_watcher;
}; };
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* __CONFIGWATCHER_H__ */
#endif // XMRIG_ICONFIGTRANSFORM_H

View file

@ -0,0 +1,56 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_IJSONREADER_H
#define XMRIG_IJSONREADER_H
#include "rapidjson/fwd.h"
namespace xmrig {
class IJsonReader
{
public:
virtual ~IJsonReader() = default;
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_IJSONREADER_H

View file

@ -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 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) { 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 xmrig::IStrategy *xmrig::Pools::createStrategy(IStrategyListener *listener) const
{ {
if (active() == 1) { if (active() == 1) {
@ -144,6 +115,10 @@ void xmrig::Pools::load(const rapidjson::Value &pools)
{ {
m_data.clear(); m_data.clear();
if (!pools.IsArray()) {
return;
}
for (const rapidjson::Value &value : pools.GetArray()) { for (const rapidjson::Value &value : pools.GetArray()) {
if (!value.IsObject()) { if (!value.IsObject()) {
continue; continue;

View file

@ -50,28 +50,16 @@ public:
Pools(); Pools();
inline bool setUserpass(const char *userpass) { return current().setUserpass(userpass); }
inline const std::vector<Pool> &data() const { return m_data; } inline const std::vector<Pool> &data() const { return m_data; }
inline int donateLevel() const { return m_donateLevel; } inline int donateLevel() const { return m_donateLevel; }
inline int retries() const { return m_retries; } inline int retries() const { return m_retries; }
inline int retryPause() const { return m_retryPause; } inline int retryPause() const { return m_retryPause; }
inline ProxyDonate proxyDonate() const { return m_proxyDonate; } 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); }
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 isEqual(const Pools &other) const;
bool setUrl(const char *url);
IStrategy *createStrategy(IStrategyListener *listener) const; IStrategy *createStrategy(IStrategyListener *listener) const;
rapidjson::Value toJSON(rapidjson::Document &doc) const; rapidjson::Value toJSON(rapidjson::Document &doc) const;
size_t active() const; size_t active() const;
@ -84,8 +72,6 @@ public:
void setRetryPause(int retryPause); void setRetryPause(int retryPause);
private: private:
Pool &current();
int m_donateLevel; int m_donateLevel;
int m_retries; int m_retries;
int m_retryPause; int m_retryPause;

View file

@ -1,426 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
#ifdef XMRIG_FEATURE_TLS
# include <openssl/opensslv.h>
#endif
#ifdef XMRIG_AMD_PROJECT
# if defined(__APPLE__)
# include <OpenCL/cl.h>
# 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<int>(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<uint64_t>(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<uint64_t>(strtol(arg, nullptr, 10)));
default:
break;
}
return true;
}
bool xmrig::CommonConfig::parseUint64(int key, uint64_t arg)
{
return parseInt(key, static_cast<int>(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;
}

View file

@ -1,262 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <limits.h>
#include <stdio.h>
#include <uv.h>
#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<kParseCommentsFlag | kParseTrailingCommasFlag>(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<offset:%zu>: \"%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());
}
}

View file

@ -176,7 +176,7 @@ void xmrig::Algorithm::parseAlgorithm(const char *algo)
m_algo = INVALID_ALGO; m_algo = INVALID_ALGO;
m_variant = VARIANT_AUTO; m_variant = VARIANT_AUTO;
assert(algo != nullptr); // assert(algo != nullptr);
if (algo == nullptr || strlen(algo) < 1) { if (algo == nullptr || strlen(algo) < 1) {
return; return;
} }

View file

@ -26,89 +26,28 @@
#include <assert.h> #include <assert.h>
#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/cpu/Cpu.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "core/config/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "net/Network.h" #include "net/Network.h"
#ifdef HAVE_SYSLOG_H xmrig::Controller::Controller(Process *process) :
# include "base/io/log/backends/SysLog.h" Base(process),
#endif m_network(nullptr)
#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<IControllerListener *> listeners;
};
xmrig::Controller::Controller(Process *process)
: d_ptr(new ControllerPrivate(process))
{ {
} }
xmrig::Controller::~Controller() xmrig::Controller::~Controller()
{ {
delete d_ptr; delete m_network;
}
xmrig::Api *xmrig::Controller::api() const
{
assert(d_ptr->api != nullptr);
return d_ptr->api;
} }
bool xmrig::Controller::isReady() const bool xmrig::Controller::isReady() const
{ {
return d_ptr->config && d_ptr->network; return Base::isReady() && m_network;
}
xmrig::Config *xmrig::Controller::config() const
{
assert(d_ptr->config != nullptr);
return d_ptr->config;
} }
@ -116,98 +55,36 @@ int xmrig::Controller::init()
{ {
Cpu::init(); Cpu::init();
d_ptr->config = Config::load(d_ptr->process, this); const int rc = Base::init();
if (!d_ptr->config) { if (rc != 0) {
return 1; return rc;
} }
# ifdef XMRIG_FEATURE_API m_network = new Network(this);
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);
return 0; 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*>(config);
for (IControllerListener *listener : d_ptr->listeners) {
listener->onConfigChanged(d_ptr->config, previousConfig);
}
delete previousConfig;
}
void xmrig::Controller::start() void xmrig::Controller::start()
{ {
Base::start();
network()->connect(); network()->connect();
# ifdef XMRIG_FEATURE_API
api()->start();
# endif
save();
} }
void xmrig::Controller::stop() void xmrig::Controller::stop()
{ {
# ifdef XMRIG_FEATURE_API Base::stop();
api()->stop();
# endif
ConfigLoader::release(); delete m_network;
m_network = nullptr;
delete d_ptr->network; }
d_ptr->network = nullptr;
xmrig::Network *xmrig::Controller::network() const
{
assert(m_network != nullptr);
return m_network;
} }

View file

@ -26,45 +26,34 @@
#define XMRIG_CONTROLLER_H #define XMRIG_CONTROLLER_H
#include "base/kernel/interfaces/IConfigListener.h" #include "base/kernel/Base.h"
namespace xmrig { namespace xmrig {
class Api;
class Config;
class ControllerPrivate;
class IControllerListener;
class Network; class Network;
class Process;
class Controller : public IConfigListener class Controller : public Base
{ {
public: public:
Controller(Process *process); Controller(Process *process);
~Controller() override; ~Controller() override;
Api *api() const; bool isReady() const override;
bool isReady() const; int init() override;
Config *config() const; void start() override;
int init(); void stop() override;
Network *network() const;
void addListener(IControllerListener *listener);
void save();
void start();
void stop();
protected: Network *network() const;
void onNewConfig(IConfig *config) override;
private: private:
ControllerPrivate *d_ptr; Network *m_network;
}; };
} /* namespace xmrig */ } // namespace xmrig
#endif /* XMRIG_CONTROLLER_H */ #endif /* XMRIG_CONTROLLER_H */

View file

@ -28,7 +28,7 @@
#include "base/io/log/Log.h" #include "base/io/log/Log.h"
#include "common/config/ConfigLoader.h" #include "base/kernel/interfaces/IJsonReader.h"
#include "common/cpu/Cpu.h" #include "common/cpu/Cpu.h"
#include "core/config/Config.h" #include "core/config/Config.h"
#include "crypto/Asm.h" #include "crypto/Asm.h"
@ -42,7 +42,7 @@
static char affinity_tmp[20] = { 0 }; static char affinity_tmp[20] = { 0 };
xmrig::Config::Config() : xmrig::CommonConfig(), xmrig::Config::Config() :
m_aesMode(AES_AUTO), m_aesMode(AES_AUTO),
m_algoVariant(AV_AUTO), m_algoVariant(AV_AUTO),
m_assembly(ASM_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<Config*>(ConfigLoader::load(process, listener));
}
bool xmrig::Config::finalize() bool xmrig::Config::finalize()
{ {
if (m_state != NoneState) {
return CommonConfig::finalize();
}
if (!CommonConfig::finalize()) {
return false;
}
if (!m_threads.cpu.empty()) { if (!m_threads.cpu.empty()) {
m_threads.mode = Advanced; m_threads.mode = Advanced;
const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT;
@ -173,117 +173,54 @@ bool xmrig::Config::finalize()
} }
m_shouldSave = m_threads.mode == Automatic; 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; return true;
} }
bool xmrig::Config::parseString(int key, const char *arg) void xmrig::Config::setAesMode(const rapidjson::Value &aesMode)
{ {
if (!CommonConfig::parseString(key, arg)) { if (aesMode.IsBool()) {
return false; 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 */ void xmrig::Config::setAlgoVariant(int av)
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"); if (av >= AV_AUTO && av < AV_MAX) {
return parseUint64(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10)); m_algoVariant = static_cast<AlgoVariant>(av);
} }
# 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::setAssembly(const rapidjson::Value &assembly)
{ {
if (!CommonConfig::parseUint64(key, arg)) { m_assembly = Asm::parse(assembly);
return false;
}
switch (key) {
case CPUAffinityKey: /* --cpu-affinity */
if (arg) {
m_threads.mask = static_cast<int64_t>(arg);
}
break;
default:
return parseInt(key, static_cast<int>(arg));
}
return true;
} }
void xmrig::Config::parseJSON(const rapidjson::Value &json) void xmrig::Config::setMaxCpuUsage(int max)
{ {
CommonConfig::parseJSON(json); if (max > 0 && max <= 100) {
m_maxCpuUsage = max;
}
}
const rapidjson::Value &threads = json["threads"];
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()) { if (threads.IsArray()) {
m_threads.cpu.clear();
for (const rapidjson::Value &value : threads.GetArray()) { for (const rapidjson::Value &value : threads.GetArray()) {
if (!value.IsObject()) { if (!value.IsObject()) {
continue; continue;
@ -298,41 +235,12 @@ void xmrig::Config::parseJSON(const rapidjson::Value &json)
} }
} }
} }
else if (threads.IsUint()) {
const unsigned count = threads.GetUint();
if (count < 1024) {
m_threads.count = count;
} }
bool xmrig::Config::parseInt(int key, int arg)
{
switch (key) {
case ThreadsKey: /* --threads */
if (arg >= 0 && arg < 1024) {
m_threads.count = arg;
} }
break;
case AVKey: /* --av */
if (arg >= AV_AUTO && arg < AV_MAX) {
m_algoVariant = static_cast<AlgoVariant>(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;
} }

View file

@ -29,7 +29,7 @@
#include <vector> #include <vector>
#include "common/config/CommonConfig.h" #include "base/kernel/config/BaseConfig.h"
#include "common/xmrig.h" #include "common/xmrig.h"
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"
#include "workers/CpuThread.h" #include "workers/CpuThread.h"
@ -55,7 +55,7 @@ class Process;
* api/worker-id * api/worker-id
* pools/ * pools/
*/ */
class Config : public CommonConfig class Config : public BaseConfig
{ {
public: public:
enum ThreadsMode { enum ThreadsMode {
@ -67,8 +67,7 @@ public:
Config(); Config();
bool reload(const rapidjson::Value &json); bool read(const IJsonReader &reader, const char *fileName) override;
void getJSON(rapidjson::Document &doc) const override; void getJSON(rapidjson::Document &doc) const override;
inline AesMode aesMode() const { return m_aesMode; } inline AesMode aesMode() const { return m_aesMode; }
@ -80,20 +79,16 @@ public:
inline int priority() const { return m_priority; } inline int priority() const { return m_priority; }
inline int threadsCount() const { return static_cast<int>(m_threads.list.size()); } inline int threadsCount() const { return static_cast<int>(m_threads.list.size()); }
inline int64_t affinity() const { return m_threads.mask; } inline int64_t affinity() const { return m_threads.mask; }
inline static IConfig *create() { return new Config(); }
inline ThreadsMode threadsMode() const { return m_threads.mode; } 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: 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; AlgoVariant getAlgoVariant() const;
# ifndef XMRIG_NO_AEON # ifndef XMRIG_NO_AEON

View file

@ -22,50 +22,28 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef XMRIG_CONFIGLOADER_H
#define XMRIG_CONFIGLOADER_H #include "core/config/ConfigTransform.h"
#include "base/kernel/interfaces/IConfig.h"
#include <stdint.h> xmrig::ConfigTransform::ConfigTransform()
#include "rapidjson/fwd.h"
struct option;
namespace xmrig {
class ConfigWatcher;
class IConfigListener;
class IConfig;
class Process;
class ConfigLoader
{ {
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();
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;
};
} /* namespace xmrig */ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const char *arg)
{
BaseTransform::transform(doc, key, arg);
}
#endif /* XMRIG_CONFIGLOADER_H */ void xmrig::ConfigTransform::transformBoolean(rapidjson::Document &doc, int key, bool enable)
{
}
void xmrig::ConfigTransform::transformUint64(rapidjson::Document &doc, int key, uint64_t arg)
{
}

View file

@ -0,0 +1,51 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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 */

View file

@ -22,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef XMRIG_CONFIGLOADER_DEFAULT_H #ifndef XMRIG_CONFIG_DEFAULT_H
#define XMRIG_CONFIGLOADER_DEFAULT_H #define XMRIG_CONFIG_DEFAULT_H
namespace xmrig { namespace xmrig {
@ -85,6 +85,7 @@ R"===(
#endif #endif
} /* namespace xmrig */ } // namespace xmrig
#endif /* XMRIG_CONFIGLOADER_DEFAULT_H */
#endif /* XMRIG_CONFIG_DEFAULT_H */

View file

@ -22,8 +22,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef XMRIG_CONFIGLOADER_PLATFORM_H #ifndef XMRIG_CONFIG_PLATFORM_H
#define XMRIG_CONFIGLOADER_PLATFORM_H #define XMRIG_CONFIG_PLATFORM_H
#ifdef _MSC_VER #ifdef _MSC_VER
@ -33,17 +33,17 @@
#endif #endif
#include "common/interfaces/IConfig.h" #include "base/kernel/interfaces/IConfig.h"
#include "version.h" #include "version.h"
namespace xmrig { 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 }, { "algo", 1, nullptr, IConfig::AlgorithmKey },
{ "api-worker-id", 1, nullptr, IConfig::ApiWorkerIdKey }, { "api-worker-id", 1, nullptr, IConfig::ApiWorkerIdKey },
{ "api-id", 1, nullptr, IConfig::ApiIdKey }, { "api-id", 1, nullptr, IConfig::ApiIdKey },
@ -65,7 +65,6 @@ static struct option const options[] = {
{ "max-cpu-usage", 1, nullptr, IConfig::MaxCPUUsageKey }, { "max-cpu-usage", 1, nullptr, IConfig::MaxCPUUsageKey },
{ "nicehash", 0, nullptr, IConfig::NicehashKey }, { "nicehash", 0, nullptr, IConfig::NicehashKey },
{ "no-color", 0, nullptr, IConfig::ColorKey }, { "no-color", 0, nullptr, IConfig::ColorKey },
{ "no-watch", 0, nullptr, IConfig::WatchKey },
{ "no-huge-pages", 0, nullptr, IConfig::HugePagesKey }, { "no-huge-pages", 0, nullptr, IConfig::HugePagesKey },
{ "variant", 1, nullptr, IConfig::VariantKey }, { "variant", 1, nullptr, IConfig::VariantKey },
{ "pass", 1, nullptr, IConfig::PasswordKey }, { "pass", 1, nullptr, IConfig::PasswordKey },
@ -115,21 +114,12 @@ static struct option const config_options[] = {
{ "syslog", 0, nullptr, IConfig::SyslogKey }, { "syslog", 0, nullptr, IConfig::SyslogKey },
{ "threads", 1, nullptr, IConfig::ThreadsKey }, { "threads", 1, nullptr, IConfig::ThreadsKey },
{ "user-agent", 1, nullptr, IConfig::UserAgentKey }, { "user-agent", 1, nullptr, IConfig::UserAgentKey },
{ "watch", 0, nullptr, IConfig::WatchKey },
{ "hw-aes", 0, nullptr, IConfig::HardwareAESKey },
{ "asm", 1, nullptr, IConfig::AssemblyKey }, { "asm", 1, nullptr, IConfig::AssemblyKey },
{ "autosave", 0, nullptr, IConfig::AutoSaveKey },
{ nullptr, 0, nullptr, 0 } { nullptr, 0, nullptr, 0 }
}; };
static struct option const api_options[] = { } // namespace xmrig
{ "worker-id", 1, nullptr, IConfig::ApiWorkerIdKey },
{ "id", 1, nullptr, IConfig::ApiIdKey },
{ nullptr, 0, nullptr, 0 }
};
} /* namespace xmrig */ #endif /* XMRIG_CONFIG_PLATFORM_H */
#endif /* XMRIG_CONFIGLOADER_PLATFORM_H */

View file

@ -30,7 +30,7 @@
#include "api/interfaces/IApiListener.h" #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/IStrategyListener.h"
#include "base/kernel/interfaces/ITimerListener.h" #include "base/kernel/interfaces/ITimerListener.h"
#include "interfaces/IJobResultListener.h" #include "interfaces/IJobResultListener.h"
@ -45,7 +45,7 @@ class Controller;
class IStrategy; 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: public:
Network(Controller *controller); Network(Controller *controller);