New config subsystem

This commit is contained in:
XMRig 2019-04-05 22:14:01 +07:00
parent 85ee55f309
commit fa2a0b9b79
37 changed files with 1628 additions and 1254 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -27,6 +27,13 @@
#include "rapidjson/document.h"
namespace xmrig {
static const rapidjson::Value kNullValue;
}
bool xmrig::Json::getBool(const rapidjson::Value &obj, const char *key, bool defaultValue)
{
auto i = obj.FindMember(key);
@ -49,6 +56,39 @@ const char *xmrig::Json::getString(const rapidjson::Value &obj, const char *key,
}
const rapidjson::Value &xmrig::Json::getArray(const rapidjson::Value &obj, const char *key)
{
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsArray()) {
return i->value;
}
return kNullValue;
}
const rapidjson::Value &xmrig::Json::getObject(const rapidjson::Value &obj, const char *key)
{
auto i = obj.FindMember(key);
if (i != obj.MemberEnd() && i->value.IsObject()) {
return i->value;
}
return kNullValue;
}
const rapidjson::Value &xmrig::Json::getValue(const rapidjson::Value &obj, const char *key)
{
auto i = obj.FindMember(key);
if (i != obj.MemberEnd()) {
return i->value;
}
return kNullValue;
}
int xmrig::Json::getInt(const rapidjson::Value &obj, const char *key, int defaultValue)
{
auto i = obj.FindMember(key);
@ -91,3 +131,9 @@ unsigned xmrig::Json::getUint(const rapidjson::Value &obj, const char *key, unsi
return defaultValue;
}
bool xmrig::JsonReader::isEmpty() const
{
return !m_obj.IsObject() || m_obj.ObjectEmpty();
}

View File

@ -26,6 +26,7 @@
#define XMRIG_JSON_H
#include "base/kernel/interfaces/IJsonReader.h"
#include "rapidjson/fwd.h"
@ -37,6 +38,9 @@ class Json
public:
static bool getBool(const rapidjson::Value &obj, const char *key, bool defaultValue = false);
static const char *getString(const rapidjson::Value &obj, const char *key, const char *defaultValue = nullptr);
static const rapidjson::Value &getArray(const rapidjson::Value &obj, const char *key);
static const rapidjson::Value &getObject(const rapidjson::Value &obj, const char *key);
static const rapidjson::Value &getValue(const rapidjson::Value &obj, const char *key);
static int getInt(const rapidjson::Value &obj, const char *key, int defaultValue = 0);
static int64_t getInt64(const rapidjson::Value &obj, const char *key, int64_t defaultValue = 0);
static uint64_t getUint64(const rapidjson::Value &obj, const char *key, uint64_t defaultValue = 0);
@ -47,6 +51,28 @@ public:
};
class JsonReader : public IJsonReader
{
public:
inline JsonReader(const rapidjson::Value &obj) : m_obj(obj) {}
inline bool getBool(const char *key, bool defaultValue = false) const override { return Json::getBool(m_obj, key, defaultValue); }
inline const char *getString(const char *key, const char *defaultValue = nullptr) const override { return Json::getString(m_obj, key, defaultValue); }
inline const rapidjson::Value &getArray(const char *key) const override { return Json::getArray(m_obj, key); }
inline const rapidjson::Value &getObject(const char *key) const override { return Json::getObject(m_obj, key); }
inline const rapidjson::Value &getValue(const char *key) const override { return Json::getValue(m_obj, key); }
inline int getInt(const char *key, int defaultValue = 0) const override { return Json::getInt(m_obj, key, defaultValue); }
inline int64_t getInt64(const char *key, int64_t defaultValue = 0) const override { return Json::getInt64(m_obj, key, defaultValue); }
inline uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const override { return Json::getUint64(m_obj, key, defaultValue); }
inline unsigned getUint(const char *key, unsigned defaultValue = 0) const override { return Json::getUint(m_obj, key, defaultValue); }
bool isEmpty() const override;
private:
const rapidjson::Value &m_obj;
};
} /* namespace xmrig */

201
src/base/io/JsonChain.cpp Normal file
View File

@ -0,0 +1,201 @@
/* 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));
}
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;
}

74
src/base/io/JsonChain.h Normal file
View File

@ -0,0 +1,74 @@
/* 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);
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;
}
# elif defined(__GNUC__)
const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_TRUNC);
const int fd = _wopen(toUtf16(fileName).c_str(), _O_WRONLY | _O_BINARY | _O_CREAT | _O_TRUNC);
if (fd == -1) {
return false;
}

283
src/base/kernel/Base.cpp Normal file
View File

@ -0,0 +1,283 @@
/* 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_default.h"
#include "core/config/Config.h"
#include "core/config/ConfigTransform.h"
#ifdef HAVE_SYSLOG_H
# include "base/io/log/backends/SysLog.h"
#endif
#ifdef XMRIG_FEATURE_API
# include "api/Api.h"
#endif
class xmrig::BasePrivate
{
public:
inline BasePrivate(Process *process) :
api(nullptr),
config(nullptr),
process(process),
watcher(nullptr)
{}
inline ~BasePrivate()
{
# ifdef XMRIG_FEATURE_API
delete api;
# endif
delete config;
delete watcher;
}
inline bool read(const JsonChain &chain, std::unique_ptr<Config> &config)
{
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());
Platform::setProcessPriority(config()->priority());
if (!config()->isBackground()) {
Log::add(new ConsoleLog());
}
if (config()->logFile()) {
Log::add(new FileLog(config()->logFile()));
}
# ifdef HAVE_SYSLOG_H
if (config()->isSyslog()) {
Log::add(new SysLog());
}
# endif
return 0;
}
void xmrig::Base::start()
{
# ifdef XMRIG_FEATURE_API
api()->start();
# endif
if (config()->isShouldSave()) {
config()->save();
}
if (config()->isWatch()) {
d_ptr->watcher = new Watcher(config()->fileName(), this);
}
}
void xmrig::Base::stop()
{
# ifdef XMRIG_FEATURE_API
api()->stop();
# endif
delete d_ptr->watcher;
d_ptr->watcher = nullptr;
}
xmrig::Api *xmrig::Base::api() const
{
assert(d_ptr->api != nullptr);
return d_ptr->api;
}
bool xmrig::Base::reload(const rapidjson::Value &json)
{
JsonReader reader(json);
if (reader.isEmpty()) {
return false;
}
Config *config = new Config();
if (!config->read(reader, d_ptr->config->fileName())) {
delete config;
return false;
}
const bool saved = config->save();
if (config->isWatch() && d_ptr->watcher && saved) {
delete config;
return true;
}
d_ptr->replace(config);
return true;
}
xmrig::Config *xmrig::Base::config() const
{
assert(d_ptr->config != nullptr);
return d_ptr->config;
}
void xmrig::Base::addListener(IBaseListener *listener)
{
d_ptr->listeners.push_back(listener);
}
void xmrig::Base::onFileChanged(const String &fileName)
{
LOG_WARN("\"%s\" was changed, reloading configuration", fileName.data());
JsonChain chain;
chain.addFile(fileName);
Config *config = new Config();
if (!config->read(chain, chain.fileName())) {
LOG_ERR("reloading failed");
delete config;
return;
}
d_ptr->replace(config);
}

View File

@ -22,42 +22,50 @@
* 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 "common/config/ConfigLoader.h"
#include "common/config/ConfigWatcher.h"
#include "core/config/Config.h"
#include "base/kernel/interfaces/IWatcherListener.h"
#include "rapidjson/fwd.h"
xmrig::ConfigWatcher::ConfigWatcher(const String &path, IConfigListener *listener) :
m_listener(listener)
namespace xmrig {
class Api;
class Config;
class BasePrivate;
class IBaseListener;
class Process;
class Base : public IWatcherListener
{
m_watcher = new Watcher(path, this);
}
public:
Base(Process *process);
~Base() override;
virtual bool isReady() const;
virtual int init();
virtual void start();
virtual void stop();
Api *api() const;
bool reload(const rapidjson::Value &json);
Config *config() const;
void addListener(IBaseListener *listener);
protected:
void onFileChanged(const String &fileName) override;
private:
BasePrivate *d_ptr;
};
xmrig::ConfigWatcher::~ConfigWatcher()
{
delete m_watcher;
}
} /* namespace xmrig */
void xmrig::ConfigWatcher::onFileChanged(const String &fileName)
{
LOG_WARN("\"%s\" was changed, reloading configuration", fileName.data());
IConfig *config = Config::create();
ConfigLoader::loadFromFile(config, fileName);
if (!config->finalize()) {
LOG_ERR("reloading failed");
delete config;
return;
}
m_listener->onNewConfig(config);
}
#endif /* XMRIG_BASE_H */

View File

@ -0,0 +1,195 @@
/* 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);
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/>.
*/
#ifndef XMRIG_COMMONCONFIG_H
#define XMRIG_COMMONCONFIG_H
#ifndef XMRIG_BASECONFIG_H
#define XMRIG_BASECONFIG_H
#include "base/kernel/interfaces/IConfig.h"
#include "base/net/http/Http.h"
#include "base/net/stratum/Pools.h"
#include "common/interfaces/IConfig.h"
#include "common/xmrig.h"
struct option;
namespace xmrig {
class CommonConfig : public IConfig
class IJsonReader;
class BaseConfig : public IConfig
{
public:
CommonConfig();
BaseConfig();
inline bool isAutoSave() const { return m_autoSave; }
inline bool isBackground() const { return m_background; }
inline bool isDryRun() const { return m_dryRun; }
inline bool isSyslog() const { return m_syslog; }
inline const String &apiId() const { return m_apiId; }
inline const String &apiWorkerId() const { return m_apiWorkerId; }
inline const char *logFile() const { return m_logFile.data(); }
inline const char *userAgent() const { return m_userAgent.data(); }
inline const Http &http() const { return m_http; }
inline const Pools &pools() const { return m_pools; }
inline int printTime() const { return m_printTime; }
inline const String &apiId() const { return m_apiId; }
inline const String &apiWorkerId() const { return m_apiWorkerId; }
inline uint32_t printTime() const { return m_printTime; }
inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); }
inline const Algorithm &algorithm() const override { return m_algorithm; }
inline const String &fileName() const override { return m_fileName; }
inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); }
inline const Algorithm &algorithm() const override { return m_algorithm; }
inline const String &fileName() const override { return m_fileName; }
inline void setFileName(const char *fileName) override { m_fileName = fileName; }
bool read(const IJsonReader &reader, const char *fileName) override;
bool save() override;
void printVersions();
protected:
enum State {
NoneState,
ReadyState,
ErrorState
};
bool finalize() override;
bool parseBoolean(int key, bool enable) override;
bool parseString(int key, const char *arg) override;
bool parseUint64(int key, uint64_t arg) override;
void parseJSON(const rapidjson::Value &json) override;
void setFileName(const char *fileName) override;
Algorithm m_algorithm;
bool m_adjusted;
bool m_autoSave;
bool m_background;
bool m_dryRun;
@ -83,20 +77,20 @@ protected:
bool m_upgrade;
bool m_watch;
Http m_http;
int m_printTime;
Pools m_pools;
State m_state;
String m_apiId;
String m_apiWorkerId;
String m_fileName;
String m_logFile;
String m_userAgent;
uint32_t m_printTime;
private:
bool parseInt(int key, int arg);
inline void setPrintTime(uint32_t printTime) { if (printTime <= 3600) { m_printTime = printTime; } }
};
} /* namespace xmrig */
} // namespace xmrig
#endif /* XMRIG_COMMONCONFIG_H */
#endif /* XMRIG_BASECONFIG_H */

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<const char *>(doc, "algo", arg);
case IConfig::UserpassKey: /* --userpass */
return add<const char *>(doc, kPools, "userpass", arg);
case IConfig::UrlKey: /* --url */
return add<const char *>(doc, kPools, "url", arg, true);
case IConfig::UserKey: /* --user */
return add<const char *>(doc, kPools, "user", arg);
case IConfig::PasswordKey: /* --pass */
return add<const char *>(doc, kPools, "pass", arg);
case IConfig::RigIdKey: /* --rig-id */
return add<const char *>(doc, kPools, "rig-id", arg);
case IConfig::FingerprintKey: /* --tls-fingerprint */
return add<const char *>(doc, kPools, "tls-fingerprint", arg);
case IConfig::VariantKey: /* --variant */
return add<const char *>(doc, kPools, "variant", arg);
case IConfig::LogFileKey: /* --log-file */
return set<const char *>(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<const char *>(doc, kHttp, "access-token", arg);
# endif
case IConfig::HttpAccessTokenKey: /* --http-access-token */
return set<const char *>(doc, kHttp, "access-token", arg);
case IConfig::HttpHostKey: /* --http-host */
return set<const char *>(doc, kHttp, "host", arg);
case IConfig::ApiWorkerIdKey: /* --api-worker-id */
return set<const char *>(doc, kApi, "worker-id", arg);
case IConfig::ApiIdKey: /* --api-id */
return set<const char *>(doc, kApi, "id", arg);
case IConfig::UserAgentKey: /* --user-agent */
return set<const char *>(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<bool>(doc, "background", enable);
case IConfig::SyslogKey: /* --syslog */
return set<bool>(doc, "syslog", enable);
case IConfig::KeepAliveKey: /* --keepalive */
return add<bool>(doc, kPools, "keepalive", enable);
case IConfig::TlsKey: /* --tls */
return add<bool>(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<bool>(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<bool>(doc, kHttp, "restricted", enable);
# endif
case IConfig::HttpRestrictedKey: /* --http-no-restricted */
return set<bool>(doc, kHttp, "restricted", enable);
case IConfig::HttpEnabledKey: /* --http-enabled */
return set<bool>(doc, kHttp, "enabled", enable);
case IConfig::DryRunKey: /* --dry-run */
return set<bool>(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<uint64_t>(doc, "retries", arg);
case IConfig::RetryPauseKey: /* --retry-pause */
return set<uint64_t>(doc, "retry-pause", arg);
case IConfig::DonateLevelKey: /* --donate-level */
return set<uint64_t>(doc, "donate-level", arg);
case IConfig::ProxyDonateKey: /* --donate-over-proxy */
return set<uint64_t>(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<uint64_t>(doc, kHttp, "port", arg);
# endif
case IConfig::HttpPort: /* --http-port */
return set<uint64_t>(doc, kHttp, "port", arg);
case IConfig::PrintTimeKey: /* --print-time */
return set<uint64_t>(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/>.
*/
#ifndef XMRIG_ICONTROLLERLISTENER_H
#define XMRIG_ICONTROLLERLISTENER_H
#ifndef XMRIG_IBASELISTENER_H
#define XMRIG_IBASELISTENER_H
namespace xmrig {
@ -32,10 +32,10 @@ namespace xmrig {
class Config;
class IControllerListener
class IBaseListener
{
public:
virtual ~IControllerListener() = default;
virtual ~IBaseListener() = default;
virtual void onConfigChanged(Config *config, Config *previousConfig) = 0;
};
@ -44,4 +44,4 @@ public:
} /* namespace xmrig */
#endif // XMRIG_ICONTROLLERLISTENER_H
#endif // XMRIG_IBASELISTENER_H

View File

@ -33,6 +33,7 @@
namespace xmrig {
class IJsonReader;
class String;
@ -66,10 +67,8 @@ public:
UserpassKey = 'O',
VariantKey = 1010,
VerboseKey = 1100,
WatchKey = 1105,
TlsKey = 1013,
FingerprintKey = 1014,
AutoSaveKey = 1016,
ProxyDonateKey = 1017,
# ifdef XMRIG_DEPRECATED
@ -92,7 +91,7 @@ public:
MaxCPUUsageKey = 1004,
SafeKey = 1005,
ThreadsKey = 't',
HardwareAESKey = 1011,
// HardwareAESKey = 1011,
AssemblyKey = 1015,
// xmrig amd
@ -141,17 +140,13 @@ public:
virtual ~IConfig() = default;
virtual bool finalize() = 0;
virtual bool isWatch() const = 0;
virtual bool parseBoolean(int key, bool enable) = 0;
virtual bool parseString(int key, const char *arg) = 0;
virtual bool parseUint64(int key, uint64_t arg) = 0;
virtual bool save() = 0;
virtual const Algorithm &algorithm() const = 0;
virtual const String &fileName() const = 0;
virtual void getJSON(rapidjson::Document &doc) const = 0;
virtual void parseJSON(const rapidjson::Value &json) = 0;
virtual void setFileName(const char *fileName) = 0;
virtual bool isWatch() const = 0;
virtual bool read(const IJsonReader &reader, const char *fileName) = 0;
virtual bool save() = 0;
virtual const Algorithm &algorithm() const = 0;
virtual const String &fileName() const = 0;
virtual void getJSON(rapidjson::Document &doc) const = 0;
virtual void setFileName(const char *fileName) = 0;
};

View File

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

View File

@ -22,50 +22,35 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_CONFIGLOADER_H
#define XMRIG_CONFIGLOADER_H
#include <stdint.h>
#ifndef XMRIG_IJSONREADER_H
#define XMRIG_IJSONREADER_H
#include "rapidjson/fwd.h"
struct option;
namespace xmrig {
class ConfigWatcher;
class IConfigListener;
class IConfig;
class Process;
class ConfigLoader
class IJsonReader
{
public:
static bool loadFromFile(IConfig *config, const char *fileName);
static bool loadFromJSON(IConfig *config, const char *json);
static bool loadFromJSON(IConfig *config, const rapidjson::Value &json);
static bool reload(IConfig *oldConfig, const rapidjson::Value &json);
static bool watch(IConfig *config);
static IConfig *load(Process *process, IConfigListener *listener);
static void release();
virtual ~IJsonReader() = default;
private:
static bool getJSON(const char *fileName, rapidjson::Document &doc);
static bool parseArg(IConfig *config, int key, const char *arg);
static void parseJSON(IConfig *config, const struct option *option, const rapidjson::Value &object);
static ConfigWatcher *m_watcher;
static IConfigListener *m_listener;
virtual bool getBool(const char *key, bool defaultValue = false) const = 0;
virtual bool isEmpty() const = 0;
virtual const char *getString(const char *key, const char *defaultValue = nullptr) const = 0;
virtual const rapidjson::Value &getArray(const char *key) const = 0;
virtual const rapidjson::Value &getObject(const char *key) const = 0;
virtual const rapidjson::Value &getValue(const char *key) const = 0;
virtual int getInt(const char *key, int defaultValue = 0) const = 0;
virtual int64_t getInt64(const char *key, int64_t defaultValue = 0) const = 0;
virtual uint64_t getUint64(const char *key, uint64_t defaultValue = 0) const = 0;
virtual unsigned getUint(const char *key, unsigned defaultValue = 0) const = 0;
};
} /* namespace xmrig */
#endif /* XMRIG_CONFIGLOADER_H */
#endif // XMRIG_IJSONREADER_H

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
{
if (m_data.size() != other.m_data.size() || m_retries != other.m_retries || m_retryPause != other.m_retryPause) {
@ -64,25 +54,6 @@ bool xmrig::Pools::isEqual(const Pools &other) const
}
bool xmrig::Pools::setUrl(const char *url)
{
if (m_data.empty() || m_data.back().isValid()) {
Pool pool(url);
if (pool.isValid()) {
m_data.push_back(std::move(pool));
return true;
}
return false;
}
current().parse(url);
return m_data.back().isValid();
}
xmrig::IStrategy *xmrig::Pools::createStrategy(IStrategyListener *listener) const
{
if (active() == 1) {
@ -144,6 +115,10 @@ void xmrig::Pools::load(const rapidjson::Value &pools)
{
m_data.clear();
if (!pools.IsArray()) {
return;
}
for (const rapidjson::Value &value : pools.GetArray()) {
if (!value.IsObject()) {
continue;

View File

@ -50,28 +50,16 @@ public:
Pools();
inline bool setUserpass(const char *userpass) { return current().setUserpass(userpass); }
inline const std::vector<Pool> &data() const { return m_data; }
inline int donateLevel() const { return m_donateLevel; }
inline int retries() const { return m_retries; }
inline int retryPause() const { return m_retryPause; }
inline ProxyDonate proxyDonate() const { return m_proxyDonate; }
inline void setFingerprint(const char *fingerprint) { current().setFingerprint(fingerprint); }
inline void setKeepAlive(bool enable) { current().setKeepAlive(enable); }
inline void setKeepAlive(int keepAlive) { current().setKeepAlive(keepAlive); }
inline void setNicehash(bool enable) { current().setNicehash(enable); }
inline void setPassword(const char *password) { current().setPassword(password); }
inline void setRigId(const char *rigId) { current().setRigId(rigId); }
inline void setTLS(bool enable) { current().setTLS(enable); }
inline void setUser(const char *user) { current().setUser(user); }
inline void setVariant(const char *variant) { current().algorithm().parseVariant(variant); }
inline void setVariant(int variant) { current().algorithm().parseVariant(variant); }
inline bool operator!=(const Pools &other) const { return !isEqual(other); }
inline bool operator==(const Pools &other) const { return isEqual(other); }
bool isEqual(const Pools &other) const;
bool setUrl(const char *url);
IStrategy *createStrategy(IStrategyListener *listener) const;
rapidjson::Value toJSON(rapidjson::Document &doc) const;
size_t active() const;
@ -84,8 +72,6 @@ public:
void setRetryPause(int retryPause);
private:
Pool &current();
int m_donateLevel;
int m_retries;
int m_retryPause;

File diff suppressed because it is too large Load Diff

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_variant = VARIANT_AUTO;
assert(algo != nullptr);
// assert(algo != nullptr);
if (algo == nullptr || strlen(algo) < 1) {
return;
}

View File

@ -26,89 +26,28 @@
#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/Platform.h"
#include "core/config/Config.h"
#include "core/Controller.h"
#include "net/Network.h"
#ifdef HAVE_SYSLOG_H
# include "base/io/log/backends/SysLog.h"
#endif
#ifdef XMRIG_FEATURE_API
# include "api/Api.h"
#endif
class xmrig::ControllerPrivate
{
public:
inline ControllerPrivate(Process *process) :
api(nullptr),
config(nullptr),
network(nullptr),
process(process)
{}
inline ~ControllerPrivate()
{
# ifdef XMRIG_FEATURE_API
delete api;
# endif
delete network;
delete config;
}
Api *api;
Config *config;
Network *network;
Process *process;
std::vector<IControllerListener *> listeners;
};
xmrig::Controller::Controller(Process *process)
: d_ptr(new ControllerPrivate(process))
xmrig::Controller::Controller(Process *process) :
Base(process),
m_network(nullptr)
{
}
xmrig::Controller::~Controller()
{
delete d_ptr;
}
xmrig::Api *xmrig::Controller::api() const
{
assert(d_ptr->api != nullptr);
return d_ptr->api;
delete m_network;
}
bool xmrig::Controller::isReady() const
{
return d_ptr->config && d_ptr->network;
}
xmrig::Config *xmrig::Controller::config() const
{
assert(d_ptr->config != nullptr);
return d_ptr->config;
return Base::isReady() && m_network;
}
@ -116,98 +55,36 @@ int xmrig::Controller::init()
{
Cpu::init();
d_ptr->config = Config::load(d_ptr->process, this);
if (!d_ptr->config) {
return 1;
const int rc = Base::init();
if (rc != 0) {
return rc;
}
# ifdef XMRIG_FEATURE_API
d_ptr->api = new Api(this);
# endif
Platform::init(config()->userAgent());
Platform::setProcessPriority(d_ptr->config->priority());
if (!config()->isBackground()) {
Log::add(new ConsoleLog());
}
if (config()->logFile()) {
Log::add(new FileLog(config()->logFile()));
}
# ifdef HAVE_SYSLOG_H
if (config()->isSyslog()) {
Log::add(new SysLog());
}
# endif
d_ptr->network = new Network(this);
m_network = new Network(this);
return 0;
}
xmrig::Network *xmrig::Controller::network() const
{
assert(d_ptr->network != nullptr);
return d_ptr->network;
}
void xmrig::Controller::addListener(IControllerListener *listener)
{
d_ptr->listeners.push_back(listener);
}
void xmrig::Controller::save()
{
if (!config()) {
return;
}
if (d_ptr->config->isShouldSave()) {
d_ptr->config->save();
}
ConfigLoader::watch(d_ptr->config);
}
void xmrig::Controller::onNewConfig(IConfig *config)
{
Config *previousConfig = d_ptr->config;
d_ptr->config = static_cast<Config*>(config);
for (IControllerListener *listener : d_ptr->listeners) {
listener->onConfigChanged(d_ptr->config, previousConfig);
}
delete previousConfig;
}
void xmrig::Controller::start()
{
Base::start();
network()->connect();
# ifdef XMRIG_FEATURE_API
api()->start();
# endif
save();
}
void xmrig::Controller::stop()
{
# ifdef XMRIG_FEATURE_API
api()->stop();
# endif
Base::stop();
ConfigLoader::release();
delete d_ptr->network;
d_ptr->network = nullptr;
delete m_network;
m_network = nullptr;
}
xmrig::Network *xmrig::Controller::network() const
{
assert(m_network != nullptr);
return m_network;
}

View File

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

Some files were not shown because too many files have changed in this diff Show More