From 04a95e3aa8fb913f75286f3a18ceedbe1b6cd84b Mon Sep 17 00:00:00 2001 From: xmrig Date: Thu, 22 Mar 2018 10:19:29 +0700 Subject: [PATCH 001/109] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b00b1f1d..383d599a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # v2.5.0 -- [#434](https://github.com/xmrig/xmrig/issues/434) **Added support for Monero v7 PoW, scheduled on March 28.** +- [#434](https://github.com/xmrig/xmrig/issues/434) **Added support for Monero v7 PoW, scheduled on April 6.** - Added full IPv6 support. - Added protocol extension, when use the miner with xmrig-proxy 2.5+ no more need manually specify `nicehash` option. - [#123](https://github.com/xmrig/xmrig-proxy/issues/123) Fixed regression (all versions since 2.4 affected) fragmented responses from pool/proxy was parsed incorrectly. From 9fe863b5d7d554724fa79e454d662066f3a22aaf Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 27 Mar 2018 14:01:38 +0700 Subject: [PATCH 002/109] Background http changes from proxy. --- CMakeLists.txt | 17 ++- src/App.cpp | 11 +- src/App.h | 10 +- src/api/Api.cpp | 45 +++--- src/api/Api.h | 20 ++- src/api/{ApiState.cpp => ApiRouter.cpp} | 91 ++++++++---- src/api/{ApiState.h => ApiRouter.h} | 36 +++-- src/api/HttpBody.h | 69 ++++++++++ src/api/HttpReply.h | 53 +++++++ src/api/HttpRequest.cpp | 175 ++++++++++++++++++++++++ src/api/HttpRequest.h | 84 ++++++++++++ src/api/Httpd.cpp | 138 ++++++++++++------- src/api/Httpd.h | 25 +++- src/core/Controller.cpp | 125 +++++++++++++++++ src/core/Controller.h | 63 +++++++++ src/interfaces/IControllerListener.h | 46 +++++++ src/interfaces/IWatcherListener.h | 46 +++++++ 17 files changed, 929 insertions(+), 125 deletions(-) rename src/api/{ApiState.cpp => ApiRouter.cpp} (77%) rename src/api/{ApiState.h => ApiRouter.h} (62%) create mode 100644 src/api/HttpBody.h create mode 100644 src/api/HttpReply.h create mode 100644 src/api/HttpRequest.cpp create mode 100644 src/api/HttpRequest.h create mode 100644 src/core/Controller.cpp create mode 100644 src/core/Controller.h create mode 100644 src/interfaces/IControllerListener.h create mode 100644 src/interfaces/IWatcherListener.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8823b078..1be15601 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,17 +12,19 @@ include (cmake/cpu.cmake) set(HEADERS src/api/Api.h - src/api/ApiState.h src/api/NetworkState.h src/App.h src/Console.h + src/core/Controller.h src/Cpu.h src/interfaces/IClientListener.h src/interfaces/IConsoleListener.h + src/interfaces/IControllerListener.h src/interfaces/IJobResultListener.h src/interfaces/ILogBackend.h src/interfaces/IStrategy.h src/interfaces/IStrategyListener.h + src/interfaces/IWatcherListener.h src/interfaces/IWorker.h src/log/ConsoleLog.h src/log/FileLog.h @@ -74,10 +76,10 @@ endif() set(SOURCES src/api/Api.cpp - src/api/ApiState.cpp src/api/NetworkState.cpp src/App.cpp src/Console.cpp + src/core/Controller.cpp src/log/ConsoleLog.cpp src/log/FileLog.cpp src/log/Log.cpp @@ -192,7 +194,16 @@ if (WITH_HTTPD) if (MHD_FOUND) include_directories(${MHD_INCLUDE_DIRS}) - set(HTTPD_SOURCES src/api/Httpd.h src/api/Httpd.cpp) + set(HTTPD_SOURCES + src/api/ApiRouter.h + src/api/HttpBody.h + src/api/Httpd.h + src/api/HttpReply.h + src/api/HttpRequest.h + src/api/ApiRouter.cpp + src/api/Httpd.cpp + src/api/HttpRequest.cpp + ) else() message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support") endif() diff --git a/src/App.cpp b/src/App.cpp index d656acc8..ed425f90 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,6 +29,7 @@ #include "api/Api.h" #include "App.h" #include "Console.h" +#include "core/Controller.h" #include "Cpu.h" #include "crypto/CryptoNight.h" #include "log/ConsoleLog.h" @@ -64,6 +65,8 @@ App::App(int argc, char **argv) : { m_self = this; + m_controller = new xmrig::Controller(); + Cpu::init(); m_options = Options::parse(argc, argv); if (!m_options) { @@ -138,11 +141,11 @@ int App::exec() } # ifndef XMRIG_NO_API - Api::start(); + Api::start(m_controller); # endif # ifndef XMRIG_NO_HTTPD - m_httpd = new Httpd(m_options->apiPort(), m_options->apiToken()); + m_httpd = new Httpd(m_options->apiPort(), m_options->apiToken(), true, true); m_httpd->start(); # endif diff --git a/src/App.h b/src/App.h index 1b96040d..9116a79a 100644 --- a/src/App.h +++ b/src/App.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,6 +37,11 @@ class Network; class Options; +namespace xmrig { + class Controller; +} + + class App : public IConsoleListener { public: @@ -64,6 +69,7 @@ private: uv_signal_t m_sigHUP; uv_signal_t m_sigINT; uv_signal_t m_sigTERM; + xmrig::Controller *m_controller; }; diff --git a/src/api/Api.cpp b/src/api/Api.cpp index 729ebccd..36859136 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,17 +25,17 @@ #include "api/Api.h" -#include "api/ApiState.h" +#include "api/ApiRouter.h" +#include "api/HttpReply.h" +#include "api/HttpRequest.h" -ApiState *Api::m_state = nullptr; -uv_mutex_t Api::m_mutex; +ApiRouter *Api::m_router = nullptr; -bool Api::start() +bool Api::start(xmrig::Controller *controller) { - uv_mutex_init(&m_mutex); - m_state = new ApiState(); + m_router = new ApiRouter(controller); return true; } @@ -43,43 +43,40 @@ bool Api::start() void Api::release() { - delete m_state; + delete m_router; } -char *Api::get(const char *url, int *status) +void Api::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) { - if (!m_state) { - return nullptr; + if (!m_router) { + reply.status = 500; + return; } - uv_mutex_lock(&m_mutex); - char *buf = m_state->get(url, status); - uv_mutex_unlock(&m_mutex); + if (req.method() == xmrig::HttpRequest::Get) { + return m_router->get(req, reply); + } - return buf; + m_router->exec(req, reply); } void Api::tick(const Hashrate *hashrate) { - if (!m_state) { + if (!m_router) { return; } - uv_mutex_lock(&m_mutex); - m_state->tick(hashrate); - uv_mutex_unlock(&m_mutex); + m_router->tick(hashrate); } void Api::tick(const NetworkState &network) { - if (!m_state) { + if (!m_router) { return; } - uv_mutex_lock(&m_mutex); - m_state->tick(network); - uv_mutex_unlock(&m_mutex); + m_router->tick(network); } diff --git a/src/api/Api.h b/src/api/Api.h index 72c65c3c..43c7b17e 100644 --- a/src/api/Api.h +++ b/src/api/Api.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,24 +28,30 @@ #include -class ApiState; +class ApiRouter; class Hashrate; class NetworkState; +namespace xmrig { + class Controller; + class HttpReply; + class HttpRequest; +} + + class Api { public: - static bool start(); + static bool start(xmrig::Controller *controller); static void release(); - static char *get(const char *url, int *status); + static void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply); static void tick(const Hashrate *hashrate); static void tick(const NetworkState &results); private: - static ApiState *m_state; - static uv_mutex_t m_mutex; + static ApiRouter *m_router; }; #endif /* __API_H__ */ diff --git a/src/api/ApiState.cpp b/src/api/ApiRouter.cpp similarity index 77% rename from src/api/ApiState.cpp rename to src/api/ApiRouter.cpp index c963a1d6..6ee8e7a4 100644 --- a/src/api/ApiState.cpp +++ b/src/api/ApiRouter.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,7 +32,9 @@ #endif -#include "api/ApiState.h" +#include "api/ApiRouter.h" +#include "api/HttpReply.h" +#include "api/HttpRequest.h" #include "Cpu.h" #include "Mem.h" #include "net/Job.h" @@ -61,7 +63,8 @@ static inline double normalize(double d) } -ApiState::ApiState() +ApiRouter::ApiRouter(xmrig::Controller *controller) : + m_controller(controller) { m_threads = Options::i()->threads(); m_hashrate = new double[m_threads * 3](); @@ -69,24 +72,18 @@ ApiState::ApiState() memset(m_totalHashrate, 0, sizeof(m_totalHashrate)); memset(m_workerId, 0, sizeof(m_workerId)); - if (Options::i()->apiWorkerId()) { - strncpy(m_workerId, Options::i()->apiWorkerId(), sizeof(m_workerId) - 1); - } - else { - gethostname(m_workerId, sizeof(m_workerId) - 1); - } - + setWorkerId(Options::i()->apiWorkerId()); genId(); } -ApiState::~ApiState() +ApiRouter::~ApiRouter() { delete [] m_hashrate; } -char *ApiState::get(const char *url, int *status) const +void ApiRouter::ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const { rapidjson::Document doc; doc.SetObject(); @@ -97,11 +94,22 @@ char *ApiState::get(const char *url, int *status) const getResults(doc); getConnection(doc); - return finalize(doc); + return finalize(reply, doc); } -void ApiState::tick(const Hashrate *hashrate) +void ApiRouter::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) +{ +// if (req.method() == xmrig::HttpRequest::Put && req.match("/1/config")) { +// m_controller->config()->reload(req.body()); +// return; +// } + + reply.status = 404; +} + + +void ApiRouter::tick(const Hashrate *hashrate) { for (int i = 0; i < m_threads; ++i) { m_hashrate[i * 3] = hashrate->calc((size_t) i, Hashrate::ShortInterval); @@ -116,24 +124,32 @@ void ApiState::tick(const Hashrate *hashrate) } -void ApiState::tick(const NetworkState &network) +void ApiRouter::tick(const NetworkState &network) { m_network = network; } -char *ApiState::finalize(rapidjson::Document &doc) const +void ApiRouter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) +{ +// updateWorkerId(config->apiWorkerId(), previousConfig->apiWorkerId()); +} + + +void ApiRouter::finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const { rapidjson::StringBuffer buffer(0, 4096); rapidjson::PrettyWriter writer(buffer); writer.SetMaxDecimalPlaces(10); doc.Accept(writer); - return strdup(buffer.GetString()); + reply.status = 200; + reply.buf = strdup(buffer.GetString()); + reply.size = buffer.GetSize(); } -void ApiState::genId() +void ApiRouter::genId() { memset(m_id, 0, sizeof(m_id)); @@ -166,7 +182,7 @@ void ApiState::genId() } -void ApiState::getConnection(rapidjson::Document &doc) const +void ApiRouter::getConnection(rapidjson::Document &doc) const { auto &allocator = doc.GetAllocator(); @@ -181,7 +197,7 @@ void ApiState::getConnection(rapidjson::Document &doc) const } -void ApiState::getHashrate(rapidjson::Document &doc) const +void ApiRouter::getHashrate(rapidjson::Document &doc) const { auto &allocator = doc.GetAllocator(); @@ -209,14 +225,14 @@ void ApiState::getHashrate(rapidjson::Document &doc) const } -void ApiState::getIdentify(rapidjson::Document &doc) const +void ApiRouter::getIdentify(rapidjson::Document &doc) const { doc.AddMember("id", rapidjson::StringRef(m_id), doc.GetAllocator()); doc.AddMember("worker_id", rapidjson::StringRef(m_workerId), doc.GetAllocator()); } -void ApiState::getMiner(rapidjson::Document &doc) const +void ApiRouter::getMiner(rapidjson::Document &doc) const { auto &allocator = doc.GetAllocator(); @@ -236,7 +252,7 @@ void ApiState::getMiner(rapidjson::Document &doc) const } -void ApiState::getResults(rapidjson::Document &doc) const +void ApiRouter::getResults(rapidjson::Document &doc) const { auto &allocator = doc.GetAllocator(); @@ -258,3 +274,30 @@ void ApiState::getResults(rapidjson::Document &doc) const doc.AddMember("results", results, allocator); } + + +void ApiRouter::setWorkerId(const char *id) +{ + memset(m_workerId, 0, sizeof(m_workerId)); + + if (id && strlen(id) > 0) { + strncpy(m_workerId, id, sizeof(m_workerId) - 1); + } + else { + gethostname(m_workerId, sizeof(m_workerId) - 1); + } +} + + +void ApiRouter::updateWorkerId(const char *id, const char *previousId) +{ + if (id == previousId) { + return; + } + + if (id != nullptr && previousId != nullptr && strcmp(id, previousId) == 0) { + return; + } + + setWorkerId(id); +} diff --git a/src/api/ApiState.h b/src/api/ApiRouter.h similarity index 62% rename from src/api/ApiState.h rename to src/api/ApiRouter.h index 7ecca36d..2ae1cc80 100644 --- a/src/api/ApiState.h +++ b/src/api/ApiRouter.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,35 +21,50 @@ * along with this program. If not, see . */ -#ifndef __APISTATE_H__ -#define __APISTATE_H__ +#ifndef __APIROUTER_H__ +#define __APIROUTER_H__ #include "api/NetworkState.h" +#include "interfaces/IControllerListener.h" #include "rapidjson/fwd.h" class Hashrate; -class ApiState +namespace xmrig { + class Controller; + class HttpReply; + class HttpRequest; +} + + +class ApiRouter : public xmrig::IControllerListener { public: - ApiState(); - ~ApiState(); + ApiRouter(xmrig::Controller *controller); + ~ApiRouter(); + + void get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const; + void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply); - char *get(const char *url, int *status) const; void tick(const Hashrate *hashrate); void tick(const NetworkState &results); +protected: + void onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) override; + private: - char *finalize(rapidjson::Document &doc) const; + void finalize(xmrig::HttpReply &reply, rapidjson::Document &doc) const; void genId(); void getConnection(rapidjson::Document &doc) const; void getHashrate(rapidjson::Document &doc) const; void getIdentify(rapidjson::Document &doc) const; void getMiner(rapidjson::Document &doc) const; void getResults(rapidjson::Document &doc) const; + void setWorkerId(const char *id); + void updateWorkerId(const char *id, const char *previousId); char m_id[17]; char m_workerId[128]; @@ -58,6 +73,7 @@ private: double m_totalHashrate[3]; int m_threads; NetworkState m_network; + xmrig::Controller *m_controller; }; -#endif /* __APISTATE_H__ */ +#endif /* __APIROUTER_H__ */ diff --git a/src/api/HttpBody.h b/src/api/HttpBody.h new file mode 100644 index 00000000..0b143fb7 --- /dev/null +++ b/src/api/HttpBody.h @@ -0,0 +1,69 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __HTTPBODY_H__ +#define __HTTPBODY_H__ + + +#include + + +namespace xmrig { + + +class HttpBody +{ +public: + inline HttpBody() : + m_pos(0) + {} + + + inline bool write(const char *data, size_t size) + { + if (size > (sizeof(m_data) - m_pos - 1)) { + return false; + } + + memcpy(m_data + m_pos, data, size); + + m_pos += size; + m_data[m_pos] = '\0'; + + return true; + } + + + inline const char *data() const { return m_data; } + +private: + char m_data[32768]; + size_t m_pos; +}; + + +} /* namespace xmrig */ + + +#endif /* __HTTPBODY_H__ */ diff --git a/src/api/HttpReply.h b/src/api/HttpReply.h new file mode 100644 index 00000000..6a6cb802 --- /dev/null +++ b/src/api/HttpReply.h @@ -0,0 +1,53 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __HTTPREPLY_H__ +#define __HTTPREPLY_H__ + + +#include + + +namespace xmrig { + + +class HttpReply +{ +public: + HttpReply() : + buf(nullptr), + status(200), + size(0) + {} + + char *buf; + int status; + size_t size; +}; + + +} /* namespace xmrig */ + + +#endif /* __HTTPREPLY_H__ */ diff --git a/src/api/HttpRequest.cpp b/src/api/HttpRequest.cpp new file mode 100644 index 00000000..ac7210bd --- /dev/null +++ b/src/api/HttpRequest.cpp @@ -0,0 +1,175 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include + +#include "api/HttpBody.h" +#include "api/HttpRequest.h" +#include "api/HttpReply.h" + + +#ifndef MHD_HTTP_PAYLOAD_TOO_LARGE +# define MHD_HTTP_PAYLOAD_TOO_LARGE 413 +#endif + + +xmrig::HttpRequest::HttpRequest(MHD_Connection *connection, const char *url, const char *method, const char *uploadData, size_t *uploadSize, void **cls) : + m_fulfilled(true), + m_restricted(true), + m_uploadData(uploadData), + m_url(url), + m_body(static_cast(*cls)), + m_method(Unsupported), + m_connection(connection), + m_uploadSize(uploadSize), + m_cls(cls) +{ + if (strcmp(method, MHD_HTTP_METHOD_OPTIONS) == 0) { + m_method = Options; + } + else if (strcmp(method, MHD_HTTP_METHOD_GET) == 0) { + m_method = Get; + } + else if (strcmp(method, MHD_HTTP_METHOD_PUT) == 0) { + m_method = Put; + } +} + + +xmrig::HttpRequest::~HttpRequest() +{ + if (m_fulfilled) { + delete m_body; + } +} + + +bool xmrig::HttpRequest::match(const char *path) const +{ + return strcmp(m_url, path) == 0; +} + + +bool xmrig::HttpRequest::process(const char *accessToken, bool restricted, xmrig::HttpReply &reply) +{ + m_restricted = restricted || !accessToken; + + if (m_body) { + if (*m_uploadSize != 0) { + if (!m_body->write(m_uploadData, *m_uploadSize)) { + *m_cls = nullptr; + m_fulfilled = true; + reply.status = MHD_HTTP_PAYLOAD_TOO_LARGE; + return false; + } + + *m_uploadSize = 0; + m_fulfilled = false; + return true; + } + + m_fulfilled = true; + return true; + } + + reply.status = auth(accessToken); + if (reply.status != MHD_HTTP_OK) { + return false; + } + + if (m_restricted && m_method != Get) { + reply.status = MHD_HTTP_FORBIDDEN; + return false; + } + + if (m_method == Get) { + return true; + } + + const char *contentType = MHD_lookup_connection_value(m_connection, MHD_HEADER_KIND, "Content-Type"); + if (!contentType || strcmp(contentType, "application/json") != 0) { + reply.status = MHD_HTTP_UNSUPPORTED_MEDIA_TYPE; + return false; + } + + m_body = new xmrig::HttpBody(); + m_fulfilled = false; + *m_cls = m_body; + + return true; +} + + +const char *xmrig::HttpRequest::body() const +{ + return m_body ? m_body->data() : nullptr; +} + + +int xmrig::HttpRequest::end(const HttpReply &reply) +{ + if (reply.buf) { + return end(reply.status, MHD_create_response_from_buffer(reply.size ? reply.size : strlen(reply.buf), (void*) reply.buf, MHD_RESPMEM_MUST_FREE)); + } + + return end(reply.status, nullptr); +} + + +int xmrig::HttpRequest::end(int status, MHD_Response *rsp) +{ + if (!rsp) { + rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT); + } + + MHD_add_response_header(rsp, "Content-Type", "application/json"); + MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*"); + MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET, PUT"); + MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization"); + + const int ret = MHD_queue_response(m_connection, status, rsp); + MHD_destroy_response(rsp); + return ret; +} + + +int xmrig::HttpRequest::auth(const char *accessToken) +{ + if (!accessToken) { + return MHD_HTTP_OK; + } + + const char *header = MHD_lookup_connection_value(m_connection, MHD_HEADER_KIND, "Authorization"); + if (accessToken && !header) { + return MHD_HTTP_UNAUTHORIZED; + } + + const size_t size = strlen(header); + if (size < 8 || strlen(accessToken) != size - 7 || memcmp("Bearer ", header, 7) != 0) { + return MHD_HTTP_FORBIDDEN; + } + + return strncmp(accessToken, header + 7, strlen(accessToken)) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN; +} diff --git a/src/api/HttpRequest.h b/src/api/HttpRequest.h new file mode 100644 index 00000000..f6ff9a40 --- /dev/null +++ b/src/api/HttpRequest.h @@ -0,0 +1,84 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __HTTPREQUEST_H__ +#define __HTTPREQUEST_H__ + + +#include + + +struct MHD_Connection; +struct MHD_Response; + + +namespace xmrig { + + +class HttpBody; +class HttpReply; + + +class HttpRequest +{ +public: + enum Method { + Unsupported, + Options, + Get, + Put + }; + + HttpRequest(MHD_Connection *connection, const char *url, const char *method, const char *uploadData, size_t *uploadSize, void **cls); + ~HttpRequest(); + + inline bool isFulfilled() const { return m_fulfilled; } + inline bool isRestricted() const { return m_restricted; } + inline Method method() const { return m_method; } + + bool match(const char *path) const; + bool process(const char *accessToken, bool restricted, xmrig::HttpReply &reply); + const char *body() const; + int end(const HttpReply &reply); + int end(int status, MHD_Response *rsp); + +private: + int auth(const char *accessToken); + + bool m_fulfilled; + bool m_restricted; + const char *m_uploadData; + const char *m_url; + HttpBody *m_body; + Method m_method; + MHD_Connection *m_connection; + size_t *m_uploadSize; + void **m_cls; +}; + + +} /* namespace xmrig */ + + +#endif /* __HTTPREQUEST_H__ */ diff --git a/src/api/Httpd.cpp b/src/api/Httpd.cpp index 861086ed..45c9ce07 100644 --- a/src/api/Httpd.cpp +++ b/src/api/Httpd.cpp @@ -28,14 +28,64 @@ #include "api/Api.h" #include "api/Httpd.h" +#include "api/HttpReply.h" +#include "api/HttpRequest.h" #include "log/Log.h" -Httpd::Httpd(int port, const char *accessToken) : - m_accessToken(accessToken), +class UploadCtx +{ +public: + inline UploadCtx() : + m_pos(0) + {} + + + inline bool write(const char *data, size_t size) + { + if (size > (sizeof(m_data) - m_pos - 1)) { + return false; + } + + memcpy(m_data + m_pos, data, size); + + m_pos += size; + m_data[m_pos] = '\0'; + + return true; + } + + + inline const char *data() const { return m_data; } + +private: + char m_data[32768]; + size_t m_pos; +}; + + +Httpd::Httpd(int port, const char *accessToken, bool IPv6, bool restricted) : + m_idle(true), + m_IPv6(IPv6), + m_restricted(restricted), + m_accessToken(accessToken ? strdup(accessToken) : nullptr), m_port(port), m_daemon(nullptr) { + uv_timer_init(uv_default_loop(), &m_timer); + m_timer.data = this; +} + + +Httpd::~Httpd() +{ + uv_timer_stop(&m_timer); + + if (m_daemon) { + MHD_stop_daemon(m_daemon); + } + + delete m_accessToken; } @@ -45,15 +95,14 @@ bool Httpd::start() return false; } - unsigned int flags = MHD_USE_SELECT_INTERNALLY; - + unsigned int flags = 0; # if MHD_VERSION >= 0x00093500 - if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) { - flags = MHD_USE_EPOLL_LINUX_ONLY | MHD_USE_EPOLL_INTERNALLY_LINUX_ONLY; + if (m_IPv6 && MHD_is_feature_supported(MHD_FEATURE_IPv6)) { + flags |= MHD_USE_DUAL_STACK; } - if (MHD_is_feature_supported(MHD_FEATURE_IPv6)) { - flags |= MHD_USE_DUAL_STACK; + if (MHD_is_feature_supported(MHD_FEATURE_EPOLL)) { + flags |= MHD_USE_EPOLL_LINUX_ONLY; } # endif @@ -63,66 +112,61 @@ bool Httpd::start() return false; } + uv_timer_start(&m_timer, Httpd::onTimer, kIdleInterval, kIdleInterval); return true; } -int Httpd::auth(const char *header) +int Httpd::process(xmrig::HttpRequest &req) { - if (!m_accessToken) { - return MHD_HTTP_OK; + xmrig::HttpReply reply; + if (!req.process(m_accessToken, m_restricted, reply)) { + return req.end(reply); } - if (m_accessToken && !header) { - return MHD_HTTP_UNAUTHORIZED; + if (!req.isFulfilled()) { + return MHD_YES; } - const size_t size = strlen(header); - if (size < 8 || strlen(m_accessToken) != size - 7 || memcmp("Bearer ", header, 7) != 0) { - return MHD_HTTP_FORBIDDEN; - } + Api::exec(req, reply); - return strncmp(m_accessToken, header + 7, strlen(m_accessToken)) == 0 ? MHD_HTTP_OK : MHD_HTTP_FORBIDDEN; + return req.end(reply); } -int Httpd::done(MHD_Connection *connection, int status, MHD_Response *rsp) +void Httpd::run() { - if (!rsp) { - rsp = MHD_create_response_from_buffer(0, nullptr, MHD_RESPMEM_PERSISTENT); + MHD_run(m_daemon); + + const MHD_DaemonInfo *info = MHD_get_daemon_info(m_daemon, MHD_DAEMON_INFO_CURRENT_CONNECTIONS); + if (m_idle && info->num_connections) { + uv_timer_set_repeat(&m_timer, kActiveInterval); + m_idle = false; + } + else if (!m_idle && !info->num_connections) { + uv_timer_set_repeat(&m_timer, kIdleInterval); + m_idle = true; } - - MHD_add_response_header(rsp, "Content-Type", "application/json"); - MHD_add_response_header(rsp, "Access-Control-Allow-Origin", "*"); - MHD_add_response_header(rsp, "Access-Control-Allow-Methods", "GET"); - MHD_add_response_header(rsp, "Access-Control-Allow-Headers", "Authorization"); - - const int ret = MHD_queue_response(connection, status, rsp); - MHD_destroy_response(rsp); - return ret; } -int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) +int Httpd::handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *uploadData, size_t *uploadSize, void **con_cls) { - if (strcmp(method, "OPTIONS") == 0) { - return done(connection, MHD_HTTP_OK, nullptr); + xmrig::HttpRequest req(connection, url, method, uploadData, uploadSize, con_cls); + + if (req.method() == xmrig::HttpRequest::Options) { + return req.end(MHD_HTTP_OK, nullptr); } - if (strcmp(method, "GET") != 0) { - return MHD_NO; + if (req.method() == xmrig::HttpRequest::Unsupported) { + return req.end(MHD_HTTP_METHOD_NOT_ALLOWED, nullptr); } - int status = static_cast(cls)->auth(MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Authorization")); - if (status != MHD_HTTP_OK) { - return done(connection, status, nullptr); - } - - char *buf = Api::get(url, &status); - if (buf == nullptr) { - return MHD_NO; - } - - MHD_Response *rsp = MHD_create_response_from_buffer(strlen(buf), (void*) buf, MHD_RESPMEM_MUST_FREE); - return done(connection, status, rsp); + return static_cast(cls)->process(req); +} + + +void Httpd::onTimer(uv_timer_t *handle) +{ + static_cast(handle->data)->run(); } diff --git a/src/api/Httpd.h b/src/api/Httpd.h index 30618e2a..adec1d71 100644 --- a/src/api/Httpd.h +++ b/src/api/Httpd.h @@ -33,21 +33,38 @@ struct MHD_Daemon; struct MHD_Response; +class UploadCtx; + + +namespace xmrig { + class HttpRequest; +} + + class Httpd { public: - Httpd(int port, const char *accessToken); + Httpd(int port, const char *accessToken, bool IPv6, bool restricted); + ~Httpd(); bool start(); private: - int auth(const char *header); + constexpr static const int kIdleInterval = 200; + constexpr static const int kActiveInterval = 25; - static int done(MHD_Connection *connection, int status, MHD_Response *rsp); - static int handler(void *cls, MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls); + int process(xmrig::HttpRequest &req); + void run(); + static int handler(void *cls, MHD_Connection *connection, const char *url, const char *method, const char *version, const char *uploadData, size_t *uploadSize, void **con_cls); + static void onTimer(uv_timer_t *handle); + + bool m_idle; + bool m_IPv6; + bool m_restricted; const char *m_accessToken; const int m_port; MHD_Daemon *m_daemon; + uv_timer_t m_timer; }; #endif /* __HTTPD_H__ */ diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp new file mode 100644 index 00000000..af8a27d5 --- /dev/null +++ b/src/core/Controller.cpp @@ -0,0 +1,125 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +//#include "core/Config.h" +//#include "core/ConfigLoader.h" +#include "core/Controller.h" +#include "log/ConsoleLog.h" +#include "log/FileLog.h" +#include "log/Log.h" +#include "Platform.h" +//#include "proxy/Proxy.h" +#include "interfaces/IControllerListener.h" + + +#ifdef HAVE_SYSLOG_H +# include "log/SysLog.h" +#endif + + +class xmrig::ControllerPrivate +{ +public: + inline ControllerPrivate() : + config(nullptr) + {} + + + inline ~ControllerPrivate() + { +// delete config; + } + + + xmrig::Config *config; + std::vector listeners; +}; + + +xmrig::Controller::Controller() + : d_ptr(new ControllerPrivate()) +{ +} + + +xmrig::Controller::~Controller() +{ +// ConfigLoader::release(); + + delete d_ptr; +} + + +xmrig::Config *xmrig::Controller::config() const +{ + return d_ptr->config; +} + + +int xmrig::Controller::init(int argc, char **argv) +{ +// d_ptr->config = xmrig::Config::load(argc, argv, this); +// if (!d_ptr->config) { +// return 1; +// } + +// Log::init(); +// Platform::init(config()->userAgent()); + +// if (!config()->background()) { +// Log::add(new ConsoleLog(this)); +// } + +// if (config()->logFile()) { +// Log::add(new FileLog(config()->logFile())); +// } + +//# ifdef HAVE_SYSLOG_H +// if (config()->syslog()) { +// Log::add(new SysLog()); +// } +//# endif + +// d_ptr->proxy = new Proxy(this); + return 0; +} + + +void xmrig::Controller::addListener(IControllerListener *listener) +{ + d_ptr->listeners.push_back(listener); +} + + +void xmrig::Controller::onNewConfig(Config *config) +{ +// xmrig::Config *previousConfig = d_ptr->config; +// d_ptr->config = config; + +// for (xmrig::IControllerListener *listener : d_ptr->listeners) { +// listener->onConfigChanged(config, previousConfig); +// } + +// delete previousConfig; +} diff --git a/src/core/Controller.h b/src/core/Controller.h new file mode 100644 index 00000000..2fe37c15 --- /dev/null +++ b/src/core/Controller.h @@ -0,0 +1,63 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CONTROLLER_H__ +#define __CONTROLLER_H__ + + +#include "interfaces/IWatcherListener.h" + + +class Proxy; +class StatsData; + + +namespace xmrig { + + +class Config; +class ControllerPrivate; +class IControllerListener; + + +class Controller : public IWatcherListener +{ +public: + Controller(); + ~Controller(); + + Config *config() const; + int init(int argc, char **argv); + Proxy *proxy() const; + void addListener(IControllerListener *listener); + +protected: + void onNewConfig(Config *config) override; + +private: + ControllerPrivate *d_ptr; +}; + +} /* namespace xmrig */ + +#endif /* __CONTROLLER_H__ */ diff --git a/src/interfaces/IControllerListener.h b/src/interfaces/IControllerListener.h new file mode 100644 index 00000000..d6077138 --- /dev/null +++ b/src/interfaces/IControllerListener.h @@ -0,0 +1,46 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __ICONTROLLERLISTENER_H__ +#define __ICONTROLLERLISTENER_H__ + + +namespace xmrig { + + +class Config; + + +class IControllerListener +{ +public: + virtual ~IControllerListener() {} + + virtual void onConfigChanged(Config *config, Config *previousConfig) = 0; +}; + + +} /* namespace xmrig */ + + +#endif // __ICONTROLLERLISTENER_H__ diff --git a/src/interfaces/IWatcherListener.h b/src/interfaces/IWatcherListener.h new file mode 100644 index 00000000..da30b1fd --- /dev/null +++ b/src/interfaces/IWatcherListener.h @@ -0,0 +1,46 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __IWATCHERLISTENER_H__ +#define __IWATCHERLISTENER_H__ + + +namespace xmrig { + + +class Config; + + +class IWatcherListener +{ +public: + virtual ~IWatcherListener() {} + + virtual void onNewConfig(Config *config) = 0; +}; + + +} /* namespace xmrig */ + + +#endif // __IWATCHERLISTENER_H__ From aad19f1a35d6e05461539c866a81ee2677c7e3f8 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 31 Mar 2018 13:48:06 +0700 Subject: [PATCH 003/109] Added initial next gen config support from proxy. --- CMakeLists.txt | 12 + src/core/CommonConfig.cpp | 380 ++++++++++++++++++++++++++++++ src/core/CommonConfig.h | 106 +++++++++ src/core/Config.cpp | 329 ++++++++++++++++++++++++++ src/core/Config.h | 122 ++++++++++ src/core/ConfigCreator.h | 50 ++++ src/core/ConfigLoader.cpp | 311 ++++++++++++++++++++++++ src/core/ConfigLoader.h | 71 ++++++ src/core/ConfigLoader_platform.h | 171 ++++++++++++++ src/core/ConfigWatcher.cpp | 107 +++++++++ src/core/ConfigWatcher.h | 69 ++++++ src/core/Controller.cpp | 2 +- src/core/Controller.h | 2 +- src/donate.h | 3 +- src/interfaces/IConfig.h | 109 +++++++++ src/interfaces/IConfigCreator.h | 45 ++++ src/interfaces/IWatcherListener.h | 4 +- src/net/Url.cpp | 8 +- src/net/Url.h | 10 +- src/xmrig.h | 5 +- 20 files changed, 1901 insertions(+), 15 deletions(-) create mode 100644 src/core/CommonConfig.cpp create mode 100644 src/core/CommonConfig.h create mode 100644 src/core/Config.cpp create mode 100644 src/core/Config.h create mode 100644 src/core/ConfigCreator.h create mode 100644 src/core/ConfigLoader.cpp create mode 100644 src/core/ConfigLoader.h create mode 100644 src/core/ConfigLoader_platform.h create mode 100644 src/core/ConfigWatcher.cpp create mode 100644 src/core/ConfigWatcher.h create mode 100644 src/interfaces/IConfig.h create mode 100644 src/interfaces/IConfigCreator.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1be15601..a4347d69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,9 +15,17 @@ set(HEADERS src/api/NetworkState.h src/App.h src/Console.h + src/core/CommonConfig.h + src/core/Config.cpp + src/core/ConfigLoader.cpp + src/core/ConfigLoader.h + src/core/ConfigLoader_platform.h + src/core/ConfigWatcher.cpp src/core/Controller.h src/Cpu.h src/interfaces/IClientListener.h + src/interfaces/IConfig.h + src/interfaces/IConfigCreator.h src/interfaces/IConsoleListener.h src/interfaces/IControllerListener.h src/interfaces/IJobResultListener.h @@ -79,6 +87,10 @@ set(SOURCES src/api/NetworkState.cpp src/App.cpp src/Console.cpp + src/core/CommonConfig.cpp + src/core/Config.cpp + src/core/ConfigLoader.cpp + src/core/ConfigWatcher.cpp src/core/Controller.cpp src/log/ConsoleLog.cpp src/log/FileLog.cpp diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp new file mode 100644 index 00000000..38233b12 --- /dev/null +++ b/src/core/CommonConfig.cpp @@ -0,0 +1,380 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include +#include +#include + + +#include "core/CommonConfig.h" +#include "donate.h" +#include "log/Log.h" +#include "net/Url.h" +#include "rapidjson/document.h" +#include "rapidjson/filewritestream.h" +#include "rapidjson/prettywriter.h" +#include "xmrig.h" + + +static const char *algoNames[] = { + "cryptonight", + "cryptonight-lite", + "cryptonight-heavy" +}; + + +#if defined(_WIN32) && !defined(strcasecmp) +# define strcasecmp _stricmp +#endif + + +xmrig::CommonConfig::CommonConfig() : + m_adjusted(false), + m_apiIPv6(true), + m_apiRestricted(true), + m_background(false), + m_colors(true), + m_apiToken(nullptr), + m_apiWorkerId(nullptr), + m_fileName(nullptr), + m_logFile(nullptr), + m_userAgent(nullptr), + m_algorithm(ALGO_CRYPTONIGHT), + m_apiPort(0), + m_donateLevel(kDefaultDonateLevel), + m_printTime(60), + m_retries(5), + m_retryPause(5) +{ + m_pools.push_back(new Url()); + +# ifdef XMRIG_PROXY_PROJECT + m_retries = 2; + m_retryPause = 1; +# endif +} + + +xmrig::CommonConfig::~CommonConfig() +{ + for (Url *url : m_pools) { + delete url; + } + + m_pools.clear(); + + free(m_fileName); + free(m_apiToken); + free(m_apiWorkerId); + free(m_logFile); + free(m_userAgent); +} + + +const char *xmrig::CommonConfig::algoName() const +{ + return algoNames[m_algorithm]; +} + + +bool xmrig::CommonConfig::adjust() +{ + if (m_adjusted) { + return false; + } + + m_adjusted = true; + + for (Url *url : m_pools) { + url->adjust(algorithm()); + } + + return true; +} + + +bool xmrig::CommonConfig::isValid() const +{ + return m_pools[0]->isValid(); +} + + +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.back()->setKeepAlive(enable ? Url::kKeepAliveTimeout : 0); + break; + +# ifndef XMRIG_PROXY_PROJECT + case NicehashKey: /* --nicehash */ + m_pools.back()->setNicehash(enable); + break; +# endif + + case ColorKey: /* --no-color */ + m_colors = enable; + break; + + case WatchKey: /* watch */ + m_watch = enable; + break; + + case ApiIPv6Key: /* ipv6 */ + m_apiIPv6 = enable; + + case ApiRestrictedKey: /* restricted */ + m_apiRestricted = enable; + + default: + break; + } + + return true; +} + + +bool xmrig::CommonConfig::parseString(int key, const char *arg) +{ + switch (key) { + case AlgorithmKey: /* --algo */ + setAlgo(arg); + break; + + case UserpassKey: /* --userpass */ + if (!m_pools.back()->setUserpass(arg)) { + return false; + } + + break; + + case UrlKey: /* --url */ + if (m_pools.size() > 1 || m_pools[0]->isValid()) { + Url *url = new Url(arg); + if (url->isValid()) { + m_pools.push_back(url); + } + else { + delete url; + } + } + else { + m_pools[0]->parse(arg); + } + + if (!m_pools.back()->isValid()) { + return false; + } + + break; + + case UserKey: /* --user */ + m_pools.back()->setUser(arg); + break; + + case PasswordKey: /* --pass */ + m_pools.back()->setPassword(arg); + break; + + case LogFileKey: /* --log-file */ + free(m_logFile); + m_logFile = strdup(arg); + break; + + case ApiAccessTokenKey: /* --api-access-token */ + free(m_apiToken); + m_apiToken = strdup(arg); + break; + + case ApiWorkerIdKey: /* --api-worker-id */ + free(m_apiWorkerId); + m_apiWorkerId = strdup(arg); + break; + + case UserAgentKey: /* --user-agent */ + free(m_userAgent); + m_userAgent = strdup(arg); + break; + + case RetriesKey: /* --retries */ + case RetryPauseKey: /* --retry-pause */ + case VariantKey: /* --variant */ + case ApiPort: /* --api-port */ + case PrintTimeKey: /* --cpu-priority */ + return parseUint64(key, strtol(arg, nullptr, 10)); + + case BackgroundKey: /* --background */ + case SyslogKey: /* --syslog */ + case KeepAliveKey: /* --keepalive */ + case NicehashKey: /* --nicehash */ + return parseBoolean(key, true); + + case ColorKey: /* --no-color */ + case WatchKey: /* --no-watch */ + case ApiRestrictedKey: /* --api-no-restricted */ + case ApiIPv6Key: /* --api-no-ipv6 */ + return parseBoolean(key, false); + +# ifdef XMRIG_PROXY_PROJECT + case 1003: /* --donate-level */ + if (strncmp(arg, "minemonero.pro", 14) == 0) { + m_donateLevel = 0; + } + else { + parseUint64(key, strtol(arg, nullptr, 10)); + } + break; +# endif + + default: + break; + } + + return true; +} + + +bool xmrig::CommonConfig::parseUint64(int key, uint64_t arg) +{ + return parseInt(key, static_cast(arg)); +} + + +bool xmrig::CommonConfig::save() +{ + if (!m_fileName) { + return false; + } + + uv_fs_t req; + const int fd = uv_fs_open(uv_default_loop(), &req, m_fileName, O_WRONLY | O_CREAT | O_TRUNC, 0644, nullptr); + if (fd < 0) { + return false; + } + + uv_fs_req_cleanup(&req); + + rapidjson::Document doc; + getJSON(doc); + + FILE *fp = fdopen(fd, "w"); + + char buf[4096]; + rapidjson::FileWriteStream os(fp, buf, sizeof(buf)); + rapidjson::PrettyWriter writer(os); + doc.Accept(writer); + + fclose(fp); + + uv_fs_close(uv_default_loop(), &req, fd, nullptr); + uv_fs_req_cleanup(&req); + + LOG_NOTICE("configuration saved to: \"%s\"", m_fileName); + return true; +} + + +void xmrig::CommonConfig::setFileName(const char *fileName) +{ + free(m_fileName); + m_fileName = fileName ? strdup(fileName) : nullptr; +} + + +bool xmrig::CommonConfig::parseInt(int key, int arg) +{ + switch (key) { + case RetriesKey: /* --retries */ + if (arg > 0 && arg <= 1000) { + m_retries = arg; + } + break; + + case RetryPauseKey: /* --retry-pause */ + if (arg > 0 && arg <= 3600) { + m_retryPause = arg; + } + break; + + case KeepAliveKey: /* --keepalive */ + m_pools.back()->setKeepAlive(arg); + break; + + case VariantKey: /* --variant */ + m_pools.back()->setVariant(arg); + break; + + case DonateLevelKey: /* --donate-level */ + if (arg >= kMinDonateLevel && arg <= 99) { + m_donateLevel = arg; + } + break; + + case ApiPort: /* --api-port */ + if (arg > 0 && arg <= 65536) { + m_apiPort = arg; + } + break; + + case PrintTimeKey: /* --print-time */ + if (arg >= 0 && arg <= 3600) { + m_printTime = arg; + } + break; + + default: + break; + } + + return true; +} + + +void xmrig::CommonConfig::setAlgo(const char *algo) +{ + if (strcasecmp(algo, "cryptonight-light") == 0) { + fprintf(stderr, "Algorithm \"cryptonight-light\" is deprecated, use \"cryptonight-lite\" instead\n"); + + m_algorithm = ALGO_CRYPTONIGHT_LITE; + return; + } + + const size_t size = sizeof(algoNames) / sizeof((algoNames)[0]); + + for (size_t i = 0; i < size; i++) { + if (algoNames[i] && strcasecmp(algo, algoNames[i]) == 0) { + m_algorithm = (int) i; + break; + } + } +} diff --git a/src/core/CommonConfig.h b/src/core/CommonConfig.h new file mode 100644 index 00000000..ab840a48 --- /dev/null +++ b/src/core/CommonConfig.h @@ -0,0 +1,106 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __COMMONCONFIG_H__ +#define __COMMONCONFIG_H__ + + +#include + + +#include "interfaces/IConfig.h" + + +class Url; + + +namespace xmrig { + + +class CommonConfig : public IConfig +{ +public: + CommonConfig(); + ~CommonConfig(); + + const char *algoName() const; + + inline bool isApiIPv6() const { return m_apiIPv6; } + inline bool isApiRestricted() const { return m_apiRestricted; } + inline bool isBackground() const { return m_background; } + inline bool isColors() const { return m_colors; } + inline bool isSyslog() const { return m_syslog; } + inline const char *apiToken() const { return m_apiToken; } + inline const char *apiWorkerId() const { return m_apiWorkerId; } + inline const char *logFile() const { return m_logFile; } + inline const char *userAgent() const { return m_userAgent; } + inline const std::vector &pools() const { return m_pools; } + inline int algorithm() const { return m_algorithm; } + inline int apiPort() const { return m_apiPort; } + inline int donateLevel() const { return m_donateLevel; } + inline int printTime() const { return m_printTime; } + inline int retries() const { return m_retries; } + inline int retryPause() const { return m_retryPause; } + inline void setColors(bool colors) { m_colors = colors; } + + inline bool isWatch() const override { return m_watch && m_fileName; } + inline const char *fileName() const override { return m_fileName; } + +protected: + bool adjust() override; + bool isValid() const override; + bool parseBoolean(int key, bool enable) override; + bool parseString(int key, const char *arg) override; + bool parseUint64(int key, uint64_t arg) override; + bool save() override; + void setFileName(const char *fileName) override; + + bool m_adjusted; + bool m_apiIPv6; + bool m_apiRestricted; + bool m_background; + bool m_colors; + bool m_syslog; + bool m_watch; + char *m_apiToken; + char *m_apiWorkerId; + char *m_fileName; + char *m_logFile; + char *m_userAgent; + int m_algorithm; + int m_apiPort; + int m_donateLevel; + int m_printTime; + int m_retries; + int m_retryPause; + std::vector m_pools; + +private: + bool parseInt(int key, int arg); + void setAlgo(const char *algo); +}; + + +} /* namespace xmrig */ + +#endif /* __COMMONCONFIG_H__ */ diff --git a/src/core/Config.cpp b/src/core/Config.cpp new file mode 100644 index 00000000..9bf44bc8 --- /dev/null +++ b/src/core/Config.cpp @@ -0,0 +1,329 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + + +#include "core/Config.h" +#include "core/ConfigCreator.h" +#include "core/ConfigLoader.h" +#include "Cpu.h" +#include "rapidjson/document.h" +#include "rapidjson/filewritestream.h" +#include "rapidjson/prettywriter.h" +#include "xmrig.h" + + +xmrig::Config::Config() : xmrig::CommonConfig(), + m_doubleHash(false), + m_dryRun(false), + m_hugePages(true), + m_safe(false), + m_algo(0), + m_algoVariant(0), + m_maxCpuUsage(75), + m_printTime(60), + m_priority(-1), + m_threads(0), + m_affinity(-1L) +{ + +} + + +xmrig::Config::~Config() +{ +} + + +bool xmrig::Config::reload(const char *json) +{ + return xmrig::ConfigLoader::reload(this, json); +} + + +void xmrig::Config::getJSON(rapidjson::Document &doc) const +{ + doc.SetObject(); + +// auto &allocator = doc.GetAllocator(); + +// doc.AddMember("access-log-file", accessLog() ? rapidjson::Value(rapidjson::StringRef(accessLog())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); +// doc.AddMember("algo", rapidjson::StringRef(algoName()), allocator); + +// rapidjson::Value api(rapidjson::kObjectType); +// api.AddMember("port", apiPort(), allocator); +// api.AddMember("access-token", apiToken() ? rapidjson::Value(rapidjson::StringRef(apiToken())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); +// api.AddMember("worker-id", apiWorkerId() ? rapidjson::Value(rapidjson::StringRef(apiWorkerId())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); +// api.AddMember("ipv6", isApiIPv6(), allocator); +// api.AddMember("restricted", isApiRestricted(), allocator); +// doc.AddMember("api", api, allocator); + +// doc.AddMember("background", isBackground(), allocator); + +// rapidjson::Value bind(rapidjson::kArrayType); +// for (const Addr *addr : m_addrs) { +// bind.PushBack(rapidjson::StringRef(addr->addr()), allocator); +// } + +// doc.AddMember("bind", bind, allocator); +// doc.AddMember("colors", isColors(), allocator); +// doc.AddMember("custom-diff", diff(), allocator); +// doc.AddMember("donate-level", donateLevel(), allocator); +// doc.AddMember("log-file", logFile() ? rapidjson::Value(rapidjson::StringRef(logFile())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); +// doc.AddMember("mode", rapidjson::StringRef(modeName()), allocator); + +// rapidjson::Value pools(rapidjson::kArrayType); + +// for (const Url *url : m_pools) { +// rapidjson::Value obj(rapidjson::kObjectType); + +// obj.AddMember("url", rapidjson::StringRef(url->url()), allocator); +// obj.AddMember("user", rapidjson::StringRef(url->user()), allocator); +// obj.AddMember("pass", rapidjson::StringRef(url->password()), allocator); +// obj.AddMember("coin", rapidjson::StringRef(url->coin()), allocator); + +// if (url->keepAlive() == 0 || url->keepAlive() == Url::kKeepAliveTimeout) { +// obj.AddMember("keepalive", url->keepAlive() > 0, allocator); +// } +// else { +// obj.AddMember("keepalive", url->keepAlive(), allocator); +// } + +// obj.AddMember("variant", url->variant(), allocator); + +// pools.PushBack(obj, allocator); +// } + +// doc.AddMember("pools", pools, allocator); + +// doc.AddMember("retries", retries(), allocator); +// doc.AddMember("retry-pause", retryPause(), allocator); +// doc.AddMember("reuse-timeout", reuseTimeout(), allocator); +// doc.AddMember("user-agent", userAgent() ? rapidjson::Value(rapidjson::StringRef(userAgent())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); + +//# ifdef HAVE_SYSLOG_H +// doc.AddMember("syslog", syslog(), allocator); +//# endif + +// doc.AddMember("verbose", isVerbose(), allocator); +// doc.AddMember("watch", m_watch, allocator); +// doc.AddMember("workers", isWorkers(), allocator); +} + + +xmrig::Config *xmrig::Config::load(int argc, char **argv, IWatcherListener *listener) +{ + return static_cast(ConfigLoader::load(argc, argv, new ConfigCreator(), listener)); +} + + +bool xmrig::Config::adjust() +{ + if (!CommonConfig::adjust()) { + return false; + } + + m_algoVariant = getAlgoVariant(); + if (m_algoVariant == AV2_AESNI_DOUBLE || m_algoVariant == AV4_SOFT_AES_DOUBLE) { + m_doubleHash = true; + } + + if (!m_threads) { + m_threads = Cpu::optimalThreadsCount(m_algo, m_doubleHash, m_maxCpuUsage); + } + else if (m_safe) { + const int count = Cpu::optimalThreadsCount(m_algo, m_doubleHash, m_maxCpuUsage); + if (m_threads > count) { + m_threads = count; + } + } + + return true; +} + + +bool xmrig::Config::parseBoolean(int key, bool enable) +{ + if (!CommonConfig::parseBoolean(key, enable)) { + return false; + } + + switch (key) { + case xmrig::IConfig::SafeKey: /* --safe */ + m_safe = enable; + break; + + case xmrig::IConfig::HugePagesKey: /* --no-huge-pages */ + m_hugePages = enable; + break; + + case xmrig::IConfig::DryRunKey: /* --dry-run */ + m_dryRun = enable; + break; + + default: + break; + } + + return true; +} + + +bool xmrig::Config::parseString(int key, const char *arg) +{ + if (!CommonConfig::parseString(key, arg)) { + return false; + } + + switch (key) { + case xmrig::IConfig::AVKey: /* --av */ + case xmrig::IConfig::MaxCPUUsageKey: /* --max-cpu-usage */ + case xmrig::IConfig::CPUPriorityKey: /* --cpu-priority */ + return parseUint64(key, strtol(arg, nullptr, 10)); + + case xmrig::IConfig::SafeKey: /* --safe */ + case xmrig::IConfig::DryRunKey: /* --dry-run */ + return parseBoolean(key, true); + + case xmrig::IConfig::HugePagesKey: /* --no-huge-pages */ + return parseBoolean(key, false); + + case xmrig::IConfig::ThreadsKey: /* --threads */ + if (strncmp(arg, "all", 3) == 0) { + m_threads = Cpu::threads(); + return true; + } + + return parseUint64(key, strtol(arg, nullptr, 10)); + + case xmrig::IConfig::CPUAffinityKey: /* --cpu-affinity */ + { + const char *p = strstr(arg, "0x"); + return parseUint64(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10)); + } + + default: + break; + } + + return true; +} + + +bool xmrig::Config::parseUint64(int key, uint64_t arg) +{ + if (!CommonConfig::parseUint64(key, arg)) { + return false; + } + + switch (key) { + case xmrig::IConfig::CPUAffinityKey: /* --cpu-affinity */ + if (arg) { + m_affinity = arg; + } + break; + + default: + return parseInt(key, static_cast(arg)); + } + + return true; +} + + +void xmrig::Config::parseJSON(const rapidjson::Document &doc) +{ +} + + +bool xmrig::Config::parseInt(int key, int arg) +{ + switch (key) { + case xmrig::IConfig::ThreadsKey: /* --threads */ + if (m_threads >= 0 && arg < 1024) { + m_threads = arg; + } + break; + + case xmrig::IConfig::AVKey: /* --av */ + if (arg >= AV0_AUTO && arg < AV_MAX) { + m_algoVariant = arg; + } + break; + + case xmrig::IConfig::MaxCPUUsageKey: /* --max-cpu-usage */ + if (m_maxCpuUsage > 0 && arg <= 100) { + m_maxCpuUsage = arg; + } + break; + + case xmrig::IConfig::CPUPriorityKey: /* --cpu-priority */ + if (arg >= 0 && arg <= 5) { + m_priority = arg; + } + break; + + default: + break; + } + + return true; +} + + +int xmrig::Config::getAlgoVariant() const +{ +# ifndef XMRIG_NO_AEON + if (m_algo == xmrig::ALGO_CRYPTONIGHT_LITE) { + return getAlgoVariantLite(); + } +# endif + + if (m_algoVariant <= AV0_AUTO || m_algoVariant >= AV_MAX) { + return Cpu::hasAES() ? AV1_AESNI : AV3_SOFT_AES; + } + + if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV2_AESNI_DOUBLE) { + return m_algoVariant + 2; + } + + return m_algoVariant; +} + + +#ifndef XMRIG_NO_AEON +int xmrig::Config::getAlgoVariantLite() const +{ + if (m_algoVariant <= AV0_AUTO || m_algoVariant >= AV_MAX) { + return Cpu::hasAES() ? AV2_AESNI_DOUBLE : AV4_SOFT_AES_DOUBLE; + } + + if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV2_AESNI_DOUBLE) { + return m_algoVariant + 2; + } + + return m_algoVariant; +} +#endif diff --git a/src/core/Config.h b/src/core/Config.h new file mode 100644 index 00000000..a10cd696 --- /dev/null +++ b/src/core/Config.h @@ -0,0 +1,122 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + + +#include +#include + + +#include "rapidjson/fwd.h" +#include "core/CommonConfig.h" + + +class Addr; +class Url; + + +namespace xmrig { + + +class ConfigLoader; +class IWatcherListener; + + +/** + * @brief The Config class + * + * Options with dynamic reload: + * colors + * debug + * verbose + * custom-diff (only for new connections) + * api/worker-id + * pools/ + */ +class Config : public CommonConfig +{ + friend class ConfigLoader; + +public: + enum AlgoVariant { + AV0_AUTO, + AV1_AESNI, + AV2_AESNI_DOUBLE, + AV3_SOFT_AES, + AV4_SOFT_AES_DOUBLE, + AV_MAX + }; + + Config(); + ~Config(); + + bool reload(const char *json); + + void getJSON(rapidjson::Document &doc) const override; + + inline bool isDoubleHash() const { return m_doubleHash; } + inline bool isDryRun() const { return m_dryRun; } + inline bool isHugePages() const { return m_hugePages; } + inline int algo() const { return m_algo; } + inline int algoVariant() const { return m_algoVariant; } + inline int printTime() const { return m_printTime; } + inline int priority() const { return m_priority; } + inline int threads() const { return m_threads; } + inline int64_t affinity() const { return m_affinity; } + + static Config *load(int argc, char **argv, IWatcherListener *listener); + +protected: + bool adjust() 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::Document &doc) override; + +private: + bool parseInt(int key, int arg); + + int getAlgoVariant() const; +# ifndef XMRIG_NO_AEON + int getAlgoVariantLite() const; +# endif + + bool m_doubleHash; + bool m_dryRun; + bool m_hugePages; + bool m_safe; + int m_algo; + int m_algoVariant; + int m_maxCpuUsage; + int m_printTime; + int m_priority; + int m_threads; + int64_t m_affinity; +}; + + +} /* namespace xmrig */ + +#endif /* __CONFIG_H__ */ diff --git a/src/core/ConfigCreator.h b/src/core/ConfigCreator.h new file mode 100644 index 00000000..fcc6c596 --- /dev/null +++ b/src/core/ConfigCreator.h @@ -0,0 +1,50 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2018 XMRig + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CONFIGCREATOR_H__ +#define __CONFIGCREATOR_H__ + + +#include "core/Config.h" +#include "interfaces/IConfigCreator.h" + + +namespace xmrig { + + +class IConfig; + + +class ConfigCreator : public IConfigCreator +{ +public: + inline IConfig *create() const override + { + return new Config(); + } +}; + + +} /* namespace xmrig */ + + +#endif // __CONFIGCREATOR_H__ diff --git a/src/core/ConfigLoader.cpp b/src/core/ConfigLoader.cpp new file mode 100644 index 00000000..1dec4eca --- /dev/null +++ b/src/core/ConfigLoader.cpp @@ -0,0 +1,311 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include +#include + + +#ifndef XMRIG_NO_HTTPD +# include +#endif + + +#include "core/ConfigCreator.h" +#include "core/ConfigLoader.h" +#include "core/ConfigLoader_platform.h" +#include "core/ConfigWatcher.h" +#include "interfaces/IConfig.h" +#include "interfaces/IWatcherListener.h" +#include "net/Url.h" +#include "Platform.h" +#include "rapidjson/document.h" +#include "rapidjson/error/en.h" +#include "rapidjson/filereadstream.h" + + +xmrig::ConfigWatcher *xmrig::ConfigLoader::m_watcher = nullptr; +xmrig::IConfigCreator *xmrig::ConfigLoader::m_creator = nullptr; +xmrig::IWatcherListener *xmrig::ConfigLoader::m_listener = nullptr; + + +#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) +{ + rapidjson::Document doc; + doc.Parse(json); + + if (doc.HasParseError() || !doc.IsObject()) { + return false; + } + + return loadFromJSON(config, doc); +} + + +bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const rapidjson::Document &doc) +{ + for (size_t i = 0; i < ARRAY_SIZE(config_options); i++) { + parseJSON(config, &config_options[i], doc); + } + + const rapidjson::Value &pools = doc["pools"]; + if (pools.IsArray()) { + for (const rapidjson::Value &value : pools.GetArray()) { + if (!value.IsObject()) { + continue; + } + + for (size_t i = 0; i < ARRAY_SIZE(pool_options); i++) { + parseJSON(config, &pool_options[i], value); + } + } + } + + const rapidjson::Value &api = doc["api"]; + if (api.IsObject()) { + for (size_t i = 0; i < ARRAY_SIZE(api_options); i++) { + parseJSON(config, &api_options[i], api); + } + } + + config->parseJSON(doc); + config->adjust(); + + return config->isValid(); +} + + +bool xmrig::ConfigLoader::reload(xmrig::IConfig *oldConfig, const char *json) +{ + xmrig::IConfig *config = m_creator->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; +} + + +xmrig::IConfig *xmrig::ConfigLoader::load(int argc, char **argv, IConfigCreator *creator, IWatcherListener *listener) +{ + m_creator = creator; + m_listener = listener; + + xmrig::IConfig *config = m_creator->create(); + int key; + + while (1) { + key = getopt_long(argc, argv, short_options, options, NULL); + 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->isValid()) { + loadFromFile(config, Platform::defaultConfigName()); + } + + if (!config->isValid()) { + fprintf(stderr, "No pool URL supplied. Exiting.\n"); + delete config; + return nullptr; + } + + if (config->isWatch()) { + m_watcher = new xmrig::ConfigWatcher(config->fileName(), creator, listener); + } + + config->adjust(); + return config; +} + + +void xmrig::ConfigLoader::release() +{ + delete m_watcher; + delete m_creator; + + m_watcher = nullptr; + m_creator = nullptr; +} + + +bool xmrig::ConfigLoader::getJSON(const char *fileName, rapidjson::Document &doc) +{ + uv_fs_t req; + const int fd = uv_fs_open(uv_default_loop(), &req, fileName, O_RDONLY, 0644, nullptr); + if (fd < 0) { + fprintf(stderr, "unable to open %s: %s\n", fileName, uv_strerror(fd)); + return false; + } + + uv_fs_req_cleanup(&req); + + FILE *fp = fdopen(fd, "rb"); + char buf[8192]; + rapidjson::FileReadStream is(fp, buf, sizeof(buf)); + + doc.ParseStream(is); + + uv_fs_close(uv_default_loop(), &req, fd, nullptr); + uv_fs_req_cleanup(&req); + + if (doc.HasParseError()) { + printf("%s<%d>: %s\n", fileName, (int) doc.GetErrorOffset(), rapidjson::GetParseError_En(doc.GetParseError())); + return false; + } + + return doc.IsObject(); +} + + +bool xmrig::ConfigLoader::parseArg(xmrig::IConfig *config, int key, const char *arg) +{ + switch (key) { + case xmrig::IConfig::VersionKey: /* --version */ + showVersion(); + return false; + + case xmrig::IConfig::HelpKey: /* --help */ + showUsage(); + return false; + + case xmrig::IConfig::ConfigKey: /* --config */ + loadFromFile(config, arg); + break; + + default: + return config->parseString(key, arg);; + } + + return true; +} + + +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()); + } +} + + +void xmrig::ConfigLoader::showUsage() +{ + printf(usage); +} + + +void xmrig::ConfigLoader::showVersion() +{ + printf(APP_NAME " " APP_VERSION "\n built on " __DATE__ + +# if defined(__clang__) + " with clang " __clang_version__); +# elif defined(__GNUC__) + " with GCC"); + printf(" %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); +# elif defined(_MSC_VER) + " with MSVC"); + printf(" %d", MSVC_VERSION); +# else + ); +# endif + + printf("\n features:" +# if defined(__i386__) || defined(_M_IX86) + " i386" +# elif defined(__x86_64__) || defined(_M_AMD64) + " x86_64" +# endif + +# if defined(__AES__) || defined(_MSC_VER) + " AES-NI" +# endif + "\n"); + + printf("\nlibuv/%s\n", uv_version_string()); + +# ifndef XMRIG_NO_HTTPD + printf("libmicrohttpd/%s\n", MHD_get_version()); +# endif +} diff --git a/src/core/ConfigLoader.h b/src/core/ConfigLoader.h new file mode 100644 index 00000000..64638af3 --- /dev/null +++ b/src/core/ConfigLoader.h @@ -0,0 +1,71 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CONFIGLOADER_H__ +#define __CONFIGLOADER_H__ + + +#include + + +#include "rapidjson/fwd.h" + + +struct option; + + +namespace xmrig { + + +class ConfigWatcher; +class IConfigCreator; +class IWatcherListener; +class IConfig; + + +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::Document &doc); + static bool reload(IConfig *oldConfig, const char *json); + static IConfig *load(int argc, char **argv, IConfigCreator *creator, IWatcherListener *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 void showUsage(); + static void showVersion(); + + static ConfigWatcher *m_watcher; + static IConfigCreator *m_creator; + static IWatcherListener *m_listener; +}; + + +} /* namespace xmrig */ + +#endif /* __CONFIGLOADER_H__ */ diff --git a/src/core/ConfigLoader_platform.h b/src/core/ConfigLoader_platform.h new file mode 100644 index 00000000..59415f78 --- /dev/null +++ b/src/core/ConfigLoader_platform.h @@ -0,0 +1,171 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CONFIGLOADER_PLATFORM_H__ +#define __CONFIGLOADER_PLATFORM_H__ + + +#ifdef _MSC_VER +# include "getopt/getopt.h" +#else +# include +#endif + + +#include "version.h" +#include "interfaces/IConfig.h" + + +namespace xmrig { + + +static char const usage[] = "\ +Usage: " APP_ID " [OPTIONS]\n\ +Options:\n\ + -a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\ + -o, --url=URL URL of mining server\n\ + -O, --userpass=U:P username:password pair for mining server\n\ + -u, --user=USERNAME username for mining server\n\ + -p, --pass=PASSWORD password for mining server\n\ + -t, --threads=N number of miner threads\n\ + -v, --av=N algorithm variation, 0 auto select\n\ + -k, --keepalive send keepalived for prevent timeout (need pool support)\n\ + -r, --retries=N number of times to retry before switch to backup server (default: 5)\n\ + -R, --retry-pause=N time to pause between retries (default: 5)\n\ + --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\ + --cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n\ + --no-huge-pages disable huge pages support\n\ + --no-color disable colored output\n\ + --variant algorithm PoW variant\n\ + --donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\ + --user-agent set custom user-agent string for pool\n\ + -B, --background run the miner in the background\n\ + -c, --config=FILE load a JSON-format configuration file\n\ + -l, --log-file=FILE log all output to a file\n" +# ifdef HAVE_SYSLOG_H +"\ + -S, --syslog use system log for output messages\n" +# endif +"\ + --max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\ + --safe safe adjust threads and av settings for current CPU\n\ + --nicehash enable nicehash/xmrig-proxy support\n\ + --print-time=N print hashrate report every N seconds\n\ + --api-port=N port for the miner API\n\ + --api-access-token=T access token for API\n\ + --api-worker-id=ID custom worker-id for API\n\ + -h, --help display this help and exit\n\ + -V, --version output version information and exit\n\ +"; + + +static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vl:S"; + + +static struct option const options[] = { + { "algo", 1, nullptr, xmrig::IConfig::AlgorithmKey }, + { "api-access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey }, + { "api-port", 1, nullptr, xmrig::IConfig::ApiPort }, + { "api-worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey }, + { "api-no-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key }, + { "api-no-restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey }, + { "av", 1, nullptr, xmrig::IConfig::AVKey }, + { "background", 0, nullptr, xmrig::IConfig::BackgroundKey }, + { "config", 1, nullptr, xmrig::IConfig::ConfigKey }, + { "cpu-affinity", 1, nullptr, xmrig::IConfig::CPUAffinityKey }, + { "cpu-priority", 1, nullptr, xmrig::IConfig::CPUPriorityKey }, + { "donate-level", 1, nullptr, xmrig::IConfig::DonateLevelKey }, + { "dry-run", 0, nullptr, xmrig::IConfig::DryRunKey }, + { "help", 0, nullptr, xmrig::IConfig::HelpKey }, + { "keepalive", 0, nullptr, xmrig::IConfig::KeepAliveKey }, + { "log-file", 1, nullptr, xmrig::IConfig::LogFileKey }, + { "max-cpu-usage", 1, nullptr, xmrig::IConfig::MaxCPUUsageKey }, + { "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey }, + { "no-color", 0, nullptr, xmrig::IConfig::ColorKey }, + { "no-huge-pages", 0, nullptr, xmrig::IConfig::HugePagesKey }, + { "variant", 1, nullptr, xmrig::IConfig::VariantKey }, + { "pass", 1, nullptr, xmrig::IConfig::PasswordKey }, + { "print-time", 1, nullptr, xmrig::IConfig::PrintTimeKey }, + { "retries", 1, nullptr, xmrig::IConfig::RetriesKey }, + { "retry-pause", 1, nullptr, xmrig::IConfig::RetryPauseKey }, + { "safe", 0, nullptr, xmrig::IConfig::SafeKey }, + { "syslog", 0, nullptr, xmrig::IConfig::SyslogKey }, + { "threads", 1, nullptr, xmrig::IConfig::ThreadsKey }, + { "url", 1, nullptr, xmrig::IConfig::UrlKey }, + { "user", 1, nullptr, xmrig::IConfig::UserKey }, + { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, + { "userpass", 1, nullptr, xmrig::IConfig::UserpassKey }, + { "version", 0, nullptr, xmrig::IConfig::VersionKey }, + { 0, 0, 0, 0 } +}; + + +static struct option const config_options[] = { + { "algo", 1, nullptr, xmrig::IConfig::AlgorithmKey }, + { "av", 1, nullptr, xmrig::IConfig::AVKey }, + { "background", 0, nullptr, xmrig::IConfig::BackgroundKey }, + { "colors", 0, nullptr, xmrig::IConfig::ColorKey }, + { "cpu-affinity", 1, nullptr, xmrig::IConfig::CPUAffinityKey }, + { "cpu-priority", 1, nullptr, xmrig::IConfig::CPUPriorityKey }, + { "donate-level", 1, nullptr, xmrig::IConfig::DonateLevelKey }, + { "dry-run", 0, nullptr, xmrig::IConfig::DryRunKey }, + { "huge-pages", 0, nullptr, xmrig::IConfig::HugePagesKey }, + { "log-file", 1, nullptr, xmrig::IConfig::LogFileKey }, + { "max-cpu-usage", 1, nullptr, xmrig::IConfig::MaxCPUUsageKey }, + { "print-time", 1, nullptr, xmrig::IConfig::PrintTimeKey }, + { "retries", 1, nullptr, xmrig::IConfig::RetriesKey }, + { "retry-pause", 1, nullptr, xmrig::IConfig::RetryPauseKey }, + { "safe", 0, nullptr, xmrig::IConfig::SafeKey }, + { "syslog", 0, nullptr, xmrig::IConfig::SyslogKey }, + { "threads", 1, nullptr, xmrig::IConfig::SafeKey }, + { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, + { 0, 0, 0, 0 } +}; + + +static struct option const pool_options[] = { + { "url", 1, nullptr, xmrig::IConfig::UrlKey }, + { "pass", 1, nullptr, xmrig::IConfig::PasswordKey }, + { "user", 1, nullptr, xmrig::IConfig::UserKey }, + { "userpass", 1, nullptr, xmrig::IConfig::UserpassKey }, + { "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey }, + { "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey }, + { "variant", 1, nullptr, xmrig::IConfig::VariantKey }, + { 0, 0, 0, 0 } +}; + + +static struct option const api_options[] = { + { "port", 1, nullptr, xmrig::IConfig::ApiPort }, + { "access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey }, + { "worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey }, + { "ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key }, + { "restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey }, + { 0, 0, 0, 0 } +}; + + +} /* namespace xmrig */ + +#endif /* __CONFIGLOADER_PLATFORM_H__ */ diff --git a/src/core/ConfigWatcher.cpp b/src/core/ConfigWatcher.cpp new file mode 100644 index 00000000..b934b52b --- /dev/null +++ b/src/core/ConfigWatcher.cpp @@ -0,0 +1,107 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + + +#include "core/ConfigCreator.h" +#include "core/ConfigLoader.h" +#include "core/ConfigWatcher.h" +#include "interfaces/IWatcherListener.h" +#include "log/Log.h" + + +xmrig::ConfigWatcher::ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener) : + m_path(strdup(path)), + m_creator(creator), + m_listener(listener) +{ + uv_fs_event_init(uv_default_loop(), &m_fsEvent); + uv_timer_init(uv_default_loop(), &m_timer); + + m_fsEvent.data = m_timer.data = this; + + start(); +} + + +xmrig::ConfigWatcher::~ConfigWatcher() +{ + uv_timer_stop(&m_timer); + uv_fs_event_stop(&m_fsEvent); + + free(m_path); +} + + +void xmrig::ConfigWatcher::onTimer(uv_timer_t* handle) +{ + static_cast(handle->data)->reload(); +} + + +void xmrig::ConfigWatcher::onFsEvent(uv_fs_event_t* handle, const char *filename, int events, int status) +{ + if (!filename) { + return; + } + + static_cast(handle->data)->queueUpdate(); +} + + +void xmrig::ConfigWatcher::queueUpdate() +{ + uv_timer_stop(&m_timer); + uv_timer_start(&m_timer, xmrig::ConfigWatcher::onTimer, kDelay, 0); +} + + +void xmrig::ConfigWatcher::reload() +{ + LOG_WARN("\"%s\" was changed, reloading configuration", m_path); + + IConfig *config = m_creator->create(); + ConfigLoader::loadFromFile(config, m_path); + + if (!config->isValid()) { + LOG_ERR("reloading failed"); + + delete config; + return; + } + + m_listener->onNewConfig(config); + +# ifndef _WIN32 + uv_fs_event_stop(&m_fsEvent); + start(); +# endif +} + + +void xmrig::ConfigWatcher::start() +{ + uv_fs_event_start(&m_fsEvent, xmrig::ConfigWatcher::onFsEvent, m_path, 0); +} diff --git a/src/core/ConfigWatcher.h b/src/core/ConfigWatcher.h new file mode 100644 index 00000000..74526e90 --- /dev/null +++ b/src/core/ConfigWatcher.h @@ -0,0 +1,69 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CONFIGWATCHER_H__ +#define __CONFIGWATCHER_H__ + + +#include +#include + +#include "rapidjson/fwd.h" + + +struct option; + + +namespace xmrig { + + +class IConfigCreator; +class IWatcherListener; + + +class ConfigWatcher +{ +public: + ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener); + ~ConfigWatcher(); + +private: + constexpr static int kDelay = 500; + + static void onFsEvent(uv_fs_event_t* handle, const char *filename, int events, int status); + static void onTimer(uv_timer_t* handle); + void queueUpdate(); + void reload(); + void start(); + + char *m_path; + IConfigCreator *m_creator; + IWatcherListener *m_listener; + uv_fs_event_t m_fsEvent; + uv_timer_t m_timer; +}; + + +} /* namespace xmrig */ + +#endif /* __CONFIGWATCHER_H__ */ diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index af8a27d5..a5ffe236 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -112,7 +112,7 @@ void xmrig::Controller::addListener(IControllerListener *listener) } -void xmrig::Controller::onNewConfig(Config *config) +void xmrig::Controller::onNewConfig(IConfig *config) { // xmrig::Config *previousConfig = d_ptr->config; // d_ptr->config = config; diff --git a/src/core/Controller.h b/src/core/Controller.h index 2fe37c15..9144cca7 100644 --- a/src/core/Controller.h +++ b/src/core/Controller.h @@ -52,7 +52,7 @@ public: void addListener(IControllerListener *listener); protected: - void onNewConfig(Config *config) override; + void onNewConfig(IConfig *config) override; private: ControllerPrivate *d_ptr; diff --git a/src/donate.h b/src/donate.h index e8230b87..bdf7a00d 100644 --- a/src/donate.h +++ b/src/donate.h @@ -38,7 +38,8 @@ * XMR: 48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD * BTC: 1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT */ -constexpr const int kDonateLevel = 5; +constexpr const int kDefaultDonateLevel = 5; +constexpr const int kMinDonateLevel = 1; #endif /* __DONATE_H__ */ diff --git a/src/interfaces/IConfig.h b/src/interfaces/IConfig.h new file mode 100644 index 00000000..89aa6217 --- /dev/null +++ b/src/interfaces/IConfig.h @@ -0,0 +1,109 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2018 XMRig + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __ICONFIG_H__ +#define __ICONFIG_H__ + + +#include "rapidjson/fwd.h" + + +namespace xmrig { + + +class IConfig +{ +public: + enum Keys { + // common + AlgorithmKey = 'a', + ApiPort = 4000, + ApiAccessTokenKey = 4001, + ApiWorkerIdKey = 4002, + ApiIPv6Key = 4003, + ApiRestrictedKey = 4004, + BackgroundKey = 'B', + ConfigKey = 'c', + DonateLevelKey = 1003, + HelpKey = 'h', + KeepAliveKey = 'k', + LogFileKey = 'l', + ColorKey = 1002, + WatchKey = 1105, + PasswordKey = 'p', + RetriesKey = 'r', + RetryPauseKey = 'R', + SyslogKey = 'S', + UrlKey = 'o', + UserKey = 'u', + UserAgentKey = 1008, + UserpassKey = 'O', + VerboseKey = 1100, + VersionKey = 'V', + VariantKey = 1010, + + // xmrig common + CPUPriorityKey = 1021, + NicehashKey = 1006, + PrintTimeKey = 1007, + + // xmrig cpu + AVKey = 'v', + CPUAffinityKey = 1020, + DryRunKey = 5000, + HugePagesKey = 1009, + MaxCPUUsageKey = 1004, + SafeKey = 1005, + ThreadsKey = 't', + + // xmrig-proxy + AccessLogFileKey = 'A', + BindKey = 'b', + CoinKey = 1104, + CustomDiffKey = 1102, + DebugKey = 1101, + ModeKey = 'm', + PoolCoinKey = 'C', + ReuseTimeoutKey = 1106, + WorkersKey = 1103, + }; + + virtual ~IConfig() {} + + virtual bool adjust() = 0; + virtual bool isValid() const = 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 char *fileName() const = 0; + virtual void getJSON(rapidjson::Document &doc) const = 0; + virtual void parseJSON(const rapidjson::Document &doc) = 0; + virtual void setFileName(const char *fileName) = 0; +}; + + +} /* namespace xmrig */ + + +#endif // __ICONFIG_H__ diff --git a/src/interfaces/IConfigCreator.h b/src/interfaces/IConfigCreator.h new file mode 100644 index 00000000..597a6b74 --- /dev/null +++ b/src/interfaces/IConfigCreator.h @@ -0,0 +1,45 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2018 XMRig + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __ICONFIGCREATOR_H__ +#define __ICONFIGCREATOR_H__ + + +namespace xmrig { + + +class IConfig; + + +class IConfigCreator +{ +public: + virtual ~IConfigCreator() {} + + virtual IConfig *create() const = 0; +}; + + +} /* namespace xmrig */ + + +#endif // __ICONFIGCREATOR_H__ diff --git a/src/interfaces/IWatcherListener.h b/src/interfaces/IWatcherListener.h index da30b1fd..bfafb9a0 100644 --- a/src/interfaces/IWatcherListener.h +++ b/src/interfaces/IWatcherListener.h @@ -28,7 +28,7 @@ namespace xmrig { -class Config; +class IConfig; class IWatcherListener @@ -36,7 +36,7 @@ class IWatcherListener public: virtual ~IWatcherListener() {} - virtual void onNewConfig(Config *config) = 0; + virtual void onNewConfig(IConfig *config) = 0; }; diff --git a/src/net/Url.cpp b/src/net/Url.cpp index c17ef690..8905e919 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -37,12 +37,12 @@ Url::Url() : - m_keepAlive(false), m_nicehash(false), m_host(nullptr), m_password(nullptr), m_user(nullptr), m_algo(xmrig::ALGO_CRYPTONIGHT), + m_keepAlive(0), m_variant(xmrig::VARIANT_AUTO), m_url(nullptr), m_port(kDefaultPort) @@ -62,12 +62,12 @@ Url::Url() : * @param url */ Url::Url(const char *url) : - m_keepAlive(false), m_nicehash(false), m_host(nullptr), m_password(nullptr), m_user(nullptr), m_algo(xmrig::ALGO_CRYPTONIGHT), + m_keepAlive(0), m_variant(xmrig::VARIANT_AUTO), m_url(nullptr), m_port(kDefaultPort) @@ -76,12 +76,12 @@ Url::Url(const char *url) : } -Url::Url(const char *host, uint16_t port, const char *user, const char *password, bool keepAlive, bool nicehash, int variant) : - m_keepAlive(keepAlive), +Url::Url(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, int variant) : m_nicehash(nicehash), m_password(password ? strdup(password) : nullptr), m_user(user ? strdup(user) : nullptr), m_algo(xmrig::ALGO_CRYPTONIGHT), + m_keepAlive(keepAlive), m_variant(variant), m_url(nullptr), m_port(port) diff --git a/src/net/Url.h b/src/net/Url.h index f861fec5..45db4457 100644 --- a/src/net/Url.h +++ b/src/net/Url.h @@ -34,22 +34,24 @@ public: constexpr static const char *kDefaultPassword = "x"; constexpr static const char *kDefaultUser = "x"; constexpr static uint16_t kDefaultPort = 3333; + constexpr static int kKeepAliveTimeout = 60; Url(); Url(const char *url); - Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr, bool keepAlive = false, bool nicehash = false, int variant = -1); + Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr, int keepAlive = 0, bool nicehash = false, int variant = -1); ~Url(); - inline bool isKeepAlive() const { return m_keepAlive; } + inline bool isKeepAlive() const { return m_keepAlive > 0; } // FIXME: replace isKeepAlive to keepAlive inline bool isNicehash() const { return m_nicehash; } inline bool isValid() const { return m_host && m_port > 0; } inline const char *host() const { return m_host; } inline const char *password() const { return m_password ? m_password : kDefaultPassword; } inline const char *user() const { return m_user ? m_user : kDefaultUser; } inline int algo() const { return m_algo; } + inline int keepAlive() const { return m_keepAlive; } inline int variant() const { return m_variant; } inline uint16_t port() const { return m_port; } - inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; } + inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } inline void setVariant(bool monero) { m_variant = monero; } @@ -67,12 +69,12 @@ public: private: bool parseIPv6(const char *addr); - bool m_keepAlive; bool m_nicehash; char *m_host; char *m_password; char *m_user; int m_algo; + int m_keepAlive; int m_variant; mutable char *m_url; uint16_t m_port; diff --git a/src/xmrig.h b/src/xmrig.h index 103e8a68..9cae73c7 100644 --- a/src/xmrig.h +++ b/src/xmrig.h @@ -30,8 +30,9 @@ namespace xmrig enum Algo { - ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */ - ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ + ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */ + ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ + ALGO_CRYPTONIGHT_HEAVY, /* CryptoNight-Heavy (SUMO) */ }; From aac7b0404ae7180e5654f5ab839d0e2af07a3dc5 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 31 Mar 2018 16:29:47 +0700 Subject: [PATCH 004/109] Options class replaced to xmrig::Config. --- CMakeLists.txt | 2 - src/App.cpp | 84 ++-- src/App.h | 2 - src/App_win.cpp | 14 +- src/Mem.cpp | 1 - src/Mem_win.cpp | 1 - src/Options.cpp | 761 ------------------------------------- src/Options.h | 133 ------- src/Summary.cpp | 69 ++-- src/Summary.h | 11 +- src/api/ApiRouter.cpp | 21 +- src/core/Config.cpp | 7 +- src/core/Config.h | 2 - src/core/Controller.cpp | 83 ++-- src/core/Controller.h | 4 +- src/crypto/CryptoNight.cpp | 9 +- src/crypto/CryptoNight.h | 4 +- src/log/ConsoleLog.cpp | 26 +- src/log/ConsoleLog.h | 13 +- src/net/Network.cpp | 37 +- src/net/Network.h | 11 +- src/workers/Hashrate.cpp | 17 +- src/workers/Hashrate.h | 12 +- src/workers/Workers.cpp | 9 +- src/workers/Workers.h | 11 +- 25 files changed, 240 insertions(+), 1104 deletions(-) delete mode 100644 src/Options.cpp delete mode 100644 src/Options.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a4347d69..28d89a85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,6 @@ set(HEADERS src/net/strategies/SinglePoolStrategy.h src/net/SubmitResult.h src/net/Url.h - src/Options.h src/Platform.h src/Summary.h src/version.h @@ -104,7 +103,6 @@ set(SOURCES src/net/strategies/SinglePoolStrategy.cpp src/net/SubmitResult.cpp src/net/Url.cpp - src/Options.cpp src/Platform.cpp src/Summary.cpp src/workers/DoubleWorker.cpp diff --git a/src/App.cpp b/src/App.cpp index ed425f90..612614ae 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -29,6 +29,7 @@ #include "api/Api.h" #include "App.h" #include "Console.h" +#include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" #include "crypto/CryptoNight.h" @@ -37,17 +38,12 @@ #include "log/Log.h" #include "Mem.h" #include "net/Network.h" -#include "Options.h" #include "Platform.h" #include "Summary.h" #include "version.h" #include "workers/Workers.h" -#ifdef HAVE_SYSLOG_H -# include "log/SysLog.h" -#endif - #ifndef XMRIG_NO_HTTPD # include "api/Httpd.h" #endif @@ -59,42 +55,19 @@ App *App::m_self = nullptr; App::App(int argc, char **argv) : m_console(nullptr), - m_httpd(nullptr), - m_network(nullptr), - m_options(nullptr) + m_httpd(nullptr) { m_self = this; m_controller = new xmrig::Controller(); - - Cpu::init(); - m_options = Options::parse(argc, argv); - if (!m_options) { + if (m_controller->init(argc, argv) != 0) { return; } - Log::init(); - - if (!m_options->background()) { - Log::add(new ConsoleLog(m_options->colors())); + if (!m_controller->config()->isBackground()) { m_console = new Console(this); } - if (m_options->logFile()) { - Log::add(new FileLog(m_options->logFile())); - } - -# ifdef HAVE_SYSLOG_H - if (m_options->syslog()) { - Log::add(new SysLog()); - } -# endif - - Platform::init(m_options->userAgent()); - Platform::setProcessPriority(m_options->priority()); - - m_network = new Network(m_options); - uv_signal_init(uv_default_loop(), &m_sigHUP); uv_signal_init(uv_default_loop(), &m_sigINT); uv_signal_init(uv_default_loop(), &m_sigTERM); @@ -103,19 +76,22 @@ App::App(int argc, char **argv) : App::~App() { + Mem::release(); + uv_tty_reset_mode(); + delete m_console; + delete m_controller; + # ifndef XMRIG_NO_HTTPD delete m_httpd; # endif - - delete m_console; } int App::exec() { - if (!m_options) { + if (!m_controller->config()) { return 2; } @@ -125,15 +101,20 @@ int App::exec() background(); - if (!CryptoNight::init(m_options->algo(), m_options->algoVariant())) { - LOG_ERR("\"%s\" hash self-test failed.", m_options->algoName()); + if (!CryptoNight::init(m_controller->config()->algorithm(), m_controller->config()->algoVariant(), m_controller->config()->isDoubleHash())) { + LOG_ERR("\"%s\" hash self-test failed.", m_controller->config()->algoName()); return 1; } - Mem::allocate(m_options->algo(), m_options->threads(), m_options->doubleHash(), m_options->hugePages()); - Summary::print(); + Mem::allocate(m_controller->config()->algorithm(), + m_controller->config()->threads(), + m_controller->config()->isDoubleHash(), + m_controller->config()->isHugePages() + ); - if (m_options->dryRun()) { + Summary::print(m_controller); + + if (m_controller->config()->isDryRun()) { LOG_NOTICE("OK"); release(); @@ -145,13 +126,19 @@ int App::exec() # endif # ifndef XMRIG_NO_HTTPD - m_httpd = new Httpd(m_options->apiPort(), m_options->apiToken(), true, true); + m_httpd = new Httpd( + m_controller->config()->apiPort(), + m_controller->config()->apiToken(), + m_controller->config()->isApiIPv6(), + m_controller->config()->isApiRestricted() + ); + m_httpd->start(); # endif - Workers::start(m_options->affinity(), m_options->priority()); + Workers::start(m_controller->config()->affinity(), m_controller->config()->priority(), m_controller); - m_network->connect(); + m_controller->network()->connect(); const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); uv_loop_close(uv_default_loop()); @@ -172,7 +159,7 @@ void App::onConsoleCommand(char command) case 'p': case 'P': if (Workers::isEnabled()) { - LOG_INFO(m_options->colors() ? "\x1B[01;33mpaused\x1B[0m, press \x1B[01;35mr\x1B[0m to resume" : "paused, press 'r' to resume"); + LOG_INFO(m_controller->config()->isColors() ? "\x1B[01;33mpaused\x1B[0m, press \x1B[01;35mr\x1B[0m to resume" : "paused, press 'r' to resume"); Workers::setEnabled(false); } break; @@ -180,7 +167,7 @@ void App::onConsoleCommand(char command) case 'r': case 'R': if (!Workers::isEnabled()) { - LOG_INFO(m_options->colors() ? "\x1B[01;32mresumed" : "resumed"); + LOG_INFO(m_controller->config()->isColors() ? "\x1B[01;32mresumed" : "resumed"); Workers::setEnabled(true); } break; @@ -198,7 +185,7 @@ void App::onConsoleCommand(char command) void App::close() { - m_network->stop(); + m_controller->network()->stop(); Workers::stop(); uv_stop(uv_default_loop()); @@ -207,13 +194,6 @@ void App::close() void App::release() { - if (m_network) { - delete m_network; - } - - Options::release(); - Mem::release(); - Platform::release(); } diff --git a/src/App.h b/src/App.h index 9116a79a..22269f67 100644 --- a/src/App.h +++ b/src/App.h @@ -64,8 +64,6 @@ private: Console *m_console; Httpd *m_httpd; - Network *m_network; - Options *m_options; uv_signal_t m_sigHUP; uv_signal_t m_sigINT; uv_signal_t m_sigTERM; diff --git a/src/App_win.cpp b/src/App_win.cpp index 895f3bdf..b3a2c4cf 100644 --- a/src/App_win.cpp +++ b/src/App_win.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,17 +27,19 @@ #include "App.h" -#include "Options.h" #include "Cpu.h" +#include "core/Controller.h" +#include "core/Config.h" void App::background() { - if (m_options->affinity() != -1L) { - Cpu::setAffinity(-1, m_options->affinity()); + const int64_t affinity = m_controller->config()->affinity(); + if (affinity != -1L) { + Cpu::setAffinity(-1, affinity); } - if (!m_options->background()) { + if (!m_controller->config()->isBackground()) { return; } diff --git a/src/Mem.cpp b/src/Mem.cpp index b32d2196..991f4398 100644 --- a/src/Mem.cpp +++ b/src/Mem.cpp @@ -28,7 +28,6 @@ #include "crypto/CryptoNight.h" #include "Mem.h" -#include "Options.h" #include "xmrig.h" diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index 239bda7d..1b35c704 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -37,7 +37,6 @@ #include "log/Log.h" #include "crypto/CryptoNight.h" #include "Mem.h" -#include "Options.h" #include "xmrig.h" diff --git a/src/Options.cpp b/src/Options.cpp deleted file mode 100644 index 939075f8..00000000 --- a/src/Options.cpp +++ /dev/null @@ -1,761 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2016-2018 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include -#include - - -#ifdef _MSC_VER -# include "getopt/getopt.h" -#else -# include -#endif - - -#ifndef XMRIG_NO_HTTPD -# include -#endif - - -#include "Cpu.h" -#include "donate.h" -#include "net/Url.h" -#include "Options.h" -#include "Platform.h" -#include "rapidjson/document.h" -#include "rapidjson/error/en.h" -#include "rapidjson/filereadstream.h" -#include "version.h" -#include "xmrig.h" - - -#ifndef ARRAY_SIZE -# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -#endif - - -Options *Options::m_self = nullptr; - - -static char const usage[] = "\ -Usage: " APP_ID " [OPTIONS]\n\ -Options:\n\ - -a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\ - -o, --url=URL URL of mining server\n\ - -O, --userpass=U:P username:password pair for mining server\n\ - -u, --user=USERNAME username for mining server\n\ - -p, --pass=PASSWORD password for mining server\n\ - -t, --threads=N number of miner threads\n\ - -v, --av=N algorithm variation, 0 auto select\n\ - -k, --keepalive send keepalived for prevent timeout (need pool support)\n\ - -r, --retries=N number of times to retry before switch to backup server (default: 5)\n\ - -R, --retry-pause=N time to pause between retries (default: 5)\n\ - --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n\ - --cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n\ - --no-huge-pages disable huge pages support\n\ - --no-color disable colored output\n\ - --variant algorithm PoW variant\n\ - --donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\ - --user-agent set custom user-agent string for pool\n\ - -B, --background run the miner in the background\n\ - -c, --config=FILE load a JSON-format configuration file\n\ - -l, --log-file=FILE log all output to a file\n" -# ifdef HAVE_SYSLOG_H -"\ - -S, --syslog use system log for output messages\n" -# endif -"\ - --max-cpu-usage=N maximum CPU usage for automatic threads mode (default 75)\n\ - --safe safe adjust threads and av settings for current CPU\n\ - --nicehash enable nicehash/xmrig-proxy support\n\ - --print-time=N print hashrate report every N seconds\n\ - --api-port=N port for the miner API\n\ - --api-access-token=T access token for API\n\ - --api-worker-id=ID custom worker-id for API\n\ - -h, --help display this help and exit\n\ - -V, --version output version information and exit\n\ -"; - - -static char const short_options[] = "a:c:khBp:Px:r:R:s:t:T:o:u:O:v:Vl:S"; - - -static struct option const options[] = { - { "algo", 1, nullptr, 'a' }, - { "api-access-token", 1, nullptr, 4001 }, - { "api-port", 1, nullptr, 4000 }, - { "api-worker-id", 1, nullptr, 4002 }, - { "av", 1, nullptr, 'v' }, - { "background", 0, nullptr, 'B' }, - { "config", 1, nullptr, 'c' }, - { "cpu-affinity", 1, nullptr, 1020 }, - { "cpu-priority", 1, nullptr, 1021 }, - { "donate-level", 1, nullptr, 1003 }, - { "dry-run", 0, nullptr, 5000 }, - { "help", 0, nullptr, 'h' }, - { "keepalive", 0, nullptr ,'k' }, - { "log-file", 1, nullptr, 'l' }, - { "max-cpu-usage", 1, nullptr, 1004 }, - { "nicehash", 0, nullptr, 1006 }, - { "no-color", 0, nullptr, 1002 }, - { "no-huge-pages", 0, nullptr, 1009 }, - { "variant", 1, nullptr, 1010 }, - { "pass", 1, nullptr, 'p' }, - { "print-time", 1, nullptr, 1007 }, - { "retries", 1, nullptr, 'r' }, - { "retry-pause", 1, nullptr, 'R' }, - { "safe", 0, nullptr, 1005 }, - { "syslog", 0, nullptr, 'S' }, - { "threads", 1, nullptr, 't' }, - { "url", 1, nullptr, 'o' }, - { "user", 1, nullptr, 'u' }, - { "user-agent", 1, nullptr, 1008 }, - { "userpass", 1, nullptr, 'O' }, - { "version", 0, nullptr, 'V' }, - { 0, 0, 0, 0 } -}; - - -static struct option const config_options[] = { - { "algo", 1, nullptr, 'a' }, - { "av", 1, nullptr, 'v' }, - { "background", 0, nullptr, 'B' }, - { "colors", 0, nullptr, 2000 }, - { "cpu-affinity", 1, nullptr, 1020 }, - { "cpu-priority", 1, nullptr, 1021 }, - { "donate-level", 1, nullptr, 1003 }, - { "dry-run", 0, nullptr, 5000 }, - { "huge-pages", 0, nullptr, 1009 }, - { "log-file", 1, nullptr, 'l' }, - { "max-cpu-usage", 1, nullptr, 1004 }, - { "print-time", 1, nullptr, 1007 }, - { "retries", 1, nullptr, 'r' }, - { "retry-pause", 1, nullptr, 'R' }, - { "safe", 0, nullptr, 1005 }, - { "syslog", 0, nullptr, 'S' }, - { "threads", 1, nullptr, 't' }, - { "user-agent", 1, nullptr, 1008 }, - { 0, 0, 0, 0 } -}; - - -static struct option const pool_options[] = { - { "url", 1, nullptr, 'o' }, - { "pass", 1, nullptr, 'p' }, - { "user", 1, nullptr, 'u' }, - { "userpass", 1, nullptr, 'O' }, - { "keepalive", 0, nullptr ,'k' }, - { "variant", 1, nullptr, 1010 }, - { "nicehash", 0, nullptr, 1006 }, - { 0, 0, 0, 0 } -}; - - -static struct option const api_options[] = { - { "port", 1, nullptr, 4000 }, - { "access-token", 1, nullptr, 4001 }, - { "worker-id", 1, nullptr, 4002 }, - { 0, 0, 0, 0 } -}; - - -static const char *algo_names[] = { - "cryptonight", -# ifndef XMRIG_NO_AEON - "cryptonight-lite" -# endif -}; - - -Options *Options::parse(int argc, char **argv) -{ - Options *options = new Options(argc, argv); - if (options->isReady()) { - m_self = options; - return m_self; - } - - delete options; - return nullptr; -} - - -const char *Options::algoName() const -{ - return algo_names[m_algo]; -} - - -Options::Options(int argc, char **argv) : - m_background(false), - m_colors(true), - m_doubleHash(false), - m_dryRun(false), - m_hugePages(true), - m_ready(false), - m_safe(false), - m_syslog(false), - m_apiToken(nullptr), - m_apiWorkerId(nullptr), - m_logFile(nullptr), - m_userAgent(nullptr), - m_algo(0), - m_algoVariant(0), - m_apiPort(0), - m_donateLevel(kDonateLevel), - m_maxCpuUsage(75), - m_printTime(60), - m_priority(-1), - m_retries(5), - m_retryPause(5), - m_threads(0), - m_affinity(-1L) -{ - m_pools.push_back(new Url()); - - int key; - - while (1) { - key = getopt_long(argc, argv, short_options, options, NULL); - if (key < 0) { - break; - } - - if (!parseArg(key, optarg)) { - return; - } - } - - if (optind < argc) { - fprintf(stderr, "%s: unsupported non-option argument '%s'\n", argv[0], argv[optind]); - return; - } - - if (!m_pools[0]->isValid()) { - parseConfig(Platform::defaultConfigName()); - } - - if (!m_pools[0]->isValid()) { - fprintf(stderr, "No pool URL supplied. Exiting.\n"); - return; - } - - m_algoVariant = getAlgoVariant(); - if (m_algoVariant == AV2_AESNI_DOUBLE || m_algoVariant == AV4_SOFT_AES_DOUBLE) { - m_doubleHash = true; - } - - if (!m_threads) { - m_threads = Cpu::optimalThreadsCount(m_algo, m_doubleHash, m_maxCpuUsage); - } - else if (m_safe) { - const int count = Cpu::optimalThreadsCount(m_algo, m_doubleHash, m_maxCpuUsage); - if (m_threads > count) { - m_threads = count; - } - } - - adjust(); - - m_ready = true; -} - - -Options::~Options() -{ -} - - -bool Options::getJSON(const char *fileName, rapidjson::Document &doc) -{ - uv_fs_t req; - const int fd = uv_fs_open(uv_default_loop(), &req, fileName, O_RDONLY, 0644, nullptr); - if (fd < 0) { - fprintf(stderr, "unable to open %s: %s\n", fileName, uv_strerror(fd)); - return false; - } - - uv_fs_req_cleanup(&req); - - FILE *fp = fdopen(fd, "rb"); - char buf[8192]; - rapidjson::FileReadStream is(fp, buf, sizeof(buf)); - - doc.ParseStream(is); - - uv_fs_close(uv_default_loop(), &req, fd, nullptr); - uv_fs_req_cleanup(&req); - - if (doc.HasParseError()) { - printf("%s:%d: %s\n", fileName, (int) doc.GetErrorOffset(), rapidjson::GetParseError_En(doc.GetParseError())); - return false; - } - - return doc.IsObject(); -} - - -bool Options::parseArg(int key, const char *arg) -{ - switch (key) { - case 'a': /* --algo */ - if (!setAlgo(arg)) { - return false; - } - break; - - case 'o': /* --url */ - if (m_pools.size() > 1 || m_pools[0]->isValid()) { - Url *url = new Url(arg); - if (url->isValid()) { - m_pools.push_back(url); - } - else { - delete url; - } - } - else { - m_pools[0]->parse(arg); - } - - if (!m_pools.back()->isValid()) { - return false; - } - break; - - case 'O': /* --userpass */ - if (!m_pools.back()->setUserpass(arg)) { - return false; - } - break; - - case 'u': /* --user */ - m_pools.back()->setUser(arg); - break; - - case 'p': /* --pass */ - m_pools.back()->setPassword(arg); - break; - - case 'l': /* --log-file */ - free(m_logFile); - m_logFile = strdup(arg); - m_colors = false; - break; - - case 4001: /* --access-token */ - free(m_apiToken); - m_apiToken = strdup(arg); - break; - - case 4002: /* --worker-id */ - free(m_apiWorkerId); - m_apiWorkerId = strdup(arg); - break; - - case 'r': /* --retries */ - case 'R': /* --retry-pause */ - case 'v': /* --av */ - case 1003: /* --donate-level */ - case 1004: /* --max-cpu-usage */ - case 1007: /* --print-time */ - case 1021: /* --cpu-priority */ - case 4000: /* --api-port */ - case 1010: /* --variant */ - return parseArg(key, strtol(arg, nullptr, 10)); - - case 'B': /* --background */ - case 'k': /* --keepalive */ - case 'S': /* --syslog */ - case 1005: /* --safe */ - case 1006: /* --nicehash */ - case 5000: /* --dry-run */ - return parseBoolean(key, true); - - case 1002: /* --no-color */ - case 1009: /* --no-huge-pages */ - return parseBoolean(key, false); - - case 't': /* --threads */ - if (strncmp(arg, "all", 3) == 0) { - m_threads = Cpu::threads(); - return true; - } - - return parseArg(key, strtol(arg, nullptr, 10)); - - case 'V': /* --version */ - showVersion(); - return false; - - case 'h': /* --help */ - showUsage(0); - return false; - - case 'c': /* --config */ - parseConfig(arg); - break; - - case 1020: { /* --cpu-affinity */ - const char *p = strstr(arg, "0x"); - return parseArg(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10)); - } - - case 1008: /* --user-agent */ - free(m_userAgent); - m_userAgent = strdup(arg); - break; - - default: - showUsage(1); - return false; - } - - return true; -} - - -bool Options::parseArg(int key, uint64_t arg) -{ - switch (key) { - case 'r': /* --retries */ - if (arg < 1 || arg > 1000) { - showUsage(1); - return false; - } - - m_retries = (int) arg; - break; - - case 'R': /* --retry-pause */ - if (arg < 1 || arg > 3600) { - showUsage(1); - return false; - } - - m_retryPause = (int) arg; - break; - - case 't': /* --threads */ - if (arg < 1 || arg > 1024) { - showUsage(1); - return false; - } - - m_threads = (int) arg; - break; - - case 'v': /* --av */ - if (arg > 1000) { - showUsage(1); - return false; - } - - m_algoVariant = (int) arg; - break; - - case 1003: /* --donate-level */ - if (arg < 1 || arg > 99) { - return true; - } - - m_donateLevel = (int) arg; - break; - - case 1004: /* --max-cpu-usage */ - if (arg < 1 || arg > 100) { - showUsage(1); - return false; - } - - m_maxCpuUsage = (int) arg; - break; - - case 1007: /* --print-time */ - if (arg > 1000) { - showUsage(1); - return false; - } - - m_printTime = (int) arg; - break; - - case 1010: /* --variant */ - m_pools.back()->setVariant((int) arg); - break; - - case 1020: /* --cpu-affinity */ - if (arg) { - m_affinity = arg; - } - break; - - case 1021: /* --cpu-priority */ - if (arg <= 5) { - m_priority = (int) arg; - } - break; - - case 4000: /* --api-port */ - if (arg <= 65536) { - m_apiPort = (int) arg; - } - break; - - default: - break; - } - - return true; -} - - -bool Options::parseBoolean(int key, bool enable) -{ - switch (key) { - case 'k': /* --keepalive */ - m_pools.back()->setKeepAlive(enable); - break; - - case 'B': /* --background */ - m_background = enable; - m_colors = enable ? false : m_colors; - break; - - case 'S': /* --syslog */ - m_syslog = enable; - m_colors = enable ? false : m_colors; - break; - - case 1002: /* --no-color */ - m_colors = enable; - break; - - case 1005: /* --safe */ - m_safe = enable; - break; - - case 1006: /* --nicehash */ - m_pools.back()->setNicehash(enable); - break; - - case 1009: /* --no-huge-pages */ - m_hugePages = enable; - break; - - case 2000: /* colors */ - m_colors = enable; - break; - - case 5000: /* --dry-run */ - m_dryRun = enable; - break; - - default: - break; - } - - return true; -} - - -Url *Options::parseUrl(const char *arg) const -{ - auto url = new Url(arg); - if (!url->isValid()) { - delete url; - return nullptr; - } - - return url; -} - - -void Options::adjust() -{ - for (Url *url : m_pools) { - url->adjust(m_algo); - } -} - - -void Options::parseConfig(const char *fileName) -{ - rapidjson::Document doc; - if (!getJSON(fileName, doc)) { - return; - } - - for (size_t i = 0; i < ARRAY_SIZE(config_options); i++) { - parseJSON(&config_options[i], doc); - } - - const rapidjson::Value &pools = doc["pools"]; - if (pools.IsArray()) { - for (const rapidjson::Value &value : pools.GetArray()) { - if (!value.IsObject()) { - continue; - } - - for (size_t i = 0; i < ARRAY_SIZE(pool_options); i++) { - parseJSON(&pool_options[i], value); - } - } - } - - const rapidjson::Value &api = doc["api"]; - if (api.IsObject()) { - for (size_t i = 0; i < ARRAY_SIZE(api_options); i++) { - parseJSON(&api_options[i], api); - } - } -} - - -void Options::parseJSON(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 && value.IsString()) { - parseArg(option->val, value.GetString()); - } - else if (option->has_arg && value.IsInt64()) { - parseArg(option->val, value.GetUint64()); - } - else if (!option->has_arg && value.IsBool()) { - parseBoolean(option->val, value.IsTrue()); - } -} - - -void Options::showUsage(int status) const -{ - if (status) { - fprintf(stderr, "Try \"" APP_ID "\" --help' for more information.\n"); - } - else { - printf(usage); - } -} - - -void Options::showVersion() -{ - printf(APP_NAME " " APP_VERSION "\n built on " __DATE__ - -# if defined(__clang__) - " with clang " __clang_version__); -# elif defined(__GNUC__) - " with GCC"); - printf(" %d.%d.%d", __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); -# elif defined(_MSC_VER) - " with MSVC"); - printf(" %d", MSVC_VERSION); -# else - ); -# endif - - printf("\n features:" -# if defined(__i386__) || defined(_M_IX86) - " i386" -# elif defined(__x86_64__) || defined(_M_AMD64) - " x86_64" -# endif - -# if defined(__AES__) || defined(_MSC_VER) - " AES-NI" -# endif - "\n"); - - printf("\nlibuv/%s\n", uv_version_string()); - -# ifndef XMRIG_NO_HTTPD - printf("libmicrohttpd/%s\n", MHD_get_version()); -# endif -} - - -bool Options::setAlgo(const char *algo) -{ - for (size_t i = 0; i < ARRAY_SIZE(algo_names); i++) { - if (algo_names[i] && !strcmp(algo, algo_names[i])) { - m_algo = (int) i; - break; - } - -# ifndef XMRIG_NO_AEON - if (i == ARRAY_SIZE(algo_names) - 1 && !strcmp(algo, "cryptonight-light")) { - m_algo = xmrig::ALGO_CRYPTONIGHT_LITE; - break; - } -# endif - - if (i == ARRAY_SIZE(algo_names) - 1) { - showUsage(1); - return false; - } - } - - return true; -} - - -int Options::getAlgoVariant() const -{ -# ifndef XMRIG_NO_AEON - if (m_algo == xmrig::ALGO_CRYPTONIGHT_LITE) { - return getAlgoVariantLite(); - } -# endif - - if (m_algoVariant <= AV0_AUTO || m_algoVariant >= AV_MAX) { - return Cpu::hasAES() ? AV1_AESNI : AV3_SOFT_AES; - } - - if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV2_AESNI_DOUBLE) { - return m_algoVariant + 2; - } - - return m_algoVariant; -} - - -#ifndef XMRIG_NO_AEON -int Options::getAlgoVariantLite() const -{ - if (m_algoVariant <= AV0_AUTO || m_algoVariant >= AV_MAX) { - return Cpu::hasAES() ? AV2_AESNI_DOUBLE : AV4_SOFT_AES_DOUBLE; - } - - if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV2_AESNI_DOUBLE) { - return m_algoVariant + 2; - } - - return m_algoVariant; -} -#endif diff --git a/src/Options.h b/src/Options.h deleted file mode 100644 index e29059ec..00000000 --- a/src/Options.h +++ /dev/null @@ -1,133 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2016-2018 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __OPTIONS_H__ -#define __OPTIONS_H__ - - -#include -#include - - -#include "rapidjson/fwd.h" - - -class Url; -struct option; - - -class Options -{ -public: - enum AlgoVariant { - AV0_AUTO, - AV1_AESNI, - AV2_AESNI_DOUBLE, - AV3_SOFT_AES, - AV4_SOFT_AES_DOUBLE, - AV_MAX - }; - - static inline Options* i() { return m_self; } - static Options *parse(int argc, char **argv); - - inline bool background() const { return m_background; } - inline bool colors() const { return m_colors; } - inline bool doubleHash() const { return m_doubleHash; } - inline bool dryRun() const { return m_dryRun; } - inline bool hugePages() const { return m_hugePages; } - inline bool syslog() const { return m_syslog; } - inline const char *apiToken() const { return m_apiToken; } - inline const char *apiWorkerId() const { return m_apiWorkerId; } - inline const char *logFile() const { return m_logFile; } - inline const char *userAgent() const { return m_userAgent; } - inline const std::vector &pools() const { return m_pools; } - inline int algo() const { return m_algo; } - inline int algoVariant() const { return m_algoVariant; } - inline int apiPort() const { return m_apiPort; } - inline int donateLevel() const { return m_donateLevel; } - inline int printTime() const { return m_printTime; } - inline int priority() const { return m_priority; } - inline int retries() const { return m_retries; } - inline int retryPause() const { return m_retryPause; } - inline int threads() const { return m_threads; } - inline int64_t affinity() const { return m_affinity; } - inline void setColors(bool colors) { m_colors = colors; } - - inline static void release() { delete m_self; } - - const char *algoName() const; - -private: - Options(int argc, char **argv); - ~Options(); - - inline bool isReady() const { return m_ready; } - - static Options *m_self; - - bool getJSON(const char *fileName, rapidjson::Document &doc); - bool parseArg(int key, const char *arg); - bool parseArg(int key, uint64_t arg); - bool parseBoolean(int key, bool enable); - Url *parseUrl(const char *arg) const; - void adjust(); - void parseConfig(const char *fileName); - void parseJSON(const struct option *option, const rapidjson::Value &object); - void showUsage(int status) const; - void showVersion(void); - - bool setAlgo(const char *algo); - - int getAlgoVariant() const; -# ifndef XMRIG_NO_AEON - int getAlgoVariantLite() const; -# endif - - bool m_background; - bool m_colors; - bool m_doubleHash; - bool m_dryRun; - bool m_hugePages; - bool m_ready; - bool m_safe; - bool m_syslog; - char *m_apiToken; - char *m_apiWorkerId; - char *m_logFile; - char *m_userAgent; - int m_algo; - int m_algoVariant; - int m_apiPort; - int m_donateLevel; - int m_maxCpuUsage; - int m_printTime; - int m_priority; - int m_retries; - int m_retryPause; - int m_threads; - int64_t m_affinity; - std::vector m_pools; -}; - -#endif /* __OPTIONS_H__ */ diff --git a/src/Summary.cpp b/src/Summary.cpp index 2d93f429..4b663fbf 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,16 +27,17 @@ #include +#include "core/Config.h" +#include "core/Controller.h" #include "Cpu.h" #include "log/Log.h" #include "Mem.h" #include "net/Url.h" -#include "Options.h" #include "Summary.h" #include "version.h" -static void print_versions() +static void print_versions(xmrig::Config *config) { char buf[16]; @@ -51,13 +52,13 @@ static void print_versions() # endif - Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s" : " * VERSIONS: XMRig/%s libuv/%s%s", + Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mVERSIONS: \x1B[01;36mXMRig/%s\x1B[01;37m libuv/%s%s" : " * VERSIONS: XMRig/%s libuv/%s%s", APP_VERSION, uv_version_string(), buf); } -static void print_memory() { - if (Options::i()->colors()) { +static void print_memory(xmrig::Config *config) { + if (config->isColors()) { Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s, %s", Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable", Mem::isHugepagesEnabled() ? "\x1B[01;32menabled" : "\x1B[01;31mdisabled"); @@ -68,9 +69,9 @@ static void print_memory() { } -static void print_cpu() +static void print_cpu(xmrig::Config *config) { - if (Options::i()->colors()) { + if (config->isColors()) { Log::i()->text("\x1B[01;32m * \x1B[01;37mCPU: %s (%d) %sx64 %sAES-NI", Cpu::brand(), Cpu::sockets(), @@ -89,32 +90,32 @@ static void print_cpu() } -static void print_threads() +static void print_threads(xmrig::Config *config) { char buf[32]; - if (Options::i()->affinity() != -1L) { - snprintf(buf, 32, ", affinity=0x%" PRIX64, Options::i()->affinity()); + if (config->affinity() != -1L) { + snprintf(buf, 32, ", affinity=0x%" PRIX64, config->affinity()); } else { buf[0] = '\0'; } - Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s", - Options::i()->threads(), - Options::i()->algoName(), - Options::i()->algoVariant(), - Options::i()->colors() && Options::i()->donateLevel() == 0 ? "\x1B[01;31m" : "", - Options::i()->donateLevel(), + Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s", + config->threads(), + config->algoName(), + config->algoVariant(), + config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", + config->donateLevel(), buf); } -static void print_pools() +static void print_pools(xmrig::Config *config) { - const std::vector &pools = Options::i()->pools(); + const std::vector &pools = config->pools(); for (size_t i = 0; i < pools.size(); ++i) { - Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d: \x1B[01;36m%s:%d" : " * POOL #%d: %s:%d", + Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d: \x1B[01;36m%s:%d" : " * POOL #%d: %s:%d", i + 1, pools[i]->host(), pools[i]->port()); @@ -129,20 +130,20 @@ static void print_pools() #ifndef XMRIG_NO_API -static void print_api() +static void print_api(xmrig::Config *config) { - if (Options::i()->apiPort() == 0) { + if (config->apiPort() == 0) { return; } - Log::i()->text(Options::i()->colors() ? "\x1B[01;32m * \x1B[01;37mAPI PORT: \x1B[01;36m%d" : " * API PORT: %d", Options::i()->apiPort()); + Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mAPI PORT: \x1B[01;36m%d" : " * API PORT: %d", config->apiPort()); } #endif -static void print_commands() +static void print_commands(xmrig::Config *config) { - if (Options::i()->colors()) { + if (config->isColors()) { Log::i()->text("\x1B[01;32m * \x1B[01;37mCOMMANDS: \x1B[01;35mh\x1B[01;37mashrate, \x1B[01;35mp\x1B[01;37mause, \x1B[01;35mr\x1B[01;37mesume"); } else { @@ -151,19 +152,19 @@ static void print_commands() } -void Summary::print() +void Summary::print(xmrig::Controller *controller) { - print_versions(); - print_memory(); - print_cpu(); - print_threads(); - print_pools(); + print_versions(controller->config()); + print_memory(controller->config()); + print_cpu(controller->config()); + print_threads(controller->config()); + print_pools(controller->config()); # ifndef XMRIG_NO_API - print_api(); + print_api(controller->config()); # endif - print_commands(); + print_commands(controller->config()); } diff --git a/src/Summary.h b/src/Summary.h index 3f64fd60..f07dba35 100644 --- a/src/Summary.h +++ b/src/Summary.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,10 +25,15 @@ #define __SUMMARY_H__ +namespace xmrig { + class Controller; +} + + class Summary { public: - static void print(); + static void print(xmrig::Controller *controller); }; diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 6ee8e7a4..bb8c7402 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -35,14 +35,15 @@ #include "api/ApiRouter.h" #include "api/HttpReply.h" #include "api/HttpRequest.h" +#include "core/Config.h" +#include "core/Controller.h" #include "Cpu.h" #include "Mem.h" #include "net/Job.h" -#include "Options.h" #include "Platform.h" #include "rapidjson/document.h" -#include "rapidjson/stringbuffer.h" #include "rapidjson/prettywriter.h" +#include "rapidjson/stringbuffer.h" #include "version.h" #include "workers/Hashrate.h" @@ -66,13 +67,13 @@ static inline double normalize(double d) ApiRouter::ApiRouter(xmrig::Controller *controller) : m_controller(controller) { - m_threads = Options::i()->threads(); + m_threads = controller->config()->threads(); m_hashrate = new double[m_threads * 3](); memset(m_totalHashrate, 0, sizeof(m_totalHashrate)); memset(m_workerId, 0, sizeof(m_workerId)); - setWorkerId(Options::i()->apiWorkerId()); + setWorkerId(controller->config()->apiWorkerId()); genId(); } @@ -100,10 +101,10 @@ void ApiRouter::ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply & void ApiRouter::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) { -// if (req.method() == xmrig::HttpRequest::Put && req.match("/1/config")) { -// m_controller->config()->reload(req.body()); -// return; -// } + if (req.method() == xmrig::HttpRequest::Put && req.match("/1/config")) { + m_controller->config()->reload(req.body()); + return; + } reply.status = 404; } @@ -246,9 +247,9 @@ void ApiRouter::getMiner(rapidjson::Document &doc) const doc.AddMember("kind", APP_KIND, allocator); doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator); doc.AddMember("cpu", cpu, allocator); - doc.AddMember("algo", rapidjson::StringRef(Options::i()->algoName()), allocator); + doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algoName()), allocator); doc.AddMember("hugepages", Mem::isHugepagesEnabled(), allocator); - doc.AddMember("donate_level", Options::i()->donateLevel(), allocator); + doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator); } diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 9bf44bc8..f30ed1f4 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -40,7 +40,6 @@ xmrig::Config::Config() : xmrig::CommonConfig(), m_dryRun(false), m_hugePages(true), m_safe(false), - m_algo(0), m_algoVariant(0), m_maxCpuUsage(75), m_printTime(60), @@ -151,10 +150,10 @@ bool xmrig::Config::adjust() } if (!m_threads) { - m_threads = Cpu::optimalThreadsCount(m_algo, m_doubleHash, m_maxCpuUsage); + m_threads = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); } else if (m_safe) { - const int count = Cpu::optimalThreadsCount(m_algo, m_doubleHash, m_maxCpuUsage); + const int count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); if (m_threads > count) { m_threads = count; } @@ -296,7 +295,7 @@ bool xmrig::Config::parseInt(int key, int arg) int xmrig::Config::getAlgoVariant() const { # ifndef XMRIG_NO_AEON - if (m_algo == xmrig::ALGO_CRYPTONIGHT_LITE) { + if (m_algorithm == xmrig::ALGO_CRYPTONIGHT_LITE) { return getAlgoVariantLite(); } # endif diff --git a/src/core/Config.h b/src/core/Config.h index a10cd696..110c61a7 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -79,7 +79,6 @@ public: inline bool isDoubleHash() const { return m_doubleHash; } inline bool isDryRun() const { return m_dryRun; } inline bool isHugePages() const { return m_hugePages; } - inline int algo() const { return m_algo; } inline int algoVariant() const { return m_algoVariant; } inline int printTime() const { return m_printTime; } inline int priority() const { return m_priority; } @@ -107,7 +106,6 @@ private: bool m_dryRun; bool m_hugePages; bool m_safe; - int m_algo; int m_algoVariant; int m_maxCpuUsage; int m_printTime; diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index a5ffe236..b8c93c82 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -22,15 +22,19 @@ */ -//#include "core/Config.h" -//#include "core/ConfigLoader.h" +#include + + +#include "core/Config.h" +#include "core/ConfigLoader.h" #include "core/Controller.h" +#include "Cpu.h" +#include "interfaces/IControllerListener.h" #include "log/ConsoleLog.h" #include "log/FileLog.h" #include "log/Log.h" +#include "net/Network.h" #include "Platform.h" -//#include "proxy/Proxy.h" -#include "interfaces/IControllerListener.h" #ifdef HAVE_SYSLOG_H @@ -42,18 +46,21 @@ class xmrig::ControllerPrivate { public: inline ControllerPrivate() : + network(nullptr), config(nullptr) {} inline ~ControllerPrivate() { -// delete config; + delete network; + delete config; } - xmrig::Config *config; + Network *network; std::vector listeners; + xmrig::Config *config; }; @@ -65,7 +72,8 @@ xmrig::Controller::Controller() xmrig::Controller::~Controller() { -// ConfigLoader::release(); + ConfigLoader::release(); + Platform::release(); delete d_ptr; } @@ -73,39 +81,52 @@ xmrig::Controller::~Controller() xmrig::Config *xmrig::Controller::config() const { + assert(d_ptr->config != nullptr); + return d_ptr->config; } int xmrig::Controller::init(int argc, char **argv) { -// d_ptr->config = xmrig::Config::load(argc, argv, this); -// if (!d_ptr->config) { -// return 1; -// } + Cpu::init(); -// Log::init(); -// Platform::init(config()->userAgent()); + d_ptr->config = xmrig::Config::load(argc, argv, this); + if (!d_ptr->config) { + return 1; + } -// if (!config()->background()) { -// Log::add(new ConsoleLog(this)); -// } + Log::init(); + Platform::init(config()->userAgent()); + Platform::setProcessPriority(d_ptr->config->priority()); -// if (config()->logFile()) { -// Log::add(new FileLog(config()->logFile())); -// } + if (!config()->isBackground()) { + Log::add(new ConsoleLog(this)); + } -//# ifdef HAVE_SYSLOG_H -// if (config()->syslog()) { -// Log::add(new SysLog()); -// } -//# endif + if (config()->logFile()) { + Log::add(new FileLog(config()->logFile())); + } -// d_ptr->proxy = new Proxy(this); +# ifdef HAVE_SYSLOG_H + if (config()->syslog()) { + Log::add(new SysLog()); + } +# endif + + d_ptr->network = new Network(this); return 0; } +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); @@ -114,12 +135,12 @@ void xmrig::Controller::addListener(IControllerListener *listener) void xmrig::Controller::onNewConfig(IConfig *config) { -// xmrig::Config *previousConfig = d_ptr->config; -// d_ptr->config = config; + Config *previousConfig = d_ptr->config; + d_ptr->config = static_cast(config); -// for (xmrig::IControllerListener *listener : d_ptr->listeners) { -// listener->onConfigChanged(config, previousConfig); -// } + for (xmrig::IControllerListener *listener : d_ptr->listeners) { + listener->onConfigChanged(d_ptr->config, previousConfig); + } -// delete previousConfig; + delete previousConfig; } diff --git a/src/core/Controller.h b/src/core/Controller.h index 9144cca7..2ba80f99 100644 --- a/src/core/Controller.h +++ b/src/core/Controller.h @@ -28,7 +28,7 @@ #include "interfaces/IWatcherListener.h" -class Proxy; +class Network; class StatsData; @@ -48,7 +48,7 @@ public: Config *config() const; int init(int argc, char **argv); - Proxy *proxy() const; + Network *network() const; void addListener(IControllerListener *listener); protected: diff --git a/src/crypto/CryptoNight.cpp b/src/crypto/CryptoNight.cpp index b605bfb8..c9a2e499 100644 --- a/src/crypto/CryptoNight.cpp +++ b/src/crypto/CryptoNight.cpp @@ -35,7 +35,6 @@ #include "crypto/CryptoNight_test.h" #include "net/Job.h" #include "net/JobResult.h" -#include "Options.h" #include "xmrig.h" @@ -131,7 +130,7 @@ bool CryptoNight::hash(const Job &job, JobResult &result, cryptonight_ctx *ctx) } -bool CryptoNight::init(int algo, int variant) +bool CryptoNight::init(int algo, int variant, bool doubleHash) { if (variant < 1 || variant > 4) { return false; @@ -145,7 +144,7 @@ bool CryptoNight::init(int algo, int variant) cryptonight_hash_ctx = cryptonight_variations[index]; - return selfTest(algo); + return selfTest(algo, doubleHash); } @@ -155,7 +154,7 @@ void CryptoNight::hash(const uint8_t *input, size_t size, uint8_t *output, crypt } -bool CryptoNight::selfTest(int algo) { +bool CryptoNight::selfTest(int algo, bool doubleHash) { if (cryptonight_hash_ctx == nullptr) { return false; } @@ -167,8 +166,6 @@ bool CryptoNight::selfTest(int algo) { cryptonight_hash_ctx(test_input, 76, output, ctx, 0); - const bool doubleHash = Options::i()->doubleHash(); - # ifndef XMRIG_NO_AEON bool rc = memcmp(output, algo == xmrig::ALGO_CRYPTONIGHT_LITE ? test_output_v0_lite : test_output_v0, (doubleHash ? 64 : 32)) == 0; # else diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index 13e9c8e8..eb17719e 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -54,11 +54,11 @@ class CryptoNight { public: static bool hash(const Job &job, JobResult &result, cryptonight_ctx *ctx); - static bool init(int algo, int variant); + static bool init(int algo, int variant, bool doubleHash); static void hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant); private: - static bool selfTest(int algo); + static bool selfTest(int algo, bool doubleHash); }; #endif /* __CRYPTONIGHT_H__ */ diff --git a/src/log/ConsoleLog.cpp b/src/log/ConsoleLog.cpp index 3656d48c..eeed7355 100644 --- a/src/log/ConsoleLog.cpp +++ b/src/log/ConsoleLog.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,18 +34,18 @@ #endif +#include "core/Config.h" +#include "core/Controller.h" #include "log/ConsoleLog.h" #include "log/Log.h" -#include "Options.h" -ConsoleLog::ConsoleLog(bool colors) : - m_colors(colors), - m_stream(nullptr) +ConsoleLog::ConsoleLog(xmrig::Controller *controller) : + m_stream(nullptr), + m_controller(controller) { if (uv_tty_init(uv_default_loop(), &m_tty, 1, 0) < 0) { - Options::i()->setColors(false); - m_colors = false; + controller->config()->setColors(false); return; } @@ -78,7 +78,9 @@ void ConsoleLog::message(int level, const char* fmt, va_list args) # endif const char* color = nullptr; - if (m_colors) { + const bool colors = m_controller->config()->isColors(); + + if (colors) { switch (level) { case Log::ERR: color = Log::kCL_RED; @@ -109,9 +111,9 @@ void ConsoleLog::message(int level, const char* fmt, va_list args) stime.tm_hour, stime.tm_min, stime.tm_sec, - m_colors ? color : "", + colors ? color : "", fmt, - m_colors ? Log::kCL_N : "" + colors ? Log::kCL_N : "" ); print(args); @@ -120,7 +122,7 @@ void ConsoleLog::message(int level, const char* fmt, va_list args) void ConsoleLog::text(const char* fmt, va_list args) { - snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_colors ? Log::kCL_N : ""); + snprintf(m_fmt, sizeof(m_fmt) - 1, "%s%s\n", fmt, m_controller->config()->isColors() ? Log::kCL_N : ""); print(args); } diff --git a/src/log/ConsoleLog.h b/src/log/ConsoleLog.h index a04a27c5..6649be84 100644 --- a/src/log/ConsoleLog.h +++ b/src/log/ConsoleLog.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,10 +31,15 @@ #include "interfaces/ILogBackend.h" +namespace xmrig { + class Controller; +} + + class ConsoleLog : public ILogBackend { public: - ConsoleLog(bool colors); + ConsoleLog(xmrig::Controller *controller); void message(int level, const char *fmt, va_list args) override; void text(const char *fmt, va_list args) override; @@ -43,12 +48,12 @@ private: bool isWritable() const; void print(va_list args); - bool m_colors; char m_buf[512]; char m_fmt[256]; uv_buf_t m_uvBuf; uv_stream_t *m_stream; uv_tty_t m_tty; + xmrig::Controller *m_controller; }; #endif /* __CONSOLELOG_H__ */ diff --git a/src/net/Network.cpp b/src/net/Network.cpp index ede3f8b4..a8e60efa 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -39,29 +39,30 @@ #include "net/strategies/SinglePoolStrategy.h" #include "net/SubmitResult.h" #include "net/Url.h" -#include "Options.h" #include "workers/Workers.h" +#include "core/Controller.h" +#include "core/Config.h" -Network::Network(const Options *options) : - m_options(options), - m_donate(nullptr) +Network::Network(xmrig::Controller *controller) : + m_donate(nullptr), + m_controller(controller) { srand(time(0) ^ (uintptr_t) this); Workers::setListener(this); - const std::vector &pools = options->pools(); + const std::vector &pools = controller->config()->pools(); if (pools.size() > 1) { - m_strategy = new FailoverStrategy(pools, options->retryPause(), options->retries(), this); + m_strategy = new FailoverStrategy(pools, controller->config()->retryPause(), controller->config()->retries(), this); } else { - m_strategy = new SinglePoolStrategy(pools.front(), options->retryPause(), this); + m_strategy = new SinglePoolStrategy(pools.front(), controller->config()->retryPause(), this); } - if (m_options->donateLevel() > 0) { - m_donate = new DonateStrategy(options->donateLevel(), options->pools().front()->user(), options->algo(), this); + if (controller->config()->donateLevel() > 0) { + m_donate = new DonateStrategy(controller->config()->donateLevel(), controller->config()->pools().front()->user(), controller->config()->algorithm(), this); } m_timer.data = this; @@ -101,7 +102,7 @@ void Network::onActive(IStrategy *strategy, Client *client) m_state.setPool(client->host(), client->port(), client->ip()); - LOG_INFO(m_options->colors() ? "\x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s" : "use pool %s:%d %s", client->host(), client->port(), client->ip()); + LOG_INFO(isColors() ? "\x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s" : "use pool %s:%d %s", client->host(), client->port(), client->ip()); } @@ -146,21 +147,27 @@ void Network::onResultAccepted(IStrategy *strategy, Client *client, const Submit m_state.add(result, error); if (error) { - LOG_INFO(m_options->colors() ? "\x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRIu64 " ms)" - : "rejected (%" PRId64 "/%" PRId64 ") diff %u \"%s\" (%" PRIu64 " ms)", + LOG_INFO(isColors() ? "\x1B[01;31mrejected\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[31m\"%s\"\x1B[0m \x1B[01;30m(%" PRIu64 " ms)" + : "rejected (%" PRId64 "/%" PRId64 ") diff %u \"%s\" (%" PRIu64 " ms)", m_state.accepted, m_state.rejected, result.diff, error, result.elapsed); } else { - LOG_INFO(m_options->colors() ? "\x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%" PRIu64 " ms)" - : "accepted (%" PRId64 "/%" PRId64 ") diff %u (%" PRIu64 " ms)", + LOG_INFO(isColors() ? "\x1B[01;32maccepted\x1B[0m (%" PRId64 "/%" PRId64 ") diff \x1B[01;37m%u\x1B[0m \x1B[01;30m(%" PRIu64 " ms)" + : "accepted (%" PRId64 "/%" PRId64 ") diff %u (%" PRIu64 " ms)", m_state.accepted, m_state.rejected, result.diff, result.elapsed); } } +bool Network::isColors() const +{ + return m_controller->config()->isColors(); +} + + void Network::setJob(Client *client, const Job &job, bool donate) { - if (m_options->colors()) { + if (isColors()) { LOG_INFO("\x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d", client->host(), client->port(), job.diff()); } else { diff --git a/src/net/Network.h b/src/net/Network.h index fae5c563..353edc77 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -35,14 +35,18 @@ class IStrategy; -class Options; class Url; +namespace xmrig { + class Controller; +} + + class Network : public IJobResultListener, public IStrategyListener { public: - Network(const Options *options); + Network(xmrig::Controller *controller); ~Network(); void connect(); @@ -58,16 +62,17 @@ protected: private: constexpr static int kTickInterval = 1 * 1000; + bool isColors() const; void setJob(Client *client, const Job &job, bool donate); void tick(); static void onTick(uv_timer_t *handle); - const Options *m_options; IStrategy *m_donate; IStrategy *m_strategy; NetworkState m_state; uv_timer_t m_timer; + xmrig::Controller *m_controller; }; diff --git a/src/workers/Hashrate.cpp b/src/workers/Hashrate.cpp index bd5b7df6..ef06eb52 100644 --- a/src/workers/Hashrate.cpp +++ b/src/workers/Hashrate.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,8 +27,10 @@ #include #include + +#include "core/Config.h" +#include "core/Controller.h" #include "log/Log.h" -#include "Options.h" #include "workers/Hashrate.h" @@ -43,9 +45,10 @@ inline const char *format(double h, char* buf, size_t size) } -Hashrate::Hashrate(int threads) : +Hashrate::Hashrate(int threads, xmrig::Controller *controller) : m_highest(0.0), - m_threads(threads) + m_threads(threads), + m_controller(controller) { m_counts = new uint64_t*[threads]; m_timestamps = new uint64_t*[threads]; @@ -60,7 +63,7 @@ Hashrate::Hashrate(int threads) : memset(m_timestamps[0], 0, sizeof(uint64_t) * kBucketSize); } - const int printTime = Options::i()->printTime(); + const int printTime = controller->config()->printTime(); if (printTime > 0) { uv_timer_init(uv_default_loop(), &m_timer); @@ -153,7 +156,7 @@ void Hashrate::print() char num3[8]; char num4[8]; - LOG_INFO(Options::i()->colors() ? "\x1B[01;37mspeed\x1B[0m 2.5s/60s/15m \x1B[01;36m%s \x1B[22;36m%s %s \x1B[01;36mH/s\x1B[0m max: \x1B[01;36m%s H/s" : "speed 2.5s/60s/15m %s %s %s H/s max: %s H/s", + LOG_INFO(m_controller->config()->isColors() ? "\x1B[01;37mspeed\x1B[0m 2.5s/60s/15m \x1B[01;36m%s \x1B[22;36m%s %s \x1B[01;36mH/s\x1B[0m max: \x1B[01;36m%s H/s" : "speed 2.5s/60s/15m %s %s %s H/s max: %s H/s", format(calc(ShortInterval), num1, sizeof(num1)), format(calc(MediumInterval), num2, sizeof(num2)), format(calc(LargeInterval), num3, sizeof(num3)), diff --git a/src/workers/Hashrate.h b/src/workers/Hashrate.h index 026c0cdf..5f4f0eaa 100644 --- a/src/workers/Hashrate.h +++ b/src/workers/Hashrate.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,6 +29,11 @@ #include +namespace xmrig { + class Controller; +} + + class Hashrate { public: @@ -38,7 +43,7 @@ public: LargeInterval = 900000 }; - Hashrate(int threads); + Hashrate(int threads, xmrig::Controller *controller); double calc(size_t ms) const; double calc(size_t threadId, size_t ms) const; void add(size_t threadId, uint64_t count, uint64_t timestamp); @@ -61,6 +66,7 @@ private: uint64_t** m_counts; uint64_t** m_timestamps; uv_timer_t m_timer; + xmrig::Controller *m_controller; }; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index f0aef448..5642751a 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,7 +27,6 @@ #include "api/Api.h" #include "interfaces/IJobResultListener.h" #include "Mem.h" -#include "Options.h" #include "workers/DoubleWorker.h" #include "workers/Handle.h" #include "workers/Hashrate.h" @@ -103,10 +102,10 @@ void Workers::setJob(const Job &job, bool donate) } -void Workers::start(int64_t affinity, int priority) +void Workers::start(int64_t affinity, int priority, xmrig::Controller *controller) { const int threads = Mem::threads(); - m_hashrate = new Hashrate(threads); + m_hashrate = new Hashrate(threads, controller); uv_mutex_init(&m_mutex); uv_rwlock_init(&m_rwlock); diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 1c85089a..942a5b58 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,6 +39,11 @@ class Hashrate; class IJobResultListener; +namespace xmrig { + class Controller; +} + + class Workers { public: @@ -46,7 +51,7 @@ public: static void printHashrate(bool detail); static void setEnabled(bool enabled); static void setJob(const Job &job, bool donate); - static void start(int64_t affinity, int priority); + static void start(int64_t affinity, int priority, xmrig::Controller *controller); static void stop(); static void submit(const JobResult &result); From 7f5d7cf7ddf3e204f36db1501ac443ed8319d337 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 31 Mar 2018 16:52:58 +0700 Subject: [PATCH 005/109] Fix Linux build. --- src/App_unix.cpp | 10 ++++++---- src/Mem_unix.cpp | 1 - src/core/Controller.cpp | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/App_unix.cpp b/src/App_unix.cpp index 674a53e6..fdb2b124 100644 --- a/src/App_unix.cpp +++ b/src/App_unix.cpp @@ -29,20 +29,22 @@ #include "App.h" +#include "core/Config.h" +#include "core/Controller.h" #include "Cpu.h" #include "log/Log.h" -#include "Options.h" void App::background() { signal(SIGPIPE, SIG_IGN); - if (m_options->affinity() != -1L) { - Cpu::setAffinity(-1, m_options->affinity()); + const int64_t affinity = m_controller->config()->affinity(); + if (affinity != -1L) { + Cpu::setAffinity(-1, affinity); } - if (!m_options->background()) { + if (!m_controller->config()->isBackground()) { return; } diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index 3e699544..3b69f267 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -37,7 +37,6 @@ #include "crypto/CryptoNight.h" #include "log/Log.h" #include "Mem.h" -#include "Options.h" #include "xmrig.h" diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index b8c93c82..35fab2a2 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -109,7 +109,7 @@ int xmrig::Controller::init(int argc, char **argv) } # ifdef HAVE_SYSLOG_H - if (config()->syslog()) { + if (config()->isSyslog()) { Log::add(new SysLog()); } # endif From af0a6fdf2056e311d14009da4b8e31a7f56798a2 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 31 Mar 2018 17:51:33 +0700 Subject: [PATCH 006/109] Small fixes. --- src/App.cpp | 2 +- src/Summary.cpp | 6 ++++-- src/core/CommonConfig.cpp | 2 ++ src/core/Controller.cpp | 6 ++++++ src/core/Controller.h | 1 + 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/App.cpp b/src/App.cpp index 612614ae..9bdd381e 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -91,7 +91,7 @@ App::~App() int App::exec() { - if (!m_controller->config()) { + if (!m_controller->isReady()) { return 2; } diff --git a/src/Summary.cpp b/src/Summary.cpp index 4b663fbf..6aa42b74 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -132,11 +132,13 @@ static void print_pools(xmrig::Config *config) #ifndef XMRIG_NO_API static void print_api(xmrig::Config *config) { - if (config->apiPort() == 0) { + const int port = config->apiPort(); + if (port == 0) { return; } - Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mAPI PORT: \x1B[01;36m%d" : " * API PORT: %d", config->apiPort()); + Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mAPI BIND: \x1B[01;36m%s:%d" : " * API BIND: %s:%d", + config->isApiIPv6() ? "[::]" : "0.0.0.0", port); } #endif diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp index 38233b12..ea17342c 100644 --- a/src/core/CommonConfig.cpp +++ b/src/core/CommonConfig.cpp @@ -56,6 +56,8 @@ xmrig::CommonConfig::CommonConfig() : m_apiRestricted(true), m_background(false), m_colors(true), + m_syslog(false), + m_watch(false), // TODO: enable config file watch by default when this feature propertly handled and tested. m_apiToken(nullptr), m_apiWorkerId(nullptr), m_fileName(nullptr), diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 35fab2a2..805861ef 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -79,6 +79,12 @@ xmrig::Controller::~Controller() } +bool xmrig::Controller::isReady() const +{ + return d_ptr->config && d_ptr->network; +} + + xmrig::Config *xmrig::Controller::config() const { assert(d_ptr->config != nullptr); diff --git a/src/core/Controller.h b/src/core/Controller.h index 2ba80f99..25f91843 100644 --- a/src/core/Controller.h +++ b/src/core/Controller.h @@ -46,6 +46,7 @@ public: Controller(); ~Controller(); + bool isReady() const; Config *config() const; int init(int argc, char **argv); Network *network() const; From 341557c34e5074e1c024363c3ff38f873f632b1a Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 31 Mar 2018 18:12:52 +0700 Subject: [PATCH 007/109] Added client storage from proxy. --- CMakeLists.txt | 1 + src/net/Client.cpp | 80 ++++++++++++++++++++------------------ src/net/Client.h | 15 ++++--- src/net/Storage.h | 97 ++++++++++++++++++++++++++++++++++++++++++++++ src/net/Url.h | 1 - 5 files changed, 147 insertions(+), 47 deletions(-) create mode 100644 src/net/Storage.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 28d89a85..1f42950e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,7 @@ set(HEADERS src/net/Job.h src/net/JobResult.h src/net/Network.h + src/net/Storage.h src/net/strategies/DonateStrategy.h src/net/strategies/FailoverStrategy.h src/net/strategies/SinglePoolStrategy.h diff --git a/src/net/Client.cpp b/src/net/Client.cpp index c8a93f24..ec9dc863 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -52,6 +52,7 @@ int64_t Client::m_sequence = 1; +xmrig::Storage Client::m_storage; Client::Client(int id, const char *agent, IClientListener *listener) : @@ -67,13 +68,17 @@ Client::Client(int id, const char *agent, IClientListener *listener) : m_state(UnconnectedState), m_expire(0), m_jobs(0), + m_keepAlive(0), + m_key(0), m_stream(nullptr), m_socket(nullptr) { + m_key = m_storage.add(this); + memset(m_ip, 0, sizeof(m_ip)); memset(&m_hints, 0, sizeof(m_hints)); - m_resolver.data = this; + m_resolver.data = m_storage.ptr(m_key); m_hints.ai_family = AF_UNSPEC; m_hints.ai_socktype = SOCK_STREAM; @@ -81,11 +86,6 @@ Client::Client(int id, const char *agent, IClientListener *listener) : m_recvBuf.base = m_buf; m_recvBuf.len = sizeof(m_buf); - -# ifndef XMRIG_PROXY_PROJECT - m_keepAliveTimer.data = this; - uv_timer_init(uv_default_loop(), &m_keepAliveTimer); -# endif } @@ -121,8 +121,13 @@ void Client::deleteLater() m_listener = nullptr; - if (!disconnect()) { - delete this; + if (state() == HostLookupState) { + uv_cancel(reinterpret_cast(&m_resolver)); + return; + } + + if (!disconnect() && m_state != ClosingState) { + m_storage.remove(m_key); } } @@ -139,17 +144,17 @@ void Client::setUrl(const Url *url) void Client::tick(uint64_t now) { - if (m_expire == 0 || now < m_expire) { - return; - } - if (m_state == ConnectedState) { - LOG_DEBUG_ERR("[%s:%u] timeout", m_url.host(), m_url.port()); - close(); + if (m_expire && now > m_expire) { + LOG_DEBUG_ERR("[%s:%u] timeout", m_url.host(), m_url.port()); + close(); + } + else if (m_keepAlive && now > m_keepAlive) { + ping(); + } } - - if (m_state == ConnectingState) { + if (m_expire && now > m_expire && m_state == ConnectingState) { connect(); } } @@ -157,12 +162,9 @@ void Client::tick(uint64_t now) bool Client::disconnect() { -# ifndef XMRIG_PROXY_PROJECT - uv_timer_stop(&m_keepAliveTimer); -# endif - - m_expire = 0; - m_failures = -1; + m_keepAlive = 0; + m_expire = 0; + m_failures = -1; return close(); } @@ -404,10 +406,10 @@ void Client::connect(sockaddr *addr) delete m_socket; uv_connect_t *req = new uv_connect_t; - req->data = this; + req->data = m_storage.ptr(m_key); m_socket = new uv_tcp_t; - m_socket->data = this; + m_socket->data = m_storage.ptr(m_key); uv_tcp_init(uv_default_loop(), m_socket); uv_tcp_nodelay(m_socket, 1); @@ -567,7 +569,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap LOG_ERR("[%s:%u] error: \"%s\", code: %d", m_url.host(), m_url.port(), message, error["code"].GetInt()); } - if (id == 1 || isCriticalError(message)) { + if (isCriticalError(message)) { close(); } @@ -613,18 +615,13 @@ void Client::ping() void Client::reconnect() { if (!m_listener) { - delete this; + m_storage.remove(m_key); return; } setState(ConnectingState); - -# ifndef XMRIG_PROXY_PROJECT - if (m_url.isKeepAlive()) { - uv_timer_stop(&m_keepAliveTimer); - } -# endif + m_keepAlive = 0; if (m_failures == -1) { return m_listener->onClose(this, -1); @@ -653,13 +650,9 @@ void Client::startTimeout() { m_expire = 0; -# ifndef XMRIG_PROXY_PROJECT - if (!m_url.isKeepAlive()) { - return; + if (m_url.keepAlive()) { + m_keepAlive = uv_now(uv_default_loop()) + (m_url.keepAlive() * 1000); } - - uv_timer_start(&m_keepAliveTimer, [](uv_timer_t *handle) { getClient(handle->data)->ping(); }, kKeepAliveTimeout, 0); -# endif } @@ -690,6 +683,7 @@ void Client::onConnect(uv_connect_t *req, int status) { auto client = getClient(req->data); if (!client) { + delete req; return; } @@ -735,6 +729,11 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) return; } + assert(client->m_listener != nullptr); + if (!client->m_listener) { + return client->reconnect(); + } + client->m_recvBufPos += nread; char* end; @@ -771,6 +770,11 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) return; } + assert(client->m_listener != nullptr); + if (!client->m_listener) { + return client->reconnect(); + } + if (status < 0) { if (!client->m_quiet) { LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status)); diff --git a/src/net/Client.h b/src/net/Client.h index fff7a156..fc0335c6 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -32,6 +32,7 @@ #include "net/Id.h" #include "net/Job.h" +#include "net/Storage.h" #include "net/SubmitResult.h" #include "net/Url.h" #include "rapidjson/fwd.h" @@ -53,9 +54,9 @@ public: }; constexpr static int kResponseTimeout = 20 * 1000; - constexpr static int kKeepAliveTimeout = 60 * 1000; Client(int id, const char *agent, IClientListener *listener); + ~Client(); bool disconnect(); int64_t submit(const JobResult &result); @@ -76,8 +77,6 @@ public: inline void setRetryPause(int ms) { m_retryPause = ms; } private: - ~Client(); - bool close(); bool isCriticalError(const char *message); bool parseJob(const rapidjson::Value ¶ms, int *code); @@ -103,7 +102,7 @@ private: static void onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf); static void onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res); - static inline Client *getClient(void *data) { return static_cast(data); } + static inline Client *getClient(void *data) { return m_storage.get(data); } addrinfo m_hints; bool m_ipv6; @@ -120,10 +119,11 @@ private: Job m_job; size_t m_recvBufPos; SocketState m_state; - static int64_t m_sequence; std::map m_results; uint64_t m_expire; uint64_t m_jobs; + uint64_t m_keepAlive; + uintptr_t m_key; Url m_url; uv_buf_t m_recvBuf; uv_getaddrinfo_t m_resolver; @@ -131,9 +131,8 @@ private: uv_tcp_t *m_socket; xmrig::Id m_rpcId; -# ifndef XMRIG_PROXY_PROJECT - uv_timer_t m_keepAliveTimer; -# endif + static int64_t m_sequence; + static xmrig::Storage m_storage; }; diff --git a/src/net/Storage.h b/src/net/Storage.h new file mode 100644 index 00000000..105547ec --- /dev/null +++ b/src/net/Storage.h @@ -0,0 +1,97 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __STORAGE_H__ +#define __STORAGE_H__ + + +#include +#include + +#include "log/Log.h" + + +namespace xmrig { + + +template +class Storage +{ +public: + inline Storage() : + m_counter(0) + { + } + + + inline uintptr_t add(TYPE *ptr) + { + m_data[m_counter] = ptr; + + return m_counter++; + } + + + inline static void *ptr(uintptr_t id) { return reinterpret_cast(id); } + + + inline TYPE *get(void *id) const { return get(reinterpret_cast(id)); } + inline TYPE *get(uintptr_t id) const + { + assert(m_data.count(id) > 0); + + if (m_data.count(id) == 0) { + return nullptr; + } + + return m_data.at(id); + } + + + inline void remove(void *id) { remove(reinterpret_cast(id)); } + inline void remove(uintptr_t id) + { + TYPE *obj = get(id); + if (obj == nullptr) { + return; + } + + auto it = m_data.find(id); + if (it != m_data.end()) { + m_data.erase(it); + } + + delete obj; + } + + +private: + std::map m_data; + uint64_t m_counter; +}; + + +} /* namespace xmrig */ + + +#endif /* __STORAGE_H__ */ diff --git a/src/net/Url.h b/src/net/Url.h index 45db4457..4c2c9435 100644 --- a/src/net/Url.h +++ b/src/net/Url.h @@ -41,7 +41,6 @@ public: Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr, int keepAlive = 0, bool nicehash = false, int variant = -1); ~Url(); - inline bool isKeepAlive() const { return m_keepAlive > 0; } // FIXME: replace isKeepAlive to keepAlive inline bool isNicehash() const { return m_nicehash; } inline bool isValid() const { return m_host && m_port > 0; } inline const char *host() const { return m_host; } From 8d4d1a3285ad4888fc09d89b60552e3f9b591342 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 31 Mar 2018 19:00:31 +0700 Subject: [PATCH 008/109] Added API endpoint "GET /1/config". --- src/api/ApiRouter.cpp | 11 ++++ src/core/Config.cpp | 110 +++++++++++++++++-------------- src/core/ConfigLoader_platform.h | 2 +- 3 files changed, 74 insertions(+), 49 deletions(-) diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index bb8c7402..e1ba9e17 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -89,6 +89,17 @@ void ApiRouter::ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply & rapidjson::Document doc; doc.SetObject(); + if (req.match("/1/config")) { + if (req.isRestricted()) { + reply.status = 403; + return; + } + + m_controller->config()->getJSON(doc); + + return finalize(reply, doc); + } + getIdentify(doc); getMiner(doc); getHashrate(doc); diff --git a/src/core/Config.cpp b/src/core/Config.cpp index f30ed1f4..ec7e5de1 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -23,18 +23,23 @@ #include #include +#include #include "core/Config.h" #include "core/ConfigCreator.h" #include "core/ConfigLoader.h" #include "Cpu.h" +#include "net/Url.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" #include "xmrig.h" +static char affinity_tmp[20] = { 0 }; + + xmrig::Config::Config() : xmrig::CommonConfig(), m_doubleHash(false), m_dryRun(false), @@ -66,69 +71,78 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const { doc.SetObject(); -// auto &allocator = doc.GetAllocator(); + auto &allocator = doc.GetAllocator(); -// doc.AddMember("access-log-file", accessLog() ? rapidjson::Value(rapidjson::StringRef(accessLog())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); -// doc.AddMember("algo", rapidjson::StringRef(algoName()), allocator); + doc.AddMember("algo", rapidjson::StringRef(algoName()), allocator); -// rapidjson::Value api(rapidjson::kObjectType); -// api.AddMember("port", apiPort(), allocator); -// api.AddMember("access-token", apiToken() ? rapidjson::Value(rapidjson::StringRef(apiToken())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); -// api.AddMember("worker-id", apiWorkerId() ? rapidjson::Value(rapidjson::StringRef(apiWorkerId())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); -// api.AddMember("ipv6", isApiIPv6(), allocator); -// api.AddMember("restricted", isApiRestricted(), allocator); -// doc.AddMember("api", api, allocator); + rapidjson::Value api(rapidjson::kObjectType); + api.AddMember("port", apiPort(), allocator); + api.AddMember("access-token", apiToken() ? rapidjson::Value(rapidjson::StringRef(apiToken())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); + api.AddMember("worker-id", apiWorkerId() ? rapidjson::Value(rapidjson::StringRef(apiWorkerId())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); + api.AddMember("ipv6", isApiIPv6(), allocator); + api.AddMember("restricted", isApiRestricted(), allocator); + doc.AddMember("api", api, allocator); -// doc.AddMember("background", isBackground(), allocator); + doc.AddMember("av", algoVariant(), allocator); + doc.AddMember("background", isBackground(), allocator); -// rapidjson::Value bind(rapidjson::kArrayType); -// for (const Addr *addr : m_addrs) { -// bind.PushBack(rapidjson::StringRef(addr->addr()), allocator); -// } + doc.AddMember("colors", isColors(), allocator); -// doc.AddMember("bind", bind, allocator); -// doc.AddMember("colors", isColors(), allocator); -// doc.AddMember("custom-diff", diff(), allocator); -// doc.AddMember("donate-level", donateLevel(), allocator); -// doc.AddMember("log-file", logFile() ? rapidjson::Value(rapidjson::StringRef(logFile())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); -// doc.AddMember("mode", rapidjson::StringRef(modeName()), allocator); + if (affinity() != -1L) { + snprintf(affinity_tmp, sizeof(affinity_tmp) - 1, "0x%" PRIX64, affinity()); + doc.AddMember("cpu-affinity", rapidjson::StringRef(affinity_tmp), allocator); + } + else { + doc.AddMember("cpu-affinity", rapidjson::kNullType, allocator); + } -// rapidjson::Value pools(rapidjson::kArrayType); + if (priority() != -1) { + doc.AddMember("cpu-priority", priority(), allocator); + } + else { + doc.AddMember("cpu-priority", rapidjson::kNullType, allocator); + } -// for (const Url *url : m_pools) { -// rapidjson::Value obj(rapidjson::kObjectType); + doc.AddMember("donate-level", donateLevel(), allocator); + doc.AddMember("huge-pages", isHugePages(), allocator); + doc.AddMember("log-file", logFile() ? rapidjson::Value(rapidjson::StringRef(logFile())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); + doc.AddMember("max-cpu-usage", m_maxCpuUsage, allocator); -// obj.AddMember("url", rapidjson::StringRef(url->url()), allocator); -// obj.AddMember("user", rapidjson::StringRef(url->user()), allocator); -// obj.AddMember("pass", rapidjson::StringRef(url->password()), allocator); -// obj.AddMember("coin", rapidjson::StringRef(url->coin()), allocator); + rapidjson::Value pools(rapidjson::kArrayType); -// if (url->keepAlive() == 0 || url->keepAlive() == Url::kKeepAliveTimeout) { -// obj.AddMember("keepalive", url->keepAlive() > 0, allocator); -// } -// else { -// obj.AddMember("keepalive", url->keepAlive(), allocator); -// } + for (const Url *url : m_pools) { + rapidjson::Value obj(rapidjson::kObjectType); -// obj.AddMember("variant", url->variant(), allocator); + obj.AddMember("url", rapidjson::StringRef(url->url()), allocator); + obj.AddMember("user", rapidjson::StringRef(url->user()), allocator); + obj.AddMember("pass", rapidjson::StringRef(url->password()), allocator); -// pools.PushBack(obj, allocator); -// } + if (url->keepAlive() == 0 || url->keepAlive() == Url::kKeepAliveTimeout) { + obj.AddMember("keepalive", url->keepAlive() > 0, allocator); + } + else { + obj.AddMember("keepalive", url->keepAlive(), allocator); + } -// doc.AddMember("pools", pools, allocator); + obj.AddMember("nicehash", url->isNicehash(), allocator); + obj.AddMember("variant", url->variant(), allocator); -// doc.AddMember("retries", retries(), allocator); -// doc.AddMember("retry-pause", retryPause(), allocator); -// doc.AddMember("reuse-timeout", reuseTimeout(), allocator); -// doc.AddMember("user-agent", userAgent() ? rapidjson::Value(rapidjson::StringRef(userAgent())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); + pools.PushBack(obj, allocator); + } -//# ifdef HAVE_SYSLOG_H -// doc.AddMember("syslog", syslog(), allocator); -//# endif + doc.AddMember("pools", pools, allocator); + doc.AddMember("print-time", printTime(), allocator); + doc.AddMember("retries", retries(), allocator); + doc.AddMember("retry-pause", retryPause(), allocator); + doc.AddMember("safe", m_safe, allocator); + doc.AddMember("threads", threads(), allocator); + doc.AddMember("user-agent", userAgent() ? rapidjson::Value(rapidjson::StringRef(userAgent())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); -// doc.AddMember("verbose", isVerbose(), allocator); -// doc.AddMember("watch", m_watch, allocator); -// doc.AddMember("workers", isWorkers(), allocator); +# ifdef HAVE_SYSLOG_H + doc.AddMember("syslog", syslog(), allocator); +# endif + + doc.AddMember("watch", m_watch, allocator); } diff --git a/src/core/ConfigLoader_platform.h b/src/core/ConfigLoader_platform.h index 59415f78..68eef639 100644 --- a/src/core/ConfigLoader_platform.h +++ b/src/core/ConfigLoader_platform.h @@ -138,7 +138,7 @@ static struct option const config_options[] = { { "retry-pause", 1, nullptr, xmrig::IConfig::RetryPauseKey }, { "safe", 0, nullptr, xmrig::IConfig::SafeKey }, { "syslog", 0, nullptr, xmrig::IConfig::SyslogKey }, - { "threads", 1, nullptr, xmrig::IConfig::SafeKey }, + { "threads", 1, nullptr, xmrig::IConfig::ThreadsKey }, { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, { 0, 0, 0, 0 } }; From edd47b12a8b3343476cc02cf4d3102bbf3018ae7 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 31 Mar 2018 19:43:16 +0700 Subject: [PATCH 009/109] Update CHANGELOG.md and version. --- CHANGELOG.md | 9 +++++++++ src/version.h | 8 ++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab31e698..f9f42d66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# v2.6.0-beta1 + - HTTP server now runs in main loop, it make possible easy extend API without worry about thread synchronization. + - Added initial graceful reload support, miner will reload configuration if config file changed, disabled by default until it will be fully implemented and tested. + - Added API endpoint `PUT /1/config` to update current config. + - Added API endpoint `GET /1/config` to get current active config. + - API endpoint `GET /` now deprecated, use `GET /1/summary` instead. + - Added `--api-no-ipv6` and similar config option to disable IPv6 support for HTTP API. + - Added `--api-no-restricted` to enable full access to api, this option has no effect if `--api-access-token` not specified. + # v2.5.2 - [#448](https://github.com/xmrig/xmrig/issues/478) Fixed broken reconnect. diff --git a/src/version.h b/src/version.h index 060edcb7..db7c2013 100644 --- a/src/version.h +++ b/src/version.h @@ -27,16 +27,16 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig CPU miner" -#define APP_VERSION "2.5.2" +#define APP_VERSION "2.6.0-beta1" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com" #define APP_KIND "cpu" #define APP_VER_MAJOR 2 -#define APP_VER_MINOR 5 -#define APP_VER_BUILD 2 -#define APP_VER_REV 0 +#define APP_VER_MINOR 6 +#define APP_VER_BUILD 0 +#define APP_VER_REV 1 #ifdef _MSC_VER # if (_MSC_VER >= 1910) From 44d56393dbb14bee4e7470de07f9bf3e3c0bf324 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 31 Mar 2018 20:26:07 +0700 Subject: [PATCH 010/109] Fix Linux build. --- src/core/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index ec7e5de1..49b40aa8 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -139,7 +139,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const doc.AddMember("user-agent", userAgent() ? rapidjson::Value(rapidjson::StringRef(userAgent())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); # ifdef HAVE_SYSLOG_H - doc.AddMember("syslog", syslog(), allocator); + doc.AddMember("syslog", isSyslog(), allocator); # endif doc.AddMember("watch", m_watch, allocator); From a042cbf8856de5df95bac73d7413e63483a56db7 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 1 Apr 2018 22:49:21 +0700 Subject: [PATCH 011/109] Added classes IThread, CpuThread and API endpoint "GET /1/threads". --- CMakeLists.txt | 3 ++ src/App.cpp | 2 +- src/Mem.cpp | 2 +- src/Mem_win.cpp | 2 +- src/Summary.cpp | 2 +- src/api/ApiRouter.cpp | 26 ++++++++-- src/api/ApiRouter.h | 1 + src/core/CommonConfig.cpp | 6 +-- src/core/CommonConfig.h | 5 +- src/core/Config.cpp | 58 ++++++++++++---------- src/core/Config.h | 41 +++++++--------- src/crypto/CryptoNight.cpp | 6 +-- src/interfaces/IThread.h | 64 ++++++++++++++++++++++++ src/net/Job.cpp | 4 +- src/net/Url.cpp | 6 +-- src/net/strategies/DonateStrategy.cpp | 2 +- src/workers/CpuThread.cpp | 68 +++++++++++++++++++++++++ src/workers/CpuThread.h | 71 +++++++++++++++++++++++++++ src/xmrig.h | 29 ++++++++--- 19 files changed, 320 insertions(+), 78 deletions(-) create mode 100644 src/interfaces/IThread.h create mode 100644 src/workers/CpuThread.cpp create mode 100644 src/workers/CpuThread.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f42950e..c9d6624f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ set(HEADERS src/interfaces/ILogBackend.h src/interfaces/IStrategy.h src/interfaces/IStrategyListener.h + src/interfaces/IThread.h src/interfaces/IWatcherListener.h src/interfaces/IWorker.h src/log/ConsoleLog.h @@ -52,6 +53,7 @@ set(HEADERS src/Platform.h src/Summary.h src/version.h + src/workers/CpuThread.h src/workers/DoubleWorker.h src/workers/Handle.h src/workers/Hashrate.h @@ -106,6 +108,7 @@ set(SOURCES src/net/Url.cpp src/Platform.cpp src/Summary.cpp + src/workers/CpuThread.cpp src/workers/DoubleWorker.cpp src/workers/Handle.cpp src/workers/Hashrate.cpp diff --git a/src/App.cpp b/src/App.cpp index 9bdd381e..a9d10774 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -107,7 +107,7 @@ int App::exec() } Mem::allocate(m_controller->config()->algorithm(), - m_controller->config()->threads(), + m_controller->config()->threadsCount(), m_controller->config()->isDoubleHash(), m_controller->config()->isHugePages() ); diff --git a/src/Mem.cpp b/src/Mem.cpp index 991f4398..f5da7865 100644 --- a/src/Mem.cpp +++ b/src/Mem.cpp @@ -43,7 +43,7 @@ alignas(16) uint8_t *Mem::m_memory = nullptr; cryptonight_ctx *Mem::create(int threadId) { # ifndef XMRIG_NO_AEON - if (m_algo == xmrig::ALGO_CRYPTONIGHT_LITE) { + if (m_algo == xmrig::CRYPTONIGHT_LITE) { return createLite(threadId); } # endif diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index 1b35c704..6cc0a6ee 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -151,7 +151,7 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled) m_threads = threads; m_doubleHash = doubleHash; - const int ratio = (doubleHash && algo != xmrig::ALGO_CRYPTONIGHT_LITE) ? 2 : 1; + const int ratio = (doubleHash && algo != xmrig::CRYPTONIGHT_LITE) ? 2 : 1; m_size = MONERO_MEMORY * (threads * ratio + 1); if (!enabled) { diff --git a/src/Summary.cpp b/src/Summary.cpp index 6aa42b74..7e341ce0 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -101,7 +101,7 @@ static void print_threads(xmrig::Config *config) } Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s", - config->threads(), + config->threadsCount(), config->algoName(), config->algoVariant(), config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index e1ba9e17..6c4f1f27 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -38,6 +38,7 @@ #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" +#include "interfaces/IThread.h" #include "Mem.h" #include "net/Job.h" #include "Platform.h" @@ -67,7 +68,7 @@ static inline double normalize(double d) ApiRouter::ApiRouter(xmrig::Controller *controller) : m_controller(controller) { - m_threads = controller->config()->threads(); + m_threads = controller->config()->threadsCount(); m_hashrate = new double[m_threads * 3](); memset(m_totalHashrate, 0, sizeof(m_totalHashrate)); @@ -87,7 +88,6 @@ ApiRouter::~ApiRouter() void ApiRouter::ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const { rapidjson::Document doc; - doc.SetObject(); if (req.match("/1/config")) { if (req.isRestricted()) { @@ -100,6 +100,14 @@ void ApiRouter::ApiRouter::get(const xmrig::HttpRequest &req, xmrig::HttpReply & return finalize(reply, doc); } + if (req.match("/1/threads")) { + getThreads(doc); + + return finalize(reply, doc); + } + + doc.SetObject(); + getIdentify(doc); getMiner(doc); getHashrate(doc); @@ -144,7 +152,7 @@ void ApiRouter::tick(const NetworkState &network) void ApiRouter::onConfigChanged(xmrig::Config *config, xmrig::Config *previousConfig) { -// updateWorkerId(config->apiWorkerId(), previousConfig->apiWorkerId()); + updateWorkerId(config->apiWorkerId(), previousConfig->apiWorkerId()); } @@ -288,6 +296,18 @@ void ApiRouter::getResults(rapidjson::Document &doc) const } +void ApiRouter::getThreads(rapidjson::Document &doc) const +{ + doc.SetArray(); + + const std::vector &threads = m_controller->config()->threads(); + + for (const xmrig::IThread *thread : threads) { + doc.PushBack(thread->toAPI(doc), doc.GetAllocator()); + } +} + + void ApiRouter::setWorkerId(const char *id) { memset(m_workerId, 0, sizeof(m_workerId)); diff --git a/src/api/ApiRouter.h b/src/api/ApiRouter.h index 2ae1cc80..e14f9e87 100644 --- a/src/api/ApiRouter.h +++ b/src/api/ApiRouter.h @@ -63,6 +63,7 @@ private: void getIdentify(rapidjson::Document &doc) const; void getMiner(rapidjson::Document &doc) const; void getResults(rapidjson::Document &doc) const; + void getThreads(rapidjson::Document &doc) const; void setWorkerId(const char *id); void updateWorkerId(const char *id, const char *previousId); diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp index ea17342c..51448654 100644 --- a/src/core/CommonConfig.cpp +++ b/src/core/CommonConfig.cpp @@ -51,6 +51,7 @@ static const char *algoNames[] = { xmrig::CommonConfig::CommonConfig() : + m_algorithm(CRYPTONIGHT), m_adjusted(false), m_apiIPv6(true), m_apiRestricted(true), @@ -63,7 +64,6 @@ xmrig::CommonConfig::CommonConfig() : m_fileName(nullptr), m_logFile(nullptr), m_userAgent(nullptr), - m_algorithm(ALGO_CRYPTONIGHT), m_apiPort(0), m_donateLevel(kDefaultDonateLevel), m_printTime(60), @@ -367,7 +367,7 @@ void xmrig::CommonConfig::setAlgo(const char *algo) if (strcasecmp(algo, "cryptonight-light") == 0) { fprintf(stderr, "Algorithm \"cryptonight-light\" is deprecated, use \"cryptonight-lite\" instead\n"); - m_algorithm = ALGO_CRYPTONIGHT_LITE; + m_algorithm = CRYPTONIGHT_LITE; return; } @@ -375,7 +375,7 @@ void xmrig::CommonConfig::setAlgo(const char *algo) for (size_t i = 0; i < size; i++) { if (algoNames[i] && strcasecmp(algo, algoNames[i]) == 0) { - m_algorithm = (int) i; + m_algorithm = static_cast(i); break; } } diff --git a/src/core/CommonConfig.h b/src/core/CommonConfig.h index ab840a48..0f6f6b8c 100644 --- a/src/core/CommonConfig.h +++ b/src/core/CommonConfig.h @@ -29,6 +29,7 @@ #include "interfaces/IConfig.h" +#include "xmrig.h" class Url; @@ -45,6 +46,7 @@ public: const char *algoName() const; + inline Algo algorithm() const { return m_algorithm; } inline bool isApiIPv6() const { return m_apiIPv6; } inline bool isApiRestricted() const { return m_apiRestricted; } inline bool isBackground() const { return m_background; } @@ -55,7 +57,6 @@ public: inline const char *logFile() const { return m_logFile; } inline const char *userAgent() const { return m_userAgent; } inline const std::vector &pools() const { return m_pools; } - inline int algorithm() const { return m_algorithm; } inline int apiPort() const { return m_apiPort; } inline int donateLevel() const { return m_donateLevel; } inline int printTime() const { return m_printTime; } @@ -75,6 +76,7 @@ protected: bool save() override; void setFileName(const char *fileName) override; + Algo m_algorithm; bool m_adjusted; bool m_apiIPv6; bool m_apiRestricted; @@ -87,7 +89,6 @@ protected: char *m_fileName; char *m_logFile; char *m_userAgent; - int m_algorithm; int m_apiPort; int m_donateLevel; int m_printTime; diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 49b40aa8..6bc2dc0f 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -34,6 +34,7 @@ #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" +#include "workers/CpuThread.h" #include "xmrig.h" @@ -41,18 +42,17 @@ static char affinity_tmp[20] = { 0 }; xmrig::Config::Config() : xmrig::CommonConfig(), + m_algoVariant(AV_AUTO), m_doubleHash(false), m_dryRun(false), m_hugePages(true), m_safe(false), - m_algoVariant(0), m_maxCpuUsage(75), m_printTime(60), m_priority(-1), - m_threads(0), - m_affinity(-1L) + m_affinity(-1L), + m_threadsCount(0) { - } @@ -135,7 +135,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const doc.AddMember("retries", retries(), allocator); doc.AddMember("retry-pause", retryPause(), allocator); doc.AddMember("safe", m_safe, allocator); - doc.AddMember("threads", threads(), allocator); + doc.AddMember("threads", threadsCount(), allocator); doc.AddMember("user-agent", userAgent() ? rapidjson::Value(rapidjson::StringRef(userAgent())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); # ifdef HAVE_SYSLOG_H @@ -159,20 +159,24 @@ bool xmrig::Config::adjust() } m_algoVariant = getAlgoVariant(); - if (m_algoVariant == AV2_AESNI_DOUBLE || m_algoVariant == AV4_SOFT_AES_DOUBLE) { + if (m_algoVariant == AV_DOUBLE || m_algoVariant == AV_DOUBLE_SOFT) { m_doubleHash = true; } - if (!m_threads) { - m_threads = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); + if (!m_threadsCount) { + m_threadsCount = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); } else if (m_safe) { - const int count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); - if (m_threads > count) { - m_threads = count; + const size_t count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); + if (m_threadsCount > count) { + m_threadsCount = count; } } + for (size_t i = 0; i < m_threadsCount; ++i) { + m_threads.push_back(CpuThread::createFromAV(i, m_algorithm, m_algoVariant, m_affinity, m_priority)); + } + return true; } @@ -225,7 +229,7 @@ bool xmrig::Config::parseString(int key, const char *arg) case xmrig::IConfig::ThreadsKey: /* --threads */ if (strncmp(arg, "all", 3) == 0) { - m_threads = Cpu::threads(); + m_threadsCount = Cpu::threads(); return true; } @@ -275,14 +279,14 @@ bool xmrig::Config::parseInt(int key, int arg) { switch (key) { case xmrig::IConfig::ThreadsKey: /* --threads */ - if (m_threads >= 0 && arg < 1024) { - m_threads = arg; + if (m_threadsCount >= 0 && arg < 1024) { + m_threadsCount = arg; } break; case xmrig::IConfig::AVKey: /* --av */ - if (arg >= AV0_AUTO && arg < AV_MAX) { - m_algoVariant = arg; + if (arg >= AV_AUTO && arg < AV_MAX) { + m_algoVariant = static_cast(arg); } break; @@ -306,20 +310,20 @@ bool xmrig::Config::parseInt(int key, int arg) } -int xmrig::Config::getAlgoVariant() const +xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const { # ifndef XMRIG_NO_AEON - if (m_algorithm == xmrig::ALGO_CRYPTONIGHT_LITE) { + if (m_algorithm == xmrig::CRYPTONIGHT_LITE) { return getAlgoVariantLite(); } # endif - if (m_algoVariant <= AV0_AUTO || m_algoVariant >= AV_MAX) { - return Cpu::hasAES() ? AV1_AESNI : AV3_SOFT_AES; + if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { + return Cpu::hasAES() ? AV_SINGLE : AV_SINGLE_SOFT; } - if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV2_AESNI_DOUBLE) { - return m_algoVariant + 2; + if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV_DOUBLE) { + return static_cast(m_algoVariant + 2); } return m_algoVariant; @@ -327,14 +331,14 @@ int xmrig::Config::getAlgoVariant() const #ifndef XMRIG_NO_AEON -int xmrig::Config::getAlgoVariantLite() const +xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const { - if (m_algoVariant <= AV0_AUTO || m_algoVariant >= AV_MAX) { - return Cpu::hasAES() ? AV2_AESNI_DOUBLE : AV4_SOFT_AES_DOUBLE; + if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { + return Cpu::hasAES() ? AV_DOUBLE : AV_DOUBLE_SOFT; } - if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV2_AESNI_DOUBLE) { - return m_algoVariant + 2; + if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV_DOUBLE) { + return static_cast(m_algoVariant + 2); } return m_algoVariant; diff --git a/src/core/Config.h b/src/core/Config.h index 110c61a7..536e1c01 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -29,8 +29,9 @@ #include -#include "rapidjson/fwd.h" #include "core/CommonConfig.h" +#include "rapidjson/fwd.h" +#include "xmrig.h" class Addr; @@ -41,6 +42,7 @@ namespace xmrig { class ConfigLoader; +class IThread; class IWatcherListener; @@ -57,18 +59,7 @@ class IWatcherListener; */ class Config : public CommonConfig { - friend class ConfigLoader; - public: - enum AlgoVariant { - AV0_AUTO, - AV1_AESNI, - AV2_AESNI_DOUBLE, - AV3_SOFT_AES, - AV4_SOFT_AES_DOUBLE, - AV_MAX - }; - Config(); ~Config(); @@ -76,14 +67,15 @@ public: void getJSON(rapidjson::Document &doc) const override; - inline bool isDoubleHash() const { return m_doubleHash; } - inline bool isDryRun() const { return m_dryRun; } - inline bool isHugePages() const { return m_hugePages; } - inline int algoVariant() const { return m_algoVariant; } - inline int printTime() const { return m_printTime; } - inline int priority() const { return m_priority; } - inline int threads() const { return m_threads; } - inline int64_t affinity() const { return m_affinity; } + inline AlgoVariant algoVariant() const { return m_algoVariant; } + inline bool isDoubleHash() const { return m_doubleHash; } + inline bool isDryRun() const { return m_dryRun; } + inline bool isHugePages() const { return m_hugePages; } + inline const std::vector &threads() const { return m_threads; } + inline int printTime() const { return m_printTime; } + inline int priority() const { return m_priority; } + inline int threadsCount() const { return m_threadsCount; } + inline int64_t affinity() const { return m_affinity; } static Config *load(int argc, char **argv, IWatcherListener *listener); @@ -97,21 +89,22 @@ protected: private: bool parseInt(int key, int arg); - int getAlgoVariant() const; + AlgoVariant getAlgoVariant() const; # ifndef XMRIG_NO_AEON - int getAlgoVariantLite() const; + AlgoVariant getAlgoVariantLite() const; # endif + AlgoVariant m_algoVariant; bool m_doubleHash; bool m_dryRun; bool m_hugePages; bool m_safe; - int m_algoVariant; int m_maxCpuUsage; int m_printTime; int m_priority; - int m_threads; int64_t m_affinity; + size_t m_threadsCount; + std::vector m_threads; }; diff --git a/src/crypto/CryptoNight.cpp b/src/crypto/CryptoNight.cpp index c9a2e499..f7dc1a37 100644 --- a/src/crypto/CryptoNight.cpp +++ b/src/crypto/CryptoNight.cpp @@ -137,7 +137,7 @@ bool CryptoNight::init(int algo, int variant, bool doubleHash) } # ifndef XMRIG_NO_AEON - const int index = algo == xmrig::ALGO_CRYPTONIGHT_LITE ? (variant + 3) : (variant - 1); + const int index = algo == xmrig::CRYPTONIGHT_LITE ? (variant + 3) : (variant - 1); # else const int index = variant - 1; # endif @@ -167,7 +167,7 @@ bool CryptoNight::selfTest(int algo, bool doubleHash) { cryptonight_hash_ctx(test_input, 76, output, ctx, 0); # ifndef XMRIG_NO_AEON - bool rc = memcmp(output, algo == xmrig::ALGO_CRYPTONIGHT_LITE ? test_output_v0_lite : test_output_v0, (doubleHash ? 64 : 32)) == 0; + bool rc = memcmp(output, algo == xmrig::CRYPTONIGHT_LITE ? test_output_v0_lite : test_output_v0, (doubleHash ? 64 : 32)) == 0; # else bool rc = memcmp(output, test_output_v0, (doubleHash ? 64 : 32)) == 0; # endif @@ -176,7 +176,7 @@ bool CryptoNight::selfTest(int algo, bool doubleHash) { cryptonight_hash_ctx(test_input, 76, output, ctx, 1); # ifndef XMRIG_NO_AEON - rc = memcmp(output, algo == xmrig::ALGO_CRYPTONIGHT_LITE ? test_output_v1_lite : test_output_v1, (doubleHash ? 64 : 32)) == 0; + rc = memcmp(output, algo == xmrig::CRYPTONIGHT_LITE ? test_output_v1_lite : test_output_v1, (doubleHash ? 64 : 32)) == 0; # else rc = memcmp(output, test_output_v1, (doubleHash ? 64 : 32)) == 0; # endif diff --git a/src/interfaces/IThread.h b/src/interfaces/IThread.h new file mode 100644 index 00000000..e2325c72 --- /dev/null +++ b/src/interfaces/IThread.h @@ -0,0 +1,64 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2018 XMRig + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __ITHREAD_H__ +#define __ITHREAD_H__ + + +#include + + +#include "rapidjson/fwd.h" +#include "xmrig.h" + + +namespace xmrig { + + +class IThread +{ +public: + enum Type { + CPU, + OpenCL, + CUDA + }; + + virtual ~IThread() {} + + virtual Algo algorithm() const = 0; + virtual int multiway() const = 0; + virtual int priority() const = 0; + virtual int64_t affinity() const = 0; + virtual size_t index() const = 0; + virtual Type type() const = 0; + +# ifndef XMRIG_NO_API + virtual rapidjson::Value toAPI(rapidjson::Document &doc) const = 0; +# endif +}; + + +} /* namespace xmrig */ + + +#endif // __ITHREAD_H__ diff --git a/src/net/Job.cpp b/src/net/Job.cpp index 7d137fac..e5714376 100644 --- a/src/net/Job.cpp +++ b/src/net/Job.cpp @@ -59,7 +59,7 @@ static inline char hf_bin2hex(unsigned char c) Job::Job() : m_nicehash(false), m_coin(), - m_algo(xmrig::ALGO_CRYPTONIGHT), + m_algo(xmrig::CRYPTONIGHT), m_poolId(-2), m_threadId(-1), m_variant(xmrig::VARIANT_AUTO), @@ -164,7 +164,7 @@ void Job::setCoin(const char *coin) } strncpy(m_coin, coin, sizeof(m_coin)); - m_algo = strcmp(m_coin, "AEON") == 0 ? xmrig::ALGO_CRYPTONIGHT_LITE : xmrig::ALGO_CRYPTONIGHT; + m_algo = strcmp(m_coin, "AEON") == 0 ? xmrig::CRYPTONIGHT_LITE : xmrig::CRYPTONIGHT; } diff --git a/src/net/Url.cpp b/src/net/Url.cpp index 8905e919..3d5f2cdd 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -41,7 +41,7 @@ Url::Url() : m_host(nullptr), m_password(nullptr), m_user(nullptr), - m_algo(xmrig::ALGO_CRYPTONIGHT), + m_algo(xmrig::CRYPTONIGHT), m_keepAlive(0), m_variant(xmrig::VARIANT_AUTO), m_url(nullptr), @@ -66,7 +66,7 @@ Url::Url(const char *url) : m_host(nullptr), m_password(nullptr), m_user(nullptr), - m_algo(xmrig::ALGO_CRYPTONIGHT), + m_algo(xmrig::CRYPTONIGHT), m_keepAlive(0), m_variant(xmrig::VARIANT_AUTO), m_url(nullptr), @@ -80,7 +80,7 @@ Url::Url(const char *host, uint16_t port, const char *user, const char *password m_nicehash(nicehash), m_password(password ? strdup(password) : nullptr), m_user(user ? strdup(user) : nullptr), - m_algo(xmrig::ALGO_CRYPTONIGHT), + m_algo(xmrig::CRYPTONIGHT), m_keepAlive(keepAlive), m_variant(variant), m_url(nullptr), diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index ae707e21..49503820 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -59,7 +59,7 @@ DonateStrategy::DonateStrategy(int level, const char *user, int algo, IStrategyL keccak(reinterpret_cast(user), static_cast(strlen(user)), hash, sizeof(hash)); Job::toHex(hash, 32, userId); - if (algo == xmrig::ALGO_CRYPTONIGHT) { + if (algo == xmrig::CRYPTONIGHT) { m_pools.push_back(new Url(kDonatePool1, 6666, userId, nullptr, false, true)); m_pools.push_back(new Url(kDonatePool1, 80, userId, nullptr, false, true)); m_pools.push_back(new Url(kDonatePool2, 5555, "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD", "emergency", false, false)); diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp new file mode 100644 index 00000000..ff3aaed7 --- /dev/null +++ b/src/workers/CpuThread.cpp @@ -0,0 +1,68 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "rapidjson/document.h" +#include "workers/CpuThread.h" + + +xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, int multiway, int64_t affinity, int priority, bool softAES, bool prefetch) : + m_algorithm(algorithm), + m_prefetch(prefetch), + m_softAES(softAES), + m_multiway(multiway), + m_priority(priority), + m_affinity(affinity), + m_index(index) +{ +} + + +xmrig::CpuThread::~CpuThread() +{ +} + + +xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority) +{ + return new CpuThread(index, algorithm, 1, affinity, priority, false, false); +} + + +#ifndef XMRIG_NO_API +rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const +{ + rapidjson::Value obj(rapidjson::kObjectType); + auto &allocator = doc.GetAllocator(); + + obj.AddMember("type", "cpu", allocator); + obj.AddMember("algo", algorithm(), allocator); + obj.AddMember("low_power_mode", multiway(), allocator); + obj.AddMember("affine_to_cpu", affinity(), allocator); + obj.AddMember("priority", priority(), allocator); + obj.AddMember("prefetch", isPrefetch(), allocator); + obj.AddMember("soft_aes", isSoftAES(), allocator); + + return obj; +} +#endif diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h new file mode 100644 index 00000000..93ef50d5 --- /dev/null +++ b/src/workers/CpuThread.h @@ -0,0 +1,71 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CPUTHREAD_H__ +#define __CPUTHREAD_H__ + + +#include "interfaces/IThread.h" +#include "xmrig.h" + + +namespace xmrig { + + +class CpuThread : public IThread +{ +public: + CpuThread(size_t index, Algo algorithm, int multiway, int64_t affinity, int priority, bool softAES, bool prefetch); + ~CpuThread(); + + static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority); + + inline bool isPrefetch() const { return m_prefetch; } + inline bool isSoftAES() const { return m_softAES; } + + inline Algo algorithm() const override { return m_algorithm; } + inline int multiway() const override { return m_multiway; } + inline int priority() const override { return m_priority; } + inline int64_t affinity() const override { return m_affinity; } + inline size_t index() const override { return m_affinity; } + inline Type type() const override { return CPU; } + +# ifndef XMRIG_NO_API + rapidjson::Value toAPI(rapidjson::Document &doc) const override; +# endif + +private: + const Algo m_algorithm; + const bool m_prefetch; + const bool m_softAES; + const int m_multiway; + const int m_priority; + const int64_t m_affinity; + const size_t m_index; +}; + + +} /* namespace xmrig */ + + +#endif /* __CPUTHREAD_H__ */ diff --git a/src/xmrig.h b/src/xmrig.h index 9cae73c7..805b7ceb 100644 --- a/src/xmrig.h +++ b/src/xmrig.h @@ -30,18 +30,35 @@ namespace xmrig enum Algo { - ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */ - ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ - ALGO_CRYPTONIGHT_HEAVY, /* CryptoNight-Heavy (SUMO) */ + CRYPTONIGHT, /* CryptoNight (Monero) */ + CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ + CRYPTONIGHT_HEAVY, /* CryptoNight-Heavy (SUMO) */ +}; + + +enum AlgoVariant { + AV_AUTO, + AV_SINGLE, + AV_DOUBLE, + AV_SINGLE_SOFT, + AV_DOUBLE_SOFT, + AV_TRIPLE, + AV_QUAD, + AV_PENTA, + AV_TRIPLE_SOFT, + AV_QUAD_SOFT, + AV_PENTA_SOFT, + AV_MAX }; enum Variant { - VARIANT_AUTO = -1, - VARIANT_NONE = 0, - VARIANT_V1 = 1 + VARIANT_AUTO = -1, // Autodetect + VARIANT_NONE = 0, // Original CryptoNight + VARIANT_V1 = 1 // Monero v7 PoW }; + } /* xmrig */ From 6c970612bfe22c9c61ba9caf3acea3664f1f2474 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 2 Apr 2018 14:05:16 +0700 Subject: [PATCH 012/109] Transform affinity and av to internal representation. --- src/core/CommonConfig.cpp | 4 +-- src/core/CommonConfig.h | 3 +- src/workers/CpuThread.cpp | 71 ++++++++++++++++++++++++++++++++++++--- src/workers/CpuThread.h | 13 +++++-- src/xmrig.h | 26 ++++++++------ 5 files changed, 96 insertions(+), 21 deletions(-) diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp index 51448654..6a2c76ac 100644 --- a/src/core/CommonConfig.cpp +++ b/src/core/CommonConfig.cpp @@ -95,9 +95,9 @@ xmrig::CommonConfig::~CommonConfig() } -const char *xmrig::CommonConfig::algoName() const +const char *xmrig::CommonConfig::algoName(Algo algorithm) { - return algoNames[m_algorithm]; + return algoNames[algorithm]; } diff --git a/src/core/CommonConfig.h b/src/core/CommonConfig.h index 0f6f6b8c..ee9c7a20 100644 --- a/src/core/CommonConfig.h +++ b/src/core/CommonConfig.h @@ -44,7 +44,7 @@ public: CommonConfig(); ~CommonConfig(); - const char *algoName() const; + static const char *algoName(Algo algorithm); inline Algo algorithm() const { return m_algorithm; } inline bool isApiIPv6() const { return m_apiIPv6; } @@ -52,6 +52,7 @@ public: inline bool isBackground() const { return m_background; } inline bool isColors() const { return m_colors; } inline bool isSyslog() const { return m_syslog; } + inline const char *algoName() const { return algoName(m_algorithm); } inline const char *apiToken() const { return m_apiToken; } inline const char *apiWorkerId() const { return m_apiWorkerId; } inline const char *logFile() const { return m_logFile; } diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index ff3aaed7..91e98a14 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -21,18 +21,22 @@ * along with this program. If not, see . */ +#include + +#include "core/CommonConfig.h" #include "rapidjson/document.h" #include "workers/CpuThread.h" -xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, int multiway, int64_t affinity, int priority, bool softAES, bool prefetch) : +xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch) : m_algorithm(algorithm), + m_av(av), m_prefetch(prefetch), m_softAES(softAES), - m_multiway(multiway), m_priority(priority), m_affinity(affinity), + m_multiway(multiway), m_index(index) { } @@ -45,7 +49,64 @@ xmrig::CpuThread::~CpuThread() xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority) { - return new CpuThread(index, algorithm, 1, affinity, priority, false, false); + assert(av > AV_AUTO && av < AV_MAX); + + Multiway multiway = SingleWay; + bool softAES = false; + + switch (av) { + case AV_SINGLE_SOFT: + softAES = true; + break; + + case AV_DOUBLE: + multiway = DoubleWay; + case AV_DOUBLE_SOFT: + softAES = true; + break; + + case AV_TRIPLE: + multiway = TripleWay; + case AV_TRIPLE_SOFT: + softAES = true; + break; + + case AV_QUAD: + multiway = QuadWay; + case AV_QUAD_SOFT: + softAES = true; + break; + + case AV_PENTA: + multiway = PentaWay; + case AV_PENTA_SOFT: + softAES = true; + break; + + default: + break; + } + + int64_t cpuId = -1L; + + if (affinity != -1L) { + size_t idx = 0; + + for (size_t i = 0; i < 64; i++) { + if (!(affinity & (1ULL << i))) { + continue; + } + + if (idx == index) { + cpuId = i; + break; + } + + idx++; + } + } + + return new CpuThread(index, algorithm, av, multiway, cpuId, priority, softAES, false); } @@ -56,11 +117,11 @@ rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const auto &allocator = doc.GetAllocator(); obj.AddMember("type", "cpu", allocator); - obj.AddMember("algo", algorithm(), allocator); + obj.AddMember("algo", rapidjson::StringRef(CommonConfig::algoName(algorithm())), allocator); + obj.AddMember("av", m_av, allocator); obj.AddMember("low_power_mode", multiway(), allocator); obj.AddMember("affine_to_cpu", affinity(), allocator); obj.AddMember("priority", priority(), allocator); - obj.AddMember("prefetch", isPrefetch(), allocator); obj.AddMember("soft_aes", isSoftAES(), allocator); return obj; diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index 93ef50d5..2b214423 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -35,7 +35,15 @@ namespace xmrig { class CpuThread : public IThread { public: - CpuThread(size_t index, Algo algorithm, int multiway, int64_t affinity, int priority, bool softAES, bool prefetch); + enum Multiway { + SingleWay, + DoubleWay, + TripleWay, + QuadWay, + PentaWay + }; + + CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch); ~CpuThread(); static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority); @@ -56,11 +64,12 @@ public: private: const Algo m_algorithm; + const AlgoVariant m_av; const bool m_prefetch; const bool m_softAES; - const int m_multiway; const int m_priority; const int64_t m_affinity; + const Multiway m_multiway; const size_t m_index; }; diff --git a/src/xmrig.h b/src/xmrig.h index 805b7ceb..eba72bb4 100644 --- a/src/xmrig.h +++ b/src/xmrig.h @@ -36,18 +36,22 @@ enum Algo { }; +//--av=1 For CPUs with hardware AES. +//--av=2 Lower power mode (double hash) of 1. +//--av=3 Software AES implementation. +//--av=4 Lower power mode (double hash) of 3. enum AlgoVariant { - AV_AUTO, - AV_SINGLE, - AV_DOUBLE, - AV_SINGLE_SOFT, - AV_DOUBLE_SOFT, - AV_TRIPLE, - AV_QUAD, - AV_PENTA, - AV_TRIPLE_SOFT, - AV_QUAD_SOFT, - AV_PENTA_SOFT, + AV_AUTO, // --av=0 Automatic mode. + AV_SINGLE, // --av=1 Single hash mode + AV_DOUBLE, // --av=2 Double hash mode + AV_SINGLE_SOFT, // --av=3 Single hash mode (Software AES) + AV_DOUBLE_SOFT, // --av=4 Double hash mode (Software AES) + AV_TRIPLE, // --av=5 Triple hash mode + AV_QUAD, // --av=6 Quard hash mode + AV_PENTA, // --av=7 Penta hash mode + AV_TRIPLE_SOFT, // --av=8 Triple hash mode (Software AES) + AV_QUAD_SOFT, // --av=9 Quard hash mode (Software AES) + AV_PENTA_SOFT, // --av=10 Penta hash mode (Software AES) AV_MAX }; From 72cd6d168e94d3aa0632e214aba9401963bf1eef Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 2 Apr 2018 15:03:56 +0700 Subject: [PATCH 013/109] Now used IThread to start threads, cpu-affinity broken, nonce allocation in double mode probably broken too. --- src/workers/CpuThread.h | 4 ++-- src/workers/DoubleWorker.cpp | 8 ++++---- src/workers/Handle.cpp | 14 ++++++-------- src/workers/Handle.h | 22 +++++++++++----------- src/workers/SingleWorker.cpp | 4 ++-- src/workers/Worker.cpp | 10 +++++----- src/workers/Worker.h | 4 ++-- src/workers/Workers.cpp | 19 +++++++++++++++---- 8 files changed, 47 insertions(+), 38 deletions(-) diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index 2b214423..ee0a3d57 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -36,7 +36,7 @@ class CpuThread : public IThread { public: enum Multiway { - SingleWay, + SingleWay = 1, DoubleWay, TripleWay, QuadWay, @@ -55,7 +55,7 @@ public: inline int multiway() const override { return m_multiway; } inline int priority() const override { return m_priority; } inline int64_t affinity() const override { return m_affinity; } - inline size_t index() const override { return m_affinity; } + inline size_t index() const override { return m_index; } inline Type type() const override { return CPU; } # ifndef XMRIG_NO_API diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index 46c8ed2e..3dba4a9f 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -134,12 +134,12 @@ void DoubleWorker::consumeJob() memcpy(m_state->blob + m_state->job.size(), m_state->job.blob(), m_state->job.size()); if (m_state->job.isNicehash()) { - m_state->nonce1 = (*Job::nonce(m_state->blob) & 0xff000000U) + (0xffffffU / (m_threads * 2) * m_id); - m_state->nonce2 = (*Job::nonce(m_state->blob + m_state->job.size()) & 0xff000000U) + (0xffffffU / (m_threads * 2) * (m_id + m_threads)); + m_state->nonce1 = (*Job::nonce(m_state->blob) & 0xff000000U) + (0xffffffU / m_totalWays * m_id); + m_state->nonce2 = (*Job::nonce(m_state->blob + m_state->job.size()) & 0xff000000U) + (0xffffffU / m_totalWays * (m_id + m_totalWays)); } else { - m_state->nonce1 = 0xffffffffU / (m_threads * 2) * m_id; - m_state->nonce2 = 0xffffffffU / (m_threads * 2) * (m_id + m_threads); + m_state->nonce1 = 0xffffffffU / m_totalWays * m_id; + m_state->nonce2 = 0xffffffffU / m_totalWays * (m_id + m_totalWays); } } diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp index c461cee7..6d7b969a 100644 --- a/src/workers/Handle.cpp +++ b/src/workers/Handle.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,12 +25,10 @@ #include "workers/Handle.h" -Handle::Handle(int threadId, int threads, int64_t affinity, int priority) : - m_priority(priority), - m_threadId(threadId), - m_threads(threads), - m_affinity(affinity), - m_worker(nullptr) +Handle::Handle(xmrig::IThread *config, size_t totalWays) : + m_worker(nullptr), + m_totalWays(totalWays), + m_config(config) { } diff --git a/src/workers/Handle.h b/src/workers/Handle.h index 9faae0d0..d63dc098 100644 --- a/src/workers/Handle.h +++ b/src/workers/Handle.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,30 +29,30 @@ #include +#include "interfaces/IThread.h" + + class IWorker; class Handle { public: - Handle(int threadId, int threads, int64_t affinity, int priority); + Handle(xmrig::IThread *config, size_t totalWays); void join(); void start(void (*callback) (void *)); - inline int priority() const { return m_priority; } - inline int threadId() const { return m_threadId; } - inline int threads() const { return m_threads; } - inline int64_t affinity() const { return m_affinity; } inline IWorker *worker() const { return m_worker; } + inline size_t threadId() const { return m_config->index(); } + inline size_t totalWays() const { return m_totalWays; } inline void setWorker(IWorker *worker) { m_worker = worker; } + inline xmrig::IThread *config() const { return m_config; } private: - int m_priority; - int m_threadId; - int m_threads; - int64_t m_affinity; IWorker *m_worker; + size_t m_totalWays; uv_thread_t m_thread; + xmrig::IThread *m_config; }; diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index 9f4a7484..9d47d947 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -104,10 +104,10 @@ void SingleWorker::consumeJob() m_result = m_job; if (m_job.isNicehash()) { - m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_threads * m_id); + m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_totalWays * m_id); } else { - m_result.nonce = 0xffffffffU / m_threads * m_id; + m_result.nonce = 0xffffffffU / m_totalWays * m_id; } } diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 7a7ff986..648bf7ed 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -33,17 +33,17 @@ Worker::Worker(Handle *handle) : m_id(handle->threadId()), - m_threads(handle->threads()), + m_totalWays(handle->totalWays()), m_hashCount(0), m_timestamp(0), m_count(0), m_sequence(0) { - if (Cpu::threads() > 1 && handle->affinity() != -1L) { - Cpu::setAffinity(m_id, handle->affinity()); - } +// if (Cpu::threads() > 1 && handle->affinity() != -1L) { +// Cpu::setAffinity(m_id, handle->affinity()); +// } - Platform::setThreadPriority(handle->priority()); + Platform::setThreadPriority(handle->config()->priority()); m_ctx = Mem::create(m_id); } diff --git a/src/workers/Worker.h b/src/workers/Worker.h index 08a0551f..a9c15ef4 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -49,8 +49,8 @@ protected: void storeStats(); cryptonight_ctx *m_ctx; - int m_id; - int m_threads; + size_t m_id; + size_t m_totalWays; std::atomic m_hashCount; std::atomic m_timestamp; uint64_t m_count; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 5642751a..faa207a0 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -25,7 +25,10 @@ #include "api/Api.h" +#include "core/Config.h" +#include "core/Controller.h" #include "interfaces/IJobResultListener.h" +#include "interfaces/IThread.h" #include "Mem.h" #include "workers/DoubleWorker.h" #include "workers/Handle.h" @@ -33,6 +36,8 @@ #include "workers/SingleWorker.h" #include "workers/Workers.h" +#include "log/Log.h" + bool Workers::m_active = false; bool Workers::m_enabled = true; @@ -104,8 +109,14 @@ void Workers::setJob(const Job &job, bool donate) void Workers::start(int64_t affinity, int priority, xmrig::Controller *controller) { - const int threads = Mem::threads(); - m_hashrate = new Hashrate(threads, controller); + const std::vector &threads = controller->config()->threads(); + + size_t totalWays = 0; + for (const xmrig::IThread *thread : threads) { + totalWays += thread->multiway(); + } + + m_hashrate = new Hashrate(threads.size(), controller); uv_mutex_init(&m_mutex); uv_rwlock_init(&m_rwlock); @@ -117,8 +128,8 @@ void Workers::start(int64_t affinity, int priority, xmrig::Controller *controlle uv_timer_init(uv_default_loop(), &m_timer); uv_timer_start(&m_timer, Workers::onTick, 500, 500); - for (int i = 0; i < threads; ++i) { - Handle *handle = new Handle(i, threads, affinity, priority); + for (xmrig::IThread *thread : threads) { + Handle *handle = new Handle(thread, totalWays); m_workers.push_back(handle); handle->start(Workers::onReady); } From 903b243308911d89de0c5a4e701f9b9a958a0494 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 3 Apr 2018 02:55:28 +0700 Subject: [PATCH 014/109] New style function selector. --- CMakeLists.txt | 6 ++ src/crypto/CryptoNight.cpp | 22 +++--- src/crypto/CryptoNight_constants.h | 117 +++++++++++++++++++++++++++++ src/crypto/CryptoNight_x86.h | 31 +++++++- src/net/Job.cpp | 11 ++- src/net/Job.h | 4 +- src/workers/CpuThread.cpp | 87 +++++++++++++++++++++ src/workers/CpuThread.h | 23 ++++-- src/workers/SingleWorker.cpp | 5 +- src/workers/Worker.cpp | 4 +- src/workers/Worker.h | 6 ++ src/xmrig.h | 2 +- 12 files changed, 287 insertions(+), 31 deletions(-) create mode 100644 src/crypto/CryptoNight_constants.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c9d6624f..5e2ac190 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,7 @@ project(xmrig) option(WITH_LIBCPUID "Use Libcpuid" ON) option(WITH_AEON "CryptoNight-Lite support" ON) +option(WITH_SUMO "CryptoNight-Heavy support" ON) option(WITH_HTTPD "HTTP REST API" ON) option(BUILD_STATIC "Build static binary" OFF) @@ -70,6 +71,7 @@ set(HEADERS_CRYPTO src/crypto/c_keccak.h src/crypto/c_skein.h src/crypto/CryptoNight.h + src/crypto/CryptoNight_constants.h src/crypto/CryptoNight_monero.h src/crypto/CryptoNight_test.h src/crypto/groestl_tables.h @@ -203,6 +205,10 @@ if (NOT WITH_AEON) add_definitions(/DXMRIG_NO_AEON) endif() +if (NOT WITH_SUMO) + add_definitions(/DXMRIG_NO_SUMO) +endif() + if (WITH_HTTPD) find_package(MHD) diff --git a/src/crypto/CryptoNight.cpp b/src/crypto/CryptoNight.cpp index f7dc1a37..d817c152 100644 --- a/src/crypto/CryptoNight.cpp +++ b/src/crypto/CryptoNight.cpp @@ -41,13 +41,13 @@ void (*cryptonight_hash_ctx)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) = nullptr; -#define CRYPTONIGHT_HASH(NAME, ITERATIONS, MEM, MASK, SOFT_AES) \ +#define CRYPTONIGHT_HASH(NAME, ALGO, SOFT_AES) \ switch (variant) { \ case xmrig::VARIANT_V1: \ - return cryptonight_##NAME##_hash(input, size, output, ctx); \ + return cryptonight_##NAME##_hash(input, size, output, ctx); \ \ case xmrig::VARIANT_NONE: \ - return cryptonight_##NAME##_hash(input, size, output, ctx); \ + return cryptonight_##NAME##_hash(input, size, output, ctx); \ \ default: \ break; \ @@ -56,50 +56,50 @@ void (*cryptonight_hash_ctx)(const uint8_t *input, size_t size, uint8_t *output, static void cryptonight_av1_aesni(const uint8_t *input, size_t size, uint8_t *output, struct cryptonight_ctx *ctx, int variant) { # if !defined(XMRIG_ARMv7) - CRYPTONIGHT_HASH(single, MONERO_ITER, MONERO_MEMORY, MONERO_MASK, false) + CRYPTONIGHT_HASH(single, xmrig::CRYPTONIGHT, false) # endif } static void cryptonight_av2_aesni_double(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) { # if !defined(XMRIG_ARMv7) - CRYPTONIGHT_HASH(double, MONERO_ITER, MONERO_MEMORY, MONERO_MASK, false) + CRYPTONIGHT_HASH(double, xmrig::CRYPTONIGHT, false) # endif } static void cryptonight_av3_softaes(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) { - CRYPTONIGHT_HASH(single, MONERO_ITER, MONERO_MEMORY, MONERO_MASK, true) + CRYPTONIGHT_HASH(single, xmrig::CRYPTONIGHT, true) } static void cryptonight_av4_softaes_double(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) { - CRYPTONIGHT_HASH(double, MONERO_ITER, MONERO_MEMORY, MONERO_MASK, true) + CRYPTONIGHT_HASH(double, xmrig::CRYPTONIGHT, true) } #ifndef XMRIG_NO_AEON static void cryptonight_lite_av1_aesni(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) { # if !defined(XMRIG_ARMv7) - CRYPTONIGHT_HASH(single, AEON_ITER, AEON_MEMORY, AEON_MASK, false) + CRYPTONIGHT_HASH(single, xmrig::CRYPTONIGHT_LITE, false) # endif } static void cryptonight_lite_av2_aesni_double(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) { # if !defined(XMRIG_ARMv7) - CRYPTONIGHT_HASH(double, AEON_ITER, AEON_MEMORY, AEON_MASK, false) + CRYPTONIGHT_HASH(double, xmrig::CRYPTONIGHT_LITE, false) # endif } static void cryptonight_lite_av3_softaes(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) { - CRYPTONIGHT_HASH(single, AEON_ITER, AEON_MEMORY, AEON_MASK, true) + CRYPTONIGHT_HASH(single, xmrig::CRYPTONIGHT_LITE, true) } static void cryptonight_lite_av4_softaes_double(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) { - CRYPTONIGHT_HASH(double, AEON_ITER, AEON_MEMORY, AEON_MASK, true) + CRYPTONIGHT_HASH(double, xmrig::CRYPTONIGHT_LITE, true) } void (*cryptonight_variations[8])(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) = { diff --git a/src/crypto/CryptoNight_constants.h b/src/crypto/CryptoNight_constants.h new file mode 100644 index 00000000..5d02baf9 --- /dev/null +++ b/src/crypto/CryptoNight_constants.h @@ -0,0 +1,117 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __CRYPTONIGHT_CONSTANTS_H__ +#define __CRYPTONIGHT_CONSTANTS_H__ + + +#include + + +#include "xmrig.h" + + +namespace xmrig +{ + +constexpr const size_t CRYPTONIGHT_MEMORY = 2 * 1024 * 1024; +constexpr const uint32_t CRYPTONIGHT_MASK = 0x1FFFF0; +constexpr const uint32_t CRYPTONIGHT_ITER = 0x80000; + +constexpr const size_t CRYPTONIGHT_LITE_MEMORY = 1 * 1024 * 1024; +constexpr const uint32_t CRYPTONIGHT_LITE_MASK = 0xFFFF0; +constexpr const uint32_t CRYPTONIGHT_LITE_ITER = 0x40000; + +constexpr const size_t CRYPTONIGHT_HEAVY_MEMORY = 4 * 1024 * 1024; +constexpr const uint32_t CRYPTONIGHT_HEAVY_MASK = 0x3FFFF0; +constexpr const uint32_t CRYPTONIGHT_HEAVY_ITER = 0x40000; + + +template inline constexpr size_t cn_select_memory() { return 0; } +template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_MEMORY; } +template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_LITE_MEMORY; } +template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_HEAVY_MEMORY; } + +inline size_t cn_select_memory(Algo algorithm) +{ + switch(algorithm) + { + case CRYPTONIGHT: + return CRYPTONIGHT_MEMORY; + + case CRYPTONIGHT_LITE: + return CRYPTONIGHT_LITE_MEMORY; + + case CRYPTONIGHT_HEAVY: + return CRYPTONIGHT_HEAVY_MEMORY; + } +} + + +template inline constexpr uint32_t cn_select_mask() { return 0; } +template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_MASK; } +template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_LITE_MASK; } +template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_HEAVY_MASK; } + +inline uint32_t cn_select_mask(Algo algorithm) +{ + switch(algorithm) + { + case CRYPTONIGHT: + return CRYPTONIGHT_MASK; + + case CRYPTONIGHT_LITE: + return CRYPTONIGHT_LITE_MASK; + + case CRYPTONIGHT_HEAVY: + return CRYPTONIGHT_HEAVY_MASK; + } +} + + +template inline constexpr uint32_t cn_select_iter() { return 0; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_LITE_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_HEAVY_ITER; } + +inline uint32_t cn_select_iter(Algo algorithm) +{ + switch(algorithm) + { + case CRYPTONIGHT: + return CRYPTONIGHT_ITER; + + case CRYPTONIGHT_LITE: + return CRYPTONIGHT_LITE_ITER; + + case CRYPTONIGHT_HEAVY: + return CRYPTONIGHT_HEAVY_ITER; + } +} + + +} /* namespace xmrig */ + + +#endif /* __CRYPTONIGHT_CONSTANTS_H__ */ diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index b7544dcc..768b2a5b 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -35,6 +35,7 @@ #include "crypto/CryptoNight.h" +#include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_monero.h" #include "crypto/soft_aes.h" @@ -309,9 +310,13 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) } -template +template inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx *__restrict__ ctx) { + constexpr size_t MASK = xmrig::cn_select_mask(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t MEM = xmrig::cn_select_memory(); + keccak(input, (int) size, ctx->state0, 200); VARIANT1_INIT(0); @@ -367,9 +372,13 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si } -template +template inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) { + constexpr size_t MASK = xmrig::cn_select_mask(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t MEM = xmrig::cn_select_memory(); + keccak(input, (int) size, ctx->state0, 200); keccak(input + size, (int) size, ctx->state1, 200); @@ -464,4 +473,22 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, output + 32); } + +template +inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +{ +} + + +template +inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +{ +} + + +template +inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +{ +} + #endif /* __CRYPTONIGHT_X86_H__ */ diff --git a/src/net/Job.cpp b/src/net/Job.cpp index e5714376..17d8266f 100644 --- a/src/net/Job.cpp +++ b/src/net/Job.cpp @@ -23,6 +23,7 @@ */ +#include #include @@ -62,11 +63,11 @@ Job::Job() : m_algo(xmrig::CRYPTONIGHT), m_poolId(-2), m_threadId(-1), - m_variant(xmrig::VARIANT_AUTO), m_size(0), m_diff(0), m_target(0), - m_blob() + m_blob(), + m_variant(xmrig::VARIANT_AUTO) { } @@ -77,12 +78,12 @@ Job::Job(int poolId, bool nicehash, int algo, int variant) : m_algo(algo), m_poolId(poolId), m_threadId(-1), - m_variant(variant), m_size(0), m_diff(0), m_target(0), m_blob() { + setVariant(variant); } @@ -174,10 +175,12 @@ void Job::setVariant(int variant) case xmrig::VARIANT_AUTO: case xmrig::VARIANT_NONE: case xmrig::VARIANT_V1: - m_variant = variant; + m_variant = static_cast(variant); break; default: + assert(false); + m_variant = xmrig::VARIANT_AUTO; break; } } diff --git a/src/net/Job.h b/src/net/Job.h index b8b9d6bc..e8964314 100644 --- a/src/net/Job.h +++ b/src/net/Job.h @@ -55,7 +55,6 @@ public: inline const xmrig::Id &id() const { return m_id; } inline int poolId() const { return m_poolId; } inline int threadId() const { return m_threadId; } - inline int variant() const { return (m_variant == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? 1 : 0) : m_variant); } inline size_t size() const { return m_size; } inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } inline uint32_t diff() const { return (uint32_t) m_diff; } @@ -63,6 +62,7 @@ public: inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } inline void setPoolId(int poolId) { m_poolId = poolId; } inline void setThreadId(int threadId) { m_threadId = threadId; } + inline xmrig::Variant variant() const { return (m_variant == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? xmrig::VARIANT_V1 : xmrig::VARIANT_NONE) : m_variant); } static bool fromHex(const char* in, unsigned int len, unsigned char* out); static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast(blob + 39); } @@ -78,12 +78,12 @@ private: int m_algo; int m_poolId; int m_threadId; - int m_variant; size_t m_size; uint64_t m_diff; uint64_t m_target; uint8_t m_blob[96]; // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk. xmrig::Id m_id; + xmrig::Variant m_variant; }; #endif /* __JOB_H__ */ diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 91e98a14..b8be966f 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -29,6 +29,13 @@ #include "workers/CpuThread.h" +#if defined(XMRIG_ARM) +# include "crypto/CryptoNight_arm.h" +#else +# include "crypto/CryptoNight_x86.h" +#endif + + xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch) : m_algorithm(algorithm), m_av(av), @@ -47,6 +54,86 @@ xmrig::CpuThread::~CpuThread() } +xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant) +{ + assert(variant == VARIANT_NONE || variant == VARIANT_V1); + + static const cn_hash_fun func_table[50] = { + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + +# ifndef XMRIG_NO_AEON + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, +# else + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, +# endif + +# ifndef XMRIG_NO_SUMO + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, +# else + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, +# endif + }; + +# ifndef XMRIG_NO_SUMO + if (algorithm == CRYPTONIGHT_HEAVY) { + variant = VARIANT_NONE; + } +# endif + + return func_table[20 * algorithm + 10 * variant + av - 1]; +} + + xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority) { assert(av > AV_AUTO && av < AV_MAX); diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index ee0a3d57..aef73719 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -29,6 +29,9 @@ #include "xmrig.h" +struct cryptonight_ctx; + + namespace xmrig { @@ -46,17 +49,21 @@ public: CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch); ~CpuThread(); + typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx); + + static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant); static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority); - inline bool isPrefetch() const { return m_prefetch; } - inline bool isSoftAES() const { return m_softAES; } + inline bool isPrefetch() const { return m_prefetch; } + inline bool isSoftAES() const { return m_softAES; } + inline cn_hash_fun fn(Variant variant) const { return fn(m_algorithm, m_av, variant); } - inline Algo algorithm() const override { return m_algorithm; } - inline int multiway() const override { return m_multiway; } - inline int priority() const override { return m_priority; } - inline int64_t affinity() const override { return m_affinity; } - inline size_t index() const override { return m_index; } - inline Type type() const override { return CPU; } + inline Algo algorithm() const override { return m_algorithm; } + inline int multiway() const override { return m_multiway; } + inline int priority() const override { return m_priority; } + inline int64_t affinity() const override { return m_affinity; } + inline size_t index() const override { return m_index; } + inline Type type() const override { return CPU; } # ifndef XMRIG_NO_API rapidjson::Value toAPI(rapidjson::Document &doc) const override; diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index 9d47d947..6df44d9d 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -26,7 +26,7 @@ #include -#include "crypto/CryptoNight.h" +#include "workers/CpuThread.h" #include "workers/SingleWorker.h" #include "workers/Workers.h" @@ -61,7 +61,8 @@ void SingleWorker::start() m_count++; *m_job.nonce() = ++m_result.nonce; - if (CryptoNight::hash(m_job, m_result, m_ctx)) { + m_thread->fn(m_job.variant())(m_job.blob(), m_job.size(), m_result.result, m_ctx); + if (*reinterpret_cast(m_result.result + 24) < m_job.target()) { Workers::submit(m_result); } diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 648bf7ed..2672f49f 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -27,6 +27,7 @@ #include "Cpu.h" #include "Mem.h" #include "Platform.h" +#include "workers/CpuThread.h" #include "workers/Handle.h" #include "workers/Worker.h" @@ -37,7 +38,8 @@ Worker::Worker(Handle *handle) : m_hashCount(0), m_timestamp(0), m_count(0), - m_sequence(0) + m_sequence(0), + m_thread(static_cast(handle->config())) { // if (Cpu::threads() > 1 && handle->affinity() != -1L) { // Cpu::setAffinity(m_id, handle->affinity()); diff --git a/src/workers/Worker.h b/src/workers/Worker.h index a9c15ef4..cb52c149 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -36,6 +36,11 @@ struct cryptonight_ctx; class Handle; +namespace xmrig { + class CpuThread; +} + + class Worker : public IWorker { public: @@ -55,6 +60,7 @@ protected: std::atomic m_timestamp; uint64_t m_count; uint64_t m_sequence; + xmrig::CpuThread *m_thread; }; diff --git a/src/xmrig.h b/src/xmrig.h index eba72bb4..f4ae8162 100644 --- a/src/xmrig.h +++ b/src/xmrig.h @@ -63,7 +63,7 @@ enum Variant { }; -} /* xmrig */ +} /* namespace xmrig */ #endif /* __XMRIG_H__ */ From c1bc6acd26045f5ec3382832a841733c3262c9e5 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 3 Apr 2018 03:01:04 +0700 Subject: [PATCH 015/109] Fix DoubleWorker. --- src/workers/DoubleWorker.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index 3dba4a9f..7bde7df9 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -26,7 +26,7 @@ #include -#include "crypto/CryptoNight.h" +#include "workers/CpuThread.h" #include "workers/DoubleWorker.h" #include "workers/Workers.h" @@ -86,7 +86,7 @@ void DoubleWorker::start() *Job::nonce(m_state->blob) = ++m_state->nonce1; *Job::nonce(m_state->blob + m_state->job.size()) = ++m_state->nonce2; - CryptoNight::hash(m_state->blob, m_state->job.size(), m_hash, m_ctx, m_state->job.variant()); + m_thread->fn(m_state->job.variant())(m_state->blob, m_state->job.size(), m_hash, m_ctx); if (*reinterpret_cast(m_hash + 24) < m_state->job.target()) { Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce1, m_hash, m_state->job.diff())); From d7c56305094902818b47ac7714b2296d7f3e24c2 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 3 Apr 2018 03:27:44 +0700 Subject: [PATCH 016/109] Fix nonce allocation in DoubleWorker. --- src/App.cpp | 2 +- src/Mem_unix.cpp | 2 +- src/workers/DoubleWorker.cpp | 4 ++-- src/workers/Handle.cpp | 3 ++- src/workers/Handle.h | 4 +++- src/workers/Worker.cpp | 1 + src/workers/Worker.h | 1 + src/workers/Workers.cpp | 4 ++-- src/workers/Workers.h | 2 +- 9 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/App.cpp b/src/App.cpp index a9d10774..8c7a16ea 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -136,7 +136,7 @@ int App::exec() m_httpd->start(); # endif - Workers::start(m_controller->config()->affinity(), m_controller->config()->priority(), m_controller); + Workers::start(m_controller); m_controller->network()->connect(); diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index 3b69f267..7978d241 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -46,7 +46,7 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled) m_threads = threads; m_doubleHash = doubleHash; - const int ratio = (doubleHash && algo != xmrig::ALGO_CRYPTONIGHT_LITE) ? 2 : 1; + const int ratio = (doubleHash && algo != xmrig::CRYPTONIGHT_LITE) ? 2 : 1; m_size = MONERO_MEMORY * (threads * ratio + 1); if (!enabled) { diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index 7bde7df9..8971f0c0 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -135,11 +135,11 @@ void DoubleWorker::consumeJob() if (m_state->job.isNicehash()) { m_state->nonce1 = (*Job::nonce(m_state->blob) & 0xff000000U) + (0xffffffU / m_totalWays * m_id); - m_state->nonce2 = (*Job::nonce(m_state->blob + m_state->job.size()) & 0xff000000U) + (0xffffffU / m_totalWays * (m_id + m_totalWays)); + m_state->nonce2 = (*Job::nonce(m_state->blob + m_state->job.size()) & 0xff000000U) + (0xffffffU / m_totalWays * (m_id + m_totalThreads)); } else { m_state->nonce1 = 0xffffffffU / m_totalWays * m_id; - m_state->nonce2 = 0xffffffffU / m_totalWays * (m_id + m_totalWays); + m_state->nonce2 = 0xffffffffU / m_totalWays * (m_id + m_totalThreads); } } diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp index 6d7b969a..29f57fb2 100644 --- a/src/workers/Handle.cpp +++ b/src/workers/Handle.cpp @@ -25,8 +25,9 @@ #include "workers/Handle.h" -Handle::Handle(xmrig::IThread *config, size_t totalWays) : +Handle::Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays) : m_worker(nullptr), + m_totalThreads(totalThreads), m_totalWays(totalWays), m_config(config) { diff --git a/src/workers/Handle.h b/src/workers/Handle.h index d63dc098..b3a7c76f 100644 --- a/src/workers/Handle.h +++ b/src/workers/Handle.h @@ -38,18 +38,20 @@ class IWorker; class Handle { public: - Handle(xmrig::IThread *config, size_t totalWays); + Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays); void join(); void start(void (*callback) (void *)); inline IWorker *worker() const { return m_worker; } inline size_t threadId() const { return m_config->index(); } + inline size_t totalThreads() const { return m_totalThreads; } inline size_t totalWays() const { return m_totalWays; } inline void setWorker(IWorker *worker) { m_worker = worker; } inline xmrig::IThread *config() const { return m_config; } private: IWorker *m_worker; + size_t m_totalThreads; size_t m_totalWays; uv_thread_t m_thread; xmrig::IThread *m_config; diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 2672f49f..bf4f62da 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -34,6 +34,7 @@ Worker::Worker(Handle *handle) : m_id(handle->threadId()), + m_totalThreads(handle->totalThreads()), m_totalWays(handle->totalWays()), m_hashCount(0), m_timestamp(0), diff --git a/src/workers/Worker.h b/src/workers/Worker.h index cb52c149..9fbce1a2 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -55,6 +55,7 @@ protected: cryptonight_ctx *m_ctx; size_t m_id; + size_t m_totalThreads; size_t m_totalWays; std::atomic m_hashCount; std::atomic m_timestamp; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index faa207a0..8ac256da 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -107,7 +107,7 @@ void Workers::setJob(const Job &job, bool donate) } -void Workers::start(int64_t affinity, int priority, xmrig::Controller *controller) +void Workers::start(xmrig::Controller *controller) { const std::vector &threads = controller->config()->threads(); @@ -129,7 +129,7 @@ void Workers::start(int64_t affinity, int priority, xmrig::Controller *controlle uv_timer_start(&m_timer, Workers::onTick, 500, 500); for (xmrig::IThread *thread : threads) { - Handle *handle = new Handle(thread, totalWays); + Handle *handle = new Handle(thread, threads.size(), totalWays); m_workers.push_back(handle); handle->start(Workers::onReady); } diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 942a5b58..ecec9e30 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -51,7 +51,7 @@ public: static void printHashrate(bool detail); static void setEnabled(bool enabled); static void setJob(const Job &job, bool donate); - static void start(int64_t affinity, int priority, xmrig::Controller *controller); + static void start(xmrig::Controller *controller); static void stop(); static void submit(const JobResult &result); From 5c6ec587ac8020e8a84538105dab7226c415666c Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 3 Apr 2018 14:51:05 +0700 Subject: [PATCH 017/109] Move selfTest to threads, remove legacy CryptoNight.cpp. --- CMakeLists.txt | 1 - src/App.cpp | 5 - src/crypto/CryptoNight.cpp | 189 ----------------------------------- src/crypto/CryptoNight.h | 15 --- src/interfaces/IWorker.h | 7 +- src/workers/DoubleWorker.cpp | 35 ++++++- src/workers/DoubleWorker.h | 3 +- src/workers/SingleWorker.cpp | 35 ++++++- src/workers/SingleWorker.h | 3 +- src/workers/Worker.h | 1 + src/workers/Workers.cpp | 9 +- 11 files changed, 85 insertions(+), 218 deletions(-) delete mode 100644 src/crypto/CryptoNight.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e2ac190..106ab30f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,7 +126,6 @@ set(SOURCES_CRYPTO src/crypto/c_blake256.c src/crypto/c_jh.c src/crypto/c_skein.c - src/crypto/CryptoNight.cpp ) if (WIN32) diff --git a/src/App.cpp b/src/App.cpp index 8c7a16ea..dc22836d 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -101,11 +101,6 @@ int App::exec() background(); - if (!CryptoNight::init(m_controller->config()->algorithm(), m_controller->config()->algoVariant(), m_controller->config()->isDoubleHash())) { - LOG_ERR("\"%s\" hash self-test failed.", m_controller->config()->algoName()); - return 1; - } - Mem::allocate(m_controller->config()->algorithm(), m_controller->config()->threadsCount(), m_controller->config()->isDoubleHash(), diff --git a/src/crypto/CryptoNight.cpp b/src/crypto/CryptoNight.cpp deleted file mode 100644 index d817c152..00000000 --- a/src/crypto/CryptoNight.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018 Lee Clagett - * Copyright 2016-2018 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include "crypto/CryptoNight.h" - - -#if defined(XMRIG_ARM) -# include "crypto/CryptoNight_arm.h" -#else -# include "crypto/CryptoNight_x86.h" -#endif - -#include "crypto/CryptoNight_test.h" -#include "net/Job.h" -#include "net/JobResult.h" -#include "xmrig.h" - - -void (*cryptonight_hash_ctx)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) = nullptr; - - -#define CRYPTONIGHT_HASH(NAME, ALGO, SOFT_AES) \ - switch (variant) { \ - case xmrig::VARIANT_V1: \ - return cryptonight_##NAME##_hash(input, size, output, ctx); \ - \ - case xmrig::VARIANT_NONE: \ - return cryptonight_##NAME##_hash(input, size, output, ctx); \ - \ - default: \ - break; \ - } - - -static void cryptonight_av1_aesni(const uint8_t *input, size_t size, uint8_t *output, struct cryptonight_ctx *ctx, int variant) { -# if !defined(XMRIG_ARMv7) - CRYPTONIGHT_HASH(single, xmrig::CRYPTONIGHT, false) -# endif -} - - -static void cryptonight_av2_aesni_double(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) { -# if !defined(XMRIG_ARMv7) - CRYPTONIGHT_HASH(double, xmrig::CRYPTONIGHT, false) -# endif -} - - -static void cryptonight_av3_softaes(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) { - CRYPTONIGHT_HASH(single, xmrig::CRYPTONIGHT, true) -} - - -static void cryptonight_av4_softaes_double(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) { - CRYPTONIGHT_HASH(double, xmrig::CRYPTONIGHT, true) -} - - -#ifndef XMRIG_NO_AEON -static void cryptonight_lite_av1_aesni(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) { -# if !defined(XMRIG_ARMv7) - CRYPTONIGHT_HASH(single, xmrig::CRYPTONIGHT_LITE, false) -# endif -} - - -static void cryptonight_lite_av2_aesni_double(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) { -# if !defined(XMRIG_ARMv7) - CRYPTONIGHT_HASH(double, xmrig::CRYPTONIGHT_LITE, false) -# endif -} - - -static void cryptonight_lite_av3_softaes(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) { - CRYPTONIGHT_HASH(single, xmrig::CRYPTONIGHT_LITE, true) -} - - -static void cryptonight_lite_av4_softaes_double(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) { - CRYPTONIGHT_HASH(double, xmrig::CRYPTONIGHT_LITE, true) -} - -void (*cryptonight_variations[8])(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) = { - cryptonight_av1_aesni, - cryptonight_av2_aesni_double, - cryptonight_av3_softaes, - cryptonight_av4_softaes_double, - cryptonight_lite_av1_aesni, - cryptonight_lite_av2_aesni_double, - cryptonight_lite_av3_softaes, - cryptonight_lite_av4_softaes_double - }; -#else -void (*cryptonight_variations[4])(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) = { - cryptonight_av1_aesni, - cryptonight_av2_aesni_double, - cryptonight_av3_softaes, - cryptonight_av4_softaes_double - }; -#endif - - -bool CryptoNight::hash(const Job &job, JobResult &result, cryptonight_ctx *ctx) -{ - cryptonight_hash_ctx(job.blob(), job.size(), result.result, ctx, job.variant()); - - return *reinterpret_cast(result.result + 24) < job.target(); -} - - -bool CryptoNight::init(int algo, int variant, bool doubleHash) -{ - if (variant < 1 || variant > 4) { - return false; - } - -# ifndef XMRIG_NO_AEON - const int index = algo == xmrig::CRYPTONIGHT_LITE ? (variant + 3) : (variant - 1); -# else - const int index = variant - 1; -# endif - - cryptonight_hash_ctx = cryptonight_variations[index]; - - return selfTest(algo, doubleHash); -} - - -void CryptoNight::hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant) -{ - cryptonight_hash_ctx(input, size, output, ctx, variant); -} - - -bool CryptoNight::selfTest(int algo, bool doubleHash) { - if (cryptonight_hash_ctx == nullptr) { - return false; - } - - uint8_t output[64]; - - struct cryptonight_ctx *ctx = static_cast(_mm_malloc(sizeof(cryptonight_ctx), 16)); - ctx->memory = static_cast(_mm_malloc(MONERO_MEMORY * 2, 16)); - - cryptonight_hash_ctx(test_input, 76, output, ctx, 0); - -# ifndef XMRIG_NO_AEON - bool rc = memcmp(output, algo == xmrig::CRYPTONIGHT_LITE ? test_output_v0_lite : test_output_v0, (doubleHash ? 64 : 32)) == 0; -# else - bool rc = memcmp(output, test_output_v0, (doubleHash ? 64 : 32)) == 0; -# endif - - if (rc) { - cryptonight_hash_ctx(test_input, 76, output, ctx, 1); - -# ifndef XMRIG_NO_AEON - rc = memcmp(output, algo == xmrig::CRYPTONIGHT_LITE ? test_output_v1_lite : test_output_v1, (doubleHash ? 64 : 32)) == 0; -# else - rc = memcmp(output, test_output_v1, (doubleHash ? 64 : 32)) == 0; -# endif - } - - _mm_free(ctx->memory); - _mm_free(ctx); - - return rc; -} diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index eb17719e..d0d61ae3 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -46,19 +46,4 @@ struct cryptonight_ctx { }; -class Job; -class JobResult; - - -class CryptoNight -{ -public: - static bool hash(const Job &job, JobResult &result, cryptonight_ctx *ctx); - static bool init(int algo, int variant, bool doubleHash); - static void hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant); - -private: - static bool selfTest(int algo, bool doubleHash); -}; - #endif /* __CRYPTONIGHT_H__ */ diff --git a/src/interfaces/IWorker.h b/src/interfaces/IWorker.h index b9b6eb0a..a90abe11 100644 --- a/src/interfaces/IWorker.h +++ b/src/interfaces/IWorker.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,9 +33,10 @@ class IWorker public: virtual ~IWorker() {} + virtual bool start() = 0; + virtual size_t id() const = 0; virtual uint64_t hashCount() const = 0; virtual uint64_t timestamp() const = 0; - virtual void start() = 0; }; diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index 8971f0c0..425dd0c2 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -26,6 +26,7 @@ #include +#include "crypto/CryptoNight_test.h" #include "workers/CpuThread.h" #include "workers/DoubleWorker.h" #include "workers/Workers.h" @@ -61,8 +62,12 @@ DoubleWorker::~DoubleWorker() } -void DoubleWorker::start() +bool DoubleWorker::start() { + if (!selfTest()) { + return false; + } + while (Workers::sequence() > 0) { if (Workers::isPaused()) { do { @@ -101,6 +106,8 @@ void DoubleWorker::start() consumeJob(); } + + return true; } @@ -115,6 +122,32 @@ bool DoubleWorker::resume(const Job &job) } +bool DoubleWorker::selfTest() +{ + if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) { + return false; + } + + m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_hash, m_ctx); + + if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_hash, test_output_v0, 64) == 0) { + m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); + + return memcmp(m_hash, test_output_v1, 64) == 0; + } + +# ifndef XMRIG_NO_AEON + if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_hash, test_output_v0_lite, 64) == 0) { + m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); + + return memcmp(m_hash, test_output_v1_lite, 64) == 0; + } +# endif + + return false; +} + + void DoubleWorker::consumeJob() { Job job = Workers::job(); diff --git a/src/workers/DoubleWorker.h b/src/workers/DoubleWorker.h index 57be59d0..e8847282 100644 --- a/src/workers/DoubleWorker.h +++ b/src/workers/DoubleWorker.h @@ -40,10 +40,11 @@ public: DoubleWorker(Handle *handle); ~DoubleWorker(); - void start() override; + bool start() override; private: bool resume(const Job &job); + bool selfTest(); void consumeJob(); void save(const Job &job); diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index 6df44d9d..2ff356c8 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -26,6 +26,7 @@ #include +#include "crypto/CryptoNight_test.h" #include "workers/CpuThread.h" #include "workers/SingleWorker.h" #include "workers/Workers.h" @@ -37,8 +38,12 @@ SingleWorker::SingleWorker(Handle *handle) } -void SingleWorker::start() +bool SingleWorker::start() { + if (!selfTest()) { + return false; + } + while (Workers::sequence() > 0) { if (Workers::isPaused()) { do { @@ -71,6 +76,8 @@ void SingleWorker::start() consumeJob(); } + + return true; } @@ -87,6 +94,32 @@ bool SingleWorker::resume(const Job &job) } +bool SingleWorker::selfTest() +{ + if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) { + return false; + } + + m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_result.result, m_ctx); + + if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_result.result, test_output_v0, 32) == 0) { + m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctx); + + return memcmp(m_result.result, test_output_v1, 32) == 0; + } + +# ifndef XMRIG_NO_AEON + if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_result.result, test_output_v0_lite, 32) == 0) { + m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctx); + + return memcmp(m_result.result, test_output_v1_lite, 32) == 0; + } +# endif + + return false; +} + + void SingleWorker::consumeJob() { Job job = Workers::job(); diff --git a/src/workers/SingleWorker.h b/src/workers/SingleWorker.h index f7d9cff8..061f5084 100644 --- a/src/workers/SingleWorker.h +++ b/src/workers/SingleWorker.h @@ -39,10 +39,11 @@ class SingleWorker : public Worker public: SingleWorker(Handle *handle); - void start() override; + bool start() override; private: bool resume(const Job &job); + bool selfTest(); void consumeJob(); void save(const Job &job); diff --git a/src/workers/Worker.h b/src/workers/Worker.h index 9fbce1a2..88f6ee42 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -47,6 +47,7 @@ public: Worker(Handle *handle); ~Worker(); + inline size_t id() const override { return m_id; } inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); } inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); } diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 8ac256da..00941c7b 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -22,6 +22,7 @@ */ #include +#include #include "api/Api.h" @@ -171,7 +172,13 @@ void Workers::onReady(void *arg) handle->setWorker(new SingleWorker(handle)); } - handle->worker()->start(); + const bool rc = handle->worker()->start(); + + if (!rc) { + uv_mutex_lock(&m_mutex); + LOG_ERR("thread %zu error: \"hash self-test failed\".", handle->worker()->id()); + uv_mutex_unlock(&m_mutex); + } } From 7d5a97137d5804d16c1c6697c3b427859cbd241d Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 3 Apr 2018 16:08:15 +0700 Subject: [PATCH 018/109] Fix autoconfig and memory allocation for heavy algo. --- src/Cpu.cpp | 19 +++++++++++++++---- src/Cpu.h | 9 ++++++--- src/Mem.cpp | 9 ++++++--- src/Mem.h | 5 ++++- src/Mem_unix.cpp | 6 +++++- src/Mem_win.cpp | 6 +++++- src/workers/SingleWorker.cpp | 2 +- 7 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/Cpu.cpp b/src/Cpu.cpp index eba993b3..f8fb092c 100644 --- a/src/Cpu.cpp +++ b/src/Cpu.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,7 +39,7 @@ int Cpu::m_totalCores = 0; int Cpu::m_totalThreads = 0; -int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage) +int Cpu::optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage) { if (m_totalThreads == 1) { return 1; @@ -54,7 +54,18 @@ int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage) } int count = 0; - const int size = (algo ? 1024 : 2048) * (doubleHash ? 2 : 1); + int size = 2048; + + if (algo == xmrig::CRYPTONIGHT_LITE) { + size = 1024; + } + else if (algo == xmrig::CRYPTONIGHT_HEAVY) { + size = 4096; + } + + if (doubleHash) { + size *= 2; + } if (cache) { count = cache / size; diff --git a/src/Cpu.h b/src/Cpu.h index 9444274d..118c7b7d 100644 --- a/src/Cpu.h +++ b/src/Cpu.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,6 +28,9 @@ #include +#include "xmrig.h" + + class Cpu { public: @@ -37,7 +40,7 @@ public: BMI2 = 4 }; - static int optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage); + static int optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage); static void init(); static void setAffinity(int id, uint64_t mask); diff --git a/src/Mem.cpp b/src/Mem.cpp index f5da7865..9de79dbd 100644 --- a/src/Mem.cpp +++ b/src/Mem.cpp @@ -27,8 +27,8 @@ #include "crypto/CryptoNight.h" +#include "crypto/CryptoNight_constants.h" #include "Mem.h" -#include "xmrig.h" bool Mem::m_doubleHash = false; @@ -48,10 +48,13 @@ cryptonight_ctx *Mem::create(int threadId) } # endif - cryptonight_ctx *ctx = reinterpret_cast(&m_memory[MONERO_MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]); + const size_t size = m_algo == xmrig::CRYPTONIGHT_HEAVY ? xmrig::cn_select_memory() + : xmrig::cn_select_memory(); + + cryptonight_ctx *ctx = reinterpret_cast(&m_memory[size - sizeof(cryptonight_ctx) * (threadId + 1)]); const int ratio = m_doubleHash ? 2 : 1; - ctx->memory = &m_memory[MONERO_MEMORY * (threadId * ratio + 1)]; + ctx->memory = &m_memory[size * (threadId * ratio + 1)]; return ctx; } diff --git a/src/Mem.h b/src/Mem.h index 18914d68..73947b42 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -30,6 +30,9 @@ #include +#include "xmrig.h" + + struct cryptonight_ctx; @@ -42,7 +45,7 @@ public: Lock = 4 }; - static bool allocate(int algo, int threads, bool doubleHash, bool enabled); + static bool allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled); static cryptonight_ctx *create(int threadId); static void *calloc(size_t num, size_t size); static void release(); diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index 7978d241..0dd833d7 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -40,7 +40,7 @@ #include "xmrig.h" -bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled) +bool Mem::allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled) { m_algo = algo; m_threads = threads; @@ -49,6 +49,10 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled) const int ratio = (doubleHash && algo != xmrig::CRYPTONIGHT_LITE) ? 2 : 1; m_size = MONERO_MEMORY * (threads * ratio + 1); + if (algo == xmrig::CRYPTONIGHT_HEAVY) { + m_size *= 2; + } + if (!enabled) { m_memory = static_cast(_mm_malloc(m_size, 16)); return true; diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index 6cc0a6ee..ec30e3e8 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -145,7 +145,7 @@ static BOOL TrySetLockPagesPrivilege() { } -bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled) +bool Mem::allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled) { m_algo = algo; m_threads = threads; @@ -154,6 +154,10 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled) const int ratio = (doubleHash && algo != xmrig::CRYPTONIGHT_LITE) ? 2 : 1; m_size = MONERO_MEMORY * (threads * ratio + 1); + if (algo == xmrig::CRYPTONIGHT_HEAVY) { + m_size *= 2; + } + if (!enabled) { m_memory = static_cast(_mm_malloc(m_size, 16)); return true; diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index 2ff356c8..5757ef77 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -116,7 +116,7 @@ bool SingleWorker::selfTest() } # endif - return false; + return true; } From dd6bc339bf04cf3dfbd2806ef4891e4f9cc05566 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 3 Apr 2018 16:55:41 +0700 Subject: [PATCH 019/109] First working cryptonight-heavy. --- src/crypto/CryptoNight_x86.h | 129 ++++++++++++++++++++++++-- src/net/strategies/DonateStrategy.cpp | 4 + src/workers/DoubleWorker.cpp | 2 +- 3 files changed, 126 insertions(+), 9 deletions(-) diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index 768b2a5b..414a1f7f 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -218,7 +218,21 @@ static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, } -template +inline void mix_and_propagate(__m128i& x0, __m128i& x1, __m128i& x2, __m128i& x3, __m128i& x4, __m128i& x5, __m128i& x6, __m128i& x7) +{ + __m128i tmp0 = x0; + x0 = _mm_xor_si128(x0, x1); + x1 = _mm_xor_si128(x1, x2); + x2 = _mm_xor_si128(x2, x3); + x3 = _mm_xor_si128(x3, x4); + x4 = _mm_xor_si128(x4, x5); + x5 = _mm_xor_si128(x5, x6); + x6 = _mm_xor_si128(x6, x7); + x7 = _mm_xor_si128(x7, tmp0); +} + + +template static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) { __m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7; @@ -235,6 +249,23 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) xin6 = _mm_load_si128(input + 10); xin7 = _mm_load_si128(input + 11); + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + for (size_t i = 0; i < 16; i++) { + aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + + mix_and_propagate(xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7); + } + } + for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) { aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); @@ -259,7 +290,7 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) } -template +template static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) { __m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7; @@ -297,6 +328,51 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7); + } + } + + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) { + xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0); + xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1); + xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2); + xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3); + xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4); + xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5); + xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6); + xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7); + + aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + + mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7); + } + + for (size_t i = 0; i < 16; i++) { + aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + + mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7); + } } _mm_store_si128(output + 4, xout0); @@ -317,11 +393,16 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si constexpr size_t ITERATIONS = xmrig::cn_select_iter(); constexpr size_t MEM = xmrig::cn_select_memory(); + if (VARIANT > 0 && size < 43) { + memset(output, 0, 32); + return; + } + keccak(input, (int) size, ctx->state0, 200); VARIANT1_INIT(0); - cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); + cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); const uint8_t* l0 = ctx->memory; uint64_t* h0 = reinterpret_cast(ctx->state0); @@ -363,9 +444,18 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si ah0 ^= ch; al0 ^= cl; idx0 = al0; + + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + int64_t n = ((int64_t*)&l0[idx0 & MASK])[0]; + int32_t d = ((int32_t*)&l0[idx0 & MASK])[2]; + int64_t q = n / (d | 0x5); + + ((int64_t*)&l0[idx0 & MASK])[0] = n ^ q; + idx0 = d ^ q; + } } - cn_implode_scratchpad((__m128i*) ctx->memory, (__m128i*) ctx->state0); + cn_implode_scratchpad((__m128i*) ctx->memory, (__m128i*) ctx->state0); keccakf(h0, 24); extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); @@ -379,6 +469,11 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si constexpr size_t ITERATIONS = xmrig::cn_select_iter(); constexpr size_t MEM = xmrig::cn_select_memory(); + if (VARIANT > 0 && size < 43) { + memset(output, 0, 64); + return; + } + keccak(input, (int) size, ctx->state0, 200); keccak(input + size, (int) size, ctx->state1, 200); @@ -390,8 +485,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si uint64_t* h0 = reinterpret_cast(ctx->state0); uint64_t* h1 = reinterpret_cast(ctx->state1); - cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); - cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); + cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); + cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); uint64_t al0 = h0[0] ^ h0[4]; uint64_t al1 = h1[0] ^ h1[4]; @@ -446,6 +541,15 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si al0 ^= cl; idx0 = al0; + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + int64_t n = ((int64_t*)&l0[idx0 & MASK])[0]; + int32_t d = ((int32_t*)&l0[idx0 & MASK])[2]; + int64_t q = n / (d | 0x5); + + ((int64_t*)&l0[idx0 & MASK])[0] = n ^ q; + idx0 = d ^ q; + } + cl = ((uint64_t*) &l1[idx1 & MASK])[0]; ch = ((uint64_t*) &l1[idx1 & MASK])[1]; lo = __umul128(idx1, cl, &hi); @@ -461,10 +565,19 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si ah1 ^= ch; al1 ^= cl; idx1 = al1; + + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + int64_t n = ((int64_t*)&l1[idx1 & MASK])[0]; + int32_t d = ((int32_t*)&l1[idx1 & MASK])[2]; + int64_t q = n / (d | 0x5); + + ((int64_t*)&l1[idx1 & MASK])[0] = n ^ q; + idx1 = d ^ q; + } } - cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); - cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); + cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); + cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); keccakf(h0, 24); keccakf(h1, 24); diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 49503820..6e7da0c4 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -64,6 +64,10 @@ DonateStrategy::DonateStrategy(int level, const char *user, int algo, IStrategyL m_pools.push_back(new Url(kDonatePool1, 80, userId, nullptr, false, true)); m_pools.push_back(new Url(kDonatePool2, 5555, "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD", "emergency", false, false)); } + else if (algo == xmrig::CRYPTONIGHT_HEAVY) { + m_pools.push_back(new Url(kDonatePool1, 8888, userId, nullptr, false, true)); + m_pools.push_back(new Url(kDonatePool1, 8889, userId, nullptr, false, true)); + } else { m_pools.push_back(new Url(kDonatePool1, 5555, userId, nullptr, false, true)); m_pools.push_back(new Url(kDonatePool1, 7777, userId, nullptr, false, true)); diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index 425dd0c2..273f1555 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -144,7 +144,7 @@ bool DoubleWorker::selfTest() } # endif - return false; + return true; } From d4123b8fa67d8e7709c1caa18b626a0ddf8db9c0 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 3 Apr 2018 17:06:03 +0700 Subject: [PATCH 020/109] Quick fix, temporary use old style affinity. --- src/workers/Handle.cpp | 3 ++- src/workers/Handle.h | 4 +++- src/workers/Worker.cpp | 6 +++--- src/workers/Workers.cpp | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp index 29f57fb2..01d032e9 100644 --- a/src/workers/Handle.cpp +++ b/src/workers/Handle.cpp @@ -25,7 +25,8 @@ #include "workers/Handle.h" -Handle::Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays) : +Handle::Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays, int64_t affinity) : + m_affinity(affinity), m_worker(nullptr), m_totalThreads(totalThreads), m_totalWays(totalWays), diff --git a/src/workers/Handle.h b/src/workers/Handle.h index b3a7c76f..8a64922a 100644 --- a/src/workers/Handle.h +++ b/src/workers/Handle.h @@ -38,10 +38,11 @@ class IWorker; class Handle { public: - Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays); + Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays, int64_t affinity); void join(); void start(void (*callback) (void *)); + inline int64_t affinity() const { return m_affinity; } inline IWorker *worker() const { return m_worker; } inline size_t threadId() const { return m_config->index(); } inline size_t totalThreads() const { return m_totalThreads; } @@ -50,6 +51,7 @@ public: inline xmrig::IThread *config() const { return m_config; } private: + int64_t m_affinity; IWorker *m_worker; size_t m_totalThreads; size_t m_totalWays; diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index bf4f62da..f9162e3f 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -42,9 +42,9 @@ Worker::Worker(Handle *handle) : m_sequence(0), m_thread(static_cast(handle->config())) { -// if (Cpu::threads() > 1 && handle->affinity() != -1L) { -// Cpu::setAffinity(m_id, handle->affinity()); -// } + if (Cpu::threads() > 1 && handle->affinity() != -1L) { + Cpu::setAffinity(m_id, handle->affinity()); + } Platform::setThreadPriority(handle->config()->priority()); m_ctx = Mem::create(m_id); diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 00941c7b..38965d8a 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -130,7 +130,7 @@ void Workers::start(xmrig::Controller *controller) uv_timer_start(&m_timer, Workers::onTick, 500, 500); for (xmrig::IThread *thread : threads) { - Handle *handle = new Handle(thread, threads.size(), totalWays); + Handle *handle = new Handle(thread, threads.size(), totalWays, controller->config()->affinity()); m_workers.push_back(handle); handle->start(Workers::onReady); } From 26e1b1402024c673ad689d0e60221a39e6b45256 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 3 Apr 2018 17:19:01 +0700 Subject: [PATCH 021/109] Added test hashes for self test. --- src/crypto/CryptoNight_test.h | 12 +++++++++++- src/workers/DoubleWorker.cpp | 2 +- src/workers/SingleWorker.cpp | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/crypto/CryptoNight_test.h b/src/crypto/CryptoNight_test.h index 0f7feda1..5717f1d3 100644 --- a/src/crypto/CryptoNight_test.h +++ b/src/crypto/CryptoNight_test.h @@ -66,7 +66,7 @@ const static uint8_t test_output_v0_lite[64] = { }; -// AEON v2 +// AEON v7 const static uint8_t test_output_v1_lite[64] = { 0x87, 0xC4, 0xE5, 0x70, 0x65, 0x3E, 0xB4, 0xC2, 0xB4, 0x2B, 0x7A, 0x0D, 0x54, 0x65, 0x59, 0x45, 0x2D, 0xFA, 0xB5, 0x73, 0xB8, 0x2E, 0xC5, 0x2F, 0x15, 0x2B, 0x7F, 0xF9, 0x8E, 0x79, 0x44, 0x6F, @@ -76,4 +76,14 @@ const static uint8_t test_output_v1_lite[64] = { #endif +#ifndef XMRIG_NO_SUMO +const static uint8_t test_output_heavy[64] = { + 0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A, + 0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D, + 0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64, + 0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2 +}; +#endif + + #endif /* __CRYPTONIGHT_TEST_H__ */ diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index 273f1555..a6176743 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -144,7 +144,7 @@ bool DoubleWorker::selfTest() } # endif - return true; + return memcmp(m_hash, test_output_heavy, 64) == 0; } diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index 5757ef77..2d428fcb 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -116,7 +116,7 @@ bool SingleWorker::selfTest() } # endif - return true; + return memcmp(m_result.result, test_output_heavy, 32) == 0; } From 4e8ef7c6ed05eb778ce6799ed674c1429659e9d7 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 3 Apr 2018 17:51:06 +0700 Subject: [PATCH 022/109] Added cryptonight-heavy support for ARM --- src/Cpu_arm.cpp | 2 +- src/crypto/CryptoNight_arm.h | 211 +++++++++++++++++++++++++++++++++-- 2 files changed, 202 insertions(+), 11 deletions(-) diff --git a/src/Cpu_arm.cpp b/src/Cpu_arm.cpp index c2047ffb..1b306789 100644 --- a/src/Cpu_arm.cpp +++ b/src/Cpu_arm.cpp @@ -37,7 +37,7 @@ int Cpu::m_totalCores = 0; int Cpu::m_totalThreads = 0; -int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage) +int Cpu::optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage) { return m_totalThreads; } diff --git a/src/crypto/CryptoNight_arm.h b/src/crypto/CryptoNight_arm.h index 18408536..fd8b58ff 100644 --- a/src/crypto/CryptoNight_arm.h +++ b/src/crypto/CryptoNight_arm.h @@ -35,6 +35,7 @@ #include "crypto/CryptoNight.h" +#include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_monero.h" #include "crypto/soft_aes.h" @@ -206,7 +207,21 @@ static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, } -template +inline void mix_and_propagate(__m128i& x0, __m128i& x1, __m128i& x2, __m128i& x3, __m128i& x4, __m128i& x5, __m128i& x6, __m128i& x7) +{ + __m128i tmp0 = x0; + x0 = _mm_xor_si128(x0, x1); + x1 = _mm_xor_si128(x1, x2); + x2 = _mm_xor_si128(x2, x3); + x3 = _mm_xor_si128(x3, x4); + x4 = _mm_xor_si128(x4, x5); + x5 = _mm_xor_si128(x5, x6); + x6 = _mm_xor_si128(x6, x7); + x7 = _mm_xor_si128(x7, tmp0); +} + + +template static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) { __m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7; @@ -223,6 +238,40 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) xin6 = _mm_load_si128(input + 10); xin7 = _mm_load_si128(input + 11); + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + for (size_t i = 0; i < 16; i++) { + if (!SOFT_AES) { + aes_round(_mm_setzero_si128(), &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + } + + aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k3, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k4, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k5, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + aes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + + if (!SOFT_AES) { + xin0 ^= k9; + xin1 ^= k9; + xin2 ^= k9; + xin3 ^= k9; + xin4 ^= k9; + xin5 ^= k9; + xin6 ^= k9; + xin7 ^= k9; + } + else { + aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); + } + + mix_and_propagate(xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7); + } + } + for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) { if (!SOFT_AES) { aes_round(_mm_setzero_si128(), &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); @@ -264,7 +313,7 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) } -template +template static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) { __m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7; @@ -319,6 +368,85 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) else { aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); } + + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7); + } + } + + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) { + xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0); + xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1); + xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2); + xout3 = _mm_xor_si128(_mm_load_si128(input + i + 3), xout3); + xout4 = _mm_xor_si128(_mm_load_si128(input + i + 4), xout4); + xout5 = _mm_xor_si128(_mm_load_si128(input + i + 5), xout5); + xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6); + xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7); + + if (!SOFT_AES) { + aes_round(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + } + + aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + + if (!SOFT_AES) { + xout0 ^= k9; + xout1 ^= k9; + xout2 ^= k9; + xout3 ^= k9; + xout4 ^= k9; + xout5 ^= k9; + xout6 ^= k9; + xout7 ^= k9; + } + else { + aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + } + + mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7); + } + + for (size_t i = 0; i < 16; i++) { + if (!SOFT_AES) { + aes_round(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + } + + aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k3, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k4, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k5, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + + if (!SOFT_AES) { + xout0 ^= k9; + xout1 ^= k9; + xout2 ^= k9; + xout3 ^= k9; + xout4 ^= k9; + xout5 ^= k9; + xout6 ^= k9; + xout7 ^= k9; + } + else { + aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); + } + + mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7); + } } _mm_store_si128(output + 4, xout0); @@ -332,14 +460,23 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) } -template +template inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx *__restrict__ ctx) { + constexpr size_t MASK = xmrig::cn_select_mask(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t MEM = xmrig::cn_select_memory(); + + if (VARIANT > 0 && size < 43) { + memset(output, 0, 32); + return; + } + keccak(input, (int) size, ctx->state0, 200); VARIANT1_INIT(0); - cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); + cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); const uint8_t* l0 = ctx->memory; uint64_t* h0 = reinterpret_cast(ctx->state0); @@ -384,18 +521,36 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si ah0 ^= ch; al0 ^= cl; idx0 = al0; + + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + int64_t n = ((int64_t*)&l0[idx0 & MASK])[0]; + int32_t d = ((int32_t*)&l0[idx0 & MASK])[2]; + int64_t q = n / (d | 0x5); + + ((int64_t*)&l0[idx0 & MASK])[0] = n ^ q; + idx0 = d ^ q; + } } - cn_implode_scratchpad((__m128i*) ctx->memory, (__m128i*) ctx->state0); + cn_implode_scratchpad((__m128i*) ctx->memory, (__m128i*) ctx->state0); keccakf(h0, 24); extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); } -template +template inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) { + constexpr size_t MASK = xmrig::cn_select_mask(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t MEM = xmrig::cn_select_memory(); + + if (VARIANT > 0 && size < 43) { + memset(output, 0, 64); + return; + } + keccak(input, (int) size, ctx->state0, 200); keccak(input + size, (int) size, ctx->state1, 200); @@ -407,8 +562,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si uint64_t* h0 = reinterpret_cast(ctx->state0); uint64_t* h1 = reinterpret_cast(ctx->state1); - cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); - cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); + cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); + cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); uint64_t al0 = h0[0] ^ h0[4]; uint64_t al1 = h1[0] ^ h1[4]; @@ -465,6 +620,15 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si al0 ^= cl; idx0 = al0; + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + int64_t n = ((int64_t*)&l0[idx0 & MASK])[0]; + int32_t d = ((int32_t*)&l0[idx0 & MASK])[2]; + int64_t q = n / (d | 0x5); + + ((int64_t*)&l0[idx0 & MASK])[0] = n ^ q; + idx0 = d ^ q; + } + cl = ((uint64_t*) &l1[idx1 & MASK])[0]; ch = ((uint64_t*) &l1[idx1 & MASK])[1]; lo = __umul128(idx1, cl, &hi); @@ -480,10 +644,19 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si ah1 ^= ch; al1 ^= cl; idx1 = al1; + + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + int64_t n = ((int64_t*)&l1[idx1 & MASK])[0]; + int32_t d = ((int32_t*)&l1[idx1 & MASK])[2]; + int64_t q = n / (d | 0x5); + + ((int64_t*)&l1[idx1 & MASK])[0] = n ^ q; + idx1 = d ^ q; + } } - cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); - cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); + cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); + cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); keccakf(h0, 24); keccakf(h1, 24); @@ -492,4 +665,22 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, output + 32); } + +template +inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +{ +} + + +template +inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +{ +} + + +template +inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +{ +} + #endif /* __CRYPTONIGHT_ARM_H__ */ From 6b710ff3b31e82f46995c83ce12a57793067b3e7 Mon Sep 17 00:00:00 2001 From: xmrig Date: Tue, 3 Apr 2018 18:12:24 +0700 Subject: [PATCH 023/109] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9f42d66..397d3b62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,10 @@ # v2.6.0-beta1 + - [#476](https://github.com/xmrig/xmrig/issues/476) **Added Cryptonight-Heavy support for Sumokoin ASIC resistance fork.** - HTTP server now runs in main loop, it make possible easy extend API without worry about thread synchronization. - Added initial graceful reload support, miner will reload configuration if config file changed, disabled by default until it will be fully implemented and tested. - Added API endpoint `PUT /1/config` to update current config. - Added API endpoint `GET /1/config` to get current active config. + - Added API endpoint `GET /1/threads` to get current active threads configuration. - API endpoint `GET /` now deprecated, use `GET /1/summary` instead. - Added `--api-no-ipv6` and similar config option to disable IPv6 support for HTTP API. - Added `--api-no-restricted` to enable full access to api, this option has no effect if `--api-access-token` not specified. From 6a1c52b904f00e33570fb034134ba529f168108e Mon Sep 17 00:00:00 2001 From: xmrig Date: Tue, 3 Apr 2018 19:02:12 +0700 Subject: [PATCH 024/109] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 962408e9..3cf26d17 100644 --- a/README.md +++ b/README.md @@ -124,10 +124,10 @@ Please note performance is highly dependent on system load. The numbers above ar ## Release checksums ### SHA-256 ``` -b070d06a3615f3db67ad3beab43d6d21f3c88026aa2b4726a93df47145cd30ec xmrig-2.5.2-xenial-amd64.tar.gz/xmrig-2.5.2/xmrig -4852135d3f04fd450ba39abce51ca40ff9131d222220c8b30804be05f6679295 xmrig-2.5.2-gcc-win32.zip/xmrig.exe -284309d07f08261af19c937ece6d2031910d9124a7359c207ded65890b2d7c5f xmrig-2.5.2-gcc-win64.zip/xmrig.exe -e1dc46158a578fb030538fb06e5663a6acc5763545fb447a00ce0a6b388c5226 xmrig-2.5.2-msvc-win64.zip/xmrig.exe +bd14bc3cfd9528e4a7583ab39aecc876250333e1e0faab83781584bb7f65e3eb xmrig-2.6.0-beta1-xenial-amd64.tar.gz/xmrig-2.6.0-beta1/xmrig +32eebf71e5631029202ae5cbf6f03caad912f1722aa86a1be01a26d491801aba xmrig-2.6.0-beta1-gcc-win32.zip/xmrig.exe +1cc08844ff019408e2e2c9560fee0c4e0b2dbc2a72bcc1c1da4a847a1787eca3 xmrig-2.6.0-beta1-gcc-win64.zip/xmrig.exe +fdf99aa8e7792a34b1be0cc6c77e4e83ff9a4b21abb27989f7927dcfed82f6e2 xmrig-2.6.0-beta1-msvc-win64.zip/xmrig.exe ``` ## Contacts From c227e3c7b42d5371b12fa93fb3e2484e46f02638 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 4 Apr 2018 00:10:53 +0700 Subject: [PATCH 025/109] Fix command line option --donate-level. --- src/core/CommonConfig.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp index 6a2c76ac..e4e03b1e 100644 --- a/src/core/CommonConfig.cpp +++ b/src/core/CommonConfig.cpp @@ -233,6 +233,7 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) case VariantKey: /* --variant */ case ApiPort: /* --api-port */ case PrintTimeKey: /* --cpu-priority */ + case DonateLevelKey: /* --donate-level */ return parseUint64(key, strtol(arg, nullptr, 10)); case BackgroundKey: /* --background */ @@ -248,7 +249,7 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) return parseBoolean(key, false); # ifdef XMRIG_PROXY_PROJECT - case 1003: /* --donate-level */ + case DonateLevelKey: /* --donate-level */ if (strncmp(arg, "minemonero.pro", 14) == 0) { m_donateLevel = 0; } From 3a67ee6d11448b8c046a373ae874461798d96a63 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 6 Apr 2018 23:32:54 +0700 Subject: [PATCH 026/109] Small fixes. --- src/core/CommonConfig.cpp | 17 ++++++++++------- src/crypto/CryptoNight_constants.h | 6 ++++++ src/workers/SingleWorker.cpp | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp index e4e03b1e..cf18d896 100644 --- a/src/core/CommonConfig.cpp +++ b/src/core/CommonConfig.cpp @@ -58,7 +58,13 @@ xmrig::CommonConfig::CommonConfig() : m_background(false), m_colors(true), m_syslog(false), + +# ifdef XMRIG_PROXY_PROJECT + m_watch(true), +# else m_watch(false), // TODO: enable config file watch by default when this feature propertly handled and tested. +# endif + m_apiToken(nullptr), m_apiWorkerId(nullptr), m_fileName(nullptr), @@ -233,7 +239,6 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) case VariantKey: /* --variant */ case ApiPort: /* --api-port */ case PrintTimeKey: /* --cpu-priority */ - case DonateLevelKey: /* --donate-level */ return parseUint64(key, strtol(arg, nullptr, 10)); case BackgroundKey: /* --background */ @@ -248,16 +253,14 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) case ApiIPv6Key: /* --api-no-ipv6 */ return parseBoolean(key, false); -# ifdef XMRIG_PROXY_PROJECT case DonateLevelKey: /* --donate-level */ +# ifdef XMRIG_PROXY_PROJECT if (strncmp(arg, "minemonero.pro", 14) == 0) { m_donateLevel = 0; + return true; } - else { - parseUint64(key, strtol(arg, nullptr, 10)); - } - break; -# endif +# endif + return parseUint64(key, strtol(arg, nullptr, 10)); default: break; diff --git a/src/crypto/CryptoNight_constants.h b/src/crypto/CryptoNight_constants.h index 5d02baf9..d576b47a 100644 --- a/src/crypto/CryptoNight_constants.h +++ b/src/crypto/CryptoNight_constants.h @@ -66,6 +66,8 @@ inline size_t cn_select_memory(Algo algorithm) case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_MEMORY; } + + return 0; } @@ -87,6 +89,8 @@ inline uint32_t cn_select_mask(Algo algorithm) case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_MASK; } + + return 0; } @@ -108,6 +112,8 @@ inline uint32_t cn_select_iter(Algo algorithm) case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_ITER; } + + return 0; } diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index 2d428fcb..ca6b93a6 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -116,7 +116,7 @@ bool SingleWorker::selfTest() } # endif - return memcmp(m_result.result, test_output_heavy, 32) == 0; + return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_result.result, test_output_heavy, 32) == 0; } From ae647699a4780af83b7c9cec22ee23e7facb056c Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 7 Apr 2018 00:44:48 +0700 Subject: [PATCH 027/109] #502 Fixed build without libmicrohttpd. --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 106ab30f..43a7c1d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,6 @@ include (cmake/cpu.cmake) set(HEADERS - src/api/Api.h src/api/NetworkState.h src/App.h src/Console.h @@ -87,7 +86,6 @@ else() endif() set(SOURCES - src/api/Api.cpp src/api/NetworkState.cpp src/App.cpp src/Console.cpp @@ -214,11 +212,13 @@ if (WITH_HTTPD) if (MHD_FOUND) include_directories(${MHD_INCLUDE_DIRS}) set(HTTPD_SOURCES + src/api/Api.h src/api/ApiRouter.h src/api/HttpBody.h src/api/Httpd.h src/api/HttpReply.h src/api/HttpRequest.h + src/api/Api.cpp src/api/ApiRouter.cpp src/api/Httpd.cpp src/api/HttpRequest.cpp From bca087f1110ac3977ad42f8616ffa49a45f9bfb2 Mon Sep 17 00:00:00 2001 From: xmrig Date: Sat, 7 Apr 2018 00:50:24 +0700 Subject: [PATCH 028/109] Update CHANGELOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 397d3b62..4f0d5a98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v2.6.0-beta2 +- Fixed regressions (v2.6.0-beta1 affected) + - [#494](https://github.com/xmrig/xmrig/issues/494) Command line option `--donate-level` was broken. + - [#502](https://github.com/xmrig/xmrig/issues/502) Build without libmicrohttpd was broken. + # v2.6.0-beta1 - [#476](https://github.com/xmrig/xmrig/issues/476) **Added Cryptonight-Heavy support for Sumokoin ASIC resistance fork.** - HTTP server now runs in main loop, it make possible easy extend API without worry about thread synchronization. From 3b83fa530c6119b15aba964e8b97a52ad72dae4e Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 7 Apr 2018 01:17:58 +0700 Subject: [PATCH 029/109] #499 Disabled IPv6 for internal HTTP API by default, was cause issues on some systems. --- src/config.json | 4 +++- src/core/CommonConfig.cpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/config.json b/src/config.json index 858435d2..3013ba62 100644 --- a/src/config.json +++ b/src/config.json @@ -27,6 +27,8 @@ "api": { "port": 0, // port for the miner API https://github.com/xmrig/xmrig/wiki/API "access-token": null, // access token for API - "worker-id": null // custom worker-id for API + "worker-id": null, // custom worker-id for API + "ipv6": false, + "restricted": true } } \ No newline at end of file diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp index cf18d896..8d2eb03a 100644 --- a/src/core/CommonConfig.cpp +++ b/src/core/CommonConfig.cpp @@ -53,7 +53,7 @@ static const char *algoNames[] = { xmrig::CommonConfig::CommonConfig() : m_algorithm(CRYPTONIGHT), m_adjusted(false), - m_apiIPv6(true), + m_apiIPv6(false), m_apiRestricted(true), m_background(false), m_colors(true), From 89c095f79e0fa48a6c1b77beb3fc80297b6324d4 Mon Sep 17 00:00:00 2001 From: xmrig Date: Sat, 7 Apr 2018 01:21:56 +0700 Subject: [PATCH 030/109] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f0d5a98..c67b8a20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ # v2.6.0-beta2 +- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 disabled for internal HTTP API by default, was cause issues on some systems. - Fixed regressions (v2.6.0-beta1 affected) - [#494](https://github.com/xmrig/xmrig/issues/494) Command line option `--donate-level` was broken. - [#502](https://github.com/xmrig/xmrig/issues/502) Build without libmicrohttpd was broken. From bb2faaddc062449cc5d4f1d4db4e388cba83b828 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 8 Apr 2018 02:44:31 +0700 Subject: [PATCH 031/109] Added short aliases for algorithm names: cn, cn-lite and cn-heavy. --- CHANGELOG.md | 1 + src/core/CommonConfig.cpp | 21 +++++++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c67b8a20..bcaf27c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # v2.6.0-beta2 - [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 disabled for internal HTTP API by default, was cause issues on some systems. +- Added short aliases for algorithm names: `cn`, `cn-lite` and `cn-heavy`. - Fixed regressions (v2.6.0-beta1 affected) - [#494](https://github.com/xmrig/xmrig/issues/494) Command line option `--donate-level` was broken. - [#502](https://github.com/xmrig/xmrig/issues/502) Build without libmicrohttpd was broken. diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp index 8d2eb03a..8950775c 100644 --- a/src/core/CommonConfig.cpp +++ b/src/core/CommonConfig.cpp @@ -22,6 +22,7 @@ */ +#include #include #include #include @@ -45,6 +46,13 @@ static const char *algoNames[] = { }; +static const char *algoNamesShort[] = { + "cn", + "cn-lite", + "cn-heavy" +}; + + #if defined(_WIN32) && !defined(strcasecmp) # define strcasecmp _stricmp #endif @@ -375,12 +383,21 @@ void xmrig::CommonConfig::setAlgo(const char *algo) return; } - const size_t size = sizeof(algoNames) / sizeof((algoNames)[0]); + const size_t size = sizeof(algoNames) / sizeof(algoNames[0]); + + assert(size == (sizeof(algoNamesShort) / sizeof(algoNamesShort[0]))); for (size_t i = 0; i < size; i++) { if (algoNames[i] && strcasecmp(algo, algoNames[i]) == 0) { m_algorithm = static_cast(i); - break; + return; + } + } + + for (size_t i = 0; i < size; i++) { + if (algoNamesShort[i] && strcasecmp(algo, algoNamesShort[i]) == 0) { + m_algorithm = static_cast(i); + return; } } } From eb56c2b56eb799097629dfd2f360a9138865db8d Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 8 Apr 2018 03:20:44 +0700 Subject: [PATCH 032/109] Better implementation for algorithm aliases. --- src/core/CommonConfig.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp index 8950775c..a36b6553 100644 --- a/src/core/CommonConfig.cpp +++ b/src/core/CommonConfig.cpp @@ -388,16 +388,9 @@ void xmrig::CommonConfig::setAlgo(const char *algo) assert(size == (sizeof(algoNamesShort) / sizeof(algoNamesShort[0]))); for (size_t i = 0; i < size; i++) { - if (algoNames[i] && strcasecmp(algo, algoNames[i]) == 0) { + if (strcasecmp(algo, algoNames[i]) == 0 || strcasecmp(algo, algoNamesShort[i]) == 0) { m_algorithm = static_cast(i); - return; - } - } - - for (size_t i = 0; i < size; i++) { - if (algoNamesShort[i] && strcasecmp(algo, algoNamesShort[i]) == 0) { - m_algorithm = static_cast(i); - return; + break; } } } From de83cfd53c1da14ac80a91d9d130ef140b762747 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 8 Apr 2018 22:19:21 +0700 Subject: [PATCH 033/109] #519 Fix donation start time randomization. --- src/core/CommonConfig.cpp | 2 +- src/donate.h | 13 +++++++++---- src/net/strategies/DonateStrategy.cpp | 6 +++--- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp index a36b6553..5b8a32ab 100644 --- a/src/core/CommonConfig.cpp +++ b/src/core/CommonConfig.cpp @@ -349,7 +349,7 @@ bool xmrig::CommonConfig::parseInt(int key, int arg) break; case DonateLevelKey: /* --donate-level */ - if (arg >= kMinDonateLevel && arg <= 99) { + if (arg >= kMinimumDonateLevel && arg <= 99) { m_donateLevel = arg; } break; diff --git a/src/donate.h b/src/donate.h index bdf7a00d..46f26b73 100644 --- a/src/donate.h +++ b/src/donate.h @@ -29,9 +29,14 @@ * Dev donation. * * Percentage of your hashing power that you want to donate to the developer, can be 0 if you don't want to do that. - * Example of how it works for the default setting of 1: - * You miner will mine into your usual pool for 99 minutes, then switch to the developer's pool for 1 minute. - * Since v2.5.1 start time randomized in range from 50 to 150 minutes minus donation time. + * + * Example of how it works for the setting of 1%: + * You miner will mine into your usual pool for random time (in range from 49.5 to 148.5 minutes), + * then switch to the developer's pool for 1 minute, then switch again to your pool for 99 minutes + * and then switch agaiin to developer's pool for 1 minute, these rounds will continue until miner working. + * + * Randomised only first round, to prevent waves on the donation pool. + * * Switching is instant, and only happens after a successful connection, so you never loose any hashes. * * If you plan on changing this setting to 0 please consider making a one off donation to my wallet: @@ -39,7 +44,7 @@ * BTC: 1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT */ constexpr const int kDefaultDonateLevel = 5; -constexpr const int kMinDonateLevel = 1; +constexpr const int kMinimumDonateLevel = 1; #endif /* __DONATE_H__ */ diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 6e7da0c4..f0ec5bde 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -41,8 +41,8 @@ const static char *kDonatePool1 = "miner.fee.xmrig.com"; const static char *kDonatePool2 = "emergency.fee.xmrig.com"; -static inline int random(int min, int max){ - return min + rand() / (RAND_MAX / (max - min + 1) + 1); +static inline float randomf(float min, float max) { + return (max - min) * ((((float) rand()) / (float) RAND_MAX)) + min; } @@ -78,7 +78,7 @@ DonateStrategy::DonateStrategy(int level, const char *user, int algo, IStrategyL m_timer.data = this; uv_timer_init(uv_default_loop(), &m_timer); - idle(random(3000, 9000) * 1000 - m_donateTime); + idle(m_idleTime * randomf(0.5, 1.5)); } From 77207eaaae32922462fcfa788f39176a405b1437 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 9 Apr 2018 20:38:02 +0700 Subject: [PATCH 034/109] Fix build with APP_DEBUG. --- src/Summary.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Summary.cpp b/src/Summary.cpp index 7e341ce0..56f3f522 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -123,7 +123,7 @@ static void print_pools(xmrig::Config *config) # ifdef APP_DEBUG for (size_t i = 0; i < pools.size(); ++i) { - Log::i()->text("%s:%d, user: %s, pass: %s, ka: %d, nicehash: %d", pools[i]->host(), pools[i]->port(), pools[i]->user(), pools[i]->password(), pools[i]->isKeepAlive(), pools[i]->isNicehash()); + Log::i()->text("%s:%d, user: %s, pass: %s, ka: %d, nicehash: %d", pools[i]->host(), pools[i]->port(), pools[i]->user(), pools[i]->password(), pools[i]->keepAlive(), pools[i]->isNicehash()); } # endif } From 5b664f368159624d3843ab4df718ec7b3e9c6b59 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 9 Apr 2018 21:21:46 +0700 Subject: [PATCH 035/109] Fix nonce calculation for --av 4. --- src/workers/CpuThread.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index b8be966f..7e68a990 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -146,28 +146,28 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A softAES = true; break; - case AV_DOUBLE: - multiway = DoubleWay; case AV_DOUBLE_SOFT: softAES = true; + case AV_DOUBLE: + multiway = DoubleWay; break; - case AV_TRIPLE: - multiway = TripleWay; case AV_TRIPLE_SOFT: softAES = true; + case AV_TRIPLE: + multiway = TripleWay; break; - case AV_QUAD: - multiway = QuadWay; case AV_QUAD_SOFT: softAES = true; + case AV_QUAD: + multiway = QuadWay; break; - case AV_PENTA: - multiway = PentaWay; case AV_PENTA_SOFT: softAES = true; + case AV_PENTA: + multiway = PentaWay; break; default: From ccbb78d4e989f18e1d89931cc6ba01a851fdb8a9 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 9 Apr 2018 21:56:15 +0700 Subject: [PATCH 036/109] Improved performance for cryptonight v7. --- CHANGELOG.md | 4 +++- src/crypto/CryptoNight_x86.h | 38 +++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bcaf27c7..95575c3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,11 @@ # v2.6.0-beta2 +- Improved performance for `cryptonight v7` especially in double hash mode. - [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 disabled for internal HTTP API by default, was cause issues on some systems. - Added short aliases for algorithm names: `cn`, `cn-lite` and `cn-heavy`. - Fixed regressions (v2.6.0-beta1 affected) - [#494](https://github.com/xmrig/xmrig/issues/494) Command line option `--donate-level` was broken. - - [#502](https://github.com/xmrig/xmrig/issues/502) Build without libmicrohttpd was broken. + - [#502](https://github.com/xmrig/xmrig/issues/502) Build without libmicrohttpd was broken. + - Fixed nonce calculation for `--av 4` (software AES, double hash) was cause reduction of effective hashrate and rejected shares on nicehash. # v2.6.0-beta1 - [#476](https://github.com/xmrig/xmrig/issues/476) **Added Cryptonight-Heavy support for Sumokoin ASIC resistance fork.** diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index 414a1f7f..417404a6 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -386,6 +386,22 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) } +static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp) +{ + mem_out[0] = EXTRACT64(tmp); + + tmp = _mm_castps_si128(_mm_movehl_ps(_mm_castsi128_ps(tmp), _mm_castsi128_ps(tmp))); + uint64_t vh = EXTRACT64(tmp); + + uint8_t x = vh >> 24; + static const uint16_t table = 0x7531; + const uint8_t index = (((x >> 3) & 6) | (x & 1)) << 1; + vh ^= ((table >> index) & 0x3) << 28; + + mem_out[1] = vh; +} + + template inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx *__restrict__ ctx) { @@ -400,7 +416,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si keccak(input, (int) size, ctx->state0, 200); - VARIANT1_INIT(0); + VARIANT1_INIT(0) cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); @@ -423,8 +439,13 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0)); } - _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); - VARIANT1_1(&l0[idx0 & MASK]); + + if (VARIANT > 0) { + cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); + } else { + _mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); + } + idx0 = EXTRACT64(cx); bx0 = cx; @@ -513,10 +534,13 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1)); } - _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); - _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); - VARIANT1_1(&l0[idx0 & MASK]); - VARIANT1_1(&l1[idx1 & MASK]); + if (VARIANT > 0) { + cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); + cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); + } else { + _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); + _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); + } idx0 = EXTRACT64(cx0); idx1 = EXTRACT64(cx1); From 82e1138158e793df1cddec701ca63db0057cfdf2 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 9 Apr 2018 23:50:01 +0700 Subject: [PATCH 037/109] v2.6.0-beta2 --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index db7c2013..4ea70a57 100644 --- a/src/version.h +++ b/src/version.h @@ -27,7 +27,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig CPU miner" -#define APP_VERSION "2.6.0-beta1" +#define APP_VERSION "2.6.0-beta2" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com" @@ -36,7 +36,7 @@ #define APP_VER_MAJOR 2 #define APP_VER_MINOR 6 #define APP_VER_BUILD 0 -#define APP_VER_REV 1 +#define APP_VER_REV 2 #ifdef _MSC_VER # if (_MSC_VER >= 1910) From 30903686bd67f7843bec84bd99f7a56c902f206f Mon Sep 17 00:00:00 2001 From: xmrig Date: Tue, 10 Apr 2018 00:30:06 +0700 Subject: [PATCH 038/109] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3cf26d17..010a03fc 100644 --- a/README.md +++ b/README.md @@ -124,10 +124,10 @@ Please note performance is highly dependent on system load. The numbers above ar ## Release checksums ### SHA-256 ``` -bd14bc3cfd9528e4a7583ab39aecc876250333e1e0faab83781584bb7f65e3eb xmrig-2.6.0-beta1-xenial-amd64.tar.gz/xmrig-2.6.0-beta1/xmrig -32eebf71e5631029202ae5cbf6f03caad912f1722aa86a1be01a26d491801aba xmrig-2.6.0-beta1-gcc-win32.zip/xmrig.exe -1cc08844ff019408e2e2c9560fee0c4e0b2dbc2a72bcc1c1da4a847a1787eca3 xmrig-2.6.0-beta1-gcc-win64.zip/xmrig.exe -fdf99aa8e7792a34b1be0cc6c77e4e83ff9a4b21abb27989f7927dcfed82f6e2 xmrig-2.6.0-beta1-msvc-win64.zip/xmrig.exe +232af0c5f3b1cdbc2d90b514873a764b434d5621d2790da67954b35c17e44fe3 xmrig-2.6.0-beta2-xenial-amd64.tar.gz/xmrig-2.6.0-beta2/xmrig +2366a06729d4de538ef511862bf11d0c7ad40fd245e7aeab3c1957307d63471a xmrig-2.6.0-beta2-gcc-win32.zip/xmrig.exe +2f6538c765e001d13ca380cbc1558d51efcb97d4bccdfa40993cb872be4e9efd xmrig-2.6.0-beta2-gcc-win64.zip/xmrig.exe +3c0479acb78a3cee8fe416ee438dbff09c786acf50fbaf28a820127fcd0c6e62 xmrig-2.6.0-beta2-msvc-win64.zip/xmrig.exe ``` ## Contacts From 916ff330589bf61d324a6b6bc99978676506ac81 Mon Sep 17 00:00:00 2001 From: xmrig Date: Tue, 10 Apr 2018 03:56:19 +0700 Subject: [PATCH 039/109] Update CHANGELOG.md --- CHANGELOG.md | 310 +++++++++++++++++++++++++-------------------------- 1 file changed, 155 insertions(+), 155 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95575c3d..71d4e5b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,156 +1,156 @@ -# v2.6.0-beta2 -- Improved performance for `cryptonight v7` especially in double hash mode. -- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 disabled for internal HTTP API by default, was cause issues on some systems. -- Added short aliases for algorithm names: `cn`, `cn-lite` and `cn-heavy`. -- Fixed regressions (v2.6.0-beta1 affected) - - [#494](https://github.com/xmrig/xmrig/issues/494) Command line option `--donate-level` was broken. +# v2.6.0-beta2 +- Improved performance for `cryptonight v7` especially in double hash mode. +- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 disabled for internal HTTP API by default, was causing issues on some systems. +- Added short aliases for algorithm names: `cn`, `cn-lite` and `cn-heavy`. +- Fixed regressions (v2.6.0-beta1 affected) + - [#494](https://github.com/xmrig/xmrig/issues/494) Command line option `--donate-level` was broken. - [#502](https://github.com/xmrig/xmrig/issues/502) Build without libmicrohttpd was broken. - - Fixed nonce calculation for `--av 4` (software AES, double hash) was cause reduction of effective hashrate and rejected shares on nicehash. - -# v2.6.0-beta1 - - [#476](https://github.com/xmrig/xmrig/issues/476) **Added Cryptonight-Heavy support for Sumokoin ASIC resistance fork.** - - HTTP server now runs in main loop, it make possible easy extend API without worry about thread synchronization. - - Added initial graceful reload support, miner will reload configuration if config file changed, disabled by default until it will be fully implemented and tested. - - Added API endpoint `PUT /1/config` to update current config. - - Added API endpoint `GET /1/config` to get current active config. - - Added API endpoint `GET /1/threads` to get current active threads configuration. - - API endpoint `GET /` now deprecated, use `GET /1/summary` instead. - - Added `--api-no-ipv6` and similar config option to disable IPv6 support for HTTP API. - - Added `--api-no-restricted` to enable full access to api, this option has no effect if `--api-access-token` not specified. - -# v2.5.2 -- [#448](https://github.com/xmrig/xmrig/issues/478) Fixed broken reconnect. - -# v2.5.1 -- [#454](https://github.com/xmrig/xmrig/issues/454) Fixed build with libmicrohttpd version below v0.9.35. -- [#456](https://github.com/xmrig/xmrig/issues/459) Verbose errors related to donation pool was not fully silenced. -- [#459](https://github.com/xmrig/xmrig/issues/459) Fixed regression (version 2.5.0 affected) with connection to **xmr.f2pool.com**. - -# v2.5.0 -- [#434](https://github.com/xmrig/xmrig/issues/434) **Added support for Monero v7 PoW, scheduled on April 6.** -- Added full IPv6 support. -- Added protocol extension, when use the miner with xmrig-proxy 2.5+ no more need manually specify `nicehash` option. -- [#123](https://github.com/xmrig/xmrig-proxy/issues/123) Fixed regression (all versions since 2.4 affected) fragmented responses from pool/proxy was parsed incorrectly. -- [#428](https://github.com/xmrig/xmrig/issues/428) Fixed regression (version 2.4.5 affected) with CPU cache size detection. - -# v2.4.5 -- [#324](https://github.com/xmrig/xmrig/pull/324) Fixed build without libmicrohttpd (CMake cache issue). -- [#341](https://github.com/xmrig/xmrig/issues/341) Fixed wrong exit code and added command line option `--dry-run`. -- [#385](https://github.com/xmrig/xmrig/pull/385) Up to 20% performance increase for non-AES CPU and fixed Intel Core 2 cache detection. - -# v2.4.4 - - Added libmicrohttpd version to --version output. - - Fixed bug in singal handler, in some cases miner wasn't shutdown properly. - - Fixed recent MSVC 2017 version detection. - - [#279](https://github.com/xmrig/xmrig/pull/279) Fixed build on some macOS versions. - -# v2.4.3 - - [#94](https://github.com/xmrig/xmrig/issues/94#issuecomment-342019257) [#216](https://github.com/xmrig/xmrig/issues/216) Added **ARMv8** and **ARMv7** support. Hardware AES supported, thanks [Imran Yusuff](https://github.com/imranyusuff). - - [#157](https://github.com/xmrig/xmrig/issues/157) [#196](https://github.com/xmrig/xmrig/issues/196) Fixed Linux compile issues. - - [#184](https://github.com/xmrig/xmrig/issues/184) Fixed cache size detection for CPUs with disabled Hyper-Threading. - - [#200](https://github.com/xmrig/xmrig/issues/200) In some cases miner was doesn't write log to stdout. - -# v2.4.2 - - [#60](https://github.com/xmrig/xmrig/issues/60) Added FreeBSD support, thanks [vcambur](https://github.com/vcambur). - - [#153](https://github.com/xmrig/xmrig/issues/153) Fixed issues with dwarfpool.com. - -# v2.4.1 - - [#147](https://github.com/xmrig/xmrig/issues/147) Fixed comparability with monero-stratum. - -# v2.4.0 - - Added [HTTP API](https://github.com/xmrig/xmrig/wiki/API). - - Added comments support in config file. - - libjansson replaced to rapidjson. - - [#98](https://github.com/xmrig/xmrig/issues/98) Ignore `keepalive` option with minergate.com and nicehash.com. - - [#101](https://github.com/xmrig/xmrig/issues/101) Fixed MSVC 2017 (15.3) compile time version detection. - - [#108](https://github.com/xmrig/xmrig/issues/108) Silently ignore invalid values for `donate-level` option. - - [#111](https://github.com/xmrig/xmrig/issues/111) Fixed build without AEON support. - -# v2.3.1 -- [#68](https://github.com/xmrig/xmrig/issues/68) Fixed compatibility with Docker containers, was nothing print on console. - -# v2.3.0 -- Added `--cpu-priority` option (0 idle, 2 normal to 5 highest). -- Added `--user-agent` option, to set custom user-agent string for pool. For example `cpuminer-multi/0.1`. -- Added `--no-huge-pages` option, to disable huge pages support. -- [#62](https://github.com/xmrig/xmrig/issues/62) Don't send the login to the dev pool. -- Force reconnect if pool block miner IP address. helps switch to backup pool. -- Fixed: failed open default config file if path contains non English characters. -- Fixed: error occurred if try use unavailable stdin or stdout, regression since version 2.2.0. -- Fixed: message about huge pages support successfully enabled on Windows was not shown in release builds. - -# v2.2.1 -- Fixed [terminal issues](https://github.com/xmrig/xmrig-proxy/issues/2#issuecomment-319914085) after exit on Linux and OS X. - -# v2.2.0 -- [#46](https://github.com/xmrig/xmrig/issues/46) Restored config file support. Now possible use multiple config files and combine with command line options also added support for default config. -- Improved colors support on Windows, now used uv_tty, legacy code removed. -- QuickEdit Mode now disabled on Windows. -- Added interactive commands in console window:: **h**ashrate, **p**ause, **r**esume. -- Fixed autoconf mode for AMD FX CPUs. - -# v2.1.0 -- [#40](https://github.com/xmrig/xmrig/issues/40) -Improved miner shutdown, fixed crash on exit for Linux and OS X. -- Fixed, login request was contain malformed JSON if username or password has some special characters for example `\`. -- [#220](https://github.com/fireice-uk/xmr-stak-cpu/pull/220) Better support for Round Robin DNS, IP address now always chosen randomly instead of stuck on first one. -- Changed donation address, new [xmrig-proxy](https://github.com/xmrig/xmrig-proxy) is coming soon. - -# v2.0.2 -- Better deal with possible duplicate jobs from pool, show warning and ignore duplicates. -- For Windows builds libuv updated to version 1.13.1 and gcc to 7.1.0. - -# v2.0.1 - - [#27](https://github.com/xmrig/xmrig/issues/27) Fixed possibility crash on 32bit systems. - -# v2.0.0 - - Option `--backup-url` removed, instead now possibility specify multiple pools for example: `-o example1.com:3333 -u user1 -p password1 -k -o example2.com:5555 -u user2 -o example3.com:4444 -u user3` - - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-l, --log-file=FILE` to write log to file. - - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-S, --syslog` to use syslog for logging, Linux only. - - [#18](https://github.com/xmrig/xmrig/issues/18) Added nice messages for accepted/rejected shares with diff and network latency. - - [#20](https://github.com/xmrig/xmrig/issues/20) Fixed `--cpu-affinity` for more than 32 threads. - - Fixed Windows XP support. - - Fixed regression, option `--no-color` was not fully disable colored output. - - Show resolved pool IP address in miner output. - -# v1.0.1 -- Fix broken software AES implementation, app has crashed if CPU not support AES-NI, only version 1.0.0 affected. - -# v1.0.0 -- Miner complete rewritten in C++ with libuv. -- This version should be fully compatible (except config file) with previos versions, many new nice features will come in next versions. -- This is still beta. If you found regression, stability or perfomance issues or have an idea for new feature please fell free to open new [issue](https://github.com/xmrig/xmrig/issues/new). -- Added new option `--print-time=N`, print hashrate report every N seconds. -- New hashrate reports, by default every 60 secons. -- Added Microsoft Visual C++ 2015 and 2017 support. -- Removed dependency on libcurl. -- To compile this version from source please switch to [dev](https://github.com/xmrig/xmrig/tree/dev) branch. - -# v0.8.2 -- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). - -# v0.8.2 -- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). -- Fixed gcc 7.1 support. - -# v0.8.1 -- Added nicehash support, detects automaticaly by pool URL, for example `cryptonight.eu.nicehash.com:3355` or manually via option `--nicehash`. - -# v0.8.0 -- Added double hash mode, also known as lower power mode. `--av=2` and `--av=4`. -- Added smart automatic CPU configuration. Default threads count now depends on size of the L3 cache of CPU. -- Added CryptoNight-Lite support for AEON `-a cryptonight-lite`. -- Added `--max-cpu-usage` option for auto CPU configuration mode. -- Added `--safe` option for adjust threads and algorithm variations to current CPU. -- No more manual steps to enable huge pages on Windows. XMRig will do it automatically. -- Removed BMI2 algorithm variation. -- Removed default pool URL. - -# v0.6.0 -- Added automatic cryptonight self test. -- New software AES algorithm variation. Will be automatically selected if cpu not support AES-NI. -- Added 32 bit builds. -- Documented [algorithm variations](https://github.com/xmrig/xmrig#algorithm-variations). - -# v0.5.0 -- Initial public release. + - Fixed nonce calculation for `--av 4` (software AES, double hash) was causing reduction of effective hashrate and rejected shares on nicehash. + +# v2.6.0-beta1 + - [#476](https://github.com/xmrig/xmrig/issues/476) **Added Cryptonight-Heavy support for Sumokoin ASIC resistance fork.** + - HTTP server now runs in main loop, it make possible easy extend API without worry about thread synchronization. + - Added initial graceful reload support, miner will reload configuration if config file changed, disabled by default until it will be fully implemented and tested. + - Added API endpoint `PUT /1/config` to update current config. + - Added API endpoint `GET /1/config` to get current active config. + - Added API endpoint `GET /1/threads` to get current active threads configuration. + - API endpoint `GET /` now deprecated, use `GET /1/summary` instead. + - Added `--api-no-ipv6` and similar config option to disable IPv6 support for HTTP API. + - Added `--api-no-restricted` to enable full access to api, this option has no effect if `--api-access-token` not specified. + +# v2.5.2 +- [#448](https://github.com/xmrig/xmrig/issues/478) Fixed broken reconnect. + +# v2.5.1 +- [#454](https://github.com/xmrig/xmrig/issues/454) Fixed build with libmicrohttpd version below v0.9.35. +- [#456](https://github.com/xmrig/xmrig/issues/459) Verbose errors related to donation pool was not fully silenced. +- [#459](https://github.com/xmrig/xmrig/issues/459) Fixed regression (version 2.5.0 affected) with connection to **xmr.f2pool.com**. + +# v2.5.0 +- [#434](https://github.com/xmrig/xmrig/issues/434) **Added support for Monero v7 PoW, scheduled on April 6.** +- Added full IPv6 support. +- Added protocol extension, when use the miner with xmrig-proxy 2.5+ no more need manually specify `nicehash` option. +- [#123](https://github.com/xmrig/xmrig-proxy/issues/123) Fixed regression (all versions since 2.4 affected) fragmented responses from pool/proxy was parsed incorrectly. +- [#428](https://github.com/xmrig/xmrig/issues/428) Fixed regression (version 2.4.5 affected) with CPU cache size detection. + +# v2.4.5 +- [#324](https://github.com/xmrig/xmrig/pull/324) Fixed build without libmicrohttpd (CMake cache issue). +- [#341](https://github.com/xmrig/xmrig/issues/341) Fixed wrong exit code and added command line option `--dry-run`. +- [#385](https://github.com/xmrig/xmrig/pull/385) Up to 20% performance increase for non-AES CPU and fixed Intel Core 2 cache detection. + +# v2.4.4 + - Added libmicrohttpd version to --version output. + - Fixed bug in singal handler, in some cases miner wasn't shutdown properly. + - Fixed recent MSVC 2017 version detection. + - [#279](https://github.com/xmrig/xmrig/pull/279) Fixed build on some macOS versions. + +# v2.4.3 + - [#94](https://github.com/xmrig/xmrig/issues/94#issuecomment-342019257) [#216](https://github.com/xmrig/xmrig/issues/216) Added **ARMv8** and **ARMv7** support. Hardware AES supported, thanks [Imran Yusuff](https://github.com/imranyusuff). + - [#157](https://github.com/xmrig/xmrig/issues/157) [#196](https://github.com/xmrig/xmrig/issues/196) Fixed Linux compile issues. + - [#184](https://github.com/xmrig/xmrig/issues/184) Fixed cache size detection for CPUs with disabled Hyper-Threading. + - [#200](https://github.com/xmrig/xmrig/issues/200) In some cases miner was doesn't write log to stdout. + +# v2.4.2 + - [#60](https://github.com/xmrig/xmrig/issues/60) Added FreeBSD support, thanks [vcambur](https://github.com/vcambur). + - [#153](https://github.com/xmrig/xmrig/issues/153) Fixed issues with dwarfpool.com. + +# v2.4.1 + - [#147](https://github.com/xmrig/xmrig/issues/147) Fixed comparability with monero-stratum. + +# v2.4.0 + - Added [HTTP API](https://github.com/xmrig/xmrig/wiki/API). + - Added comments support in config file. + - libjansson replaced to rapidjson. + - [#98](https://github.com/xmrig/xmrig/issues/98) Ignore `keepalive` option with minergate.com and nicehash.com. + - [#101](https://github.com/xmrig/xmrig/issues/101) Fixed MSVC 2017 (15.3) compile time version detection. + - [#108](https://github.com/xmrig/xmrig/issues/108) Silently ignore invalid values for `donate-level` option. + - [#111](https://github.com/xmrig/xmrig/issues/111) Fixed build without AEON support. + +# v2.3.1 +- [#68](https://github.com/xmrig/xmrig/issues/68) Fixed compatibility with Docker containers, was nothing print on console. + +# v2.3.0 +- Added `--cpu-priority` option (0 idle, 2 normal to 5 highest). +- Added `--user-agent` option, to set custom user-agent string for pool. For example `cpuminer-multi/0.1`. +- Added `--no-huge-pages` option, to disable huge pages support. +- [#62](https://github.com/xmrig/xmrig/issues/62) Don't send the login to the dev pool. +- Force reconnect if pool block miner IP address. helps switch to backup pool. +- Fixed: failed open default config file if path contains non English characters. +- Fixed: error occurred if try use unavailable stdin or stdout, regression since version 2.2.0. +- Fixed: message about huge pages support successfully enabled on Windows was not shown in release builds. + +# v2.2.1 +- Fixed [terminal issues](https://github.com/xmrig/xmrig-proxy/issues/2#issuecomment-319914085) after exit on Linux and OS X. + +# v2.2.0 +- [#46](https://github.com/xmrig/xmrig/issues/46) Restored config file support. Now possible use multiple config files and combine with command line options also added support for default config. +- Improved colors support on Windows, now used uv_tty, legacy code removed. +- QuickEdit Mode now disabled on Windows. +- Added interactive commands in console window:: **h**ashrate, **p**ause, **r**esume. +- Fixed autoconf mode for AMD FX CPUs. + +# v2.1.0 +- [#40](https://github.com/xmrig/xmrig/issues/40) +Improved miner shutdown, fixed crash on exit for Linux and OS X. +- Fixed, login request was contain malformed JSON if username or password has some special characters for example `\`. +- [#220](https://github.com/fireice-uk/xmr-stak-cpu/pull/220) Better support for Round Robin DNS, IP address now always chosen randomly instead of stuck on first one. +- Changed donation address, new [xmrig-proxy](https://github.com/xmrig/xmrig-proxy) is coming soon. + +# v2.0.2 +- Better deal with possible duplicate jobs from pool, show warning and ignore duplicates. +- For Windows builds libuv updated to version 1.13.1 and gcc to 7.1.0. + +# v2.0.1 + - [#27](https://github.com/xmrig/xmrig/issues/27) Fixed possibility crash on 32bit systems. + +# v2.0.0 + - Option `--backup-url` removed, instead now possibility specify multiple pools for example: `-o example1.com:3333 -u user1 -p password1 -k -o example2.com:5555 -u user2 -o example3.com:4444 -u user3` + - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-l, --log-file=FILE` to write log to file. + - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-S, --syslog` to use syslog for logging, Linux only. + - [#18](https://github.com/xmrig/xmrig/issues/18) Added nice messages for accepted/rejected shares with diff and network latency. + - [#20](https://github.com/xmrig/xmrig/issues/20) Fixed `--cpu-affinity` for more than 32 threads. + - Fixed Windows XP support. + - Fixed regression, option `--no-color` was not fully disable colored output. + - Show resolved pool IP address in miner output. + +# v1.0.1 +- Fix broken software AES implementation, app has crashed if CPU not support AES-NI, only version 1.0.0 affected. + +# v1.0.0 +- Miner complete rewritten in C++ with libuv. +- This version should be fully compatible (except config file) with previos versions, many new nice features will come in next versions. +- This is still beta. If you found regression, stability or perfomance issues or have an idea for new feature please fell free to open new [issue](https://github.com/xmrig/xmrig/issues/new). +- Added new option `--print-time=N`, print hashrate report every N seconds. +- New hashrate reports, by default every 60 secons. +- Added Microsoft Visual C++ 2015 and 2017 support. +- Removed dependency on libcurl. +- To compile this version from source please switch to [dev](https://github.com/xmrig/xmrig/tree/dev) branch. + +# v0.8.2 +- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). + +# v0.8.2 +- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). +- Fixed gcc 7.1 support. + +# v0.8.1 +- Added nicehash support, detects automaticaly by pool URL, for example `cryptonight.eu.nicehash.com:3355` or manually via option `--nicehash`. + +# v0.8.0 +- Added double hash mode, also known as lower power mode. `--av=2` and `--av=4`. +- Added smart automatic CPU configuration. Default threads count now depends on size of the L3 cache of CPU. +- Added CryptoNight-Lite support for AEON `-a cryptonight-lite`. +- Added `--max-cpu-usage` option for auto CPU configuration mode. +- Added `--safe` option for adjust threads and algorithm variations to current CPU. +- No more manual steps to enable huge pages on Windows. XMRig will do it automatically. +- Removed BMI2 algorithm variation. +- Removed default pool URL. + +# v0.6.0 +- Added automatic cryptonight self test. +- New software AES algorithm variation. Will be automatically selected if cpu not support AES-NI. +- Added 32 bit builds. +- Documented [algorithm variations](https://github.com/xmrig/xmrig#algorithm-variations). + +# v0.5.0 +- Initial public release. From 0bfd409bdf5bf5dc401b0e26391c501867b17ada Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 10 Apr 2018 23:22:49 +0700 Subject: [PATCH 040/109] Remove unused class UploadCtx. --- src/api/Httpd.cpp | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/src/api/Httpd.cpp b/src/api/Httpd.cpp index 45c9ce07..e0901b77 100644 --- a/src/api/Httpd.cpp +++ b/src/api/Httpd.cpp @@ -33,37 +33,6 @@ #include "log/Log.h" -class UploadCtx -{ -public: - inline UploadCtx() : - m_pos(0) - {} - - - inline bool write(const char *data, size_t size) - { - if (size > (sizeof(m_data) - m_pos - 1)) { - return false; - } - - memcpy(m_data + m_pos, data, size); - - m_pos += size; - m_data[m_pos] = '\0'; - - return true; - } - - - inline const char *data() const { return m_data; } - -private: - char m_data[32768]; - size_t m_pos; -}; - - Httpd::Httpd(int port, const char *accessToken, bool IPv6, bool restricted) : m_idle(true), m_IPv6(IPv6), From ad7545d1496daa7421144c123304ab22d0b52799 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 11 Apr 2018 03:52:23 +0700 Subject: [PATCH 041/109] Refactoring. --- CMakeLists.txt | 1 + src/core/CommonConfig.cpp | 30 ++----- src/core/CommonConfig.h | 23 +++--- src/core/ConfigWatcher.cpp | 12 ++- src/core/ConfigWatcher.h | 4 +- src/core/utils/c_str.h | 94 ++++++++++++++++++++++ src/net/Client.cpp | 2 +- src/net/Client.h | 1 + src/net/Url.cpp | 160 ++++++++++--------------------------- src/net/Url.h | 60 +++++++------- 10 files changed, 197 insertions(+), 190 deletions(-) create mode 100644 src/core/utils/c_str.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 43a7c1d4..734913e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,7 @@ set(HEADERS src/core/ConfigLoader_platform.h src/core/ConfigWatcher.cpp src/core/Controller.h + src/core/utils/c_str.h src/Cpu.h src/interfaces/IClientListener.h src/interfaces/IConfig.h diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp index 5b8a32ab..78eea5d9 100644 --- a/src/core/CommonConfig.cpp +++ b/src/core/CommonConfig.cpp @@ -73,11 +73,6 @@ xmrig::CommonConfig::CommonConfig() : m_watch(false), // TODO: enable config file watch by default when this feature propertly handled and tested. # endif - m_apiToken(nullptr), - m_apiWorkerId(nullptr), - m_fileName(nullptr), - m_logFile(nullptr), - m_userAgent(nullptr), m_apiPort(0), m_donateLevel(kDefaultDonateLevel), m_printTime(60), @@ -100,12 +95,6 @@ xmrig::CommonConfig::~CommonConfig() } m_pools.clear(); - - free(m_fileName); - free(m_apiToken); - free(m_apiWorkerId); - free(m_logFile); - free(m_userAgent); } @@ -223,23 +212,19 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) break; case LogFileKey: /* --log-file */ - free(m_logFile); - m_logFile = strdup(arg); + m_logFile = arg; break; case ApiAccessTokenKey: /* --api-access-token */ - free(m_apiToken); - m_apiToken = strdup(arg); + m_apiToken = arg; break; case ApiWorkerIdKey: /* --api-worker-id */ - free(m_apiWorkerId); - m_apiWorkerId = strdup(arg); + m_apiWorkerId = arg; break; case UserAgentKey: /* --user-agent */ - free(m_userAgent); - m_userAgent = strdup(arg); + m_userAgent = arg; break; case RetriesKey: /* --retries */ @@ -286,12 +271,12 @@ bool xmrig::CommonConfig::parseUint64(int key, uint64_t arg) bool xmrig::CommonConfig::save() { - if (!m_fileName) { + if (m_fileName.isNull()) { return false; } uv_fs_t req; - const int fd = uv_fs_open(uv_default_loop(), &req, m_fileName, O_WRONLY | O_CREAT | O_TRUNC, 0644, nullptr); + const int fd = uv_fs_open(uv_default_loop(), &req, m_fileName.data(), O_WRONLY | O_CREAT | O_TRUNC, 0644, nullptr); if (fd < 0) { return false; } @@ -320,8 +305,7 @@ bool xmrig::CommonConfig::save() void xmrig::CommonConfig::setFileName(const char *fileName) { - free(m_fileName); - m_fileName = fileName ? strdup(fileName) : nullptr; + m_fileName = fileName; } diff --git a/src/core/CommonConfig.h b/src/core/CommonConfig.h index ee9c7a20..07ff72d7 100644 --- a/src/core/CommonConfig.h +++ b/src/core/CommonConfig.h @@ -28,6 +28,7 @@ #include +#include "core/utils/c_str.h" #include "interfaces/IConfig.h" #include "xmrig.h" @@ -53,10 +54,10 @@ public: inline bool isColors() const { return m_colors; } inline bool isSyslog() const { return m_syslog; } inline const char *algoName() const { return algoName(m_algorithm); } - inline const char *apiToken() const { return m_apiToken; } - inline const char *apiWorkerId() const { return m_apiWorkerId; } - inline const char *logFile() const { return m_logFile; } - inline const char *userAgent() const { return m_userAgent; } + inline const char *apiToken() const { return m_apiToken.data(); } + inline const char *apiWorkerId() const { return m_apiWorkerId.data(); } + inline const char *logFile() const { return m_logFile.data(); } + inline const char *userAgent() const { return m_userAgent.data(); } inline const std::vector &pools() const { return m_pools; } inline int apiPort() const { return m_apiPort; } inline int donateLevel() const { return m_donateLevel; } @@ -65,8 +66,8 @@ public: inline int retryPause() const { return m_retryPause; } inline void setColors(bool colors) { m_colors = colors; } - inline bool isWatch() const override { return m_watch && m_fileName; } - inline const char *fileName() const override { return m_fileName; } + inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); } + inline const char *fileName() const override { return m_fileName.data(); } protected: bool adjust() override; @@ -85,17 +86,17 @@ protected: bool m_colors; bool m_syslog; bool m_watch; - char *m_apiToken; - char *m_apiWorkerId; - char *m_fileName; - char *m_logFile; - char *m_userAgent; int m_apiPort; int m_donateLevel; int m_printTime; int m_retries; int m_retryPause; std::vector m_pools; + xmrig::c_str m_apiToken; + xmrig::c_str m_apiWorkerId; + xmrig::c_str m_fileName; + xmrig::c_str m_logFile; + xmrig::c_str m_userAgent; private: bool parseInt(int key, int arg); diff --git a/src/core/ConfigWatcher.cpp b/src/core/ConfigWatcher.cpp index b934b52b..092a0f3a 100644 --- a/src/core/ConfigWatcher.cpp +++ b/src/core/ConfigWatcher.cpp @@ -33,9 +33,9 @@ xmrig::ConfigWatcher::ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener) : - m_path(strdup(path)), m_creator(creator), - m_listener(listener) + m_listener(listener), + m_path(path) { uv_fs_event_init(uv_default_loop(), &m_fsEvent); uv_timer_init(uv_default_loop(), &m_timer); @@ -50,8 +50,6 @@ xmrig::ConfigWatcher::~ConfigWatcher() { uv_timer_stop(&m_timer); uv_fs_event_stop(&m_fsEvent); - - free(m_path); } @@ -80,10 +78,10 @@ void xmrig::ConfigWatcher::queueUpdate() void xmrig::ConfigWatcher::reload() { - LOG_WARN("\"%s\" was changed, reloading configuration", m_path); + LOG_WARN("\"%s\" was changed, reloading configuration", m_path.data()); IConfig *config = m_creator->create(); - ConfigLoader::loadFromFile(config, m_path); + ConfigLoader::loadFromFile(config, m_path.data()); if (!config->isValid()) { LOG_ERR("reloading failed"); @@ -103,5 +101,5 @@ void xmrig::ConfigWatcher::reload() void xmrig::ConfigWatcher::start() { - uv_fs_event_start(&m_fsEvent, xmrig::ConfigWatcher::onFsEvent, m_path, 0); + uv_fs_event_start(&m_fsEvent, xmrig::ConfigWatcher::onFsEvent, m_path.data(), 0); } diff --git a/src/core/ConfigWatcher.h b/src/core/ConfigWatcher.h index 74526e90..a5d25864 100644 --- a/src/core/ConfigWatcher.h +++ b/src/core/ConfigWatcher.h @@ -28,6 +28,8 @@ #include #include + +#include "core/utils/c_str.h" #include "rapidjson/fwd.h" @@ -56,11 +58,11 @@ private: void reload(); void start(); - char *m_path; IConfigCreator *m_creator; IWatcherListener *m_listener; uv_fs_event_t m_fsEvent; uv_timer_t m_timer; + xmrig::c_str m_path; }; diff --git a/src/core/utils/c_str.h b/src/core/utils/c_str.h new file mode 100644 index 00000000..393c349b --- /dev/null +++ b/src/core/utils/c_str.h @@ -0,0 +1,94 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __C_STR_H__ +#define __C_STR_H__ + + +#include +#include + +#include + + +namespace xmrig { + + +/** + * @brief Simple C string wrapper. + * + * 1. I know about std:string. + * 2. For some reason I prefer don't use std:string in miner, eg because of file size of MSYS2 builds. + */ +class c_str +{ +public: + inline c_str() : m_data(nullptr) {} + inline c_str(const char *str) : m_data(nullptr) { set(str); } + inline ~c_str() { free(m_data); } + + + inline void set(const char *str) + { + free(m_data); + + m_data = str != nullptr ? strdup(str) : nullptr; + } + + + inline void set(char *str) + { + free(m_data); + + m_data = str; + } + + + inline bool isEqual(const char *str) const + { + return (m_data != nullptr && str != nullptr && strcmp(m_data, str)) || (m_data == nullptr && m_data == nullptr); + } + + + inline bool isNull() const { return m_data == nullptr; } + inline const char *data() const { return m_data; } + inline size_t size() const { return m_data == nullptr ? 0 : strlen(m_data); } + + + inline bool operator!=(const c_str &str) const { return !isEqual(str.data()); } + inline bool operator!=(const char *str) const { return !isEqual(str); } + inline bool operator==(const c_str &str) const { return isEqual(str.data()); } + inline bool operator==(const char *str) const { return isEqual(str); } + inline c_str &operator=(char *str) { set(str); return *this; } + inline c_str &operator=(const c_str &str) { set(str.data()); return *this; } + inline c_str &operator=(const char *str) { set(str); return *this; } + + +private: + char *m_data; +}; + + +} /* namespace xmrig */ + +#endif /* __C_STR_H__ */ diff --git a/src/net/Client.cpp b/src/net/Client.cpp index ec9dc863..bf64408a 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -138,7 +138,7 @@ void Client::setUrl(const Url *url) return; } - m_url = url; + m_url = *url; } diff --git a/src/net/Client.h b/src/net/Client.h index fc0335c6..e6af6503 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -30,6 +30,7 @@ #include +#include "core/utils/c_str.h" #include "net/Id.h" #include "net/Job.h" #include "net/Storage.h" diff --git a/src/net/Url.cpp b/src/net/Url.cpp index 3d5f2cdd..c2094d15 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -22,13 +22,13 @@ */ +#include #include #include #include #include "net/Url.h" -#include "xmrig.h" #ifdef _MSC_VER @@ -38,14 +38,10 @@ Url::Url() : m_nicehash(false), - m_host(nullptr), - m_password(nullptr), - m_user(nullptr), - m_algo(xmrig::CRYPTONIGHT), m_keepAlive(0), - m_variant(xmrig::VARIANT_AUTO), - m_url(nullptr), - m_port(kDefaultPort) + m_port(kDefaultPort), + m_algo(xmrig::CRYPTONIGHT), + m_variant(xmrig::VARIANT_AUTO) { } @@ -63,47 +59,40 @@ Url::Url() : */ Url::Url(const char *url) : m_nicehash(false), - m_host(nullptr), - m_password(nullptr), - m_user(nullptr), - m_algo(xmrig::CRYPTONIGHT), m_keepAlive(0), - m_variant(xmrig::VARIANT_AUTO), - m_url(nullptr), - m_port(kDefaultPort) + m_port(kDefaultPort), + m_algo(xmrig::CRYPTONIGHT), + m_url(url), + m_variant(xmrig::VARIANT_AUTO) { parse(url); } -Url::Url(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, int variant) : +Url::Url(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, xmrig::Variant variant) : m_nicehash(nicehash), - m_password(password ? strdup(password) : nullptr), - m_user(user ? strdup(user) : nullptr), - m_algo(xmrig::CRYPTONIGHT), m_keepAlive(keepAlive), - m_variant(variant), - m_url(nullptr), - m_port(port) + m_port(port), + m_algo(xmrig::CRYPTONIGHT), + m_host(host), + m_password(password), + m_user(user), + m_variant(variant) { - m_host = strdup(host); -} + const size_t size = m_host.size() + 8; + assert(size > 8); + char *url = new char[size](); + snprintf(url, size - 1, "%s:%d", m_host.data(), m_port); -Url::~Url() -{ - free(m_host); - free(m_password); - free(m_user); - - if (m_url) { - delete [] m_url; - } + m_url = url; } bool Url::parse(const char *url) { + assert(url != nullptr); + const char *p = strstr(url, "://"); const char *base = url; @@ -130,10 +119,12 @@ bool Url::parse(const char *url) } const size_t size = port++ - base + 1; - m_host = new char[size](); - memcpy(m_host, base, size - 1); + char *host = new char[size](); + memcpy(host, base, size - 1); + + m_host = host; + m_port = static_cast(strtol(port, nullptr, 10)); - m_port = (uint16_t) strtol(port, nullptr, 10); return true; } @@ -145,31 +136,17 @@ bool Url::setUserpass(const char *userpass) return false; } - free(m_user); - free(m_password); + char *user = new char[p - userpass + 1](); + strncpy(user, userpass, p - userpass); - m_user = static_cast(calloc(p - userpass + 1, 1)); - strncpy(m_user, userpass, p - userpass); - m_password = strdup(p + 1); + m_user = user; + m_password = p + 1; return true; } -const char *Url::url() const -{ - if (!m_url) { - const size_t size = strlen(m_host) + 8; - m_url = new char[size]; - - snprintf(m_url, size - 1, "%s:%d", m_host, m_port); - } - - return m_url; -} - - -void Url::adjust(int algo) +void Url::adjust(xmrig::Algo algo) { if (!isValid()) { return; @@ -177,91 +154,33 @@ void Url::adjust(int algo) m_algo = algo; - if (strstr(m_host, ".nicehash.com")) { + if (strstr(m_host.data(), ".nicehash.com")) { m_keepAlive = false; m_nicehash = true; } - if (strstr(m_host, ".minergate.com")) { + if (strstr(m_host.data(), ".minergate.com")) { m_keepAlive = false; } } -void Url::setPassword(const char *password) -{ - if (!password) { - return; - } - - free(m_password); - m_password = strdup(password); -} - - -void Url::setUser(const char *user) -{ - if (!user) { - return; - } - - free(m_user); - m_user = strdup(user); -} - - void Url::setVariant(int variant) { switch (variant) { case xmrig::VARIANT_AUTO: case xmrig::VARIANT_NONE: case xmrig::VARIANT_V1: - m_variant = variant; + m_variant = static_cast(variant); break; default: + assert(false); break; } } -bool Url::operator==(const Url &other) const -{ - if (m_port != other.m_port || m_keepAlive != other.m_keepAlive || m_nicehash != other.m_nicehash) { - return false; - } - - if (strcmp(host(), other.host()) != 0 || strcmp(user(), other.user()) != 0 || strcmp(password(), other.password()) != 0) { - return false; - } - - return true; -} - - -Url &Url::operator=(const Url *other) -{ - m_keepAlive = other->m_keepAlive; - m_algo = other->m_algo; - m_variant = other->m_variant; - m_nicehash = other->m_nicehash; - m_port = other->m_port; - - free(m_host); - m_host = strdup(other->m_host); - - setPassword(other->m_password); - setUser(other->m_user); - - if (m_url) { - delete [] m_url; - m_url = nullptr; - } - - return *this; -} - - bool Url::parseIPv6(const char *addr) { const char *end = strchr(addr, ']'); @@ -275,10 +194,11 @@ bool Url::parseIPv6(const char *addr) } const size_t size = end - addr; - m_host = new char[size](); - memcpy(m_host, addr + 1, size - 1); + char *host = new char[size](); + memcpy(host, addr + 1, size - 1); - m_port = (uint16_t) strtol(port + 1, nullptr, 10); + m_host = host; + m_port = static_cast(strtol(port + 1, nullptr, 10)); return true; } diff --git a/src/net/Url.h b/src/net/Url.h index 4c2c9435..7a461132 100644 --- a/src/net/Url.h +++ b/src/net/Url.h @@ -28,6 +28,10 @@ #include +#include "core/utils/c_str.h" +#include "xmrig.h" + + class Url { public: @@ -38,45 +42,47 @@ public: Url(); Url(const char *url); - Url(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr, int keepAlive = 0, bool nicehash = false, int variant = -1); - ~Url(); + Url(const char *host, + uint16_t port, + const char *user = nullptr, + const char *password = nullptr, + int keepAlive = 0, + bool nicehash = false, + xmrig::Variant variant = xmrig::VARIANT_AUTO + ); - inline bool isNicehash() const { return m_nicehash; } - inline bool isValid() const { return m_host && m_port > 0; } - inline const char *host() const { return m_host; } - inline const char *password() const { return m_password ? m_password : kDefaultPassword; } - inline const char *user() const { return m_user ? m_user : kDefaultUser; } - inline int algo() const { return m_algo; } - inline int keepAlive() const { return m_keepAlive; } - inline int variant() const { return m_variant; } - inline uint16_t port() const { return m_port; } - inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } - inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } - inline void setVariant(bool monero) { m_variant = monero; } + inline bool isNicehash() const { return m_nicehash; } + inline bool isValid() const { return !m_host.isNull() && m_port > 0; } + inline const char *host() const { return m_host.data(); } + inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; } + inline const char *url() const { return m_url.data(); } + inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; } + inline int keepAlive() const { return m_keepAlive; } + inline uint16_t port() const { return m_port; } + inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } + inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } + inline void setPassword(const char *password) { m_password = password; } + inline void setUser(const char *user) { m_user = user; } + inline xmrig::Algo algo() const { return m_algo; } + inline xmrig::Variant variant() const { return m_variant; } bool parse(const char *url); bool setUserpass(const char *userpass); - const char *url() const; - void adjust(int algo); - void setPassword(const char *password); - void setUser(const char *user); + void adjust(xmrig::Algo algo); void setVariant(int variant); - bool operator==(const Url &other) const; - Url &operator=(const Url *other); - private: bool parseIPv6(const char *addr); bool m_nicehash; - char *m_host; - char *m_password; - char *m_user; - int m_algo; int m_keepAlive; - int m_variant; - mutable char *m_url; uint16_t m_port; + xmrig::Algo m_algo; + xmrig::c_str m_host; + xmrig::c_str m_password; + xmrig::c_str m_url; + xmrig::c_str m_user; + xmrig::Variant m_variant; }; #endif /* __URL_H__ */ From 36ef254c730b33bb166715248f2efd9cfa42adcc Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 11 Apr 2018 06:09:34 +0700 Subject: [PATCH 042/109] Rename class Url to Pool. --- CMakeLists.txt | 4 +- src/Summary.cpp | 10 ++-- src/core/CommonConfig.cpp | 45 ++++++++---------- src/core/CommonConfig.h | 8 ++-- src/core/Config.cpp | 20 ++++---- src/core/ConfigLoader.cpp | 2 +- src/core/utils/c_str.h | 8 ++-- src/net/Client.cpp | 58 +++++++++++------------ src/net/Client.h | 13 +++-- src/net/Network.cpp | 5 +- src/net/{Url.cpp => Pool.cpp} | 34 +++++++++---- src/net/{Url.h => Pool.h} | 19 +++++--- src/net/strategies/DonateStrategy.cpp | 14 +++--- src/net/strategies/DonateStrategy.h | 3 +- src/net/strategies/FailoverStrategy.cpp | 8 ++-- src/net/strategies/FailoverStrategy.h | 5 +- src/net/strategies/SinglePoolStrategy.cpp | 4 +- src/net/strategies/SinglePoolStrategy.h | 2 +- 18 files changed, 136 insertions(+), 126 deletions(-) rename src/net/{Url.cpp => Pool.cpp} (82%) rename src/net/{Url.h => Pool.h} (90%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 734913e8..5502405c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,12 +45,12 @@ set(HEADERS src/net/Job.h src/net/JobResult.h src/net/Network.h + src/net/Pool.h src/net/Storage.h src/net/strategies/DonateStrategy.h src/net/strategies/FailoverStrategy.h src/net/strategies/SinglePoolStrategy.h src/net/SubmitResult.h - src/net/Url.h src/Platform.h src/Summary.h src/version.h @@ -102,11 +102,11 @@ set(SOURCES src/net/Client.cpp src/net/Job.cpp src/net/Network.cpp + src/net/Pool.cpp src/net/strategies/DonateStrategy.cpp src/net/strategies/FailoverStrategy.cpp src/net/strategies/SinglePoolStrategy.cpp src/net/SubmitResult.cpp - src/net/Url.cpp src/Platform.cpp src/Summary.cpp src/workers/CpuThread.cpp diff --git a/src/Summary.cpp b/src/Summary.cpp index 56f3f522..6de1cd3a 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -32,7 +32,7 @@ #include "Cpu.h" #include "log/Log.h" #include "Mem.h" -#include "net/Url.h" +#include "net/Pool.h" #include "Summary.h" #include "version.h" @@ -112,13 +112,13 @@ static void print_threads(xmrig::Config *config) static void print_pools(xmrig::Config *config) { - const std::vector &pools = config->pools(); + const std::vector &pools = config->pools(); for (size_t i = 0; i < pools.size(); ++i) { - Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d: \x1B[01;36m%s:%d" : " * POOL #%d: %s:%d", + Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mPOOL #%d: \x1B[01;36m%s" : " * POOL #%d: %s", i + 1, - pools[i]->host(), - pools[i]->port()); + pools[i].url() + ); } # ifdef APP_DEBUG diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp index 78eea5d9..b8af451b 100644 --- a/src/core/CommonConfig.cpp +++ b/src/core/CommonConfig.cpp @@ -32,7 +32,7 @@ #include "core/CommonConfig.h" #include "donate.h" #include "log/Log.h" -#include "net/Url.h" +#include "net/Pool.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" @@ -79,7 +79,7 @@ xmrig::CommonConfig::CommonConfig() : m_retries(5), m_retryPause(5) { - m_pools.push_back(new Url()); + m_pools.push_back(Pool()); # ifdef XMRIG_PROXY_PROJECT m_retries = 2; @@ -90,11 +90,6 @@ xmrig::CommonConfig::CommonConfig() : xmrig::CommonConfig::~CommonConfig() { - for (Url *url : m_pools) { - delete url; - } - - m_pools.clear(); } @@ -112,8 +107,8 @@ bool xmrig::CommonConfig::adjust() m_adjusted = true; - for (Url *url : m_pools) { - url->adjust(algorithm()); + for (Pool &pool : m_pools) { + pool.adjust(algorithm()); } return true; @@ -122,7 +117,7 @@ bool xmrig::CommonConfig::adjust() bool xmrig::CommonConfig::isValid() const { - return m_pools[0]->isValid(); + return m_pools[0].isValid(); } @@ -138,12 +133,12 @@ bool xmrig::CommonConfig::parseBoolean(int key, bool enable) break; case KeepAliveKey: /* --keepalive */ - m_pools.back()->setKeepAlive(enable ? Url::kKeepAliveTimeout : 0); + m_pools.back().setKeepAlive(enable ? Pool::kKeepAliveTimeout : 0); break; # ifndef XMRIG_PROXY_PROJECT case NicehashKey: /* --nicehash */ - m_pools.back()->setNicehash(enable); + m_pools.back().setNicehash(enable); break; # endif @@ -177,38 +172,36 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) break; case UserpassKey: /* --userpass */ - if (!m_pools.back()->setUserpass(arg)) { + if (!m_pools.back().setUserpass(arg)) { return false; } break; case UrlKey: /* --url */ - if (m_pools.size() > 1 || m_pools[0]->isValid()) { - Url *url = new Url(arg); - if (url->isValid()) { - m_pools.push_back(url); - } - else { - delete url; + if (m_pools.size() > 1 || m_pools[0].isValid()) { + Pool pool(arg); + + if (pool.isValid()) { + m_pools.push_back(std::move(pool)); } } else { - m_pools[0]->parse(arg); + m_pools[0].parse(arg); } - if (!m_pools.back()->isValid()) { + if (!m_pools.back().isValid()) { return false; } break; case UserKey: /* --user */ - m_pools.back()->setUser(arg); + m_pools.back().setUser(arg); break; case PasswordKey: /* --pass */ - m_pools.back()->setPassword(arg); + m_pools.back().setPassword(arg); break; case LogFileKey: /* --log-file */ @@ -325,11 +318,11 @@ bool xmrig::CommonConfig::parseInt(int key, int arg) break; case KeepAliveKey: /* --keepalive */ - m_pools.back()->setKeepAlive(arg); + m_pools.back().setKeepAlive(arg); break; case VariantKey: /* --variant */ - m_pools.back()->setVariant(arg); + m_pools.back().setVariant(arg); break; case DonateLevelKey: /* --donate-level */ diff --git a/src/core/CommonConfig.h b/src/core/CommonConfig.h index 07ff72d7..89dbc7ed 100644 --- a/src/core/CommonConfig.h +++ b/src/core/CommonConfig.h @@ -31,9 +31,7 @@ #include "core/utils/c_str.h" #include "interfaces/IConfig.h" #include "xmrig.h" - - -class Url; +#include "net/Pool.h" namespace xmrig { @@ -58,7 +56,7 @@ public: inline const char *apiWorkerId() const { return m_apiWorkerId.data(); } inline const char *logFile() const { return m_logFile.data(); } inline const char *userAgent() const { return m_userAgent.data(); } - inline const std::vector &pools() const { return m_pools; } + inline const std::vector &pools() const { return m_pools; } inline int apiPort() const { return m_apiPort; } inline int donateLevel() const { return m_donateLevel; } inline int printTime() const { return m_printTime; } @@ -91,7 +89,7 @@ protected: int m_printTime; int m_retries; int m_retryPause; - std::vector m_pools; + std::vector m_pools; xmrig::c_str m_apiToken; xmrig::c_str m_apiWorkerId; xmrig::c_str m_fileName; diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 6bc2dc0f..a9136660 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -30,7 +30,7 @@ #include "core/ConfigCreator.h" #include "core/ConfigLoader.h" #include "Cpu.h" -#include "net/Url.h" +#include "net/Pool.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" @@ -110,22 +110,22 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const rapidjson::Value pools(rapidjson::kArrayType); - for (const Url *url : m_pools) { + for (const Pool &pool : m_pools) { rapidjson::Value obj(rapidjson::kObjectType); - obj.AddMember("url", rapidjson::StringRef(url->url()), allocator); - obj.AddMember("user", rapidjson::StringRef(url->user()), allocator); - obj.AddMember("pass", rapidjson::StringRef(url->password()), allocator); + obj.AddMember("url", rapidjson::StringRef(pool.url()), allocator); + obj.AddMember("user", rapidjson::StringRef(pool.user()), allocator); + obj.AddMember("pass", rapidjson::StringRef(pool.password()), allocator); - if (url->keepAlive() == 0 || url->keepAlive() == Url::kKeepAliveTimeout) { - obj.AddMember("keepalive", url->keepAlive() > 0, allocator); + if (pool.keepAlive() == 0 || pool.keepAlive() == Pool::kKeepAliveTimeout) { + obj.AddMember("keepalive", pool.keepAlive() > 0, allocator); } else { - obj.AddMember("keepalive", url->keepAlive(), allocator); + obj.AddMember("keepalive", pool.keepAlive(), allocator); } - obj.AddMember("nicehash", url->isNicehash(), allocator); - obj.AddMember("variant", url->variant(), allocator); + obj.AddMember("nicehash", pool.isNicehash(), allocator); + obj.AddMember("variant", pool.variant(), allocator); pools.PushBack(obj, allocator); } diff --git a/src/core/ConfigLoader.cpp b/src/core/ConfigLoader.cpp index 1dec4eca..8c7f6546 100644 --- a/src/core/ConfigLoader.cpp +++ b/src/core/ConfigLoader.cpp @@ -38,7 +38,7 @@ #include "core/ConfigWatcher.h" #include "interfaces/IConfig.h" #include "interfaces/IWatcherListener.h" -#include "net/Url.h" +#include "net/Pool.h" #include "Platform.h" #include "rapidjson/document.h" #include "rapidjson/error/en.h" diff --git a/src/core/utils/c_str.h b/src/core/utils/c_str.h index 393c349b..9a11ade6 100644 --- a/src/core/utils/c_str.h +++ b/src/core/utils/c_str.h @@ -43,9 +43,11 @@ namespace xmrig { class c_str { public: - inline c_str() : m_data(nullptr) {} - inline c_str(const char *str) : m_data(nullptr) { set(str); } - inline ~c_str() { free(m_data); } + inline c_str() : m_data(nullptr) {} + inline c_str(c_str &&other) { m_data = other.m_data; other.m_data = nullptr; } + inline c_str(const c_str &other) : m_data(nullptr) { set(other.data()); } + inline c_str(const char *str) : m_data(nullptr) { set(str); } + inline ~c_str() { free(m_data); } inline void set(const char *str) diff --git a/src/net/Client.cpp b/src/net/Client.cpp index bf64408a..5574f37f 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -32,7 +32,6 @@ #include "interfaces/IClientListener.h" #include "log/Log.h" #include "net/Client.h" -#include "net/Url.h" #include "rapidjson/document.h" #include "rapidjson/error/en.h" #include "rapidjson/stringbuffer.h" @@ -97,7 +96,7 @@ Client::~Client() void Client::connect() { - resolve(m_url.host()); + resolve(m_pool.host()); } @@ -106,10 +105,10 @@ void Client::connect() * * @param url */ -void Client::connect(const Url *url) +void Client::connect(const Pool &url) { setUrl(url); - resolve(m_url.host()); + connect(); } @@ -132,13 +131,13 @@ void Client::deleteLater() } -void Client::setUrl(const Url *url) +void Client::setUrl(const Pool &pool) { - if (!url || !url->isValid()) { + if (!pool.isValid()) { return; } - m_url = *url; + m_pool = pool; } @@ -146,7 +145,7 @@ void Client::tick(uint64_t now) { if (m_state == ConnectedState) { if (m_expire && now > m_expire) { - LOG_DEBUG_ERR("[%s:%u] timeout", m_url.host(), m_url.port()); + LOG_DEBUG_ERR("[%s] timeout", m_pool.url()); close(); } else if (m_keepAlive && now > m_keepAlive) { @@ -266,11 +265,10 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) } # ifdef XMRIG_PROXY_PROJECT - Job job(m_id, m_url.variant()); + Job job(m_id, m_pool.variant()); job.setClientId(m_rpcId); - job.setCoin(m_url.coin()); # else - Job job(m_id, m_nicehash, m_url.algo(), m_url.variant()); + Job job(m_id, m_nicehash, m_pool.algo(), m_pool.variant()); # endif if (!job.setId(params["job_id"].GetString())) { @@ -307,7 +305,7 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) } if (!m_quiet) { - LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port()); + LOG_WARN("[%s] duplicate job received, reconnect", m_pool.url()); } close(); @@ -323,7 +321,7 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code) } # ifndef XMRIG_PROXY_PROJECT - m_nicehash = m_url.isNicehash(); + m_nicehash = m_pool.isNicehash(); # endif if (result.HasMember("extensions")) { @@ -351,7 +349,7 @@ int Client::resolve(const char *host) const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, nullptr, &m_hints); if (r) { if (!m_quiet) { - LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_url.port(), uv_strerror(r)); + LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_pool.port(), uv_strerror(r)); } return 1; } @@ -402,7 +400,7 @@ void Client::connect(sockaddr *addr) { setState(ConnectingState); - reinterpret_cast(addr)->sin_port = htons(m_url.port()); + reinterpret_cast(addr)->sin_port = htons(m_pool.port()); delete m_socket; uv_connect_t *req = new uv_connect_t; @@ -436,9 +434,9 @@ void Client::login() doc.AddMember("method", "login", allocator); rapidjson::Value params(rapidjson::kObjectType); - params.AddMember("login", rapidjson::StringRef(m_url.user()), allocator); - params.AddMember("pass", rapidjson::StringRef(m_url.password()), allocator); - params.AddMember("agent", rapidjson::StringRef(m_agent), allocator); + params.AddMember("login", rapidjson::StringRef(m_pool.user()), allocator); + params.AddMember("pass", rapidjson::StringRef(m_pool.password()), allocator); + params.AddMember("agent", rapidjson::StringRef(m_agent), allocator); doc.AddMember("params", params, allocator); @@ -481,7 +479,7 @@ void Client::parse(char *line, size_t len) if (len < 32 || line[0] != '{') { if (!m_quiet) { - LOG_ERR("[%s:%u] JSON decode failed", m_url.host(), m_url.port()); + LOG_ERR("[%s] JSON decode failed", m_pool.url()); } return; @@ -490,7 +488,7 @@ void Client::parse(char *line, size_t len) rapidjson::Document doc; if (doc.ParseInsitu(line).HasParseError()) { if (!m_quiet) { - LOG_ERR("[%s:%u] JSON decode failed: \"%s\"", m_url.host(), m_url.port(), rapidjson::GetParseError_En(doc.GetParseError())); + LOG_ERR("[%s] JSON decode failed: \"%s\"", m_pool.url(), rapidjson::GetParseError_En(doc.GetParseError())); } return; @@ -532,7 +530,7 @@ void Client::parseNotification(const char *method, const rapidjson::Value ¶m { if (error.IsObject()) { if (!m_quiet) { - LOG_ERR("[%s:%u] error: \"%s\", code: %d", m_url.host(), m_url.port(), error["message"].GetString(), error["code"].GetInt()); + LOG_ERR("[%s] error: \"%s\", code: %d", m_pool.url(), error["message"].GetString(), error["code"].GetInt()); } return; } @@ -550,7 +548,7 @@ void Client::parseNotification(const char *method, const rapidjson::Value ¶m return; } - LOG_WARN("[%s:%u] unsupported method: \"%s\"", m_url.host(), m_url.port(), method); + LOG_WARN("[%s] unsupported method: \"%s\"", m_pool.url(), method); } @@ -566,7 +564,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap m_results.erase(it); } else if (!m_quiet) { - LOG_ERR("[%s:%u] error: \"%s\", code: %d", m_url.host(), m_url.port(), message, error["code"].GetInt()); + LOG_ERR("[%s] error: \"%s\", code: %d", m_pool.url(), message, error["code"].GetInt()); } if (isCriticalError(message)) { @@ -584,7 +582,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap int code = -1; if (!parseLogin(result, &code)) { if (!m_quiet) { - LOG_ERR("[%s:%u] login error code: %d", m_url.host(), m_url.port(), code); + LOG_ERR("[%s] login error code: %d", m_pool.url(), code); } close(); @@ -650,8 +648,8 @@ void Client::startTimeout() { m_expire = 0; - if (m_url.keepAlive()) { - m_keepAlive = uv_now(uv_default_loop()) + (m_url.keepAlive() * 1000); + if (m_pool.keepAlive()) { + m_keepAlive = uv_now(uv_default_loop()) + (m_pool.keepAlive() * 1000); } } @@ -689,7 +687,7 @@ void Client::onConnect(uv_connect_t *req, int status) if (status < 0) { if (!client->m_quiet) { - LOG_ERR("[%s:%u] connect error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status)); + LOG_ERR("[%s] connect error: \"%s\"", client->m_pool.url(), uv_strerror(status)); } delete req; @@ -717,7 +715,7 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) if (nread < 0) { if (nread != UV_EOF && !client->m_quiet) { - LOG_ERR("[%s:%u] read error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror((int) nread)); + LOG_ERR("[%s] read error: \"%s\"", client->m_pool.url(), uv_strerror((int) nread)); } client->close(); @@ -777,7 +775,7 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) if (status < 0) { if (!client->m_quiet) { - LOG_ERR("[%s:%u] DNS error: \"%s\"", client->m_url.host(), client->m_url.port(), uv_strerror(status)); + LOG_ERR("[%s] DNS error: \"%s\"", client->m_pool.url(), uv_strerror(status)); } return client->reconnect(); @@ -801,7 +799,7 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) if (ipv4.empty() && ipv6.empty()) { if (!client->m_quiet) { - LOG_ERR("[%s:%u] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_url.host(), client->m_url.port()); + LOG_ERR("[%s] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_pool.url()); } uv_freeaddrinfo(res); diff --git a/src/net/Client.h b/src/net/Client.h index e6af6503..910c8379 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -30,12 +30,11 @@ #include -#include "core/utils/c_str.h" #include "net/Id.h" #include "net/Job.h" #include "net/Storage.h" #include "net/SubmitResult.h" -#include "net/Url.h" +#include "net/Pool.h" #include "rapidjson/fwd.h" @@ -62,18 +61,18 @@ public: bool disconnect(); int64_t submit(const JobResult &result); void connect(); - void connect(const Url *url); + void connect(const Pool &pool); void deleteLater(); - void setUrl(const Url *url); + void setUrl(const Pool &pool); void tick(uint64_t now); inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } - inline const char *host() const { return m_url.host(); } + inline const char *host() const { return m_pool.host(); } inline const char *ip() const { return m_ip; } inline const Job &job() const { return m_job; } inline int id() const { return m_id; } inline SocketState state() const { return m_state; } - inline uint16_t port() const { return m_url.port(); } + inline uint16_t port() const { return m_pool.port(); } inline void setQuiet(bool quiet) { m_quiet = quiet; } inline void setRetryPause(int ms) { m_retryPause = ms; } @@ -118,6 +117,7 @@ private: int m_retryPause; int64_t m_failures; Job m_job; + Pool m_pool; size_t m_recvBufPos; SocketState m_state; std::map m_results; @@ -125,7 +125,6 @@ private: uint64_t m_jobs; uint64_t m_keepAlive; uintptr_t m_key; - Url m_url; uv_buf_t m_recvBuf; uv_getaddrinfo_t m_resolver; uv_stream_t *m_stream; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index a8e60efa..98ce7e8d 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -38,7 +38,6 @@ #include "net/strategies/FailoverStrategy.h" #include "net/strategies/SinglePoolStrategy.h" #include "net/SubmitResult.h" -#include "net/Url.h" #include "workers/Workers.h" #include "core/Controller.h" #include "core/Config.h" @@ -52,7 +51,7 @@ Network::Network(xmrig::Controller *controller) : Workers::setListener(this); - const std::vector &pools = controller->config()->pools(); + const std::vector &pools = controller->config()->pools(); if (pools.size() > 1) { m_strategy = new FailoverStrategy(pools, controller->config()->retryPause(), controller->config()->retries(), this); @@ -62,7 +61,7 @@ Network::Network(xmrig::Controller *controller) : } if (controller->config()->donateLevel() > 0) { - m_donate = new DonateStrategy(controller->config()->donateLevel(), controller->config()->pools().front()->user(), controller->config()->algorithm(), this); + m_donate = new DonateStrategy(controller->config()->donateLevel(), controller->config()->pools().front().user(), controller->config()->algorithm(), this); } m_timer.data = this; diff --git a/src/net/Url.cpp b/src/net/Pool.cpp similarity index 82% rename from src/net/Url.cpp rename to src/net/Pool.cpp index c2094d15..ff7d461a 100644 --- a/src/net/Url.cpp +++ b/src/net/Pool.cpp @@ -28,7 +28,7 @@ #include -#include "net/Url.h" +#include "net/Pool.h" #ifdef _MSC_VER @@ -36,7 +36,7 @@ #endif -Url::Url() : +Pool::Pool() : m_nicehash(false), m_keepAlive(0), m_port(kDefaultPort), @@ -57,7 +57,7 @@ Url::Url() : * * @param url */ -Url::Url(const char *url) : +Pool::Pool(const char *url) : m_nicehash(false), m_keepAlive(0), m_port(kDefaultPort), @@ -69,7 +69,7 @@ Url::Url(const char *url) : } -Url::Url(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, xmrig::Variant variant) : +Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, xmrig::Variant variant) : m_nicehash(nicehash), m_keepAlive(keepAlive), m_port(port), @@ -89,7 +89,7 @@ Url::Url(const char *host, uint16_t port, const char *user, const char *password } -bool Url::parse(const char *url) +bool Pool::parse(const char *url) { assert(url != nullptr); @@ -114,7 +114,7 @@ bool Url::parse(const char *url) const char *port = strchr(base, ':'); if (!port) { - m_host = strdup(base); + m_host = base; return false; } @@ -129,7 +129,7 @@ bool Url::parse(const char *url) } -bool Url::setUserpass(const char *userpass) +bool Pool::setUserpass(const char *userpass) { const char *p = strchr(userpass, ':'); if (!p) { @@ -146,7 +146,7 @@ bool Url::setUserpass(const char *userpass) } -void Url::adjust(xmrig::Algo algo) +void Pool::adjust(xmrig::Algo algo) { if (!isValid()) { return; @@ -165,7 +165,7 @@ void Url::adjust(xmrig::Algo algo) } -void Url::setVariant(int variant) +void Pool::setVariant(int variant) { switch (variant) { case xmrig::VARIANT_AUTO: @@ -181,7 +181,21 @@ void Url::setVariant(int variant) } -bool Url::parseIPv6(const char *addr) +bool Pool::isEqual(const Pool &other) const +{ + return (m_nicehash == other.m_nicehash + && m_keepAlive == other.m_keepAlive + && m_port == other.m_port + && m_algo == other.m_algo + && m_host == other.m_host + && m_password == other.m_password + && m_url == other.m_url + && m_user == other.m_user + && m_variant == other.m_variant); +} + + +bool Pool::parseIPv6(const char *addr) { const char *end = strchr(addr, ']'); if (!end) { diff --git a/src/net/Url.h b/src/net/Pool.h similarity index 90% rename from src/net/Url.h rename to src/net/Pool.h index 7a461132..5a2c3529 100644 --- a/src/net/Url.h +++ b/src/net/Pool.h @@ -21,8 +21,8 @@ * along with this program. If not, see . */ -#ifndef __URL_H__ -#define __URL_H__ +#ifndef __POOL_H__ +#define __POOL_H__ #include @@ -32,7 +32,7 @@ #include "xmrig.h" -class Url +class Pool { public: constexpr static const char *kDefaultPassword = "x"; @@ -40,9 +40,9 @@ public: constexpr static uint16_t kDefaultPort = 3333; constexpr static int kKeepAliveTimeout = 60; - Url(); - Url(const char *url); - Url(const char *host, + Pool(); + Pool(const char *url); + Pool(const char *host, uint16_t port, const char *user = nullptr, const char *password = nullptr, @@ -66,11 +66,16 @@ public: inline xmrig::Algo algo() const { return m_algo; } inline xmrig::Variant variant() const { return m_variant; } + inline bool operator!=(const Pool &other) const { return !isEqual(other); } + inline bool operator==(const Pool &other) const { return isEqual(other); } + bool parse(const char *url); bool setUserpass(const char *userpass); void adjust(xmrig::Algo algo); void setVariant(int variant); + bool isEqual(const Pool &other) const; + private: bool parseIPv6(const char *addr); @@ -85,4 +90,4 @@ private: xmrig::Variant m_variant; }; -#endif /* __URL_H__ */ +#endif /* __POOL_H__ */ diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index f0ec5bde..311ca424 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -60,17 +60,17 @@ DonateStrategy::DonateStrategy(int level, const char *user, int algo, IStrategyL Job::toHex(hash, 32, userId); if (algo == xmrig::CRYPTONIGHT) { - m_pools.push_back(new Url(kDonatePool1, 6666, userId, nullptr, false, true)); - m_pools.push_back(new Url(kDonatePool1, 80, userId, nullptr, false, true)); - m_pools.push_back(new Url(kDonatePool2, 5555, "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD", "emergency", false, false)); + m_pools.push_back(Pool(kDonatePool1, 6666, userId, nullptr, false, true)); + m_pools.push_back(Pool(kDonatePool1, 80, userId, nullptr, false, true)); + m_pools.push_back(Pool(kDonatePool2, 5555, "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD", "emergency", false, false)); } else if (algo == xmrig::CRYPTONIGHT_HEAVY) { - m_pools.push_back(new Url(kDonatePool1, 8888, userId, nullptr, false, true)); - m_pools.push_back(new Url(kDonatePool1, 8889, userId, nullptr, false, true)); + m_pools.push_back(Pool(kDonatePool1, 8888, userId, nullptr, false, true)); + m_pools.push_back(Pool(kDonatePool1, 8889, userId, nullptr, false, true)); } else { - m_pools.push_back(new Url(kDonatePool1, 5555, userId, nullptr, false, true)); - m_pools.push_back(new Url(kDonatePool1, 7777, userId, nullptr, false, true)); + m_pools.push_back(Pool(kDonatePool1, 5555, userId, nullptr, false, true)); + m_pools.push_back(Pool(kDonatePool1, 7777, userId, nullptr, false, true)); } m_strategy = new FailoverStrategy(m_pools, 1, 1, this, true); diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index 4ef29958..cad360b1 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -32,6 +32,7 @@ #include "interfaces/IClientListener.h" #include "interfaces/IStrategy.h" #include "interfaces/IStrategyListener.h" +#include "net/Pool.h" class Client; @@ -71,7 +72,7 @@ private: const int m_idleTime; IStrategy *m_strategy; IStrategyListener *m_listener; - std::vector m_pools; + std::vector m_pools; uv_timer_t m_timer; }; diff --git a/src/net/strategies/FailoverStrategy.cpp b/src/net/strategies/FailoverStrategy.cpp index dbfeb311..7a581407 100644 --- a/src/net/strategies/FailoverStrategy.cpp +++ b/src/net/strategies/FailoverStrategy.cpp @@ -28,7 +28,7 @@ #include "Platform.h" -FailoverStrategy::FailoverStrategy(const std::vector &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) : +FailoverStrategy::FailoverStrategy(const std::vector &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) : m_quiet(quiet), m_retries(retries), m_retryPause(retryPause), @@ -36,7 +36,7 @@ FailoverStrategy::FailoverStrategy(const std::vector &urls, int retryPause m_index(0), m_listener(listener) { - for (const Url *url : urls) { + for (const Pool &url : urls) { add(url); } } @@ -153,10 +153,10 @@ void FailoverStrategy::onResultAccepted(Client *client, const SubmitResult &resu } -void FailoverStrategy::add(const Url *url) +void FailoverStrategy::add(const Pool &pool) { Client *client = new Client((int) m_pools.size(), Platform::userAgent(), this); - client->setUrl(url); + client->setUrl(pool); client->setRetryPause(m_retryPause * 1000); client->setQuiet(m_quiet); diff --git a/src/net/strategies/FailoverStrategy.h b/src/net/strategies/FailoverStrategy.h index 8ad767ca..a48496fb 100644 --- a/src/net/strategies/FailoverStrategy.h +++ b/src/net/strategies/FailoverStrategy.h @@ -30,6 +30,7 @@ #include "interfaces/IClientListener.h" #include "interfaces/IStrategy.h" +#include "net/Pool.h" class Client; @@ -40,7 +41,7 @@ class Url; class FailoverStrategy : public IStrategy, public IClientListener { public: - FailoverStrategy(const std::vector &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet = false); + FailoverStrategy(const std::vector &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet = false); ~FailoverStrategy(); public: @@ -59,7 +60,7 @@ protected: void onResultAccepted(Client *client, const SubmitResult &result, const char *error) override; private: - void add(const Url *url); + void add(const Pool &pool); const bool m_quiet; const int m_retries; diff --git a/src/net/strategies/SinglePoolStrategy.cpp b/src/net/strategies/SinglePoolStrategy.cpp index fc7f209e..42a60b30 100644 --- a/src/net/strategies/SinglePoolStrategy.cpp +++ b/src/net/strategies/SinglePoolStrategy.cpp @@ -28,12 +28,12 @@ #include "Platform.h" -SinglePoolStrategy::SinglePoolStrategy(const Url *url, int retryPause, IStrategyListener *listener, bool quiet) : +SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, IStrategyListener *listener, bool quiet) : m_active(false), m_listener(listener) { m_client = new Client(0, Platform::userAgent(), this); - m_client->setUrl(url); + m_client->setUrl(pool); m_client->setRetryPause(retryPause * 1000); m_client->setQuiet(quiet); } diff --git a/src/net/strategies/SinglePoolStrategy.h b/src/net/strategies/SinglePoolStrategy.h index d5682cf7..ce3d0f7f 100644 --- a/src/net/strategies/SinglePoolStrategy.h +++ b/src/net/strategies/SinglePoolStrategy.h @@ -37,7 +37,7 @@ class Url; class SinglePoolStrategy : public IStrategy, public IClientListener { public: - SinglePoolStrategy(const Url *url, int retryPause, IStrategyListener *listener, bool quiet = false); + SinglePoolStrategy(const Pool &pool, int retryPause, IStrategyListener *listener, bool quiet = false); ~SinglePoolStrategy(); public: From 1ebaf677e0f056400b9c0ce951abd4456f2302e3 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 11 Apr 2018 06:39:24 +0700 Subject: [PATCH 043/109] Move static algo name conversions to Pool class. --- src/core/CommonConfig.cpp | 43 +-------------------------------------- src/core/CommonConfig.h | 6 ++---- src/net/Pool.cpp | 42 ++++++++++++++++++++++++++++++++++++++ src/net/Pool.h | 3 +++ src/workers/CpuThread.cpp | 2 +- 5 files changed, 49 insertions(+), 47 deletions(-) diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp index b8af451b..b1758921 100644 --- a/src/core/CommonConfig.cpp +++ b/src/core/CommonConfig.cpp @@ -39,25 +39,6 @@ #include "xmrig.h" -static const char *algoNames[] = { - "cryptonight", - "cryptonight-lite", - "cryptonight-heavy" -}; - - -static const char *algoNamesShort[] = { - "cn", - "cn-lite", - "cn-heavy" -}; - - -#if defined(_WIN32) && !defined(strcasecmp) -# define strcasecmp _stricmp -#endif - - xmrig::CommonConfig::CommonConfig() : m_algorithm(CRYPTONIGHT), m_adjusted(false), @@ -93,12 +74,6 @@ xmrig::CommonConfig::~CommonConfig() } -const char *xmrig::CommonConfig::algoName(Algo algorithm) -{ - return algoNames[algorithm]; -} - - bool xmrig::CommonConfig::adjust() { if (m_adjusted) { @@ -353,21 +328,5 @@ bool xmrig::CommonConfig::parseInt(int key, int arg) void xmrig::CommonConfig::setAlgo(const char *algo) { - if (strcasecmp(algo, "cryptonight-light") == 0) { - fprintf(stderr, "Algorithm \"cryptonight-light\" is deprecated, use \"cryptonight-lite\" instead\n"); - - m_algorithm = CRYPTONIGHT_LITE; - return; - } - - const size_t size = sizeof(algoNames) / sizeof(algoNames[0]); - - assert(size == (sizeof(algoNamesShort) / sizeof(algoNamesShort[0]))); - - for (size_t i = 0; i < size; i++) { - if (strcasecmp(algo, algoNames[i]) == 0 || strcasecmp(algo, algoNamesShort[i]) == 0) { - m_algorithm = static_cast(i); - break; - } - } + m_algorithm = Pool::algorithm(algo); } diff --git a/src/core/CommonConfig.h b/src/core/CommonConfig.h index 89dbc7ed..0b72b7e1 100644 --- a/src/core/CommonConfig.h +++ b/src/core/CommonConfig.h @@ -30,8 +30,8 @@ #include "core/utils/c_str.h" #include "interfaces/IConfig.h" -#include "xmrig.h" #include "net/Pool.h" +#include "xmrig.h" namespace xmrig { @@ -43,15 +43,13 @@ public: CommonConfig(); ~CommonConfig(); - static const char *algoName(Algo algorithm); - inline Algo algorithm() const { return m_algorithm; } inline bool isApiIPv6() const { return m_apiIPv6; } inline bool isApiRestricted() const { return m_apiRestricted; } inline bool isBackground() const { return m_background; } inline bool isColors() const { return m_colors; } inline bool isSyslog() const { return m_syslog; } - inline const char *algoName() const { return algoName(m_algorithm); } + inline const char *algoName() const { return Pool::algoName(m_algorithm); } inline const char *apiToken() const { return m_apiToken.data(); } inline const char *apiWorkerId() const { return m_apiWorkerId.data(); } inline const char *logFile() const { return m_logFile.data(); } diff --git a/src/net/Pool.cpp b/src/net/Pool.cpp index ff7d461a..f6816567 100644 --- a/src/net/Pool.cpp +++ b/src/net/Pool.cpp @@ -36,6 +36,20 @@ #endif +static const char *algoNames[] = { + "cryptonight", + "cryptonight-lite", + "cryptonight-heavy" +}; + + +static const char *algoNamesShort[] = { + "cn", + "cn-lite", + "cn-heavy" +}; + + Pool::Pool() : m_nicehash(false), m_keepAlive(0), @@ -89,6 +103,34 @@ Pool::Pool(const char *host, uint16_t port, const char *user, const char *passwo } +const char *Pool::algoName(xmrig::Algo algorithm) +{ + return algoNames[algorithm]; +} + + +xmrig::Algo Pool::algorithm(const char *algo) +{ + if (strcasecmp(algo, "cryptonight-light") == 0) { + fprintf(stderr, "Algorithm \"cryptonight-light\" is deprecated, use \"cryptonight-lite\" instead\n"); + + return xmrig::CRYPTONIGHT_LITE; + } + + const size_t size = sizeof(algoNames) / sizeof(algoNames[0]); + + assert(size == (sizeof(algoNamesShort) / sizeof(algoNamesShort[0]))); + + for (size_t i = 0; i < size; i++) { + if (strcasecmp(algo, algoNames[i]) == 0 || strcasecmp(algo, algoNamesShort[i]) == 0) { + return static_cast(i); + } + } + + return xmrig::CRYPTONIGHT; +} + + bool Pool::parse(const char *url) { assert(url != nullptr); diff --git a/src/net/Pool.h b/src/net/Pool.h index 5a2c3529..efa3e3a7 100644 --- a/src/net/Pool.h +++ b/src/net/Pool.h @@ -51,6 +51,9 @@ public: xmrig::Variant variant = xmrig::VARIANT_AUTO ); + static const char *algoName(xmrig::Algo algorithm); + static xmrig::Algo algorithm(const char *algo); + inline bool isNicehash() const { return m_nicehash; } inline bool isValid() const { return !m_host.isNull() && m_port > 0; } inline const char *host() const { return m_host.data(); } diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 7e68a990..482b4305 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -204,7 +204,7 @@ rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const auto &allocator = doc.GetAllocator(); obj.AddMember("type", "cpu", allocator); - obj.AddMember("algo", rapidjson::StringRef(CommonConfig::algoName(algorithm())), allocator); + obj.AddMember("algo", rapidjson::StringRef(Pool::algoName(algorithm())), allocator); obj.AddMember("av", m_av, allocator); obj.AddMember("low_power_mode", multiway(), allocator); obj.AddMember("affine_to_cpu", affinity(), allocator); From a73ad9b08924ff4b1ccfe78ae949a6e27a5cb2e1 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 11 Apr 2018 08:29:02 +0700 Subject: [PATCH 044/109] Fixed build with APP_DEBUG. --- src/Summary.cpp | 2 +- src/net/Client.cpp | 12 ++++++------ src/net/Client.h | 2 +- src/net/Pool.cpp | 4 ++-- src/net/strategies/FailoverStrategy.cpp | 2 +- src/net/strategies/SinglePoolStrategy.cpp | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Summary.cpp b/src/Summary.cpp index 6de1cd3a..5acda5c2 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -123,7 +123,7 @@ static void print_pools(xmrig::Config *config) # ifdef APP_DEBUG for (size_t i = 0; i < pools.size(); ++i) { - Log::i()->text("%s:%d, user: %s, pass: %s, ka: %d, nicehash: %d", pools[i]->host(), pools[i]->port(), pools[i]->user(), pools[i]->password(), pools[i]->keepAlive(), pools[i]->isNicehash()); + Log::i()->text("%s:%d, user: %s, pass: %s, ka: %d, nicehash: %d", pools[i].host(), pools[i].port(), pools[i].user(), pools[i].password(), pools[i].keepAlive(), pools[i].isNicehash()); } # endif } diff --git a/src/net/Client.cpp b/src/net/Client.cpp index 5574f37f..c4387a7c 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -107,7 +107,7 @@ void Client::connect() */ void Client::connect(const Pool &url) { - setUrl(url); + setPool(url); connect(); } @@ -131,7 +131,7 @@ void Client::deleteLater() } -void Client::setUrl(const Pool &pool) +void Client::setPool(const Pool &pool) { if (!pool.isValid()) { return; @@ -360,9 +360,9 @@ int Client::resolve(const char *host) int64_t Client::send(size_t size) { - LOG_DEBUG("[%s:%u] send (%d bytes): \"%s\"", m_url.host(), m_url.port(), size, m_sendBuf); + LOG_DEBUG("[%s] send (%d bytes): \"%s\"", m_pool.url(), size, m_sendBuf); if (state() != ConnectedState || !uv_is_writable(m_stream)) { - LOG_DEBUG_ERR("[%s:%u] send failed, invalid state: %d", m_url.host(), m_url.port(), m_state); + LOG_DEBUG_ERR("[%s] send failed, invalid state: %d", m_pool.url(), m_state); return -1; } @@ -475,7 +475,7 @@ void Client::parse(char *line, size_t len) line[len - 1] = '\0'; - LOG_DEBUG("[%s:%u] received (%d bytes): \"%s\"", m_url.host(), m_url.port(), len, line); + LOG_DEBUG("[%s] received (%d bytes): \"%s\"", m_pool.url(), len, line); if (len < 32 || line[0] != '{') { if (!m_quiet) { @@ -634,7 +634,7 @@ void Client::reconnect() void Client::setState(SocketState state) { - LOG_DEBUG("[%s:%u] state: %d", m_url.host(), m_url.port(), state); + LOG_DEBUG("[%s] state: %d", m_pool.url(), state); if (m_state == state) { return; diff --git a/src/net/Client.h b/src/net/Client.h index 910c8379..0692d38b 100644 --- a/src/net/Client.h +++ b/src/net/Client.h @@ -63,7 +63,7 @@ public: void connect(); void connect(const Pool &pool); void deleteLater(); - void setUrl(const Pool &pool); + void setPool(const Pool &pool); void tick(uint64_t now); inline bool isReady() const { return m_state == ConnectedState && m_failures == 0; } diff --git a/src/net/Pool.cpp b/src/net/Pool.cpp index f6816567..b3766b08 100644 --- a/src/net/Pool.cpp +++ b/src/net/Pool.cpp @@ -76,7 +76,6 @@ Pool::Pool(const char *url) : m_keepAlive(0), m_port(kDefaultPort), m_algo(xmrig::CRYPTONIGHT), - m_url(url), m_variant(xmrig::VARIANT_AUTO) { parse(url); @@ -150,6 +149,7 @@ bool Pool::parse(const char *url) return false; } + m_url = url; if (base[0] == '[') { return parseIPv6(base); } @@ -157,7 +157,7 @@ bool Pool::parse(const char *url) const char *port = strchr(base, ':'); if (!port) { m_host = base; - return false; + return true; } const size_t size = port++ - base + 1; diff --git a/src/net/strategies/FailoverStrategy.cpp b/src/net/strategies/FailoverStrategy.cpp index 7a581407..a4e25277 100644 --- a/src/net/strategies/FailoverStrategy.cpp +++ b/src/net/strategies/FailoverStrategy.cpp @@ -156,7 +156,7 @@ void FailoverStrategy::onResultAccepted(Client *client, const SubmitResult &resu void FailoverStrategy::add(const Pool &pool) { Client *client = new Client((int) m_pools.size(), Platform::userAgent(), this); - client->setUrl(pool); + client->setPool(pool); client->setRetryPause(m_retryPause * 1000); client->setQuiet(m_quiet); diff --git a/src/net/strategies/SinglePoolStrategy.cpp b/src/net/strategies/SinglePoolStrategy.cpp index 42a60b30..8c113d93 100644 --- a/src/net/strategies/SinglePoolStrategy.cpp +++ b/src/net/strategies/SinglePoolStrategy.cpp @@ -33,7 +33,7 @@ SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, IStrate m_listener(listener) { m_client = new Client(0, Platform::userAgent(), this); - m_client->setUrl(pool); + m_client->setPool(pool); m_client->setRetryPause(retryPause * 1000); m_client->setQuiet(quiet); } From b13640e4a161d566db325d244c6e406d603e130d Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 12 Apr 2018 11:38:43 +0700 Subject: [PATCH 045/109] Fixes for build without cn-lite and cn-heavy. --- src/core/CommonConfig.cpp | 2 +- src/core/ConfigLoader.cpp | 8 ++++---- src/core/ConfigLoader_platform.h | 12 +++++++++++- src/crypto/CryptoNight_constants.h | 9 +++++++++ src/net/Pool.cpp | 23 +++++++++++++++++++++-- src/workers/DoubleWorker.cpp | 6 +++++- src/workers/SingleWorker.cpp | 4 ++++ src/xmrig.h | 1 + 8 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp index b1758921..b444537e 100644 --- a/src/core/CommonConfig.cpp +++ b/src/core/CommonConfig.cpp @@ -92,7 +92,7 @@ bool xmrig::CommonConfig::adjust() bool xmrig::CommonConfig::isValid() const { - return m_pools[0].isValid(); + return m_pools[0].isValid() && m_algorithm != INVALID_ALGO; } diff --git a/src/core/ConfigLoader.cpp b/src/core/ConfigLoader.cpp index 8c7f6546..c84ba962 100644 --- a/src/core/ConfigLoader.cpp +++ b/src/core/ConfigLoader.cpp @@ -168,7 +168,7 @@ xmrig::IConfig *xmrig::ConfigLoader::load(int argc, char **argv, IConfigCreator } if (!config->isValid()) { - fprintf(stderr, "No pool URL supplied. Exiting.\n"); + fprintf(stderr, "No valid configuration found. Exiting.\n"); delete config; return nullptr; } @@ -293,13 +293,13 @@ void xmrig::ConfigLoader::showVersion() printf("\n features:" # if defined(__i386__) || defined(_M_IX86) - " i386" + " 32-bit" # elif defined(__x86_64__) || defined(_M_AMD64) - " x86_64" + " 64-bit" # endif # if defined(__AES__) || defined(_MSC_VER) - " AES-NI" + " AES" # endif "\n"); diff --git a/src/core/ConfigLoader_platform.h b/src/core/ConfigLoader_platform.h index 68eef639..a090fb99 100644 --- a/src/core/ConfigLoader_platform.h +++ b/src/core/ConfigLoader_platform.h @@ -43,7 +43,17 @@ namespace xmrig { static char const usage[] = "\ Usage: " APP_ID " [OPTIONS]\n\ Options:\n\ - -a, --algo=ALGO cryptonight (default) or cryptonight-lite\n\ + -a, --algo=ALGO specify the algorithm to use\n\ + cryptonight\n" +#ifndef XMRIG_NO_AEON +"\ + cryptonight-lite\n" +#endif +#ifndef XMRIG_NO_SUMO +"\ + cryptonight-heavy\n" +#endif +"\ -o, --url=URL URL of mining server\n\ -O, --userpass=U:P username:password pair for mining server\n\ -u, --user=USERNAME username for mining server\n\ diff --git a/src/crypto/CryptoNight_constants.h b/src/crypto/CryptoNight_constants.h index d576b47a..60f0df08 100644 --- a/src/crypto/CryptoNight_constants.h +++ b/src/crypto/CryptoNight_constants.h @@ -65,6 +65,9 @@ inline size_t cn_select_memory(Algo algorithm) case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_MEMORY; + + default: + break; } return 0; @@ -88,6 +91,9 @@ inline uint32_t cn_select_mask(Algo algorithm) case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_MASK; + + default: + break; } return 0; @@ -111,6 +117,9 @@ inline uint32_t cn_select_iter(Algo algorithm) case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_ITER; + + default: + break; } return 0; diff --git a/src/net/Pool.cpp b/src/net/Pool.cpp index b3766b08..4d1d7439 100644 --- a/src/net/Pool.cpp +++ b/src/net/Pool.cpp @@ -38,15 +38,31 @@ static const char *algoNames[] = { "cryptonight", +# ifndef XMRIG_NO_AEON "cryptonight-lite", +# else + nullptr, +# endif +# ifndef XMRIG_NO_SUMO "cryptonight-heavy" +# else + nullptr +# endif }; static const char *algoNamesShort[] = { "cn", +# ifndef XMRIG_NO_AEON "cn-lite", +# else + nullptr, +# endif +# ifndef XMRIG_NO_SUMO "cn-heavy" +# else + nullptr +# endif }; @@ -110,23 +126,26 @@ const char *Pool::algoName(xmrig::Algo algorithm) xmrig::Algo Pool::algorithm(const char *algo) { +# ifndef XMRIG_NO_AEON if (strcasecmp(algo, "cryptonight-light") == 0) { fprintf(stderr, "Algorithm \"cryptonight-light\" is deprecated, use \"cryptonight-lite\" instead\n"); return xmrig::CRYPTONIGHT_LITE; } +# endif const size_t size = sizeof(algoNames) / sizeof(algoNames[0]); assert(size == (sizeof(algoNamesShort) / sizeof(algoNamesShort[0]))); for (size_t i = 0; i < size; i++) { - if (strcasecmp(algo, algoNames[i]) == 0 || strcasecmp(algo, algoNamesShort[i]) == 0) { + if ((algoNames[i] && strcasecmp(algo, algoNames[i]) == 0) || (algoNamesShort[i] && strcasecmp(algo, algoNamesShort[i]) == 0)) { return static_cast(i); } } - return xmrig::CRYPTONIGHT; + fprintf(stderr, "Unknown algorithm \"%s\" specified.\n", algo); + return xmrig::INVALID_ALGO; } diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index a6176743..6ba5c47f 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -144,7 +144,11 @@ bool DoubleWorker::selfTest() } # endif - return memcmp(m_hash, test_output_heavy, 64) == 0; +# ifndef XMRIG_NO_SUMO + return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_hash, test_output_heavy, 64) == 0; +# else + return false; +# endif } diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index ca6b93a6..815b965d 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -116,7 +116,11 @@ bool SingleWorker::selfTest() } # endif +# ifndef XMRIG_NO_SUMO return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_result.result, test_output_heavy, 32) == 0; +# else + return false; +# endif } diff --git a/src/xmrig.h b/src/xmrig.h index f4ae8162..7196aee3 100644 --- a/src/xmrig.h +++ b/src/xmrig.h @@ -30,6 +30,7 @@ namespace xmrig enum Algo { + INVALID_ALGO = -1, CRYPTONIGHT, /* CryptoNight (Monero) */ CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ CRYPTONIGHT_HEAVY, /* CryptoNight-Heavy (SUMO) */ From 01c824584643690f9dc7e015cb88e8e831f878e9 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 13 Apr 2018 05:05:53 +0700 Subject: [PATCH 046/109] #548 Fixed macOS build. --- src/core/CommonConfig.cpp | 2 +- src/core/Config.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/CommonConfig.cpp b/src/core/CommonConfig.cpp index b444537e..726b0e37 100644 --- a/src/core/CommonConfig.cpp +++ b/src/core/CommonConfig.cpp @@ -266,7 +266,7 @@ bool xmrig::CommonConfig::save() uv_fs_close(uv_default_loop(), &req, fd, nullptr); uv_fs_req_cleanup(&req); - LOG_NOTICE("configuration saved to: \"%s\"", m_fileName); + LOG_NOTICE("configuration saved to: \"%s\"", m_fileName.data()); return true; } diff --git a/src/core/Config.cpp b/src/core/Config.cpp index a9136660..f7211250 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -279,7 +279,7 @@ bool xmrig::Config::parseInt(int key, int arg) { switch (key) { case xmrig::IConfig::ThreadsKey: /* --threads */ - if (m_threadsCount >= 0 && arg < 1024) { + if (arg >= 0 && arg < 1024) { m_threadsCount = arg; } break; From f197f6b1ebb13f6c46ec1e79fe3547961a7902f8 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 13 Apr 2018 06:38:18 +0700 Subject: [PATCH 047/109] Changed directory structure. --- CMakeLists.txt | 15 +++++++-------- src/{core => common/config}/CommonConfig.cpp | 2 +- src/{core => common/config}/CommonConfig.h | 2 +- src/{core => common/config}/ConfigLoader.cpp | 4 ++-- src/{core => common/config}/ConfigLoader.h | 0 src/{core => common/config}/ConfigWatcher.cpp | 4 ++-- src/{core => common/config}/ConfigWatcher.h | 2 +- src/{core => common}/utils/c_str.h | 0 src/core/Config.cpp | 2 +- src/core/Config.h | 2 +- src/core/Controller.cpp | 2 +- src/net/Pool.h | 2 +- src/workers/CpuThread.cpp | 2 +- 13 files changed, 19 insertions(+), 20 deletions(-) rename src/{core => common/config}/CommonConfig.cpp (99%) rename src/{core => common/config}/CommonConfig.h (99%) rename src/{core => common/config}/ConfigLoader.cpp (98%) rename src/{core => common/config}/ConfigLoader.h (100%) rename src/{core => common/config}/ConfigWatcher.cpp (97%) rename src/{core => common/config}/ConfigWatcher.h (98%) rename src/{core => common}/utils/c_str.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5502405c..096fa97f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,15 +14,14 @@ include (cmake/cpu.cmake) set(HEADERS src/api/NetworkState.h src/App.h + src/common/config/CommonConfig.h + src/common/config/ConfigLoader.h + src/common/config/ConfigWatcher.h + src/common/utils/c_str.h src/Console.h - src/core/CommonConfig.h src/core/Config.cpp - src/core/ConfigLoader.cpp - src/core/ConfigLoader.h src/core/ConfigLoader_platform.h - src/core/ConfigWatcher.cpp src/core/Controller.h - src/core/utils/c_str.h src/Cpu.h src/interfaces/IClientListener.h src/interfaces/IConfig.h @@ -89,11 +88,11 @@ endif() set(SOURCES src/api/NetworkState.cpp src/App.cpp + src/common/config/CommonConfig.cpp + src/common/config/ConfigLoader.cpp + src/common/config/ConfigWatcher.cpp src/Console.cpp - src/core/CommonConfig.cpp src/core/Config.cpp - src/core/ConfigLoader.cpp - src/core/ConfigWatcher.cpp src/core/Controller.cpp src/log/ConsoleLog.cpp src/log/FileLog.cpp diff --git a/src/core/CommonConfig.cpp b/src/common/config/CommonConfig.cpp similarity index 99% rename from src/core/CommonConfig.cpp rename to src/common/config/CommonConfig.cpp index 726b0e37..6902b7a2 100644 --- a/src/core/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -29,7 +29,7 @@ #include -#include "core/CommonConfig.h" +#include "common/config/CommonConfig.h" #include "donate.h" #include "log/Log.h" #include "net/Pool.h" diff --git a/src/core/CommonConfig.h b/src/common/config/CommonConfig.h similarity index 99% rename from src/core/CommonConfig.h rename to src/common/config/CommonConfig.h index 0b72b7e1..f4cf4b43 100644 --- a/src/core/CommonConfig.h +++ b/src/common/config/CommonConfig.h @@ -28,7 +28,7 @@ #include -#include "core/utils/c_str.h" +#include "common/utils/c_str.h" #include "interfaces/IConfig.h" #include "net/Pool.h" #include "xmrig.h" diff --git a/src/core/ConfigLoader.cpp b/src/common/config/ConfigLoader.cpp similarity index 98% rename from src/core/ConfigLoader.cpp rename to src/common/config/ConfigLoader.cpp index c84ba962..a9c802f6 100644 --- a/src/core/ConfigLoader.cpp +++ b/src/common/config/ConfigLoader.cpp @@ -32,10 +32,10 @@ #endif +#include "common/config/ConfigLoader.h" +#include "common/config/ConfigWatcher.h" #include "core/ConfigCreator.h" -#include "core/ConfigLoader.h" #include "core/ConfigLoader_platform.h" -#include "core/ConfigWatcher.h" #include "interfaces/IConfig.h" #include "interfaces/IWatcherListener.h" #include "net/Pool.h" diff --git a/src/core/ConfigLoader.h b/src/common/config/ConfigLoader.h similarity index 100% rename from src/core/ConfigLoader.h rename to src/common/config/ConfigLoader.h diff --git a/src/core/ConfigWatcher.cpp b/src/common/config/ConfigWatcher.cpp similarity index 97% rename from src/core/ConfigWatcher.cpp rename to src/common/config/ConfigWatcher.cpp index 092a0f3a..21d73188 100644 --- a/src/core/ConfigWatcher.cpp +++ b/src/common/config/ConfigWatcher.cpp @@ -25,9 +25,9 @@ #include +#include "common/config/ConfigLoader.h" +#include "common/config/ConfigWatcher.h" #include "core/ConfigCreator.h" -#include "core/ConfigLoader.h" -#include "core/ConfigWatcher.h" #include "interfaces/IWatcherListener.h" #include "log/Log.h" diff --git a/src/core/ConfigWatcher.h b/src/common/config/ConfigWatcher.h similarity index 98% rename from src/core/ConfigWatcher.h rename to src/common/config/ConfigWatcher.h index a5d25864..7f38b45a 100644 --- a/src/core/ConfigWatcher.h +++ b/src/common/config/ConfigWatcher.h @@ -29,7 +29,7 @@ #include -#include "core/utils/c_str.h" +#include "common/utils/c_str.h" #include "rapidjson/fwd.h" diff --git a/src/core/utils/c_str.h b/src/common/utils/c_str.h similarity index 100% rename from src/core/utils/c_str.h rename to src/common/utils/c_str.h diff --git a/src/core/Config.cpp b/src/core/Config.cpp index f7211250..ee305091 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -26,9 +26,9 @@ #include +#include "common/config/ConfigLoader.h" #include "core/Config.h" #include "core/ConfigCreator.h" -#include "core/ConfigLoader.h" #include "Cpu.h" #include "net/Pool.h" #include "rapidjson/document.h" diff --git a/src/core/Config.h b/src/core/Config.h index 536e1c01..999f3059 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -29,7 +29,7 @@ #include -#include "core/CommonConfig.h" +#include "common/config/CommonConfig.h" #include "rapidjson/fwd.h" #include "xmrig.h" diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 805861ef..954e5b10 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -25,8 +25,8 @@ #include +#include "common/config/ConfigLoader.h" #include "core/Config.h" -#include "core/ConfigLoader.h" #include "core/Controller.h" #include "Cpu.h" #include "interfaces/IControllerListener.h" diff --git a/src/net/Pool.h b/src/net/Pool.h index efa3e3a7..aff1ea31 100644 --- a/src/net/Pool.h +++ b/src/net/Pool.h @@ -28,7 +28,7 @@ #include -#include "core/utils/c_str.h" +#include "common/utils/c_str.h" #include "xmrig.h" diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 482b4305..20a8006f 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -24,7 +24,7 @@ #include -#include "core/CommonConfig.h" +#include "net/Pool.h" #include "rapidjson/document.h" #include "workers/CpuThread.h" From 51422f4b1e3e7fe0df5506c12b01c547d18c55df Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 13 Apr 2018 07:00:51 +0700 Subject: [PATCH 048/109] Move xmrig.h to common/xmrig.h. --- CMakeLists.txt | 2 +- src/Cpu.h | 2 +- src/Mem.h | 2 +- src/Mem_win.cpp | 4 ++-- src/common/config/CommonConfig.cpp | 1 - src/common/config/CommonConfig.h | 2 +- src/{ => common}/xmrig.h | 0 src/core/Config.cpp | 1 - src/core/Config.h | 2 +- src/crypto/CryptoNight_constants.h | 2 +- src/interfaces/IThread.h | 2 +- src/net/Job.h | 2 +- src/net/Pool.h | 2 +- src/net/strategies/DonateStrategy.cpp | 2 +- src/workers/CpuThread.h | 2 +- 15 files changed, 13 insertions(+), 15 deletions(-) rename src/{ => common}/xmrig.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 096fa97f..97d3e51b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ set(HEADERS src/common/config/ConfigLoader.h src/common/config/ConfigWatcher.h src/common/utils/c_str.h + src/common/xmrig.h src/Console.h src/core/Config.cpp src/core/ConfigLoader_platform.h @@ -60,7 +61,6 @@ set(HEADERS src/workers/SingleWorker.h src/workers/Worker.h src/workers/Workers.h - src/xmrig.h ) set(HEADERS_CRYPTO diff --git a/src/Cpu.h b/src/Cpu.h index 118c7b7d..e739ccce 100644 --- a/src/Cpu.h +++ b/src/Cpu.h @@ -28,7 +28,7 @@ #include -#include "xmrig.h" +#include "common/xmrig.h" class Cpu diff --git a/src/Mem.h b/src/Mem.h index 73947b42..06b470c8 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -30,7 +30,7 @@ #include -#include "xmrig.h" +#include "common/xmrig.h" struct cryptonight_ctx; diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index ec30e3e8..1f3066ea 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -34,10 +34,10 @@ # include #endif -#include "log/Log.h" +#include "common/xmrig.h" #include "crypto/CryptoNight.h" +#include "log/Log.h" #include "Mem.h" -#include "xmrig.h" /***************************************************************** diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp index 6902b7a2..2cce845c 100644 --- a/src/common/config/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -36,7 +36,6 @@ #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" -#include "xmrig.h" xmrig::CommonConfig::CommonConfig() : diff --git a/src/common/config/CommonConfig.h b/src/common/config/CommonConfig.h index f4cf4b43..5a229269 100644 --- a/src/common/config/CommonConfig.h +++ b/src/common/config/CommonConfig.h @@ -29,9 +29,9 @@ #include "common/utils/c_str.h" +#include "common/xmrig.h" #include "interfaces/IConfig.h" #include "net/Pool.h" -#include "xmrig.h" namespace xmrig { diff --git a/src/xmrig.h b/src/common/xmrig.h similarity index 100% rename from src/xmrig.h rename to src/common/xmrig.h diff --git a/src/core/Config.cpp b/src/core/Config.cpp index ee305091..07f11192 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -35,7 +35,6 @@ #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" #include "workers/CpuThread.h" -#include "xmrig.h" static char affinity_tmp[20] = { 0 }; diff --git a/src/core/Config.h b/src/core/Config.h index 999f3059..fd33b614 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -30,8 +30,8 @@ #include "common/config/CommonConfig.h" +#include "common/xmrig.h" #include "rapidjson/fwd.h" -#include "xmrig.h" class Addr; diff --git a/src/crypto/CryptoNight_constants.h b/src/crypto/CryptoNight_constants.h index 60f0df08..3c746d47 100644 --- a/src/crypto/CryptoNight_constants.h +++ b/src/crypto/CryptoNight_constants.h @@ -29,7 +29,7 @@ #include -#include "xmrig.h" +#include "common/xmrig.h" namespace xmrig diff --git a/src/interfaces/IThread.h b/src/interfaces/IThread.h index e2325c72..5b3efa0d 100644 --- a/src/interfaces/IThread.h +++ b/src/interfaces/IThread.h @@ -27,8 +27,8 @@ #include +#include "common/xmrig.h" #include "rapidjson/fwd.h" -#include "xmrig.h" namespace xmrig { diff --git a/src/net/Job.h b/src/net/Job.h index e8964314..a60f061c 100644 --- a/src/net/Job.h +++ b/src/net/Job.h @@ -30,8 +30,8 @@ #include +#include "common/xmrig.h" #include "net/Id.h" -#include "xmrig.h" class Job diff --git a/src/net/Pool.h b/src/net/Pool.h index aff1ea31..ecce865a 100644 --- a/src/net/Pool.h +++ b/src/net/Pool.h @@ -29,7 +29,7 @@ #include "common/utils/c_str.h" -#include "xmrig.h" +#include "common/xmrig.h" class Pool diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 311ca424..da25e23f 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -22,13 +22,13 @@ */ +#include "common/xmrig.h" #include "interfaces/IStrategyListener.h" #include "net/Client.h" #include "net/Job.h" #include "net/strategies/DonateStrategy.h" #include "net/strategies/FailoverStrategy.h" #include "Platform.h" -#include "xmrig.h" extern "C" diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index aef73719..dadd0424 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -25,8 +25,8 @@ #define __CPUTHREAD_H__ +#include "common/xmrig.h" #include "interfaces/IThread.h" -#include "xmrig.h" struct cryptonight_ctx; From a6b698d4ebc93525adc592f85e82fd41d7a2d2d2 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 13 Apr 2018 07:12:53 +0700 Subject: [PATCH 049/109] Move common parts of API. --- CMakeLists.txt | 12 ++++++------ src/App.cpp | 2 +- src/api/Api.cpp | 4 ++-- src/api/ApiRouter.cpp | 4 ++-- src/{ => common}/api/HttpBody.h | 0 src/{ => common}/api/HttpReply.h | 0 src/{ => common}/api/HttpRequest.cpp | 6 +++--- src/{ => common}/api/HttpRequest.h | 0 src/{ => common}/api/Httpd.cpp | 6 +++--- src/{ => common}/api/Httpd.h | 0 10 files changed, 17 insertions(+), 17 deletions(-) rename src/{ => common}/api/HttpBody.h (100%) rename src/{ => common}/api/HttpReply.h (100%) rename src/{ => common}/api/HttpRequest.cpp (97%) rename src/{ => common}/api/HttpRequest.h (100%) rename src/{ => common}/api/Httpd.cpp (97%) rename src/{ => common}/api/Httpd.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97d3e51b..0da768b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -214,14 +214,14 @@ if (WITH_HTTPD) set(HTTPD_SOURCES src/api/Api.h src/api/ApiRouter.h - src/api/HttpBody.h - src/api/Httpd.h - src/api/HttpReply.h - src/api/HttpRequest.h + src/common/api/HttpBody.h + src/common/api/Httpd.h + src/common/api/HttpReply.h + src/common/api/HttpRequest.h src/api/Api.cpp src/api/ApiRouter.cpp - src/api/Httpd.cpp - src/api/HttpRequest.cpp + src/common/api/Httpd.cpp + src/common/api/HttpRequest.cpp ) else() message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support") diff --git a/src/App.cpp b/src/App.cpp index dc22836d..9ac78500 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -45,7 +45,7 @@ #ifndef XMRIG_NO_HTTPD -# include "api/Httpd.h" +# include "common/api/Httpd.h" #endif diff --git a/src/api/Api.cpp b/src/api/Api.cpp index 36859136..6f9991ee 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -26,8 +26,8 @@ #include "api/Api.h" #include "api/ApiRouter.h" -#include "api/HttpReply.h" -#include "api/HttpRequest.h" +#include "common/api/HttpReply.h" +#include "common/api/HttpRequest.h" ApiRouter *Api::m_router = nullptr; diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 6c4f1f27..81f765c5 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -33,8 +33,8 @@ #include "api/ApiRouter.h" -#include "api/HttpReply.h" -#include "api/HttpRequest.h" +#include "common/api/HttpReply.h" +#include "common/api/HttpRequest.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" diff --git a/src/api/HttpBody.h b/src/common/api/HttpBody.h similarity index 100% rename from src/api/HttpBody.h rename to src/common/api/HttpBody.h diff --git a/src/api/HttpReply.h b/src/common/api/HttpReply.h similarity index 100% rename from src/api/HttpReply.h rename to src/common/api/HttpReply.h diff --git a/src/api/HttpRequest.cpp b/src/common/api/HttpRequest.cpp similarity index 97% rename from src/api/HttpRequest.cpp rename to src/common/api/HttpRequest.cpp index ac7210bd..01245dfc 100644 --- a/src/api/HttpRequest.cpp +++ b/src/common/api/HttpRequest.cpp @@ -25,9 +25,9 @@ #include #include -#include "api/HttpBody.h" -#include "api/HttpRequest.h" -#include "api/HttpReply.h" +#include "common/api/HttpBody.h" +#include "common/api/HttpRequest.h" +#include "common/api/HttpReply.h" #ifndef MHD_HTTP_PAYLOAD_TOO_LARGE diff --git a/src/api/HttpRequest.h b/src/common/api/HttpRequest.h similarity index 100% rename from src/api/HttpRequest.h rename to src/common/api/HttpRequest.h diff --git a/src/api/Httpd.cpp b/src/common/api/Httpd.cpp similarity index 97% rename from src/api/Httpd.cpp rename to src/common/api/Httpd.cpp index e0901b77..135ac7c9 100644 --- a/src/api/Httpd.cpp +++ b/src/common/api/Httpd.cpp @@ -27,9 +27,9 @@ #include "api/Api.h" -#include "api/Httpd.h" -#include "api/HttpReply.h" -#include "api/HttpRequest.h" +#include "common/api/Httpd.h" +#include "common/api/HttpReply.h" +#include "common/api/HttpRequest.h" #include "log/Log.h" diff --git a/src/api/Httpd.h b/src/common/api/Httpd.h similarity index 100% rename from src/api/Httpd.h rename to src/common/api/Httpd.h From c1800094d0a5b91755ea66498ebd0c50261a4a1b Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 13 Apr 2018 07:23:01 +0700 Subject: [PATCH 050/109] Move Platform. --- CMakeLists.txt | 10 +++++----- src/App.cpp | 2 +- src/api/ApiRouter.cpp | 2 +- src/{ => common}/Platform.cpp | 0 src/{ => common}/Platform.h | 0 src/{ => common}/Platform_mac.cpp | 0 src/{ => common}/Platform_unix.cpp | 0 src/{ => common}/Platform_win.cpp | 0 src/common/config/ConfigLoader.cpp | 2 +- src/core/Controller.cpp | 2 +- src/net/strategies/DonateStrategy.cpp | 2 +- src/net/strategies/FailoverStrategy.cpp | 2 +- src/net/strategies/SinglePoolStrategy.cpp | 2 +- src/workers/Worker.cpp | 2 +- 14 files changed, 13 insertions(+), 13 deletions(-) rename src/{ => common}/Platform.cpp (100%) rename src/{ => common}/Platform.h (100%) rename src/{ => common}/Platform_mac.cpp (100%) rename src/{ => common}/Platform_unix.cpp (100%) rename src/{ => common}/Platform_win.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0da768b2..c8d381d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ set(HEADERS src/common/config/CommonConfig.h src/common/config/ConfigLoader.h src/common/config/ConfigWatcher.h + src/common/Platform.h src/common/utils/c_str.h src/common/xmrig.h src/Console.h @@ -51,7 +52,6 @@ set(HEADERS src/net/strategies/FailoverStrategy.h src/net/strategies/SinglePoolStrategy.h src/net/SubmitResult.h - src/Platform.h src/Summary.h src/version.h src/workers/CpuThread.h @@ -91,6 +91,7 @@ set(SOURCES src/common/config/CommonConfig.cpp src/common/config/ConfigLoader.cpp src/common/config/ConfigWatcher.cpp + src/common/Platform.cpp src/Console.cpp src/core/Config.cpp src/core/Controller.cpp @@ -106,7 +107,6 @@ set(SOURCES src/net/strategies/FailoverStrategy.cpp src/net/strategies/SinglePoolStrategy.cpp src/net/SubmitResult.cpp - src/Platform.cpp src/Summary.cpp src/workers/CpuThread.cpp src/workers/DoubleWorker.cpp @@ -130,9 +130,9 @@ if (WIN32) set(SOURCES_OS res/app.rc src/App_win.cpp + src/common/Platform_win.cpp src/Cpu_win.cpp src/Mem_win.cpp - src/Platform_win.cpp ) add_definitions(/DWIN32) @@ -140,16 +140,16 @@ if (WIN32) elseif (APPLE) set(SOURCES_OS src/App_unix.cpp + src/common/Platform_mac.cpp src/Cpu_mac.cpp src/Mem_unix.cpp - src/Platform_mac.cpp ) else() set(SOURCES_OS src/App_unix.cpp + src/common/Platform_unix.cpp src/Cpu_unix.cpp src/Mem_unix.cpp - src/Platform_unix.cpp ) set(EXTRA_LIBS pthread rt) diff --git a/src/App.cpp b/src/App.cpp index 9ac78500..3d0cb3df 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -28,6 +28,7 @@ #include "api/Api.h" #include "App.h" +#include "common/Platform.h" #include "Console.h" #include "core/Config.h" #include "core/Controller.h" @@ -38,7 +39,6 @@ #include "log/Log.h" #include "Mem.h" #include "net/Network.h" -#include "Platform.h" #include "Summary.h" #include "version.h" #include "workers/Workers.h" diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 81f765c5..cb7a8005 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -35,13 +35,13 @@ #include "api/ApiRouter.h" #include "common/api/HttpReply.h" #include "common/api/HttpRequest.h" +#include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" #include "interfaces/IThread.h" #include "Mem.h" #include "net/Job.h" -#include "Platform.h" #include "rapidjson/document.h" #include "rapidjson/prettywriter.h" #include "rapidjson/stringbuffer.h" diff --git a/src/Platform.cpp b/src/common/Platform.cpp similarity index 100% rename from src/Platform.cpp rename to src/common/Platform.cpp diff --git a/src/Platform.h b/src/common/Platform.h similarity index 100% rename from src/Platform.h rename to src/common/Platform.h diff --git a/src/Platform_mac.cpp b/src/common/Platform_mac.cpp similarity index 100% rename from src/Platform_mac.cpp rename to src/common/Platform_mac.cpp diff --git a/src/Platform_unix.cpp b/src/common/Platform_unix.cpp similarity index 100% rename from src/Platform_unix.cpp rename to src/common/Platform_unix.cpp diff --git a/src/Platform_win.cpp b/src/common/Platform_win.cpp similarity index 100% rename from src/Platform_win.cpp rename to src/common/Platform_win.cpp diff --git a/src/common/config/ConfigLoader.cpp b/src/common/config/ConfigLoader.cpp index a9c802f6..47c6cdf9 100644 --- a/src/common/config/ConfigLoader.cpp +++ b/src/common/config/ConfigLoader.cpp @@ -34,12 +34,12 @@ #include "common/config/ConfigLoader.h" #include "common/config/ConfigWatcher.h" +#include "common/Platform.h" #include "core/ConfigCreator.h" #include "core/ConfigLoader_platform.h" #include "interfaces/IConfig.h" #include "interfaces/IWatcherListener.h" #include "net/Pool.h" -#include "Platform.h" #include "rapidjson/document.h" #include "rapidjson/error/en.h" #include "rapidjson/filereadstream.h" diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 954e5b10..f120c0c1 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -26,6 +26,7 @@ #include "common/config/ConfigLoader.h" +#include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" @@ -34,7 +35,6 @@ #include "log/FileLog.h" #include "log/Log.h" #include "net/Network.h" -#include "Platform.h" #ifdef HAVE_SYSLOG_H diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index da25e23f..27beae33 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -22,13 +22,13 @@ */ +#include "common/Platform.h" #include "common/xmrig.h" #include "interfaces/IStrategyListener.h" #include "net/Client.h" #include "net/Job.h" #include "net/strategies/DonateStrategy.h" #include "net/strategies/FailoverStrategy.h" -#include "Platform.h" extern "C" diff --git a/src/net/strategies/FailoverStrategy.cpp b/src/net/strategies/FailoverStrategy.cpp index a4e25277..cef9da0c 100644 --- a/src/net/strategies/FailoverStrategy.cpp +++ b/src/net/strategies/FailoverStrategy.cpp @@ -22,10 +22,10 @@ */ +#include "common/Platform.h" #include "interfaces/IStrategyListener.h" #include "net/Client.h" #include "net/strategies/FailoverStrategy.h" -#include "Platform.h" FailoverStrategy::FailoverStrategy(const std::vector &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) : diff --git a/src/net/strategies/SinglePoolStrategy.cpp b/src/net/strategies/SinglePoolStrategy.cpp index 8c113d93..c74a794b 100644 --- a/src/net/strategies/SinglePoolStrategy.cpp +++ b/src/net/strategies/SinglePoolStrategy.cpp @@ -22,10 +22,10 @@ */ +#include "common/Platform.h" #include "interfaces/IStrategyListener.h" #include "net/Client.h" #include "net/strategies/SinglePoolStrategy.h" -#include "Platform.h" SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, IStrategyListener *listener, bool quiet) : diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index f9162e3f..30305ac6 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -24,9 +24,9 @@ #include +#include "common/Platform.h" #include "Cpu.h" #include "Mem.h" -#include "Platform.h" #include "workers/CpuThread.h" #include "workers/Handle.h" #include "workers/Worker.h" From 9ce9147dad8924e9c14537ab76639076b7eb6dbf Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 13 Apr 2018 09:27:37 +0700 Subject: [PATCH 051/109] Use new method to set affinity. --- src/App_unix.cpp | 6 ------ src/App_win.cpp | 6 ------ src/Cpu.h | 1 - src/Cpu_unix.cpp | 25 ------------------------- src/Cpu_win.cpp | 11 ----------- src/Mem_unix.cpp | 2 +- src/common/Platform.cpp | 9 +++++---- src/common/Platform.h | 14 ++++++++++---- src/common/Platform_mac.cpp | 19 +++++++++++++++---- src/common/Platform_unix.cpp | 34 ++++++++++++++++++++++++++++++---- src/common/Platform_win.cpp | 21 +++++++++++++++------ src/core/Controller.cpp | 1 - src/workers/Handle.cpp | 3 +-- src/workers/Handle.h | 4 +--- src/workers/Worker.cpp | 6 +++--- src/workers/Workers.cpp | 2 +- 16 files changed, 82 insertions(+), 82 deletions(-) diff --git a/src/App_unix.cpp b/src/App_unix.cpp index fdb2b124..f739e42e 100644 --- a/src/App_unix.cpp +++ b/src/App_unix.cpp @@ -31,7 +31,6 @@ #include "App.h" #include "core/Config.h" #include "core/Controller.h" -#include "Cpu.h" #include "log/Log.h" @@ -39,11 +38,6 @@ void App::background() { signal(SIGPIPE, SIG_IGN); - const int64_t affinity = m_controller->config()->affinity(); - if (affinity != -1L) { - Cpu::setAffinity(-1, affinity); - } - if (!m_controller->config()->isBackground()) { return; } diff --git a/src/App_win.cpp b/src/App_win.cpp index b3a2c4cf..9b923870 100644 --- a/src/App_win.cpp +++ b/src/App_win.cpp @@ -27,18 +27,12 @@ #include "App.h" -#include "Cpu.h" #include "core/Controller.h" #include "core/Config.h" void App::background() { - const int64_t affinity = m_controller->config()->affinity(); - if (affinity != -1L) { - Cpu::setAffinity(-1, affinity); - } - if (!m_controller->config()->isBackground()) { return; } diff --git a/src/Cpu.h b/src/Cpu.h index e739ccce..97e593ed 100644 --- a/src/Cpu.h +++ b/src/Cpu.h @@ -42,7 +42,6 @@ public: static int optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage); static void init(); - static void setAffinity(int id, uint64_t mask); static inline bool hasAES() { return (m_flags & AES) != 0; } static inline bool isX64() { return (m_flags & X86_64) != 0; } diff --git a/src/Cpu_unix.cpp b/src/Cpu_unix.cpp index 9a13e7a5..b895c897 100644 --- a/src/Cpu_unix.cpp +++ b/src/Cpu_unix.cpp @@ -52,28 +52,3 @@ void Cpu::init() initCommon(); } - - -void Cpu::setAffinity(int id, uint64_t mask) -{ - cpu_set_t set; - CPU_ZERO(&set); - - for (int i = 0; i < m_totalThreads; i++) { - if (mask & (1UL << i)) { - CPU_SET(i, &set); - } - } - - if (id == -1) { -# ifndef __FreeBSD__ - sched_setaffinity(0, sizeof(&set), &set); -# endif - } else { -# ifndef __ANDROID__ - pthread_setaffinity_np(pthread_self(), sizeof(&set), &set); -# else - sched_setaffinity(gettid(), sizeof(&set), &set); -# endif - } -} diff --git a/src/Cpu_win.cpp b/src/Cpu_win.cpp index 13113a17..7258f726 100644 --- a/src/Cpu_win.cpp +++ b/src/Cpu_win.cpp @@ -39,14 +39,3 @@ void Cpu::init() initCommon(); } - - -void Cpu::setAffinity(int id, uint64_t mask) -{ - if (id == -1) { - SetProcessAffinityMask(GetCurrentProcess(), mask); - } - else { - SetThreadAffinityMask(GetCurrentThread(), mask); - } -} diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index 0dd833d7..df7aaad2 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -34,10 +34,10 @@ #endif +#include "common/xmrig.h" #include "crypto/CryptoNight.h" #include "log/Log.h" #include "Mem.h" -#include "xmrig.h" bool Mem::allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled) diff --git a/src/common/Platform.cpp b/src/common/Platform.cpp index 4ddb1429..52b55987 100644 --- a/src/common/Platform.cpp +++ b/src/common/Platform.cpp @@ -29,16 +29,16 @@ #include "Platform.h" -char *Platform::m_defaultConfigName = nullptr; -char *Platform::m_userAgent = nullptr; +char Platform::m_defaultConfigName[520] = { 0 }; +xmrig::c_str Platform::m_userAgent; const char *Platform::defaultConfigName() { size_t size = 520; - if (m_defaultConfigName == nullptr) { - m_defaultConfigName = new char[size]; + if (*m_defaultConfigName) { + return m_defaultConfigName; } if (uv_exepath(m_defaultConfigName, &size) < 0) { @@ -58,5 +58,6 @@ const char *Platform::defaultConfigName() } } + *m_defaultConfigName = '\0'; return nullptr; } diff --git a/src/common/Platform.h b/src/common/Platform.h index 87c8cc4d..8704604a 100644 --- a/src/common/Platform.h +++ b/src/common/Platform.h @@ -25,20 +25,26 @@ #define __PLATFORM_H__ +#include + + +#include "common/utils/c_str.h" + + class Platform { public: + static bool setThreadAffinity(uint64_t cpu_id); static const char *defaultConfigName(); static void init(const char *userAgent); - static void release(); static void setProcessPriority(int priority); static void setThreadPriority(int priority); - static inline const char *userAgent() { return m_userAgent; } + static inline const char *userAgent() { return m_userAgent.data(); } private: - static char *m_defaultConfigName; - static char *m_userAgent; + static char m_defaultConfigName[520]; + static xmrig::c_str m_userAgent; }; diff --git a/src/common/Platform_mac.cpp b/src/common/Platform_mac.cpp index ba541f1d..b8181cc4 100644 --- a/src/common/Platform_mac.cpp +++ b/src/common/Platform_mac.cpp @@ -22,6 +22,8 @@ */ +#include +#include #include #include #include @@ -53,15 +55,24 @@ static inline char *createUserAgent() } -void Platform::init(const char *userAgent) +bool Platform::setThreadAffinity(uint64_t cpu_id) { - m_userAgent = userAgent ? strdup(userAgent) : createUserAgent(); + thread_port_t mach_thread; + thread_affinity_policy_data_t policy = { static_cast(cpu_id) }; + mach_thread = pthread_mach_thread_np(pthread_self()); + + return thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1) == KERN_SUCCESS; } -void Platform::release() +void Platform::init(const char *userAgent) { - delete [] m_userAgent; + if (userAgent) { + m_userAgent = userAgent; + } + else { + m_userAgent = createUserAgent(); + } } diff --git a/src/common/Platform_unix.cpp b/src/common/Platform_unix.cpp index c0589307..624594e9 100644 --- a/src/common/Platform_unix.cpp +++ b/src/common/Platform_unix.cpp @@ -21,6 +21,14 @@ * along with this program. If not, see . */ +#ifdef __FreeBSD__ +# include +# include +# include +# include +#endif + + #include #include #include @@ -37,6 +45,11 @@ #endif +#ifdef __FreeBSD__ +typedef cpuset_t cpu_set_t; +#endif + + static inline char *createUserAgent() { const size_t max = 160; @@ -63,15 +76,28 @@ static inline char *createUserAgent() } -void Platform::init(const char *userAgent) +bool Platform::setThreadAffinity(uint64_t cpu_id) { - m_userAgent = userAgent ? strdup(userAgent) : createUserAgent(); + cpu_set_t mn; + CPU_ZERO(&mn); + CPU_SET(cpu_id, &mn); + +# ifndef __ANDROID__ + return pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mn) == 0; +# else + return sched_setaffinity(gettid(), sizeof(cpu_set_t), &mn) == 0; +# endif } -void Platform::release() +void Platform::init(const char *userAgent) { - delete [] m_userAgent; + if (userAgent) { + m_userAgent = userAgent; + } + else { + m_userAgent = createUserAgent(); + } } diff --git a/src/common/Platform_win.cpp b/src/common/Platform_win.cpp index 880bdd98..47f41867 100644 --- a/src/common/Platform_win.cpp +++ b/src/common/Platform_win.cpp @@ -27,9 +27,11 @@ #include +#include "log/Log.h" #include "Platform.h" #include "version.h" + #ifdef XMRIG_NVIDIA_PROJECT # include "nvidia/cryptonight.h" #endif @@ -82,16 +84,24 @@ static inline char *createUserAgent() } -void Platform::init(const char *userAgent) +bool Platform::setThreadAffinity(uint64_t cpu_id) { - m_userAgent = userAgent ? strdup(userAgent) : createUserAgent(); + if (cpu_id >= 64) { + LOG_ERR("Unable to set affinity. Windows supports only affinity up to 63."); + } + + return SetThreadAffinityMask(GetCurrentThread(), 1ULL << cpu_id) != 0; } -void Platform::release() +void Platform::init(const char *userAgent) { - delete [] m_defaultConfigName; - delete [] m_userAgent; + if (userAgent) { + m_userAgent = userAgent; + } + else { + m_userAgent = createUserAgent(); + } } @@ -131,7 +141,6 @@ void Platform::setProcessPriority(int priority) } - void Platform::setThreadPriority(int priority) { if (priority == -1) { diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index f120c0c1..5f0a9bb3 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -73,7 +73,6 @@ xmrig::Controller::Controller() xmrig::Controller::~Controller() { ConfigLoader::release(); - Platform::release(); delete d_ptr; } diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp index 01d032e9..29f57fb2 100644 --- a/src/workers/Handle.cpp +++ b/src/workers/Handle.cpp @@ -25,8 +25,7 @@ #include "workers/Handle.h" -Handle::Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays, int64_t affinity) : - m_affinity(affinity), +Handle::Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays) : m_worker(nullptr), m_totalThreads(totalThreads), m_totalWays(totalWays), diff --git a/src/workers/Handle.h b/src/workers/Handle.h index 8a64922a..b3a7c76f 100644 --- a/src/workers/Handle.h +++ b/src/workers/Handle.h @@ -38,11 +38,10 @@ class IWorker; class Handle { public: - Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays, int64_t affinity); + Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays); void join(); void start(void (*callback) (void *)); - inline int64_t affinity() const { return m_affinity; } inline IWorker *worker() const { return m_worker; } inline size_t threadId() const { return m_config->index(); } inline size_t totalThreads() const { return m_totalThreads; } @@ -51,7 +50,6 @@ public: inline xmrig::IThread *config() const { return m_config; } private: - int64_t m_affinity; IWorker *m_worker; size_t m_totalThreads; size_t m_totalWays; diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 30305ac6..59434390 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -42,11 +42,11 @@ Worker::Worker(Handle *handle) : m_sequence(0), m_thread(static_cast(handle->config())) { - if (Cpu::threads() > 1 && handle->affinity() != -1L) { - Cpu::setAffinity(m_id, handle->affinity()); + if (Cpu::threads() > 1 && m_thread->affinity() != -1L) { + Platform::setThreadAffinity(m_thread->affinity()); } - Platform::setThreadPriority(handle->config()->priority()); + Platform::setThreadPriority(m_thread->priority()); m_ctx = Mem::create(m_id); } diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 38965d8a..00941c7b 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -130,7 +130,7 @@ void Workers::start(xmrig::Controller *controller) uv_timer_start(&m_timer, Workers::onTick, 500, 500); for (xmrig::IThread *thread : threads) { - Handle *handle = new Handle(thread, threads.size(), totalWays, controller->config()->affinity()); + Handle *handle = new Handle(thread, threads.size(), totalWays); m_workers.push_back(handle); handle->start(Workers::onReady); } From c44b2997504b93e0e47cce634cc494daf3ead088 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 13 Apr 2018 17:59:27 +0700 Subject: [PATCH 052/109] Added reader for advanced threads. --- src/common/xmrig.h | 7 +++++++ src/core/Config.cpp | 40 +++++++++++++++++++++++++++------------ src/core/Config.h | 25 ++++++++++++++++++------ src/workers/CpuThread.cpp | 27 ++++++++++++++++++++++++++ src/workers/CpuThread.h | 20 ++++++++++++++++++++ 5 files changed, 101 insertions(+), 18 deletions(-) diff --git a/src/common/xmrig.h b/src/common/xmrig.h index 7196aee3..0aa6b842 100644 --- a/src/common/xmrig.h +++ b/src/common/xmrig.h @@ -64,6 +64,13 @@ enum Variant { }; +enum AesMode { + AES_AUTO, + AES_HW, + AES_SOFT +}; + + } /* namespace xmrig */ diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 07f11192..2b8809ff 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -41,6 +41,7 @@ static char affinity_tmp[20] = { 0 }; xmrig::Config::Config() : xmrig::CommonConfig(), + m_aesMode(AES_AUTO), m_algoVariant(AV_AUTO), m_doubleHash(false), m_dryRun(false), @@ -48,9 +49,7 @@ xmrig::Config::Config() : xmrig::CommonConfig(), m_safe(false), m_maxCpuUsage(75), m_printTime(60), - m_priority(-1), - m_affinity(-1L), - m_threadsCount(0) + m_priority(-1) { } @@ -162,18 +161,18 @@ bool xmrig::Config::adjust() m_doubleHash = true; } - if (!m_threadsCount) { - m_threadsCount = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); + if (!m_threads.count) { + m_threads.count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); } else if (m_safe) { const size_t count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); - if (m_threadsCount > count) { - m_threadsCount = count; + if (m_threads.count > count) { + m_threads.count = count; } } - for (size_t i = 0; i < m_threadsCount; ++i) { - m_threads.push_back(CpuThread::createFromAV(i, m_algorithm, m_algoVariant, m_affinity, m_priority)); + for (size_t i = 0; i < m_threads.count; ++i) { + m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm, m_algoVariant, m_threads.mask, m_priority)); } return true; @@ -228,7 +227,7 @@ bool xmrig::Config::parseString(int key, const char *arg) case xmrig::IConfig::ThreadsKey: /* --threads */ if (strncmp(arg, "all", 3) == 0) { - m_threadsCount = Cpu::threads(); + m_threads.count = Cpu::threads(); return true; } @@ -257,7 +256,7 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg) switch (key) { case xmrig::IConfig::CPUAffinityKey: /* --cpu-affinity */ if (arg) { - m_affinity = arg; + m_threads.mask = arg; } break; @@ -271,6 +270,23 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg) void xmrig::Config::parseJSON(const rapidjson::Document &doc) { + const rapidjson::Value &threads = doc["threads"]; + + if (threads.IsArray()) { + for (const rapidjson::Value &value : threads.GetArray()) { + if (!value.IsObject()) { + continue; + } + + if (value.HasMember("low_power_mode")) { + auto data = CpuThread::parse(value); + + if (data.valid) { + m_threads.cpu.push_back(std::move(data)); + } + } + } + } } @@ -279,7 +295,7 @@ bool xmrig::Config::parseInt(int key, int arg) switch (key) { case xmrig::IConfig::ThreadsKey: /* --threads */ if (arg >= 0 && arg < 1024) { - m_threadsCount = arg; + m_threads.count = arg; } break; diff --git a/src/core/Config.h b/src/core/Config.h index fd33b614..657679ec 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -32,6 +32,7 @@ #include "common/config/CommonConfig.h" #include "common/xmrig.h" #include "rapidjson/fwd.h" +#include "workers/CpuThread.h" class Addr; @@ -67,15 +68,16 @@ public: void getJSON(rapidjson::Document &doc) const override; + inline AesMode aesMode() const { return m_aesMode; } inline AlgoVariant algoVariant() const { return m_algoVariant; } inline bool isDoubleHash() const { return m_doubleHash; } inline bool isDryRun() const { return m_dryRun; } inline bool isHugePages() const { return m_hugePages; } - inline const std::vector &threads() const { return m_threads; } + inline const std::vector &threads() const { return m_threads.list; } inline int printTime() const { return m_printTime; } inline int priority() const { return m_priority; } - inline int threadsCount() const { return m_threadsCount; } - inline int64_t affinity() const { return m_affinity; } + inline int threadsCount() const { return m_threads.count; } + inline int64_t affinity() const { return m_threads.mask; } static Config *load(int argc, char **argv, IWatcherListener *listener); @@ -94,6 +96,19 @@ private: AlgoVariant getAlgoVariantLite() const; # endif + + struct Threads + { + inline Threads() : mask(-1L), count(0) {} + + int64_t mask; + size_t count; + std::vector cpu; + std::vector list; + }; + + + AesMode m_aesMode; AlgoVariant m_algoVariant; bool m_doubleHash; bool m_dryRun; @@ -102,9 +117,7 @@ private: int m_maxCpuUsage; int m_printTime; int m_priority; - int64_t m_affinity; - size_t m_threadsCount; - std::vector m_threads; + Threads m_threads; }; diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 20a8006f..5a707a58 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -197,6 +197,33 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A } +xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object) +{ + Data data; + + const auto &multiway = object["low_power_mode"]; + if (multiway.IsBool()) { + data.multiway = multiway.IsTrue() ? DoubleWay : SingleWay; + data.valid = true; + } + else if (multiway.IsUint()) { + data.setMultiway(multiway.GetInt()); + } + + if (!data.valid) { + return data; + } + + const auto &affinity = object["affine_to_cpu"]; + + if (affinity.IsUint64()) { + data.affinity = affinity.GetInt64(); + } + + return data; +} + + #ifndef XMRIG_NO_API rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const { diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index dadd0424..f9640a6c 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -46,6 +46,25 @@ public: PentaWay }; + + struct Data + { + inline Data() : valid(false), affinity(-1L), multiway(SingleWay) {} + + inline void setMultiway(int value) + { + if (value >= SingleWay && value <= PentaWay) { + multiway = static_cast(value); + valid = true; + } + } + + bool valid; + int64_t affinity; + Multiway multiway; + }; + + CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch); ~CpuThread(); @@ -53,6 +72,7 @@ public: static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant); static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority); + static Data parse(const rapidjson::Value &object); inline bool isPrefetch() const { return m_prefetch; } inline bool isSoftAES() const { return m_softAES; } From c81401ab2d2aabfc8219cdeee11f8fc5c7b79321 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 14 Apr 2018 07:01:12 +0700 Subject: [PATCH 053/109] Basic advanced config reader, only single hash supported. --- src/core/Config.cpp | 12 ++++++++++++ src/core/Config.h | 2 +- src/log/Log.cpp | 12 ++++++++++-- src/log/Log.h | 21 +++++++++++++++------ src/workers/CpuThread.cpp | 18 ++++++++++++++++++ src/workers/CpuThread.h | 1 + src/workers/Workers.cpp | 7 +++++-- 7 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 2b8809ff..ddce6980 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -156,6 +156,18 @@ bool xmrig::Config::adjust() return false; } + if (m_aesMode == AES_AUTO) { + m_aesMode = Cpu::hasAES() ? AES_SOFT : AES_SOFT; + } + + if (!m_threads.cpu.empty()) { + for (size_t i = 0; i < m_threads.cpu.size(); ++i) { + m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm, m_threads.cpu[i], m_priority, m_aesMode == AES_SOFT)); + } + + return true; + } + m_algoVariant = getAlgoVariant(); if (m_algoVariant == AV_DOUBLE || m_algoVariant == AV_DOUBLE_SOFT) { m_doubleHash = true; diff --git a/src/core/Config.h b/src/core/Config.h index 657679ec..720557a7 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -76,7 +76,7 @@ public: inline const std::vector &threads() const { return m_threads.list; } inline int printTime() const { return m_printTime; } inline int priority() const { return m_priority; } - inline int threadsCount() const { return m_threads.count; } + inline int threadsCount() const { return m_threads.list.size(); } inline int64_t affinity() const { return m_threads.mask; } static Config *load(int argc, char **argv, IWatcherListener *listener); diff --git a/src/log/Log.cpp b/src/log/Log.cpp index 3e5d5671..131faa54 100644 --- a/src/log/Log.cpp +++ b/src/log/Log.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,6 +38,8 @@ Log *Log::m_self = nullptr; void Log::message(Log::Level level, const char* fmt, ...) { + uv_mutex_lock(&m_mutex); + va_list args; va_list copy; va_start(args, fmt); @@ -47,11 +49,15 @@ void Log::message(Log::Level level, const char* fmt, ...) backend->message(level, fmt, copy); va_end(copy); } + + uv_mutex_unlock(&m_mutex); } void Log::text(const char* fmt, ...) { + uv_mutex_lock(&m_mutex); + va_list args; va_list copy; va_start(args, fmt); @@ -63,6 +69,8 @@ void Log::text(const char* fmt, ...) } va_end(args); + + uv_mutex_unlock(&m_mutex); } diff --git a/src/log/Log.h b/src/log/Log.h index fd944d80..f8c6a401 100644 --- a/src/log/Log.h +++ b/src/log/Log.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,6 +25,7 @@ #define __LOG_H__ +#include #include #include @@ -54,20 +55,28 @@ public: constexpr static const char* kCL_GRAY = "\x1B[90m"; # endif - static inline Log* i() { return m_self; } + static inline Log* i() { assert(m_self != nullptr); return m_self; } static inline void add(ILogBackend *backend) { i()->m_backends.push_back(backend); } - static inline void init() { if (!m_self) { m_self = new Log();} } - static inline void release() { delete m_self; } + static inline void init() { if (!m_self) { new Log(); } } + static inline void release() { assert(m_self != nullptr); delete m_self; } void message(Level level, const char* fmt, ...); void text(const char* fmt, ...); private: - inline Log() {} + inline Log() { + assert(m_self == nullptr); + + uv_mutex_init(&m_mutex); + + m_self = this; + } + ~Log(); static Log *m_self; std::vector m_backends; + uv_mutex_t m_mutex; }; diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 5a707a58..07fbbb64 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -197,6 +197,24 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A } +xmrig::CpuThread *xmrig::CpuThread::createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES) +{ + int av = AV_AUTO; + const Multiway multiway = data.multiway; + + if (multiway <= DoubleWay) { + av = softAES ? (multiway + 2) : multiway; + } + else { + av = softAES ? (multiway + 5) : (multiway + 2); + } + + assert(av > AV_AUTO && av < AV_MAX); + + return new CpuThread(index, algorithm, static_cast(av), multiway, data.affinity, priority, softAES, false); +} + + xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object) { Data data; diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index f9640a6c..9d1bc4e7 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -72,6 +72,7 @@ public: static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant); static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority); + static CpuThread *createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES); static Data parse(const rapidjson::Value &object); inline bool isPrefetch() const { return m_prefetch; } diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 00941c7b..44ac399f 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -112,6 +112,8 @@ void Workers::start(xmrig::Controller *controller) { const std::vector &threads = controller->config()->threads(); + LOG_NOTICE("- %d", std::this_thread::get_id()); + size_t totalWays = 0; for (const xmrig::IThread *thread : threads) { totalWays += thread->multiway(); @@ -165,6 +167,9 @@ void Workers::submit(const JobResult &result) void Workers::onReady(void *arg) { auto handle = static_cast(arg); + + LOG_NOTICE("%zu %d", handle->threadId(), std::this_thread::get_id()); + if (Mem::isDoubleHash()) { handle->setWorker(new DoubleWorker(handle)); } @@ -175,9 +180,7 @@ void Workers::onReady(void *arg) const bool rc = handle->worker()->start(); if (!rc) { - uv_mutex_lock(&m_mutex); LOG_ERR("thread %zu error: \"hash self-test failed\".", handle->worker()->id()); - uv_mutex_unlock(&m_mutex); } } From 4b71b7aa29e6ff89e20e8679625f4599edf75b40 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 14 Apr 2018 22:14:57 +0700 Subject: [PATCH 054/109] Added class MultiWorker and remove classes SingleWorker and DoubleWorker. --- CMakeLists.txt | 6 +- src/interfaces/IWorker.h | 3 +- src/net/Job.cpp | 11 + src/net/Job.h | 4 + src/workers/DoubleWorker.cpp | 189 ------------------ src/workers/DoubleWorker.h | 59 ------ src/workers/Handle.cpp | 4 +- src/workers/Handle.h | 9 +- .../{SingleWorker.cpp => MultiWorker.cpp} | 135 +++++++------ src/workers/{SingleWorker.h => MultiWorker.h} | 34 +++- src/workers/Worker.cpp | 4 +- src/workers/Worker.h | 8 +- src/workers/Workers.cpp | 52 +++-- 13 files changed, 173 insertions(+), 345 deletions(-) delete mode 100644 src/workers/DoubleWorker.cpp delete mode 100644 src/workers/DoubleWorker.h rename src/workers/{SingleWorker.cpp => MultiWorker.cpp} (61%) rename src/workers/{SingleWorker.h => MultiWorker.h} (72%) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8d381d4..ecb65b22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,10 +55,9 @@ set(HEADERS src/Summary.h src/version.h src/workers/CpuThread.h - src/workers/DoubleWorker.h src/workers/Handle.h src/workers/Hashrate.h - src/workers/SingleWorker.h + src/workers/MultiWorker.h src/workers/Worker.h src/workers/Workers.h ) @@ -109,10 +108,9 @@ set(SOURCES src/net/SubmitResult.cpp src/Summary.cpp src/workers/CpuThread.cpp - src/workers/DoubleWorker.cpp src/workers/Handle.cpp src/workers/Hashrate.cpp - src/workers/SingleWorker.cpp + src/workers/MultiWorker.cpp src/workers/Worker.cpp src/workers/Workers.cpp src/xmrig.cpp diff --git a/src/interfaces/IWorker.h b/src/interfaces/IWorker.h index a90abe11..90394c2c 100644 --- a/src/interfaces/IWorker.h +++ b/src/interfaces/IWorker.h @@ -33,10 +33,11 @@ class IWorker public: virtual ~IWorker() {} - virtual bool start() = 0; + virtual bool selfTest() = 0; virtual size_t id() const = 0; virtual uint64_t hashCount() const = 0; virtual uint64_t timestamp() const = 0; + virtual void start() = 0; }; diff --git a/src/net/Job.cpp b/src/net/Job.cpp index 17d8266f..1434c87f 100644 --- a/src/net/Job.cpp +++ b/src/net/Job.cpp @@ -209,6 +209,17 @@ void Job::toHex(const unsigned char* in, unsigned int len, char* out) } +#ifdef APP_DEBUG +char *Job::toHex(const unsigned char* in, unsigned int len) +{ + char *out = new char[len * 2 + 1](); + toHex(in, len, out); + + return out; +} +#endif + + bool Job::operator==(const Job &other) const { return m_id == other.m_id && memcmp(m_blob, other.m_blob, sizeof(m_blob)) == 0; diff --git a/src/net/Job.h b/src/net/Job.h index a60f061c..ee4728e3 100644 --- a/src/net/Job.h +++ b/src/net/Job.h @@ -69,6 +69,10 @@ public: static inline uint64_t toDiff(uint64_t target) { return 0xFFFFFFFFFFFFFFFFULL / target; } static void toHex(const unsigned char* in, unsigned int len, char* out); +# ifdef APP_DEBUG + static char *toHex(const unsigned char* in, unsigned int len); +# endif + bool operator==(const Job &other) const; bool operator!=(const Job &other) const; diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp deleted file mode 100644 index 6ba5c47f..00000000 --- a/src/workers/DoubleWorker.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018 Lee Clagett - * Copyright 2016-2018 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include - - -#include "crypto/CryptoNight_test.h" -#include "workers/CpuThread.h" -#include "workers/DoubleWorker.h" -#include "workers/Workers.h" - - -class DoubleWorker::State -{ -public: - inline State() : - nonce1(0), - nonce2(0) - {} - - Job job; - uint32_t nonce1; - uint32_t nonce2; - uint8_t blob[84 * 2]; -}; - - -DoubleWorker::DoubleWorker(Handle *handle) - : Worker(handle) -{ - m_state = new State(); - m_pausedState = new State(); -} - - -DoubleWorker::~DoubleWorker() -{ - delete m_state; - delete m_pausedState; -} - - -bool DoubleWorker::start() -{ - if (!selfTest()) { - return false; - } - - while (Workers::sequence() > 0) { - if (Workers::isPaused()) { - do { - std::this_thread::sleep_for(std::chrono::milliseconds(200)); - } - while (Workers::isPaused()); - - if (Workers::sequence() == 0) { - break; - } - - consumeJob(); - } - - while (!Workers::isOutdated(m_sequence)) { - if ((m_count & 0xF) == 0) { - storeStats(); - } - - m_count += 2; - *Job::nonce(m_state->blob) = ++m_state->nonce1; - *Job::nonce(m_state->blob + m_state->job.size()) = ++m_state->nonce2; - - m_thread->fn(m_state->job.variant())(m_state->blob, m_state->job.size(), m_hash, m_ctx); - - if (*reinterpret_cast(m_hash + 24) < m_state->job.target()) { - Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce1, m_hash, m_state->job.diff())); - } - - if (*reinterpret_cast(m_hash + 32 + 24) < m_state->job.target()) { - Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce2, m_hash + 32, m_state->job.diff())); - } - - std::this_thread::yield(); - } - - consumeJob(); - } - - return true; -} - - -bool DoubleWorker::resume(const Job &job) -{ - if (m_state->job.poolId() == -1 && job.poolId() >= 0 && job.id() == m_pausedState->job.id()) { - *m_state = *m_pausedState; - return true; - } - - return false; -} - - -bool DoubleWorker::selfTest() -{ - if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) { - return false; - } - - m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_hash, m_ctx); - - if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_hash, test_output_v0, 64) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); - - return memcmp(m_hash, test_output_v1, 64) == 0; - } - -# ifndef XMRIG_NO_AEON - if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_hash, test_output_v0_lite, 64) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); - - return memcmp(m_hash, test_output_v1_lite, 64) == 0; - } -# endif - -# ifndef XMRIG_NO_SUMO - return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_hash, test_output_heavy, 64) == 0; -# else - return false; -# endif -} - - -void DoubleWorker::consumeJob() -{ - Job job = Workers::job(); - m_sequence = Workers::sequence(); - if (m_state->job == job) { - return; - } - - save(job); - - if (resume(job)) { - return; - } - - m_state->job = std::move(job); - memcpy(m_state->blob, m_state->job.blob(), m_state->job.size()); - memcpy(m_state->blob + m_state->job.size(), m_state->job.blob(), m_state->job.size()); - - if (m_state->job.isNicehash()) { - m_state->nonce1 = (*Job::nonce(m_state->blob) & 0xff000000U) + (0xffffffU / m_totalWays * m_id); - m_state->nonce2 = (*Job::nonce(m_state->blob + m_state->job.size()) & 0xff000000U) + (0xffffffU / m_totalWays * (m_id + m_totalThreads)); - } - else { - m_state->nonce1 = 0xffffffffU / m_totalWays * m_id; - m_state->nonce2 = 0xffffffffU / m_totalWays * (m_id + m_totalThreads); - } -} - - -void DoubleWorker::save(const Job &job) -{ - if (job.poolId() == -1 && m_state->job.poolId() >= 0) { - *m_pausedState = *m_state; - } -} diff --git a/src/workers/DoubleWorker.h b/src/workers/DoubleWorker.h deleted file mode 100644 index e8847282..00000000 --- a/src/workers/DoubleWorker.h +++ /dev/null @@ -1,59 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018 Lee Clagett - * Copyright 2016-2018 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __DOUBLEWORKER_H__ -#define __DOUBLEWORKER_H__ - - -#include "net/Job.h" -#include "net/JobResult.h" -#include "workers/Worker.h" - - -class Handle; - - -class DoubleWorker : public Worker -{ -public: - DoubleWorker(Handle *handle); - ~DoubleWorker(); - - bool start() override; - -private: - bool resume(const Job &job); - bool selfTest(); - void consumeJob(); - void save(const Job &job); - - class State; - - uint8_t m_hash[64]; - State *m_state; - State *m_pausedState; -}; - - -#endif /* __SINGLEWORKER_H__ */ diff --git a/src/workers/Handle.cpp b/src/workers/Handle.cpp index 29f57fb2..d42ea368 100644 --- a/src/workers/Handle.cpp +++ b/src/workers/Handle.cpp @@ -25,10 +25,10 @@ #include "workers/Handle.h" -Handle::Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays) : +Handle::Handle(xmrig::IThread *config, uint32_t offset, size_t totalWays) : m_worker(nullptr), - m_totalThreads(totalThreads), m_totalWays(totalWays), + m_offset(offset), m_config(config) { } diff --git a/src/workers/Handle.h b/src/workers/Handle.h index b3a7c76f..4bb899f9 100644 --- a/src/workers/Handle.h +++ b/src/workers/Handle.h @@ -25,6 +25,7 @@ #define __HANDLE_H__ +#include #include #include @@ -38,21 +39,21 @@ class IWorker; class Handle { public: - Handle(xmrig::IThread *config, size_t totalThreads, size_t totalWays); + Handle(xmrig::IThread *config, uint32_t offset, size_t totalWays); void join(); void start(void (*callback) (void *)); inline IWorker *worker() const { return m_worker; } inline size_t threadId() const { return m_config->index(); } - inline size_t totalThreads() const { return m_totalThreads; } inline size_t totalWays() const { return m_totalWays; } - inline void setWorker(IWorker *worker) { m_worker = worker; } + inline uint32_t offset() const { return m_offset; } + inline void setWorker(IWorker *worker) { assert(worker != nullptr); m_worker = worker; } inline xmrig::IThread *config() const { return m_config; } private: IWorker *m_worker; - size_t m_totalThreads; size_t m_totalWays; + uint32_t m_offset; uv_thread_t m_thread; xmrig::IThread *m_config; }; diff --git a/src/workers/SingleWorker.cpp b/src/workers/MultiWorker.cpp similarity index 61% rename from src/workers/SingleWorker.cpp rename to src/workers/MultiWorker.cpp index 815b965d..0007b0cb 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -28,22 +28,51 @@ #include "crypto/CryptoNight_test.h" #include "workers/CpuThread.h" -#include "workers/SingleWorker.h" +#include "workers/MultiWorker.h" #include "workers/Workers.h" -SingleWorker::SingleWorker(Handle *handle) +template +MultiWorker::MultiWorker(Handle *handle) : Worker(handle) { } -bool SingleWorker::start() +template +bool MultiWorker::selfTest() { - if (!selfTest()) { + if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) { return false; } + m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_result.result, m_ctxLegacy); + + if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_result.result, test_output_v0, 32) == 0) { + m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctxLegacy); + + return memcmp(m_result.result, test_output_v1, 32) == 0; + } + +# ifndef XMRIG_NO_AEON + if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_result.result, test_output_v0_lite, 32) == 0) { + m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctxLegacy); + + return memcmp(m_result.result, test_output_v1_lite, 32) == 0; + } +# endif + +# ifndef XMRIG_NO_SUMO + return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_result.result, test_output_heavy, 32) == 0; +# else + return false; +# endif +} + + +template +void MultiWorker::start() +{ while (Workers::sequence() > 0) { if (Workers::isPaused()) { do { @@ -59,34 +88,35 @@ bool SingleWorker::start() } while (!Workers::isOutdated(m_sequence)) { - if ((m_count & 0xF) == 0) { + if ((m_count & 0x7) == 0) { storeStats(); } - m_count++; - *m_job.nonce() = ++m_result.nonce; + m_thread->fn(m_state.job.variant())(m_state.blob, m_state.job.size(), m_hash, m_ctxLegacy); - m_thread->fn(m_job.variant())(m_job.blob(), m_job.size(), m_result.result, m_ctx); - if (*reinterpret_cast(m_result.result + 24) < m_job.target()) { - Workers::submit(m_result); + for (size_t i = 0; i < N; ++i) { + if (*reinterpret_cast(m_hash + (i * 32) + 24) < m_state.job.target()) { + Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash, m_state.job.diff())); + } + + *nonce(i) += 1; } + m_count += N; + std::this_thread::yield(); } consumeJob(); } - - return true; } -bool SingleWorker::resume(const Job &job) +template +bool MultiWorker::resume(const Job &job) { - if (m_job.poolId() == -1 && job.poolId() >= 0 && job.id() == m_paused.id()) { - m_job = m_paused; - m_result = m_job; - m_result.nonce = *m_job.nonce(); + if (m_state.job.poolId() == -1 && job.poolId() >= 0 && job.id() == m_pausedState.job.id()) { + m_state = m_pausedState; return true; } @@ -94,41 +124,12 @@ bool SingleWorker::resume(const Job &job) } -bool SingleWorker::selfTest() -{ - if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) { - return false; - } - - m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_result.result, m_ctx); - - if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_result.result, test_output_v0, 32) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctx); - - return memcmp(m_result.result, test_output_v1, 32) == 0; - } - -# ifndef XMRIG_NO_AEON - if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_result.result, test_output_v0_lite, 32) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctx); - - return memcmp(m_result.result, test_output_v1_lite, 32) == 0; - } -# endif - -# ifndef XMRIG_NO_SUMO - return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_result.result, test_output_heavy, 32) == 0; -# else - return false; -# endif -} - - -void SingleWorker::consumeJob() +template +void MultiWorker::consumeJob() { Job job = Workers::job(); m_sequence = Workers::sequence(); - if (m_job == job) { + if (m_state.job == job) { return; } @@ -138,21 +139,39 @@ void SingleWorker::consumeJob() return; } - m_job = std::move(job); - m_result = m_job; + m_state.job = job; - if (m_job.isNicehash()) { - m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_totalWays * m_id); + const size_t size = m_state.job.size(); + memcpy(m_state.blob, m_state.job.blob(), m_state.job.size()); + + if (N > 1) { + for (size_t i = 1; i < N; ++i) { + memcpy(m_state.blob + (i * size), m_state.blob, size); + } } - else { - m_result.nonce = 0xffffffffU / m_totalWays * m_id; + + for (size_t i = 0; i < N; ++i) { + if (m_state.job.isNicehash()) { + *nonce(i) = (*nonce(i) & 0xff000000U) + (0xffffffU / m_totalWays * (m_offset + i)); + } + else { + *nonce(i) = 0xffffffffU / m_totalWays * (m_offset + i); + } } } -void SingleWorker::save(const Job &job) +template +void MultiWorker::save(const Job &job) { - if (job.poolId() == -1 && m_job.poolId() >= 0) { - m_paused = m_job; + if (job.poolId() == -1 && m_state.job.poolId() >= 0) { + m_pausedState = m_state; } } + + +template class MultiWorker<1>; +template class MultiWorker<2>; +template class MultiWorker<3>; +template class MultiWorker<4>; +template class MultiWorker<5>; diff --git a/src/workers/SingleWorker.h b/src/workers/MultiWorker.h similarity index 72% rename from src/workers/SingleWorker.h rename to src/workers/MultiWorker.h index 061f5084..d384b0ba 100644 --- a/src/workers/SingleWorker.h +++ b/src/workers/MultiWorker.h @@ -22,8 +22,8 @@ * along with this program. If not, see . */ -#ifndef __SINGLEWORKER_H__ -#define __SINGLEWORKER_H__ +#ifndef __MULTIWORKER_H__ +#define __MULTIWORKER_H__ #include "net/Job.h" @@ -34,23 +34,43 @@ class Handle; -class SingleWorker : public Worker +template +class MultiWorker : public Worker { public: - SingleWorker(Handle *handle); + MultiWorker(Handle *handle); - bool start() override; +protected: + bool selfTest() override; + void start() override; private: bool resume(const Job &job); - bool selfTest(); void consumeJob(); void save(const Job &job); + inline uint32_t *nonce(size_t index) + { + return reinterpret_cast(m_state.blob + (index * m_state.job.size()) + 39); + } + + struct State + { + alignas(16) uint8_t blob[96 * N]; + Job job; + }; + + +// cryptonight_ctx *m_ctx[N]; + + uint8_t m_hash[N * 32]; + State m_state; + State m_pausedState; + Job m_job; Job m_paused; JobResult m_result; }; -#endif /* __SINGLEWORKER_H__ */ +#endif /* __MULTIWORKER_H__ */ diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 59434390..e0ed846b 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -34,8 +34,8 @@ Worker::Worker(Handle *handle) : m_id(handle->threadId()), - m_totalThreads(handle->totalThreads()), m_totalWays(handle->totalWays()), + m_offset(handle->offset()), m_hashCount(0), m_timestamp(0), m_count(0), @@ -47,7 +47,7 @@ Worker::Worker(Handle *handle) : } Platform::setThreadPriority(m_thread->priority()); - m_ctx = Mem::create(m_id); + m_ctxLegacy = Mem::create(m_id); } diff --git a/src/workers/Worker.h b/src/workers/Worker.h index 88f6ee42..72b3beb2 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -54,10 +54,10 @@ public: protected: void storeStats(); - cryptonight_ctx *m_ctx; - size_t m_id; - size_t m_totalThreads; - size_t m_totalWays; + const size_t m_id; + const size_t m_totalWays; + const uint32_t m_offset; + cryptonight_ctx *m_ctxLegacy; std::atomic m_hashCount; std::atomic m_timestamp; uint64_t m_count; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 44ac399f..21379db4 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -30,15 +30,13 @@ #include "core/Controller.h" #include "interfaces/IJobResultListener.h" #include "interfaces/IThread.h" +#include "log/Log.h" #include "Mem.h" -#include "workers/DoubleWorker.h" #include "workers/Handle.h" #include "workers/Hashrate.h" -#include "workers/SingleWorker.h" +#include "workers/MultiWorker.h" #include "workers/Workers.h" -#include "log/Log.h" - bool Workers::m_active = false; bool Workers::m_enabled = true; @@ -112,8 +110,6 @@ void Workers::start(xmrig::Controller *controller) { const std::vector &threads = controller->config()->threads(); - LOG_NOTICE("- %d", std::this_thread::get_id()); - size_t totalWays = 0; for (const xmrig::IThread *thread : threads) { totalWays += thread->multiway(); @@ -131,8 +127,12 @@ void Workers::start(xmrig::Controller *controller) uv_timer_init(uv_default_loop(), &m_timer); uv_timer_start(&m_timer, Workers::onTick, 500, 500); + uint32_t offset = 0; + for (xmrig::IThread *thread : threads) { - Handle *handle = new Handle(thread, threads.size(), totalWays); + Handle *handle = new Handle(thread, offset, totalWays); + offset += thread->multiway(); + m_workers.push_back(handle); handle->start(Workers::onReady); } @@ -168,20 +168,42 @@ void Workers::onReady(void *arg) { auto handle = static_cast(arg); - LOG_NOTICE("%zu %d", handle->threadId(), std::this_thread::get_id()); + IWorker *worker = nullptr; - if (Mem::isDoubleHash()) { - handle->setWorker(new DoubleWorker(handle)); - } - else { - handle->setWorker(new SingleWorker(handle)); + switch (handle->config()->multiway()) { + case 1: + worker = new MultiWorker<1>(handle); + break; + + case 2: + worker = new MultiWorker<2>(handle); + break; + + case 3: + worker = new MultiWorker<3>(handle); + break; + + case 4: + worker = new MultiWorker<4>(handle); + break; + + case 5: + worker = new MultiWorker<5>(handle); + break; + + default: + break; } - const bool rc = handle->worker()->start(); + handle->setWorker(worker); - if (!rc) { + if (!worker->selfTest()) { LOG_ERR("thread %zu error: \"hash self-test failed\".", handle->worker()->id()); + + return; } + + worker->start(); } From 9125b6c2512bb5539424894c766ef178ded93fbd Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 11:08:47 +0700 Subject: [PATCH 055/109] Rewrite memory allocation. --- CMakeLists.txt | 1 + src/App.cpp | 8 +--- src/Mem.cpp | 79 ++++++++++++--------------------- src/Mem.h | 35 +++++++-------- src/Mem_unix.cpp | 60 ++++++++++--------------- src/Mem_win.cpp | 66 +++++++++++++-------------- src/Summary.cpp | 9 ++-- src/api/ApiRouter.cpp | 2 +- src/common/utils/mm_malloc.h | 43 ++++++++++++++++++ src/crypto/CryptoNight.h | 3 +- src/crypto/CryptoNight_arm.h | 8 +--- src/crypto/CryptoNight_monero.h | 2 +- src/crypto/CryptoNight_x86.h | 38 ++++++++-------- src/interfaces/IThread.h | 20 ++++++--- src/workers/CpuThread.h | 13 +----- src/workers/MultiWorker.cpp | 26 +++++++---- src/workers/MultiWorker.h | 14 +++--- src/workers/Worker.cpp | 7 --- src/workers/Worker.h | 2 - 19 files changed, 212 insertions(+), 224 deletions(-) create mode 100644 src/common/utils/mm_malloc.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ecb65b22..c7017b01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ set(HEADERS src/common/config/ConfigWatcher.h src/common/Platform.h src/common/utils/c_str.h + src/common/utils/mm_malloc.h src/common/xmrig.h src/Console.h src/core/Config.cpp diff --git a/src/App.cpp b/src/App.cpp index 3d0cb3df..78d6b328 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -76,8 +76,6 @@ App::App(int argc, char **argv) : App::~App() { - Mem::release(); - uv_tty_reset_mode(); delete m_console; @@ -101,11 +99,7 @@ int App::exec() background(); - Mem::allocate(m_controller->config()->algorithm(), - m_controller->config()->threadsCount(), - m_controller->config()->isDoubleHash(), - m_controller->config()->isHugePages() - ); + Mem::init(m_controller->config()->isHugePages()); Summary::print(m_controller); diff --git a/src/Mem.cpp b/src/Mem.cpp index 9de79dbd..2efaac8a 100644 --- a/src/Mem.cpp +++ b/src/Mem.cpp @@ -23,70 +23,49 @@ */ -#include - - +#include "common/utils/mm_malloc.h" #include "crypto/CryptoNight.h" #include "crypto/CryptoNight_constants.h" #include "Mem.h" -bool Mem::m_doubleHash = false; -int Mem::m_algo = 0; -int Mem::m_flags = 0; -int Mem::m_threads = 0; -size_t Mem::m_offset = 0; -size_t Mem::m_size = 0; -alignas(16) uint8_t *Mem::m_memory = nullptr; +bool Mem::m_enabled = true; +int Mem::m_flags = 0; -cryptonight_ctx *Mem::create(int threadId) + +MemInfo Mem::create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count) { + using namespace xmrig; + + MemInfo info; + info.size = cn_select_memory(algorithm) * count; + # ifndef XMRIG_NO_AEON - if (m_algo == xmrig::CRYPTONIGHT_LITE) { - return createLite(threadId); - } + info.size += info.size % cn_select_memory(); # endif - const size_t size = m_algo == xmrig::CRYPTONIGHT_HEAVY ? xmrig::cn_select_memory() - : xmrig::cn_select_memory(); + info.pages = info.size / cn_select_memory(); - cryptonight_ctx *ctx = reinterpret_cast(&m_memory[size - sizeof(cryptonight_ctx) * (threadId + 1)]); + allocate(info, m_enabled); - const int ratio = m_doubleHash ? 2 : 1; - ctx->memory = &m_memory[size * (threadId * ratio + 1)]; + for (size_t i = 0; i < count; ++i) { + cryptonight_ctx *c = static_cast(_mm_malloc(sizeof(cryptonight_ctx), 16)); + c->memory = info.memory + (i * cn_select_memory(algorithm)); - return ctx; -} - - - -void *Mem::calloc(size_t num, size_t size) -{ - void *mem = &m_memory[m_offset]; - m_offset += (num * size); - - memset(mem, 0, num * size); - - return mem; -} - - -#ifndef XMRIG_NO_AEON -cryptonight_ctx *Mem::createLite(int threadId) { - cryptonight_ctx *ctx; - - if (!m_doubleHash) { - const size_t offset = MONERO_MEMORY * (threadId + 1); - - ctx = reinterpret_cast(&m_memory[offset + AEON_MEMORY]); - ctx->memory = &m_memory[offset]; - return ctx; + ctx[i] = c; } - ctx = reinterpret_cast(&m_memory[MONERO_MEMORY - sizeof(cryptonight_ctx) * (threadId + 1)]); - ctx->memory = &m_memory[MONERO_MEMORY * (threadId + 1)]; - - return ctx; + return info; } -#endif + + +void Mem::release(cryptonight_ctx **ctx, size_t count, MemInfo &info) +{ + release(info); + + for (size_t i = 0; i < count; ++i) { + _mm_free(ctx[i]); + } +} + diff --git a/src/Mem.h b/src/Mem.h index 06b470c8..6fd18fc1 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -36,6 +36,16 @@ struct cryptonight_ctx; +struct MemInfo +{ + alignas(16) uint8_t *memory; + + size_t hugePages; + size_t pages; + size_t size; +}; + + class Mem { public: @@ -45,29 +55,18 @@ public: Lock = 4 }; - static bool allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled); - static cryptonight_ctx *create(int threadId); - static void *calloc(size_t num, size_t size); - static void release(); + static MemInfo create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count); + static void init(bool enabled); + static void release(cryptonight_ctx **ctx, size_t count, MemInfo &info); - static inline bool isDoubleHash() { return m_doubleHash; } static inline bool isHugepagesAvailable() { return (m_flags & HugepagesAvailable) != 0; } - static inline bool isHugepagesEnabled() { return (m_flags & HugepagesEnabled) != 0; } - static inline int flags() { return m_flags; } - static inline int threads() { return m_threads; } private: - static bool m_doubleHash; - static int m_algo; - static int m_flags; - static int m_threads; - static size_t m_offset; - static size_t m_size; - alignas(16) static uint8_t *m_memory; + static void allocate(MemInfo &info, bool enabled); + static void release(MemInfo &info); -# ifndef XMRIG_NO_AEON - static cryptonight_ctx *createLite(int threadId); -# endif + static int m_flags; + static bool m_enabled; }; diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index df7aaad2..550033c4 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -27,75 +27,63 @@ #include -#if defined(XMRIG_ARM) && !defined(__clang__) -# include "aligned_malloc.h" -#else -# include -#endif - - +#include "common/utils/mm_malloc.h" #include "common/xmrig.h" #include "crypto/CryptoNight.h" #include "log/Log.h" #include "Mem.h" -bool Mem::allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled) +void Mem::init(bool enabled) { - m_algo = algo; - m_threads = threads; - m_doubleHash = doubleHash; + m_enabled = enabled; +} - const int ratio = (doubleHash && algo != xmrig::CRYPTONIGHT_LITE) ? 2 : 1; - m_size = MONERO_MEMORY * (threads * ratio + 1); - if (algo == xmrig::CRYPTONIGHT_HEAVY) { - m_size *= 2; - } +void Mem::allocate(MemInfo &info, bool enabled) +{ + info.hugePages = 0; if (!enabled) { - m_memory = static_cast(_mm_malloc(m_size, 16)); - return true; - } + info.memory = static_cast(_mm_malloc(info.size, 16)); - m_flags |= HugepagesAvailable; + return; + } # if defined(__APPLE__) - m_memory = static_cast(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0)); + info.memory = static_cast(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0)); # elif defined(__FreeBSD__) - m_memory = static_cast(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0)); + info.memory = static_cast(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0)); # else - m_memory = static_cast(mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0)); + info.memory = static_cast(mmap(0, info.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, 0, 0)); # endif - if (m_memory == MAP_FAILED) { - m_memory = static_cast(_mm_malloc(m_size, 16)); - return true; + + if (info.memory == MAP_FAILED) { + return allocate(info, false);; } - m_flags |= HugepagesEnabled; + info.hugePages = info.pages; - if (madvise(m_memory, m_size, MADV_RANDOM | MADV_WILLNEED) != 0) { + if (madvise(info.memory, info.size, MADV_RANDOM | MADV_WILLNEED) != 0) { LOG_ERR("madvise failed"); } - if (mlock(m_memory, m_size) == 0) { + if (mlock(info.memory, info.size) == 0) { m_flags |= Lock; } - - return true; } -void Mem::release() +void Mem::release(MemInfo &info) { - if (m_flags & HugepagesEnabled) { + if (info.hugePages) { if (m_flags & Lock) { - munlock(m_memory, m_size); + munlock(info.memory, info.size); } - munmap(m_memory, m_size); + munmap(info.memory, info.size); } else { - _mm_free(m_memory); + _mm_free(info.memory); } } diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index 1f3066ea..d0b698f6 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -28,14 +28,11 @@ #include #include -#ifdef __GNUC__ -# include -#else -# include -#endif +#include "common/utils/mm_malloc.h" #include "common/xmrig.h" #include "crypto/CryptoNight.h" +#include "crypto/CryptoNight_constants.h" #include "log/Log.h" #include "Mem.h" @@ -145,46 +142,43 @@ static BOOL TrySetLockPagesPrivilege() { } -bool Mem::allocate(xmrig::Algo algo, int threads, bool doubleHash, bool enabled) +void Mem::init(bool enabled) { - m_algo = algo; - m_threads = threads; - m_doubleHash = doubleHash; + m_enabled = enabled; - const int ratio = (doubleHash && algo != xmrig::CRYPTONIGHT_LITE) ? 2 : 1; - m_size = MONERO_MEMORY * (threads * ratio + 1); - - if (algo == xmrig::CRYPTONIGHT_HEAVY) { - m_size *= 2; - } - - if (!enabled) { - m_memory = static_cast(_mm_malloc(m_size, 16)); - return true; - } - - if (TrySetLockPagesPrivilege()) { + if (enabled && TrySetLockPagesPrivilege()) { m_flags |= HugepagesAvailable; } - - m_memory = static_cast(VirtualAlloc(NULL, m_size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE)); - if (!m_memory) { - m_memory = static_cast(_mm_malloc(m_size, 16)); - } - else { - m_flags |= HugepagesEnabled; - } - - return true; } -void Mem::release() +void Mem::allocate(MemInfo &info, bool enabled) { - if (m_flags & HugepagesEnabled) { - VirtualFree(m_memory, 0, MEM_RELEASE); + info.hugePages = 0; + + if (!enabled) { + info.memory = static_cast(_mm_malloc(info.size, 16)); + + return; + } + + info.memory = static_cast(VirtualAlloc(nullptr, info.size, MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE)); + if (info.memory) { + info.hugePages = info.pages; + + return; + } + + allocate(info, false); +} + + +void Mem::release(MemInfo &info) +{ + if (info.hugePages) { + VirtualFree(info.memory, 0, MEM_RELEASE); } else { - _mm_free(m_memory); + _mm_free(info.memory); } } diff --git a/src/Summary.cpp b/src/Summary.cpp index 5acda5c2..a54214e4 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -58,14 +58,15 @@ static void print_versions(xmrig::Config *config) static void print_memory(xmrig::Config *config) { +# ifdef _WIN32 if (config->isColors()) { - Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s, %s", - Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable", - Mem::isHugepagesEnabled() ? "\x1B[01;32menabled" : "\x1B[01;31mdisabled"); + Log::i()->text("\x1B[01;32m * \x1B[01;37mHUGE PAGES: %s", + Mem::isHugepagesAvailable() ? "\x1B[01;32mavailable" : "\x1B[01;31munavailable"); } else { - Log::i()->text(" * HUGE PAGES: %s, %s", Mem::isHugepagesAvailable() ? "available" : "unavailable", Mem::isHugepagesEnabled() ? "enabled" : "disabled"); + Log::i()->text(" * HUGE PAGES: %s", Mem::isHugepagesAvailable() ? "available" : "unavailable"); } +# endif } diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index cb7a8005..0893bc8b 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -267,7 +267,7 @@ void ApiRouter::getMiner(rapidjson::Document &doc) const doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator); doc.AddMember("cpu", cpu, allocator); doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algoName()), allocator); - doc.AddMember("hugepages", Mem::isHugepagesEnabled(), allocator); + doc.AddMember("hugepages", false, allocator); doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator); } diff --git a/src/common/utils/mm_malloc.h b/src/common/utils/mm_malloc.h new file mode 100644 index 00000000..30c721a3 --- /dev/null +++ b/src/common/utils/mm_malloc.h @@ -0,0 +1,43 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __MM_MALLOC_PORTABLE_H__ +#define __MM_MALLOC_PORTABLE_H__ + + +#ifdef _WIN32 +# ifdef __GNUC__ +# include +# else +# include +# endif +#else +# if defined(XMRIG_ARM) && !defined(__clang__) +# include "aligned_malloc.h" +# else +# include +# endif +#endif + + +#endif /* __MM_MALLOC_PORTABLE_H__ */ diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index d0d61ae3..5a4a266d 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -40,8 +40,7 @@ struct cryptonight_ctx { - alignas(16) uint8_t state0[200]; - alignas(16) uint8_t state1[200]; + alignas(16) uint8_t state[200]; alignas(16) uint8_t* memory; }; diff --git a/src/crypto/CryptoNight_arm.h b/src/crypto/CryptoNight_arm.h index fd8b58ff..d9677d06 100644 --- a/src/crypto/CryptoNight_arm.h +++ b/src/crypto/CryptoNight_arm.h @@ -27,13 +27,7 @@ #define __CRYPTONIGHT_ARM_H__ -#if defined(XMRIG_ARM) && !defined(__clang__) -# include "aligned_malloc.h" -#else -# include -#endif - - +#include "common/utils/mm_malloc.h" #include "crypto/CryptoNight.h" #include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_monero.h" diff --git a/src/crypto/CryptoNight_monero.h b/src/crypto/CryptoNight_monero.h index a667a3b3..a34f3ba8 100644 --- a/src/crypto/CryptoNight_monero.h +++ b/src/crypto/CryptoNight_monero.h @@ -32,7 +32,7 @@ uint64_t tweak1_2_##part = 0; \ if (VARIANT > 0) { \ tweak1_2_##part = (*reinterpret_cast(input + 35 + part * size) ^ \ - *(reinterpret_cast(ctx->state##part) + 24)); \ + *(reinterpret_cast(ctx[part]->state) + 24)); \ } #else # define VARIANT1_INIT(part) \ diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index 417404a6..824dd99c 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -403,7 +403,7 @@ static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp) template -inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); constexpr size_t ITERATIONS = xmrig::cn_select_iter(); @@ -414,14 +414,14 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si return; } - keccak(input, (int) size, ctx->state0, 200); + keccak(input, (int) size, ctx[0]->state, 200); VARIANT1_INIT(0) - cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); + cn_explode_scratchpad((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); - const uint8_t* l0 = ctx->memory; - uint64_t* h0 = reinterpret_cast(ctx->state0); + const uint8_t* l0 = ctx[0]->memory; + uint64_t* h0 = reinterpret_cast(ctx[0]->state); uint64_t al0 = h0[0] ^ h0[4]; uint64_t ah0 = h0[1] ^ h0[5]; @@ -476,15 +476,15 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si } } - cn_implode_scratchpad((__m128i*) ctx->memory, (__m128i*) ctx->state0); + cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); keccakf(h0, 24); - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); } template -inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); constexpr size_t ITERATIONS = xmrig::cn_select_iter(); @@ -495,16 +495,16 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si return; } - keccak(input, (int) size, ctx->state0, 200); - keccak(input + size, (int) size, ctx->state1, 200); + keccak(input, (int) size, ctx[0]->state, 200); + keccak(input + size, (int) size, ctx[1]->state, 200); VARIANT1_INIT(0); VARIANT1_INIT(1); - const uint8_t* l0 = ctx->memory; - const uint8_t* l1 = ctx->memory + MEM; - uint64_t* h0 = reinterpret_cast(ctx->state0); - uint64_t* h1 = reinterpret_cast(ctx->state1); + const uint8_t* l0 = ctx[0]->memory; + const uint8_t* l1 = ctx[1]->memory; + uint64_t* h0 = reinterpret_cast(ctx[0]->state); + uint64_t* h1 = reinterpret_cast(ctx[1]->state); cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); @@ -606,25 +606,25 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si keccakf(h0, 24); keccakf(h1, 24); - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); - extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, output + 32); + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); + extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); } template -inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { } template -inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { } template -inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { } diff --git a/src/interfaces/IThread.h b/src/interfaces/IThread.h index 5b3efa0d..f517ed18 100644 --- a/src/interfaces/IThread.h +++ b/src/interfaces/IThread.h @@ -43,14 +43,22 @@ public: CUDA }; + enum Multiway { + SingleWay = 1, + DoubleWay, + TripleWay, + QuadWay, + PentaWay + }; + virtual ~IThread() {} - virtual Algo algorithm() const = 0; - virtual int multiway() const = 0; - virtual int priority() const = 0; - virtual int64_t affinity() const = 0; - virtual size_t index() const = 0; - virtual Type type() const = 0; + virtual Algo algorithm() const = 0; + virtual int priority() const = 0; + virtual int64_t affinity() const = 0; + virtual Multiway multiway() const = 0; + virtual size_t index() const = 0; + virtual Type type() const = 0; # ifndef XMRIG_NO_API virtual rapidjson::Value toAPI(rapidjson::Document &doc) const = 0; diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index 9d1bc4e7..e14c79f1 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -38,15 +38,6 @@ namespace xmrig { class CpuThread : public IThread { public: - enum Multiway { - SingleWay = 1, - DoubleWay, - TripleWay, - QuadWay, - PentaWay - }; - - struct Data { inline Data() : valid(false), affinity(-1L), multiway(SingleWay) {} @@ -68,7 +59,7 @@ public: CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch); ~CpuThread(); - typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx); + typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx); static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant); static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority); @@ -80,9 +71,9 @@ public: inline cn_hash_fun fn(Variant variant) const { return fn(m_algorithm, m_av, variant); } inline Algo algorithm() const override { return m_algorithm; } - inline int multiway() const override { return m_multiway; } inline int priority() const override { return m_priority; } inline int64_t affinity() const override { return m_affinity; } + inline Multiway multiway() const override { return m_multiway; } inline size_t index() const override { return m_index; } inline Type type() const override { return CPU; } diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index 0007b0cb..a75adecc 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -36,6 +36,14 @@ template MultiWorker::MultiWorker(Handle *handle) : Worker(handle) { + m_memory = Mem::create(m_ctx, m_thread->algorithm(), N); +} + + +template +MultiWorker::~MultiWorker() +{ + Mem::release(m_ctx, N, m_memory); } @@ -46,24 +54,24 @@ bool MultiWorker::selfTest() return false; } - m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_result.result, m_ctxLegacy); + m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_hash, m_ctx); - if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_result.result, test_output_v0, 32) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctxLegacy); + if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_hash, test_output_v0, sizeof m_hash) == 0) { + m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); - return memcmp(m_result.result, test_output_v1, 32) == 0; + return memcmp(m_hash, test_output_v1, sizeof m_hash) == 0; } # ifndef XMRIG_NO_AEON - if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_result.result, test_output_v0_lite, 32) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_result.result, m_ctxLegacy); + if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_hash, test_output_v0_lite, sizeof m_hash) == 0) { + m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); - return memcmp(m_result.result, test_output_v1_lite, 32) == 0; + return memcmp(m_hash, test_output_v1_lite, sizeof m_hash) == 0; } # endif # ifndef XMRIG_NO_SUMO - return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_result.result, test_output_heavy, 32) == 0; + return m_thread->algorithm() == xmrig::CRYPTONIGHT_HEAVY && memcmp(m_hash, test_output_heavy, sizeof m_hash) == 0; # else return false; # endif @@ -92,7 +100,7 @@ void MultiWorker::start() storeStats(); } - m_thread->fn(m_state.job.variant())(m_state.blob, m_state.job.size(), m_hash, m_ctxLegacy); + m_thread->fn(m_state.job.variant())(m_state.blob, m_state.job.size(), m_hash, m_ctx); for (size_t i = 0; i < N; ++i) { if (*reinterpret_cast(m_hash + (i * 32) + 24) < m_state.job.target()) { diff --git a/src/workers/MultiWorker.h b/src/workers/MultiWorker.h index d384b0ba..ba57f81e 100644 --- a/src/workers/MultiWorker.h +++ b/src/workers/MultiWorker.h @@ -26,6 +26,7 @@ #define __MULTIWORKER_H__ +#include "Mem.h" #include "net/Job.h" #include "net/JobResult.h" #include "workers/Worker.h" @@ -39,6 +40,7 @@ class MultiWorker : public Worker { public: MultiWorker(Handle *handle); + ~MultiWorker(); protected: bool selfTest() override; @@ -61,15 +63,11 @@ private: }; -// cryptonight_ctx *m_ctx[N]; - - uint8_t m_hash[N * 32]; - State m_state; + cryptonight_ctx *m_ctx[N]; + MemInfo m_memory; State m_pausedState; - - Job m_job; - Job m_paused; - JobResult m_result; + State m_state; + uint8_t m_hash[N * 32]; }; diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index e0ed846b..567b3e08 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -26,7 +26,6 @@ #include "common/Platform.h" #include "Cpu.h" -#include "Mem.h" #include "workers/CpuThread.h" #include "workers/Handle.h" #include "workers/Worker.h" @@ -47,12 +46,6 @@ Worker::Worker(Handle *handle) : } Platform::setThreadPriority(m_thread->priority()); - m_ctxLegacy = Mem::create(m_id); -} - - -Worker::~Worker() -{ } diff --git a/src/workers/Worker.h b/src/workers/Worker.h index 72b3beb2..0ae30530 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -45,7 +45,6 @@ class Worker : public IWorker { public: Worker(Handle *handle); - ~Worker(); inline size_t id() const override { return m_id; } inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); } @@ -57,7 +56,6 @@ protected: const size_t m_id; const size_t m_totalWays; const uint32_t m_offset; - cryptonight_ctx *m_ctxLegacy; std::atomic m_hashCount; std::atomic m_timestamp; uint64_t m_count; From 8716f362f893cd7a40c3000d6c1ef23bdb7b7208 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 11:36:48 +0700 Subject: [PATCH 056/109] Fixed HW AES detection. --- src/core/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index ddce6980..1eb8e6e5 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -157,7 +157,7 @@ bool xmrig::Config::adjust() } if (m_aesMode == AES_AUTO) { - m_aesMode = Cpu::hasAES() ? AES_SOFT : AES_SOFT; + m_aesMode = Cpu::hasAES() ? AES_HW : AES_SOFT; } if (!m_threads.cpu.empty()) { From 6b4f2d0a9137528b359506808430caef921a2efa Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 12:58:17 +0700 Subject: [PATCH 057/109] Fixed ARM build. --- src/Mem.cpp | 2 +- src/Mem_unix.cpp | 2 +- src/Mem_win.cpp | 2 +- src/crypto/CryptoNight_arm.h | 38 ++++++++++++++++----------------- src/crypto/CryptoNight_monero.h | 2 +- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Mem.cpp b/src/Mem.cpp index 2efaac8a..bb2da646 100644 --- a/src/Mem.cpp +++ b/src/Mem.cpp @@ -50,7 +50,7 @@ MemInfo Mem::create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count) allocate(info, m_enabled); for (size_t i = 0; i < count; ++i) { - cryptonight_ctx *c = static_cast(_mm_malloc(sizeof(cryptonight_ctx), 16)); + cryptonight_ctx *c = static_cast(_mm_malloc(sizeof(cryptonight_ctx), 4096)); c->memory = info.memory + (i * cn_select_memory(algorithm)); ctx[i] = c; diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index 550033c4..229a0d46 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -45,7 +45,7 @@ void Mem::allocate(MemInfo &info, bool enabled) info.hugePages = 0; if (!enabled) { - info.memory = static_cast(_mm_malloc(info.size, 16)); + info.memory = static_cast(_mm_malloc(info.size, 4096)); return; } diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index d0b698f6..9a81b039 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -157,7 +157,7 @@ void Mem::allocate(MemInfo &info, bool enabled) info.hugePages = 0; if (!enabled) { - info.memory = static_cast(_mm_malloc(info.size, 16)); + info.memory = static_cast(_mm_malloc(info.size, 4096)); return; } diff --git a/src/crypto/CryptoNight_arm.h b/src/crypto/CryptoNight_arm.h index d9677d06..101a1f58 100644 --- a/src/crypto/CryptoNight_arm.h +++ b/src/crypto/CryptoNight_arm.h @@ -455,7 +455,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) template -inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); constexpr size_t ITERATIONS = xmrig::cn_select_iter(); @@ -466,14 +466,14 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si return; } - keccak(input, (int) size, ctx->state0, 200); + keccak(input, (int) size, ctx[0]->state, 200); VARIANT1_INIT(0); - cn_explode_scratchpad((__m128i*) ctx->state0, (__m128i*) ctx->memory); + cn_explode_scratchpad((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); - const uint8_t* l0 = ctx->memory; - uint64_t* h0 = reinterpret_cast(ctx->state0); + const uint8_t* l0 = ctx[0]->memory; + uint64_t* h0 = reinterpret_cast(ctx[0]->state); uint64_t al0 = h0[0] ^ h0[4]; uint64_t ah0 = h0[1] ^ h0[5]; @@ -526,15 +526,15 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si } } - cn_implode_scratchpad((__m128i*) ctx->memory, (__m128i*) ctx->state0); + cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); keccakf(h0, 24); - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); } template -inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) { constexpr size_t MASK = xmrig::cn_select_mask(); constexpr size_t ITERATIONS = xmrig::cn_select_iter(); @@ -545,16 +545,16 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si return; } - keccak(input, (int) size, ctx->state0, 200); - keccak(input + size, (int) size, ctx->state1, 200); + keccak(input, (int) size, ctx[0]->state, 200); + keccak(input + size, (int) size, ctx[1]->state, 200); VARIANT1_INIT(0); VARIANT1_INIT(1); - const uint8_t* l0 = ctx->memory; - const uint8_t* l1 = ctx->memory + MEM; - uint64_t* h0 = reinterpret_cast(ctx->state0); - uint64_t* h1 = reinterpret_cast(ctx->state1); + const uint8_t* l0 = ctx[0]->memory; + const uint8_t* l1 = ctx[1]->memory; + uint64_t* h0 = reinterpret_cast(ctx[0]->state); + uint64_t* h1 = reinterpret_cast(ctx[1]->state); cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); @@ -655,25 +655,25 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si keccakf(h0, 24); keccakf(h1, 24); - extra_hashes[ctx->state0[0] & 3](ctx->state0, 200, output); - extra_hashes[ctx->state1[0] & 3](ctx->state1, 200, output + 32); + extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); + extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); } template -inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) { } template -inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) { } template -inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) +inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx) { } diff --git a/src/crypto/CryptoNight_monero.h b/src/crypto/CryptoNight_monero.h index a34f3ba8..ea1622ab 100644 --- a/src/crypto/CryptoNight_monero.h +++ b/src/crypto/CryptoNight_monero.h @@ -39,7 +39,7 @@ uint64_t tweak1_2_##part = 0; \ if (VARIANT > 0) { \ volatile const uint64_t a = *reinterpret_cast(input + 35 + part * size); \ - volatile const uint64_t b = *(reinterpret_cast(ctx->state##part) + 24); \ + volatile const uint64_t b = *(reinterpret_cast(ctx[part]->state) + 24); \ tweak1_2_##part = a ^ b; \ } #endif From e2d85d78a7e89ad062f68706a93a6aa3367cb4c6 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 14:49:39 +0700 Subject: [PATCH 058/109] Added information about started threads. --- src/workers/MultiWorker.h | 1 - src/workers/Worker.h | 3 +++ src/workers/Workers.cpp | 41 +++++++++++++++++++++++++++++++++++---- src/workers/Workers.h | 25 ++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/src/workers/MultiWorker.h b/src/workers/MultiWorker.h index ba57f81e..2c231e8d 100644 --- a/src/workers/MultiWorker.h +++ b/src/workers/MultiWorker.h @@ -64,7 +64,6 @@ private: cryptonight_ctx *m_ctx[N]; - MemInfo m_memory; State m_pausedState; State m_state; uint8_t m_hash[N * 32]; diff --git a/src/workers/Worker.h b/src/workers/Worker.h index 0ae30530..aad9e3c5 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -30,6 +30,7 @@ #include "interfaces/IWorker.h" +#include "Mem.h" struct cryptonight_ctx; @@ -46,6 +47,7 @@ class Worker : public IWorker public: Worker(Handle *handle); + inline const MemInfo &memory() const { return m_memory; } inline size_t id() const override { return m_id; } inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); } inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); } @@ -56,6 +58,7 @@ protected: const size_t m_id; const size_t m_totalWays; const uint32_t m_offset; + MemInfo m_memory; std::atomic m_hashCount; std::atomic m_timestamp; uint64_t m_count; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 21379db4..6d6deb3b 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -43,6 +43,7 @@ bool Workers::m_enabled = true; Hashrate *Workers::m_hashrate = nullptr; IJobResultListener *Workers::m_listener = nullptr; Job Workers::m_job; +Workers::LaunchStatus Workers::m_status; std::atomic Workers::m_paused; std::atomic Workers::m_sequence; std::list Workers::m_queue; @@ -109,10 +110,12 @@ void Workers::setJob(const Job &job, bool donate) void Workers::start(xmrig::Controller *controller) { const std::vector &threads = controller->config()->threads(); + m_status.algo = controller->config()->algorithm(); + m_status.colors = controller->config()->isHugePages(); + m_status.threads = threads.size(); - size_t totalWays = 0; for (const xmrig::IThread *thread : threads) { - totalWays += thread->multiway(); + m_status.ways += thread->multiway(); } m_hashrate = new Hashrate(threads.size(), controller); @@ -130,7 +133,7 @@ void Workers::start(xmrig::Controller *controller) uint32_t offset = 0; for (xmrig::IThread *thread : threads) { - Handle *handle = new Handle(thread, offset, totalWays); + Handle *handle = new Handle(thread, offset, m_status.ways); offset += thread->multiway(); m_workers.push_back(handle); @@ -203,7 +206,7 @@ void Workers::onReady(void *arg) return; } - worker->start(); + start(worker); } @@ -244,3 +247,33 @@ void Workers::onTick(uv_timer_t *handle) Api::tick(m_hashrate); # endif } + + +void Workers::start(IWorker *worker) +{ + const Worker *w = static_cast(worker); + + uv_mutex_lock(&m_mutex); + m_status.started++; + m_status.pages += w->memory().pages; + m_status.hugePages += w->memory().hugePages; + + if (m_status.started == m_status.threads) { + const double percent = (double) m_status.hugePages / m_status.pages * 100.0; + + if (m_status.colors) { + LOG_INFO("\x1B[01;32mREADY (CPU)\x1B[0m threads \x1B[01;36m%zu(%zu)\x1B[0m huge pages %s%zu/%zu %1.0f%%\x1B[0m memory \x1B[01;36m%zu.0 MB", + m_status.threads, m_status.ways, + (m_status.hugePages == m_status.pages ? "\x1B[01;32m" : (m_status.hugePages == 0 ? "\x1B[01;31m" : "\x1B[01;33m")), + m_status.hugePages, m_status.pages, percent, m_status.pages * 2); + } + else { + LOG_INFO("READY (CPU) threads %zu(%zu) huge pages %zu/%zu %f%% memory %zu.0 MB", + m_status.threads, m_status.ways, m_status.hugePages, m_status.pages, percent, m_status.pages * 2); + } + } + + uv_mutex_unlock(&m_mutex); + + worker->start(); +} diff --git a/src/workers/Workers.h b/src/workers/Workers.h index ecec9e30..81b3411a 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -37,6 +37,7 @@ class Handle; class Hashrate; class IJobResultListener; +class IWorker; namespace xmrig { @@ -66,12 +67,36 @@ private: static void onReady(void *arg); static void onResult(uv_async_t *handle); static void onTick(uv_timer_t *handle); + static void start(IWorker *worker); + + class LaunchStatus + { + public: + inline LaunchStatus() : + colors(true), + hugePages(0), + pages(0), + started(0), + threads(0), + ways(0), + algo(xmrig::CRYPTONIGHT) + {} + + bool colors; + size_t hugePages; + size_t pages; + size_t started; + size_t threads; + size_t ways; + xmrig::Algo algo; + }; static bool m_active; static bool m_enabled; static Hashrate *m_hashrate; static IJobResultListener *m_listener; static Job m_job; + static LaunchStatus m_status; static std::atomic m_paused; static std::atomic m_sequence; static std::list m_queue; From 6de83dddd6d96e6c2b48a4f04318ec6ac1cb821a Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 15:01:41 +0700 Subject: [PATCH 059/109] Fix wrong memory usage displayed for cn-lite. --- src/workers/Workers.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 6d6deb3b..40dbb00c 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -260,16 +260,17 @@ void Workers::start(IWorker *worker) if (m_status.started == m_status.threads) { const double percent = (double) m_status.hugePages / m_status.pages * 100.0; + const size_t ratio = m_status.algo == xmrig::CRYPTONIGHT_LITE ? 1 : 2; if (m_status.colors) { LOG_INFO("\x1B[01;32mREADY (CPU)\x1B[0m threads \x1B[01;36m%zu(%zu)\x1B[0m huge pages %s%zu/%zu %1.0f%%\x1B[0m memory \x1B[01;36m%zu.0 MB", m_status.threads, m_status.ways, (m_status.hugePages == m_status.pages ? "\x1B[01;32m" : (m_status.hugePages == 0 ? "\x1B[01;31m" : "\x1B[01;33m")), - m_status.hugePages, m_status.pages, percent, m_status.pages * 2); + m_status.hugePages, m_status.pages, percent, m_status.pages * ratio); } else { LOG_INFO("READY (CPU) threads %zu(%zu) huge pages %zu/%zu %f%% memory %zu.0 MB", - m_status.threads, m_status.ways, m_status.hugePages, m_status.pages, percent, m_status.pages * 2); + m_status.threads, m_status.ways, m_status.hugePages, m_status.pages, percent, m_status.pages * ratio); } } From f0158ae5059573fe2627a2c085c8e8dbca708ef1 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 15:10:41 +0700 Subject: [PATCH 060/109] Fix again. --- src/workers/Workers.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 40dbb00c..e26b2030 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -28,6 +28,7 @@ #include "api/Api.h" #include "core/Config.h" #include "core/Controller.h" +#include "crypto/CryptoNight_constants.h" #include "interfaces/IJobResultListener.h" #include "interfaces/IThread.h" #include "log/Log.h" @@ -260,17 +261,17 @@ void Workers::start(IWorker *worker) if (m_status.started == m_status.threads) { const double percent = (double) m_status.hugePages / m_status.pages * 100.0; - const size_t ratio = m_status.algo == xmrig::CRYPTONIGHT_LITE ? 1 : 2; + const size_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo) / 1048576; if (m_status.colors) { LOG_INFO("\x1B[01;32mREADY (CPU)\x1B[0m threads \x1B[01;36m%zu(%zu)\x1B[0m huge pages %s%zu/%zu %1.0f%%\x1B[0m memory \x1B[01;36m%zu.0 MB", m_status.threads, m_status.ways, (m_status.hugePages == m_status.pages ? "\x1B[01;32m" : (m_status.hugePages == 0 ? "\x1B[01;31m" : "\x1B[01;33m")), - m_status.hugePages, m_status.pages, percent, m_status.pages * ratio); + m_status.hugePages, m_status.pages, percent, memory); } else { LOG_INFO("READY (CPU) threads %zu(%zu) huge pages %zu/%zu %f%% memory %zu.0 MB", - m_status.threads, m_status.ways, m_status.hugePages, m_status.pages, percent, m_status.pages * ratio); + m_status.threads, m_status.ways, m_status.hugePages, m_status.pages, percent, memory); } } From f8bf48a522c3bcf6f6a3b2e3f83363cbeb3c89eb Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 19:25:09 +0700 Subject: [PATCH 061/109] Added config only boolean option "hw-aes". --- src/core/Config.cpp | 58 +++++++++++++++----------------- src/core/ConfigLoader_platform.h | 1 + src/interfaces/IConfig.h | 1 + 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 1eb8e6e5..f75e058a 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -67,53 +67,49 @@ bool xmrig::Config::reload(const char *json) void xmrig::Config::getJSON(rapidjson::Document &doc) const { + using namespace rapidjson; + doc.SetObject(); auto &allocator = doc.GetAllocator(); - doc.AddMember("algo", rapidjson::StringRef(algoName()), allocator); + doc.AddMember("algo", StringRef(algoName()), allocator); - rapidjson::Value api(rapidjson::kObjectType); + Value api(kObjectType); api.AddMember("port", apiPort(), allocator); - api.AddMember("access-token", apiToken() ? rapidjson::Value(rapidjson::StringRef(apiToken())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); - api.AddMember("worker-id", apiWorkerId() ? rapidjson::Value(rapidjson::StringRef(apiWorkerId())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); + api.AddMember("access-token", apiToken() ? Value(StringRef(apiToken())).Move() : Value(kNullType).Move(), allocator); + api.AddMember("worker-id", apiWorkerId() ? Value(StringRef(apiWorkerId())).Move() : Value(kNullType).Move(), allocator); api.AddMember("ipv6", isApiIPv6(), allocator); api.AddMember("restricted", isApiRestricted(), allocator); doc.AddMember("api", api, allocator); doc.AddMember("av", algoVariant(), allocator); doc.AddMember("background", isBackground(), allocator); - - doc.AddMember("colors", isColors(), allocator); + doc.AddMember("colors", isColors(), allocator); if (affinity() != -1L) { snprintf(affinity_tmp, sizeof(affinity_tmp) - 1, "0x%" PRIX64, affinity()); - doc.AddMember("cpu-affinity", rapidjson::StringRef(affinity_tmp), allocator); + doc.AddMember("cpu-affinity", StringRef(affinity_tmp), allocator); } else { - doc.AddMember("cpu-affinity", rapidjson::kNullType, allocator); - } - - if (priority() != -1) { - doc.AddMember("cpu-priority", priority(), allocator); - } - else { - doc.AddMember("cpu-priority", rapidjson::kNullType, allocator); + doc.AddMember("cpu-affinity", kNullType, allocator); } + doc.AddMember("cpu-priority", priority() != -1 ? Value(priority()) : Value(kNullType), allocator); doc.AddMember("donate-level", donateLevel(), allocator); doc.AddMember("huge-pages", isHugePages(), allocator); - doc.AddMember("log-file", logFile() ? rapidjson::Value(rapidjson::StringRef(logFile())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); + doc.AddMember("hw-aes", m_aesMode == AES_AUTO ? Value(kNullType) : Value(m_aesMode == AES_HW), allocator); + doc.AddMember("log-file", logFile() ? Value(StringRef(logFile())).Move() : Value(kNullType).Move(), allocator); doc.AddMember("max-cpu-usage", m_maxCpuUsage, allocator); - rapidjson::Value pools(rapidjson::kArrayType); + Value pools(kArrayType); for (const Pool &pool : m_pools) { - rapidjson::Value obj(rapidjson::kObjectType); + Value obj(kObjectType); - obj.AddMember("url", rapidjson::StringRef(pool.url()), allocator); - obj.AddMember("user", rapidjson::StringRef(pool.user()), allocator); - obj.AddMember("pass", rapidjson::StringRef(pool.password()), allocator); + obj.AddMember("url", StringRef(pool.url()), allocator); + obj.AddMember("user", StringRef(pool.user()), allocator); + obj.AddMember("pass", StringRef(pool.password()), allocator); if (pool.keepAlive() == 0 || pool.keepAlive() == Pool::kKeepAliveTimeout) { obj.AddMember("keepalive", pool.keepAlive() > 0, allocator); @@ -134,7 +130,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const doc.AddMember("retry-pause", retryPause(), allocator); doc.AddMember("safe", m_safe, allocator); doc.AddMember("threads", threadsCount(), allocator); - doc.AddMember("user-agent", userAgent() ? rapidjson::Value(rapidjson::StringRef(userAgent())).Move() : rapidjson::Value(rapidjson::kNullType).Move(), allocator); + doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator); # ifdef HAVE_SYSLOG_H doc.AddMember("syslog", isSyslog(), allocator); @@ -156,13 +152,11 @@ bool xmrig::Config::adjust() return false; } - if (m_aesMode == AES_AUTO) { - m_aesMode = Cpu::hasAES() ? AES_HW : AES_SOFT; - } - if (!m_threads.cpu.empty()) { + const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; + for (size_t i = 0; i < m_threads.cpu.size(); ++i) { - m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm, m_threads.cpu[i], m_priority, m_aesMode == AES_SOFT)); + m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm, m_threads.cpu[i], m_priority, softAES)); } return true; @@ -198,18 +192,22 @@ bool xmrig::Config::parseBoolean(int key, bool enable) } switch (key) { - case xmrig::IConfig::SafeKey: /* --safe */ + case IConfig::SafeKey: /* --safe */ m_safe = enable; break; - case xmrig::IConfig::HugePagesKey: /* --no-huge-pages */ + case IConfig::HugePagesKey: /* --no-huge-pages */ m_hugePages = enable; break; - case xmrig::IConfig::DryRunKey: /* --dry-run */ + case IConfig::DryRunKey: /* --dry-run */ m_dryRun = enable; break; + case IConfig::HardwareAESKey: /* hw-aes config only */ + m_aesMode = enable ? AES_HW : AES_SOFT; + break; + default: break; } diff --git a/src/core/ConfigLoader_platform.h b/src/core/ConfigLoader_platform.h index a090fb99..7e1a4baa 100644 --- a/src/core/ConfigLoader_platform.h +++ b/src/core/ConfigLoader_platform.h @@ -150,6 +150,7 @@ static struct option const config_options[] = { { "syslog", 0, nullptr, xmrig::IConfig::SyslogKey }, { "threads", 1, nullptr, xmrig::IConfig::ThreadsKey }, { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, + { "hw-aes", 0, nullptr, xmrig::IConfig::HardwareAESKey }, { 0, 0, 0, 0 } }; diff --git a/src/interfaces/IConfig.h b/src/interfaces/IConfig.h index 89aa6217..f7433d7f 100644 --- a/src/interfaces/IConfig.h +++ b/src/interfaces/IConfig.h @@ -74,6 +74,7 @@ public: MaxCPUUsageKey = 1004, SafeKey = 1005, ThreadsKey = 't', + HardwareAESKey = 1011, // xmrig-proxy AccessLogFileKey = 'A', From dba1acd30201bf0d3bf09b44a89c72abb197b595 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 15 Apr 2018 21:41:03 +0700 Subject: [PATCH 062/109] Finalize config changes. --- src/core/Config.cpp | 32 ++++++++++++++++++++++---------- src/core/Config.h | 15 ++++++++++----- src/interfaces/IThread.h | 13 +++++++------ src/workers/CpuThread.cpp | 18 +++++++++++++++++- src/workers/CpuThread.h | 3 +++ 5 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/core/Config.cpp b/src/core/Config.cpp index f75e058a..b3564f92 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -43,12 +43,10 @@ static char affinity_tmp[20] = { 0 }; xmrig::Config::Config() : xmrig::CommonConfig(), m_aesMode(AES_AUTO), m_algoVariant(AV_AUTO), - m_doubleHash(false), m_dryRun(false), m_hugePages(true), m_safe(false), m_maxCpuUsage(75), - m_printTime(60), m_priority(-1) { } @@ -129,8 +127,21 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const doc.AddMember("retries", retries(), allocator); doc.AddMember("retry-pause", retryPause(), allocator); doc.AddMember("safe", m_safe, allocator); - doc.AddMember("threads", threadsCount(), allocator); - doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator); + + if (threadsMode() == Advanced) { + Value threads(kArrayType); + + for (const IThread *thread : m_threads.list) { + threads.PushBack(thread->toConfig(doc), doc.GetAllocator()); + } + + doc.AddMember("threads", threads, allocator); + } + else { + doc.AddMember("threads", threadsMode() == Automatic ? Value(kNullType) : Value(threadsCount()), allocator); + } + + doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator); # ifdef HAVE_SYSLOG_H doc.AddMember("syslog", isSyslog(), allocator); @@ -153,6 +164,7 @@ bool xmrig::Config::adjust() } if (!m_threads.cpu.empty()) { + m_threads.mode = Advanced; const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; for (size_t i = 0; i < m_threads.cpu.size(); ++i) { @@ -162,16 +174,16 @@ bool xmrig::Config::adjust() return true; } - m_algoVariant = getAlgoVariant(); - if (m_algoVariant == AV_DOUBLE || m_algoVariant == AV_DOUBLE_SOFT) { - m_doubleHash = true; - } + m_algoVariant = getAlgoVariant(); + m_threads.mode = m_threads.count ? Simple : Automatic; + + const bool doubleHash = m_algoVariant == AV_DOUBLE || m_algoVariant == AV_DOUBLE_SOFT; if (!m_threads.count) { - m_threads.count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); + m_threads.count = Cpu::optimalThreadsCount(m_algorithm, doubleHash, m_maxCpuUsage); } else if (m_safe) { - const size_t count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); + const size_t count = Cpu::optimalThreadsCount(m_algorithm, doubleHash, m_maxCpuUsage); if (m_threads.count > count) { m_threads.count = count; } diff --git a/src/core/Config.h b/src/core/Config.h index 720557a7..13320a80 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -61,6 +61,13 @@ class IWatcherListener; class Config : public CommonConfig { public: + enum ThreadsMode { + Automatic, + Simple, + Advanced + }; + + Config(); ~Config(); @@ -70,14 +77,13 @@ public: inline AesMode aesMode() const { return m_aesMode; } inline AlgoVariant algoVariant() const { return m_algoVariant; } - inline bool isDoubleHash() const { return m_doubleHash; } inline bool isDryRun() const { return m_dryRun; } inline bool isHugePages() const { return m_hugePages; } inline const std::vector &threads() const { return m_threads.list; } - inline int printTime() const { return m_printTime; } inline int priority() const { return m_priority; } inline int threadsCount() const { return m_threads.list.size(); } inline int64_t affinity() const { return m_threads.mask; } + inline ThreadsMode threadsMode() const { return m_threads.mode; } static Config *load(int argc, char **argv, IWatcherListener *listener); @@ -99,23 +105,22 @@ private: struct Threads { - inline Threads() : mask(-1L), count(0) {} + inline Threads() : mask(-1L), count(0), mode(Automatic) {} int64_t mask; size_t count; std::vector cpu; std::vector list; + ThreadsMode mode; }; AesMode m_aesMode; AlgoVariant m_algoVariant; - bool m_doubleHash; bool m_dryRun; bool m_hugePages; bool m_safe; int m_maxCpuUsage; - int m_printTime; int m_priority; Threads m_threads; }; diff --git a/src/interfaces/IThread.h b/src/interfaces/IThread.h index f517ed18..2e9e3c39 100644 --- a/src/interfaces/IThread.h +++ b/src/interfaces/IThread.h @@ -53,12 +53,13 @@ public: virtual ~IThread() {} - virtual Algo algorithm() const = 0; - virtual int priority() const = 0; - virtual int64_t affinity() const = 0; - virtual Multiway multiway() const = 0; - virtual size_t index() const = 0; - virtual Type type() const = 0; + virtual Algo algorithm() const = 0; + virtual int priority() const = 0; + virtual int64_t affinity() const = 0; + virtual Multiway multiway() const = 0; + virtual rapidjson::Value toConfig(rapidjson::Document &doc) const = 0; + virtual size_t index() const = 0; + virtual Type type() const = 0; # ifndef XMRIG_NO_API virtual rapidjson::Value toAPI(rapidjson::Document &doc) const = 0; diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 07fbbb64..ac733ef6 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -245,7 +245,9 @@ xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object) #ifndef XMRIG_NO_API rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const { - rapidjson::Value obj(rapidjson::kObjectType); + using namespace rapidjson; + + Value obj(kObjectType); auto &allocator = doc.GetAllocator(); obj.AddMember("type", "cpu", allocator); @@ -259,3 +261,17 @@ rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const return obj; } #endif + + +rapidjson::Value xmrig::CpuThread::toConfig(rapidjson::Document &doc) const +{ + using namespace rapidjson; + + Value obj(kObjectType); + auto &allocator = doc.GetAllocator(); + + obj.AddMember("low_power_mode", multiway(), allocator); + obj.AddMember("affine_to_cpu", affinity() == -1L ? Value(kFalseType) : Value(affinity()), allocator); + + return obj; +} diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index e14c79f1..ba36cc87 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -77,10 +77,13 @@ public: inline size_t index() const override { return m_index; } inline Type type() const override { return CPU; } +protected: # ifndef XMRIG_NO_API rapidjson::Value toAPI(rapidjson::Document &doc) const override; # endif + rapidjson::Value toConfig(rapidjson::Document &doc) const override; + private: const Algo m_algorithm; const AlgoVariant m_av; From 9e3f2ae9f9adfdb35e26a7519acc92b261288d90 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 16 Apr 2018 15:40:37 +0700 Subject: [PATCH 063/109] Added x3 x4 x5 hashing modes. --- cmake/flags.cmake | 4 +- src/api/ApiRouter.cpp | 8 +- src/crypto/CryptoNight_test.h | 69 +++++-- src/crypto/CryptoNight_x86.h | 362 +++++++++++++++++++++++++++++++++- src/crypto/soft_aes.h | 17 ++ src/workers/MultiWorker.cpp | 2 +- 6 files changed, 442 insertions(+), 20 deletions(-) diff --git a/cmake/flags.cmake b/cmake/flags.cmake index 13e50564..498f2165 100644 --- a/cmake/flags.cmake +++ b/cmake/flags.cmake @@ -13,10 +13,10 @@ endif() if (CMAKE_CXX_COMPILER_ID MATCHES GNU) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-strict-aliasing") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s") if (XMRIG_ARMv8) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a+crypto") diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 0893bc8b..8206aa3e 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -298,13 +298,17 @@ void ApiRouter::getResults(rapidjson::Document &doc) const void ApiRouter::getThreads(rapidjson::Document &doc) const { - doc.SetArray(); + doc.SetObject(); + auto &allocator = doc.GetAllocator(); const std::vector &threads = m_controller->config()->threads(); + rapidjson::Value list(rapidjson::kArrayType); for (const xmrig::IThread *thread : threads) { - doc.PushBack(thread->toAPI(doc), doc.GetAllocator()); + list.PushBack(thread->toAPI(doc), allocator); } + + doc.AddMember("threads", list, allocator); } diff --git a/src/crypto/CryptoNight_test.h b/src/crypto/CryptoNight_test.h index 5717f1d3..52dd2965 100644 --- a/src/crypto/CryptoNight_test.h +++ b/src/crypto/CryptoNight_test.h @@ -26,7 +26,7 @@ #define __CRYPTONIGHT_TEST_H__ -const static uint8_t test_input[152] = { +const static uint8_t test_input[380] = { 0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19, 0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9, 0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F, @@ -36,52 +36,97 @@ const static uint8_t test_input[152] = { 0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B, 0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62, 0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92, - 0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01 + 0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01, + 0x07, 0x07, 0xB4, 0x87, 0xD0, 0xD6, 0x05, 0x26, 0xE0, 0xC6, 0xDD, 0x9B, 0xC7, 0x18, 0xC3, 0xCF, + 0x52, 0x04, 0xBD, 0x4F, 0x9B, 0x27, 0xF6, 0x73, 0xB9, 0x3F, 0xEF, 0x7B, 0xB2, 0xF7, 0x2B, 0xBB, + 0x3F, 0x3E, 0x9C, 0x3E, 0x9D, 0x33, 0x1E, 0xDE, 0xAD, 0xBE, 0xEF, 0x4E, 0x00, 0x91, 0x81, 0x29, + 0x74, 0xB2, 0x70, 0xE7, 0x6D, 0xD2, 0x2A, 0x5F, 0x52, 0x04, 0x93, 0xE6, 0x18, 0x89, 0x40, 0xD8, + 0xC6, 0xE3, 0x90, 0x6E, 0xAA, 0x6A, 0xB7, 0xE2, 0x08, 0x7E, 0x78, 0x0E, + 0x01, 0x00, 0xEE, 0xB2, 0xD1, 0xD6, 0x05, 0xFF, 0x27, 0x7F, 0x26, 0xDB, 0xAA, 0xB2, 0xC9, 0x26, + 0x30, 0xC6, 0xCF, 0x11, 0x64, 0xEA, 0x6C, 0x8A, 0xE0, 0x98, 0x01, 0xF8, 0x75, 0x4B, 0x49, 0xAF, + 0x79, 0x70, 0xAE, 0xEE, 0xA7, 0x62, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x47, 0x8C, 0x63, 0xE7, 0xD8, + 0x40, 0x02, 0x3C, 0xDA, 0xEA, 0x92, 0x52, 0x53, 0xAC, 0xFD, 0xC7, 0x8A, 0x4C, 0x31, 0xB2, 0xF2, + 0xEC, 0x72, 0x7B, 0xFF, 0xCE, 0xC0, 0xE7, 0x12, 0xD4, 0xE9, 0x2A, 0x01, + 0x07, 0x07, 0xA9, 0xB7, 0xD1, 0xD6, 0x05, 0x3F, 0x0D, 0x5E, 0xFD, 0xC7, 0x03, 0xFC, 0xFC, 0xD2, + 0xCE, 0xBC, 0x44, 0xD8, 0xAB, 0x44, 0xA6, 0xA0, 0x3A, 0xE4, 0x4D, 0x8F, 0x15, 0xAF, 0x62, 0x17, + 0xD1, 0xE0, 0x92, 0x85, 0xE4, 0x73, 0xF9, 0x00, 0x00, 0x00, 0xA0, 0xFC, 0x09, 0xDE, 0xAB, 0xF5, + 0x8B, 0x6F, 0x1D, 0xCA, 0xA8, 0xBA, 0xAC, 0x74, 0xDD, 0x74, 0x19, 0xD5, 0xD6, 0x10, 0xEC, 0x38, + 0xCF, 0x50, 0x29, 0x6A, 0x07, 0x0B, 0x93, 0x8F, 0x8F, 0xA8, 0x10, 0x04 }; -const static uint8_t test_output_v0[64] = { +const static uint8_t test_output_v0[160] = { 0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66, 0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F, 0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7, - 0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00 + 0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00, + 0xA1, 0xB4, 0xFA, 0xE3, 0xE5, 0x76, 0xCE, 0xCF, 0xB7, 0x9C, 0xAF, 0x3E, 0x29, 0x92, 0xE4, 0xE0, + 0x31, 0x24, 0x05, 0x48, 0xBF, 0x8D, 0x5F, 0x7B, 0x11, 0x03, 0x60, 0xAA, 0xD7, 0x50, 0x3F, 0x0C, + 0x2D, 0x30, 0xF3, 0x87, 0x4F, 0x86, 0xA1, 0x4A, 0xB5, 0xA2, 0x1A, 0x08, 0xD0, 0x44, 0x2C, 0x9D, + 0x16, 0xE9, 0x28, 0x49, 0xA1, 0xFF, 0x85, 0x6F, 0x12, 0xBB, 0x7D, 0xAB, 0x11, 0x1C, 0xE7, 0xF7, + 0x2D, 0x9D, 0x19, 0xE4, 0xD2, 0x26, 0x44, 0x1E, 0xCD, 0x22, 0x08, 0x24, 0xA8, 0x97, 0x46, 0x62, + 0x04, 0x84, 0x90, 0x4A, 0xEE, 0x99, 0x14, 0xED, 0xB8, 0xC6, 0x0D, 0x37, 0xA1, 0x66, 0x17, 0xB0 }; // Monero v7 -const static uint8_t test_output_v1[64] = { +const static uint8_t test_output_v1[160] = { 0xC9, 0xFA, 0xE8, 0x42, 0x5D, 0x86, 0x88, 0xDC, 0x23, 0x6B, 0xCD, 0xBC, 0x42, 0xFD, 0xB4, 0x2D, 0x37, 0x6C, 0x6E, 0xC1, 0x90, 0x50, 0x1A, 0xA8, 0x4B, 0x04, 0xA4, 0xB4, 0xCF, 0x1E, 0xE1, 0x22, 0xF2, 0x2D, 0x3D, 0x62, 0x03, 0xD2, 0xA0, 0x8B, 0x41, 0xD9, 0x02, 0x72, 0x78, 0xD8, 0xBC, 0xC9, - 0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9 + 0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9, + 0xE7, 0x8C, 0x5A, 0x6E, 0x38, 0x30, 0x68, 0x4A, 0x73, 0xFC, 0x1B, 0xC6, 0x6D, 0xFC, 0x8D, 0x98, + 0xB4, 0xC2, 0x23, 0x39, 0xAD, 0xE0, 0x9D, 0xF6, 0x6D, 0x8C, 0x6A, 0xAA, 0xF9, 0xB2, 0xE3, 0x4C, + 0xB6, 0x90, 0x6C, 0xE6, 0x15, 0x5E, 0x46, 0x07, 0x9C, 0xB2, 0x6B, 0xAC, 0x3B, 0xAC, 0x1A, 0xDE, + 0x92, 0x2C, 0xD6, 0x0C, 0x46, 0x9D, 0x9B, 0xC2, 0x84, 0x52, 0x65, 0xF6, 0xBD, 0xFA, 0x0D, 0x74, + 0x00, 0x66, 0x10, 0x07, 0xF1, 0x19, 0x06, 0x3A, 0x6C, 0xFF, 0xEE, 0xB2, 0x40, 0xE5, 0x88, 0x2B, + 0x6C, 0xAB, 0x6B, 0x1D, 0x88, 0xB8, 0x44, 0x25, 0xF4, 0xEA, 0xB7, 0xEC, 0xBA, 0x12, 0x8A, 0x24 }; #ifndef XMRIG_NO_AEON -const static uint8_t test_output_v0_lite[64] = { +const static uint8_t test_output_v0_lite[160] = { 0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE, 0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD, 0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E, - 0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88 + 0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88, + 0x38, 0x08, 0xE1, 0x17, 0x0B, 0x99, 0x8D, 0x1A, 0x3C, 0xCE, 0x35, 0xC5, 0xC7, 0x3A, 0x00, 0x2E, + 0xCB, 0x54, 0xF0, 0x78, 0x2E, 0x9E, 0xDB, 0xC7, 0xDF, 0x2E, 0x71, 0x9A, 0x16, 0x97, 0xC4, 0x18, + 0x4B, 0x97, 0x07, 0xFE, 0x5D, 0x98, 0x9A, 0xD6, 0xD8, 0xE5, 0x92, 0x66, 0x87, 0x7F, 0x19, 0x37, + 0xA2, 0x5E, 0xE6, 0x96, 0xB5, 0x97, 0x33, 0x89, 0xE0, 0xA7, 0xC9, 0xDD, 0x4A, 0x7E, 0x9E, 0x53, + 0xBE, 0x91, 0x2B, 0xF5, 0xF5, 0xAF, 0xDD, 0x09, 0xA2, 0xF4, 0xA4, 0x56, 0xEB, 0x96, 0x22, 0xC9, + 0x94, 0xFB, 0x7B, 0x28, 0xC9, 0x97, 0x65, 0x04, 0xAC, 0x4F, 0x84, 0x71, 0xDA, 0x6E, 0xD8, 0xC5 }; // AEON v7 -const static uint8_t test_output_v1_lite[64] = { +const static uint8_t test_output_v1_lite[160] = { 0x87, 0xC4, 0xE5, 0x70, 0x65, 0x3E, 0xB4, 0xC2, 0xB4, 0x2B, 0x7A, 0x0D, 0x54, 0x65, 0x59, 0x45, 0x2D, 0xFA, 0xB5, 0x73, 0xB8, 0x2E, 0xC5, 0x2F, 0x15, 0x2B, 0x7F, 0xF9, 0x8E, 0x79, 0x44, 0x6F, 0x6D, 0x8C, 0xDC, 0x44, 0x4E, 0x9B, 0xBB, 0xFD, 0x68, 0xFC, 0x43, 0xFC, 0xD4, 0x85, 0x5B, 0x22, - 0x8C, 0x8A, 0x1B, 0xD9, 0x1D, 0x9D, 0x00, 0x28, 0x5B, 0xEC, 0x02, 0xB7, 0xCA, 0x2D, 0x67, 0x41 + 0x8C, 0x8A, 0x1B, 0xD9, 0x1D, 0x9D, 0x00, 0x28, 0x5B, 0xEC, 0x02, 0xB7, 0xCA, 0x2D, 0x67, 0x41, + 0x16, 0x08, 0x74, 0xC7, 0xA2, 0xD2, 0xA3, 0x97, 0x95, 0x76, 0xCA, 0x4D, 0x06, 0x39, 0x7A, 0xAB, + 0x6C, 0x87, 0x58, 0x33, 0x4D, 0xC8, 0x5A, 0xAB, 0x04, 0x27, 0xFE, 0x8B, 0x1C, 0x23, 0x2F, 0x32, + 0xC0, 0x44, 0xFF, 0x0D, 0xB5, 0x3B, 0x27, 0x96, 0x06, 0x89, 0x7B, 0xA3, 0x0B, 0xD0, 0xCE, 0x9E, + 0x90, 0x22, 0x77, 0x5A, 0xAD, 0xA1, 0xE5, 0xB6, 0xFC, 0xCB, 0x39, 0x7E, 0x2B, 0x10, 0xEE, 0xB4, + 0x8C, 0x2B, 0xA4, 0x1F, 0x60, 0x76, 0x39, 0xD7, 0xF6, 0x46, 0x77, 0x18, 0x20, 0xAD, 0xD4, 0xC9, + 0x87, 0xF7, 0x37, 0xDA, 0xFD, 0xBA, 0xBA, 0xD2, 0xF2, 0x68, 0xDC, 0x26, 0x8D, 0x1B, 0x08, 0xC6 }; #endif #ifndef XMRIG_NO_SUMO -const static uint8_t test_output_heavy[64] = { +const static uint8_t test_output_heavy[160] = { 0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A, 0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D, 0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64, - 0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2 + 0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2, + 0x3E, 0xE1, 0x23, 0x03, 0x5A, 0x63, 0x7B, 0x66, 0xF6, 0xD7, 0xC2, 0x2A, 0x34, 0x5E, 0x88, 0xE7, + 0xFA, 0xC4, 0x25, 0x36, 0x54, 0xCB, 0xD2, 0x5C, 0x2F, 0x80, 0x2A, 0xF9, 0xCC, 0x43, 0xF7, 0xCD, + 0xE5, 0x18, 0xA8, 0x05, 0x60, 0x18, 0xA5, 0x73, 0x72, 0x9B, 0x32, 0xDC, 0x69, 0x83, 0xC1, 0xE1, + 0x1F, 0xDB, 0xDA, 0x6B, 0xAC, 0xEC, 0x9F, 0x67, 0xF8, 0x27, 0x1D, 0xC7, 0xE6, 0x46, 0x42, 0xF9, + 0x53, 0x62, 0x0A, 0x54, 0x7D, 0x43, 0xEA, 0x18, 0x94, 0xED, 0xD8, 0x92, 0x06, 0x6A, 0xA1, 0x51, + 0xAD, 0xB1, 0xFD, 0x89, 0xFB, 0x5C, 0xB4, 0x25, 0x6A, 0xDD, 0xB0, 0x09, 0xC5, 0x72, 0x87, 0xEB }; #endif diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index 824dd99c..3dafe724 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -427,7 +427,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si uint64_t ah0 = h0[1] ^ h0[5]; __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - uint64_t idx0 = h0[0] ^ h0[4]; + uint64_t idx0 = al0; for (size_t i = 0; i < ITERATIONS; i++) { __m128i cx; @@ -517,8 +517,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); - uint64_t idx0 = h0[0] ^ h0[4]; - uint64_t idx1 = h1[0] ^ h1[4]; + uint64_t idx0 = al0; + uint64_t idx1 = al1; for (size_t i = 0; i < ITERATIONS; i++) { __m128i cx0, cx1; @@ -611,21 +611,377 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si } +#define CN_STEP1(a, b, c, l, ptr, idx) \ + ptr = reinterpret_cast<__m128i*>(&l[idx & MASK]); \ + c = _mm_load_si128(ptr); + + +#define CN_STEP2(a, b, c, l, ptr, idx) \ + if (SOFT_AES) { \ + c = soft_aesenc(c, a); \ + } else { \ + c = _mm_aesenc_si128(c, a); \ + } \ + \ + b = _mm_xor_si128(b, c); \ + \ + if (VARIANT > 0) { \ + cryptonight_monero_tweak(reinterpret_cast(ptr), b); \ + } else { \ + _mm_store_si128(ptr, b); \ + } + + +#define CN_STEP3(a, b, c, l, ptr, idx) \ + idx = EXTRACT64(c); \ + ptr = reinterpret_cast<__m128i*>(&l[idx & MASK]); \ + b = _mm_load_si128(ptr); + + +#define CN_STEP4(a, b, c, l, mc, ptr, idx) \ + lo = __umul128(idx, EXTRACT64(b), &hi); \ + a = _mm_add_epi64(a, _mm_set_epi64x(lo, hi)); \ + \ + if (VARIANT > 0) { \ + _mm_store_si128(ptr, _mm_xor_si128(a, mc)); \ + } else { \ + _mm_store_si128(ptr, a); \ + } \ + \ + a = _mm_xor_si128(a, b); \ + idx = EXTRACT64(a); \ + \ + if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { \ + int64_t n = ((int64_t*)&l[idx & MASK])[0]; \ + int32_t d = ((int32_t*)&l[idx & MASK])[2]; \ + int64_t q = n / (d | 0x5); \ + ((int64_t*)&l[idx & MASK])[0] = n ^ q; \ + idx = d ^ q; \ + } + + +#define CONST_INIT(ctx, n) \ + __m128i mc##n; \ + if (VARIANT > 0) { \ + mc##n = _mm_set_epi64x(*reinterpret_cast(input + n * size + 35) ^ \ + *(reinterpret_cast((ctx)->state) + 24), 0); \ + } + + template inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { + constexpr size_t MASK = xmrig::cn_select_mask(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t MEM = xmrig::cn_select_memory(); + + if (VARIANT > 0 && size < 43) { + memset(output, 0, 32 * 3); + return; + } + + for (size_t i = 0; i < 3; i++) { + keccak(input + size * i, static_cast(size), ctx[i]->state, 200); + cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); + } + + CONST_INIT(ctx[0], 0); + CONST_INIT(ctx[1], 1); + CONST_INIT(ctx[2], 2); + + uint8_t* l0 = ctx[0]->memory; + uint8_t* l1 = ctx[1]->memory; + uint8_t* l2 = ctx[2]->memory; + uint64_t* h0 = reinterpret_cast(ctx[0]->state); + uint64_t* h1 = reinterpret_cast(ctx[1]->state); + uint64_t* h2 = reinterpret_cast(ctx[2]->state); + + __m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]); + __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]); + __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); + __m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]); + __m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]); + __m128i cx0 = _mm_set_epi64x(0, 0); + __m128i cx1 = _mm_set_epi64x(0, 0); + __m128i cx2 = _mm_set_epi64x(0, 0); + + uint64_t idx0, idx1, idx2; + idx0 = EXTRACT64(ax0); + idx1 = EXTRACT64(ax1); + idx2 = EXTRACT64(ax2); + + for (size_t i = 0; i < ITERATIONS / 2; i++) { + uint64_t hi, lo; + __m128i *ptr0, *ptr1, *ptr2; + + // EVEN ROUND + CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2); + + CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2); + + CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2); + + CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0); + CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1); + CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2); + + // ODD ROUND + CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2); + + CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2); + + CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2); + + CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0); + CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1); + CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2); + } + + for (size_t i = 0; i < 3; i++) { + cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); + keccakf(reinterpret_cast(ctx[i]->state), 24); + extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); + } } template inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { + constexpr size_t MASK = xmrig::cn_select_mask(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t MEM = xmrig::cn_select_memory(); + + if (VARIANT > 0 && size < 43) { + memset(output, 0, 32 * 4); + return; + } + + for (size_t i = 0; i < 4; i++) { + keccak(input + size * i, static_cast(size), ctx[i]->state, 200); + cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); + } + + CONST_INIT(ctx[0], 0); + CONST_INIT(ctx[1], 1); + CONST_INIT(ctx[2], 2); + CONST_INIT(ctx[3], 3); + + uint8_t* l0 = ctx[0]->memory; + uint8_t* l1 = ctx[1]->memory; + uint8_t* l2 = ctx[2]->memory; + uint8_t* l3 = ctx[3]->memory; + uint64_t* h0 = reinterpret_cast(ctx[0]->state); + uint64_t* h1 = reinterpret_cast(ctx[1]->state); + uint64_t* h2 = reinterpret_cast(ctx[2]->state); + uint64_t* h3 = reinterpret_cast(ctx[3]->state); + + __m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]); + __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]); + __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); + __m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]); + __m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]); + __m128i ax3 = _mm_set_epi64x(h3[1] ^ h3[5], h3[0] ^ h3[4]); + __m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]); + __m128i cx0 = _mm_set_epi64x(0, 0); + __m128i cx1 = _mm_set_epi64x(0, 0); + __m128i cx2 = _mm_set_epi64x(0, 0); + __m128i cx3 = _mm_set_epi64x(0, 0); + + uint64_t idx0, idx1, idx2, idx3; + idx0 = _mm_cvtsi128_si64(ax0); + idx1 = _mm_cvtsi128_si64(ax1); + idx2 = _mm_cvtsi128_si64(ax2); + idx3 = _mm_cvtsi128_si64(ax3); + + for (size_t i = 0; i < ITERATIONS / 2; i++) + { + uint64_t hi, lo; + __m128i *ptr0, *ptr1, *ptr2, *ptr3; + + // EVEN ROUND + CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP1(ax3, bx3, cx3, l3, ptr3, idx3); + + CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP2(ax3, bx3, cx3, l3, ptr3, idx3); + + CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP3(ax3, bx3, cx3, l3, ptr3, idx3); + + CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0); + CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1); + CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2); + CN_STEP4(ax3, bx3, cx3, l3, mc3, ptr3, idx3); + + // ODD ROUND + CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2); + CN_STEP1(ax3, cx3, bx3, l3, ptr3, idx3); + + CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2); + CN_STEP2(ax3, cx3, bx3, l3, ptr3, idx3); + + CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2); + CN_STEP3(ax3, cx3, bx3, l3, ptr3, idx3); + + CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0); + CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1); + CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2); + CN_STEP4(ax3, cx3, bx3, l3, mc3, ptr3, idx3); + } + + for (size_t i = 0; i < 4; i++) { + cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); + keccakf(reinterpret_cast(ctx[i]->state), 24); + extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); + } } template inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { + constexpr size_t MASK = xmrig::cn_select_mask(); + constexpr size_t ITERATIONS = xmrig::cn_select_iter(); + constexpr size_t MEM = xmrig::cn_select_memory(); + + if (VARIANT > 0 && size < 43) { + memset(output, 0, 32 * 5); + return; + } + + for (size_t i = 0; i < 5; i++) { + keccak(input + size * i, static_cast(size), ctx[i]->state, 200); + cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); + } + + CONST_INIT(ctx[0], 0); + CONST_INIT(ctx[1], 1); + CONST_INIT(ctx[2], 2); + CONST_INIT(ctx[3], 3); + CONST_INIT(ctx[4], 4); + + uint8_t* l0 = ctx[0]->memory; + uint8_t* l1 = ctx[1]->memory; + uint8_t* l2 = ctx[2]->memory; + uint8_t* l3 = ctx[3]->memory; + uint8_t* l4 = ctx[4]->memory; + uint64_t* h0 = reinterpret_cast(ctx[0]->state); + uint64_t* h1 = reinterpret_cast(ctx[1]->state); + uint64_t* h2 = reinterpret_cast(ctx[2]->state); + uint64_t* h3 = reinterpret_cast(ctx[3]->state); + uint64_t* h4 = reinterpret_cast(ctx[4]->state); + + __m128i ax0 = _mm_set_epi64x(h0[1] ^ h0[5], h0[0] ^ h0[4]); + __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i ax1 = _mm_set_epi64x(h1[1] ^ h1[5], h1[0] ^ h1[4]); + __m128i bx1 = _mm_set_epi64x(h1[3] ^ h1[7], h1[2] ^ h1[6]); + __m128i ax2 = _mm_set_epi64x(h2[1] ^ h2[5], h2[0] ^ h2[4]); + __m128i bx2 = _mm_set_epi64x(h2[3] ^ h2[7], h2[2] ^ h2[6]); + __m128i ax3 = _mm_set_epi64x(h3[1] ^ h3[5], h3[0] ^ h3[4]); + __m128i bx3 = _mm_set_epi64x(h3[3] ^ h3[7], h3[2] ^ h3[6]); + __m128i ax4 = _mm_set_epi64x(h4[1] ^ h4[5], h4[0] ^ h4[4]); + __m128i bx4 = _mm_set_epi64x(h4[3] ^ h4[7], h4[2] ^ h4[6]); + __m128i cx0 = _mm_set_epi64x(0, 0); + __m128i cx1 = _mm_set_epi64x(0, 0); + __m128i cx2 = _mm_set_epi64x(0, 0); + __m128i cx3 = _mm_set_epi64x(0, 0); + __m128i cx4 = _mm_set_epi64x(0, 0); + + uint64_t idx0, idx1, idx2, idx3, idx4; + idx0 = _mm_cvtsi128_si64(ax0); + idx1 = _mm_cvtsi128_si64(ax1); + idx2 = _mm_cvtsi128_si64(ax2); + idx3 = _mm_cvtsi128_si64(ax3); + idx4 = _mm_cvtsi128_si64(ax4); + + for (size_t i = 0; i < ITERATIONS / 2; i++) + { + uint64_t hi, lo; + __m128i *ptr0, *ptr1, *ptr2, *ptr3, *ptr4; + + // EVEN ROUND + CN_STEP1(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP1(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP1(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP1(ax3, bx3, cx3, l3, ptr3, idx3); + CN_STEP1(ax4, bx4, cx4, l4, ptr4, idx4); + + CN_STEP2(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP2(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP2(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP2(ax3, bx3, cx3, l3, ptr3, idx3); + CN_STEP2(ax4, bx4, cx4, l4, ptr4, idx4); + + CN_STEP3(ax0, bx0, cx0, l0, ptr0, idx0); + CN_STEP3(ax1, bx1, cx1, l1, ptr1, idx1); + CN_STEP3(ax2, bx2, cx2, l2, ptr2, idx2); + CN_STEP3(ax3, bx3, cx3, l3, ptr3, idx3); + CN_STEP3(ax4, bx4, cx4, l4, ptr4, idx4); + + CN_STEP4(ax0, bx0, cx0, l0, mc0, ptr0, idx0); + CN_STEP4(ax1, bx1, cx1, l1, mc1, ptr1, idx1); + CN_STEP4(ax2, bx2, cx2, l2, mc2, ptr2, idx2); + CN_STEP4(ax3, bx3, cx3, l3, mc3, ptr3, idx3); + CN_STEP4(ax4, bx4, cx4, l4, mc4, ptr4, idx4); + + // ODD ROUND + CN_STEP1(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP1(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP1(ax2, cx2, bx2, l2, ptr2, idx2); + CN_STEP1(ax3, cx3, bx3, l3, ptr3, idx3); + CN_STEP1(ax4, cx4, bx4, l4, ptr4, idx4); + + CN_STEP2(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP2(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP2(ax2, cx2, bx2, l2, ptr2, idx2); + CN_STEP2(ax3, cx3, bx3, l3, ptr3, idx3); + CN_STEP2(ax4, cx4, bx4, l4, ptr4, idx4); + + CN_STEP3(ax0, cx0, bx0, l0, ptr0, idx0); + CN_STEP3(ax1, cx1, bx1, l1, ptr1, idx1); + CN_STEP3(ax2, cx2, bx2, l2, ptr2, idx2); + CN_STEP3(ax3, cx3, bx3, l3, ptr3, idx3); + CN_STEP3(ax4, cx4, bx4, l4, ptr4, idx4); + + CN_STEP4(ax0, cx0, bx0, l0, mc0, ptr0, idx0); + CN_STEP4(ax1, cx1, bx1, l1, mc1, ptr1, idx1); + CN_STEP4(ax2, cx2, bx2, l2, mc2, ptr2, idx2); + CN_STEP4(ax3, cx3, bx3, l3, mc3, ptr3, idx3); + CN_STEP4(ax4, cx4, bx4, l4, mc4, ptr4, idx4); + } + + for (size_t i = 0; i < 5; i++) { + cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); + keccakf(reinterpret_cast(ctx[i]->state), 24); + extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); + } } #endif /* __CRYPTONIGHT_X86_H__ */ diff --git a/src/crypto/soft_aes.h b/src/crypto/soft_aes.h index 0703f98d..26c1b06a 100644 --- a/src/crypto/soft_aes.h +++ b/src/crypto/soft_aes.h @@ -105,6 +105,23 @@ static inline __m128i soft_aesenc(const uint32_t* in, __m128i key) return _mm_xor_si128(out, key); } +static inline __m128i soft_aesenc(__m128i in, __m128i key) +{ + uint32_t x0, x1, x2, x3; + x0 = _mm_cvtsi128_si32(in); + x1 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0x55)); + x2 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0xAA)); + x3 = _mm_cvtsi128_si32(_mm_shuffle_epi32(in, 0xFF)); + + __m128i out = _mm_set_epi32( + (saes_table[0][x3 & 0xff] ^ saes_table[1][(x0 >> 8) & 0xff] ^ saes_table[2][(x1 >> 16) & 0xff] ^ saes_table[3][x2 >> 24]), + (saes_table[0][x2 & 0xff] ^ saes_table[1][(x3 >> 8) & 0xff] ^ saes_table[2][(x0 >> 16) & 0xff] ^ saes_table[3][x1 >> 24]), + (saes_table[0][x1 & 0xff] ^ saes_table[1][(x2 >> 8) & 0xff] ^ saes_table[2][(x3 >> 16) & 0xff] ^ saes_table[3][x0 >> 24]), + (saes_table[0][x0 & 0xff] ^ saes_table[1][(x1 >> 8) & 0xff] ^ saes_table[2][(x2 >> 16) & 0xff] ^ saes_table[3][x3 >> 24])); + + return _mm_xor_si128(out, key); +} + static inline uint32_t sub_word(uint32_t key) { return (saes_sbox[key >> 24 ] << 24) | diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index a75adecc..09dd568f 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -104,7 +104,7 @@ void MultiWorker::start() for (size_t i = 0; i < N; ++i) { if (*reinterpret_cast(m_hash + (i * 32) + 24) < m_state.job.target()) { - Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash, m_state.job.diff())); + Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash + (i * 32), m_state.job.diff())); } *nonce(i) += 1; From b32ec5342eefa6cec814708f81f37819787b0972 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 17 Apr 2018 09:42:53 +0700 Subject: [PATCH 064/109] Fixed automatic threads mode for --av above 4 --- CMakeLists.txt | 2 +- src/Cpu.cpp | 39 +++++++++----------- src/Cpu.h | 7 ++-- src/core/Config.cpp | 7 ++-- src/workers/CpuThread.cpp | 75 ++++++++++++++++++++------------------- src/workers/CpuThread.h | 2 ++ 6 files changed, 63 insertions(+), 69 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c7017b01..ae2a4ed7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,7 +167,7 @@ endif() add_definitions(/D__STDC_FORMAT_MACROS) add_definitions(/DUNICODE) -#add_definitions(/DAPP_DEBUG) +add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") diff --git a/src/Cpu.cpp b/src/Cpu.cpp index f8fb092c..eebe585d 100644 --- a/src/Cpu.cpp +++ b/src/Cpu.cpp @@ -26,26 +26,27 @@ #include #include + #include "Cpu.h" -bool Cpu::m_l2_exclusive = false; -char Cpu::m_brand[64] = { 0 }; -int Cpu::m_flags = 0; -int Cpu::m_l2_cache = 0; -int Cpu::m_l3_cache = 0; -int Cpu::m_sockets = 1; -int Cpu::m_totalCores = 0; -int Cpu::m_totalThreads = 0; +bool Cpu::m_l2_exclusive = false; +char Cpu::m_brand[64] = { 0 }; +int Cpu::m_flags = 0; +int Cpu::m_l2_cache = 0; +int Cpu::m_l3_cache = 0; +int Cpu::m_sockets = 1; +int Cpu::m_totalCores = 0; +size_t Cpu::m_totalThreads = 0; -int Cpu::optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage) +size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage) { if (m_totalThreads == 1) { return 1; } - int cache = 0; + size_t cache = 0; if (m_l3_cache) { cache = m_l2_exclusive ? (m_l2_cache + m_l3_cache) : m_l3_cache; } @@ -53,22 +54,14 @@ int Cpu::optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage) cache = m_l2_cache; } - int count = 0; - int size = 2048; - - if (algo == xmrig::CRYPTONIGHT_LITE) { - size = 1024; - } - else if (algo == xmrig::CRYPTONIGHT_HEAVY) { - size = 4096; - } - - if (doubleHash) { - size *= 2; - } + size_t count = 0; if (cache) { count = cache / size; + + if (cache % size >= size / 2) { + count++; + } } else { count = m_totalThreads / 2; diff --git a/src/Cpu.h b/src/Cpu.h index 97e593ed..a125bae8 100644 --- a/src/Cpu.h +++ b/src/Cpu.h @@ -28,9 +28,6 @@ #include -#include "common/xmrig.h" - - class Cpu { public: @@ -40,7 +37,7 @@ public: BMI2 = 4 }; - static int optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage); + static size_t optimalThreadsCount(size_t size, int maxCpuUsage); static void init(); static inline bool hasAES() { return (m_flags & AES) != 0; } @@ -62,7 +59,7 @@ private: static int m_l3_cache; static int m_sockets; static int m_totalCores; - static int m_totalThreads; + static size_t m_totalThreads; }; diff --git a/src/core/Config.cpp b/src/core/Config.cpp index b3564f92..4d48af29 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -30,6 +30,7 @@ #include "core/Config.h" #include "core/ConfigCreator.h" #include "Cpu.h" +#include "crypto/CryptoNight_constants.h" #include "net/Pool.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" @@ -177,13 +178,13 @@ bool xmrig::Config::adjust() m_algoVariant = getAlgoVariant(); m_threads.mode = m_threads.count ? Simple : Automatic; - const bool doubleHash = m_algoVariant == AV_DOUBLE || m_algoVariant == AV_DOUBLE_SOFT; + const size_t size = CpuThread::multiway(m_algoVariant) * cn_select_memory(m_algorithm) / 1024; if (!m_threads.count) { - m_threads.count = Cpu::optimalThreadsCount(m_algorithm, doubleHash, m_maxCpuUsage); + m_threads.count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); } else if (m_safe) { - const size_t count = Cpu::optimalThreadsCount(m_algorithm, doubleHash, m_maxCpuUsage); + const size_t count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); if (m_threads.count > count) { m_threads.count = count; } diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index ac733ef6..3632e193 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -54,6 +54,12 @@ xmrig::CpuThread::~CpuThread() } +bool xmrig::CpuThread::isSoftAES(AlgoVariant av) +{ + return av == AV_SINGLE_SOFT || av == AV_DOUBLE_SOFT || av > AV_PENTA; +} + + xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant) { assert(variant == VARIANT_NONE || variant == VARIANT_V1); @@ -138,42 +144,6 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A { assert(av > AV_AUTO && av < AV_MAX); - Multiway multiway = SingleWay; - bool softAES = false; - - switch (av) { - case AV_SINGLE_SOFT: - softAES = true; - break; - - case AV_DOUBLE_SOFT: - softAES = true; - case AV_DOUBLE: - multiway = DoubleWay; - break; - - case AV_TRIPLE_SOFT: - softAES = true; - case AV_TRIPLE: - multiway = TripleWay; - break; - - case AV_QUAD_SOFT: - softAES = true; - case AV_QUAD: - multiway = QuadWay; - break; - - case AV_PENTA_SOFT: - softAES = true; - case AV_PENTA: - multiway = PentaWay; - break; - - default: - break; - } - int64_t cpuId = -1L; if (affinity != -1L) { @@ -193,7 +163,7 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A } } - return new CpuThread(index, algorithm, av, multiway, cpuId, priority, softAES, false); + return new CpuThread(index, algorithm, av, multiway(av), cpuId, priority, isSoftAES(av), false); } @@ -242,6 +212,37 @@ xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object) } +xmrig::IThread::Multiway xmrig::CpuThread::multiway(AlgoVariant av) +{ + switch (av) { + case AV_SINGLE: + case AV_SINGLE_SOFT: + return SingleWay; + + case AV_DOUBLE_SOFT: + case AV_DOUBLE: + return DoubleWay; + + case AV_TRIPLE_SOFT: + case AV_TRIPLE: + return TripleWay; + + case AV_QUAD_SOFT: + case AV_QUAD: + return QuadWay; + + case AV_PENTA_SOFT: + case AV_PENTA: + return PentaWay; + + default: + break; + } + + return SingleWay; +} + + #ifndef XMRIG_NO_API rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const { diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index ba36cc87..0e364764 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -61,10 +61,12 @@ public: typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx); + static bool isSoftAES(AlgoVariant av); static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant); static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority); static CpuThread *createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES); static Data parse(const rapidjson::Value &object); + static Multiway multiway(AlgoVariant av); inline bool isPrefetch() const { return m_prefetch; } inline bool isSoftAES() const { return m_softAES; } From c221bf09f626eda15bbfd212dfd96d3a09b68867 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 17 Apr 2018 10:29:37 +0700 Subject: [PATCH 065/109] Use direct access to hashrate in API. --- src/api/Api.cpp | 10 ---------- src/api/Api.h | 1 - src/api/ApiRouter.cpp | 41 ++++++++++++---------------------------- src/api/ApiRouter.h | 5 ----- src/workers/Hashrate.cpp | 18 +++++++++--------- src/workers/Hashrate.h | 6 +++--- src/workers/Workers.cpp | 4 ---- src/workers/Workers.h | 2 ++ 8 files changed, 26 insertions(+), 61 deletions(-) diff --git a/src/api/Api.cpp b/src/api/Api.cpp index 6f9991ee..3fff45b5 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -62,16 +62,6 @@ void Api::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) } -void Api::tick(const Hashrate *hashrate) -{ - if (!m_router) { - return; - } - - m_router->tick(hashrate); -} - - void Api::tick(const NetworkState &network) { if (!m_router) { diff --git a/src/api/Api.h b/src/api/Api.h index 43c7b17e..316bb0fa 100644 --- a/src/api/Api.h +++ b/src/api/Api.h @@ -47,7 +47,6 @@ public: static void release(); static void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply); - static void tick(const Hashrate *hashrate); static void tick(const NetworkState &results); private: diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 8206aa3e..08cd9bf6 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -47,6 +47,7 @@ #include "rapidjson/stringbuffer.h" #include "version.h" #include "workers/Hashrate.h" +#include "workers/Workers.h" extern "C" @@ -68,10 +69,6 @@ static inline double normalize(double d) ApiRouter::ApiRouter(xmrig::Controller *controller) : m_controller(controller) { - m_threads = controller->config()->threadsCount(); - m_hashrate = new double[m_threads * 3](); - - memset(m_totalHashrate, 0, sizeof(m_totalHashrate)); memset(m_workerId, 0, sizeof(m_workerId)); setWorkerId(controller->config()->apiWorkerId()); @@ -81,7 +78,6 @@ ApiRouter::ApiRouter(xmrig::Controller *controller) : ApiRouter::~ApiRouter() { - delete [] m_hashrate; } @@ -129,21 +125,6 @@ void ApiRouter::exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) } -void ApiRouter::tick(const Hashrate *hashrate) -{ - for (int i = 0; i < m_threads; ++i) { - m_hashrate[i * 3] = hashrate->calc((size_t) i, Hashrate::ShortInterval); - m_hashrate[i * 3 + 1] = hashrate->calc((size_t) i, Hashrate::MediumInterval); - m_hashrate[i * 3 + 2] = hashrate->calc((size_t) i, Hashrate::LargeInterval); - } - - m_totalHashrate[0] = hashrate->calc(Hashrate::ShortInterval); - m_totalHashrate[1] = hashrate->calc(Hashrate::MediumInterval); - m_totalHashrate[2] = hashrate->calc(Hashrate::LargeInterval); - m_highestHashrate = hashrate->highest(); -} - - void ApiRouter::tick(const NetworkState &network) { m_network = network; @@ -225,21 +206,23 @@ void ApiRouter::getHashrate(rapidjson::Document &doc) const rapidjson::Value total(rapidjson::kArrayType); rapidjson::Value threads(rapidjson::kArrayType); - for (int i = 0; i < 3; ++i) { - total.PushBack(normalize(m_totalHashrate[i]), allocator); - } + const Hashrate *hr = Workers::hashrate(); - for (int i = 0; i < m_threads * 3; i += 3) { + total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator); + total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator); + total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator); + + for (size_t i = 0; i < Workers::threads(); i++) { rapidjson::Value thread(rapidjson::kArrayType); - thread.PushBack(normalize(m_hashrate[i]), allocator); - thread.PushBack(normalize(m_hashrate[i + 1]), allocator); - thread.PushBack(normalize(m_hashrate[i + 2]), allocator); + thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); + thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); + thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); threads.PushBack(thread, allocator); } - hashrate.AddMember("total", total, allocator); - hashrate.AddMember("highest", normalize(m_highestHashrate), allocator); + hashrate.AddMember("total", total, allocator); + hashrate.AddMember("highest", normalize(hr->highest()), allocator); hashrate.AddMember("threads", threads, allocator); doc.AddMember("hashrate", hashrate, allocator); } diff --git a/src/api/ApiRouter.h b/src/api/ApiRouter.h index e14f9e87..3ed458d4 100644 --- a/src/api/ApiRouter.h +++ b/src/api/ApiRouter.h @@ -49,7 +49,6 @@ public: void get(const xmrig::HttpRequest &req, xmrig::HttpReply &reply) const; void exec(const xmrig::HttpRequest &req, xmrig::HttpReply &reply); - void tick(const Hashrate *hashrate); void tick(const NetworkState &results); protected: @@ -69,10 +68,6 @@ private: char m_id[17]; char m_workerId[128]; - double *m_hashrate; - double m_highestHashrate; - double m_totalHashrate[3]; - int m_threads; NetworkState m_network; xmrig::Controller *m_controller; }; diff --git a/src/workers/Hashrate.cpp b/src/workers/Hashrate.cpp index ef06eb52..7d2e6a4c 100644 --- a/src/workers/Hashrate.cpp +++ b/src/workers/Hashrate.cpp @@ -22,6 +22,7 @@ */ +#include #include #include #include @@ -45,7 +46,7 @@ inline const char *format(double h, char* buf, size_t size) } -Hashrate::Hashrate(int threads, xmrig::Controller *controller) : +Hashrate::Hashrate(size_t threads, xmrig::Controller *controller) : m_highest(0.0), m_threads(threads), m_controller(controller) @@ -54,13 +55,10 @@ Hashrate::Hashrate(int threads, xmrig::Controller *controller) : m_timestamps = new uint64_t*[threads]; m_top = new uint32_t[threads]; - for (int i = 0; i < threads; i++) { - m_counts[i] = new uint64_t[kBucketSize]; - m_timestamps[i] = new uint64_t[kBucketSize]; - m_top[i] = 0; - - memset(m_counts[0], 0, sizeof(uint64_t) * kBucketSize); - memset(m_timestamps[0], 0, sizeof(uint64_t) * kBucketSize); + for (size_t i = 0; i < threads; i++) { + m_counts[i] = new uint64_t[kBucketSize](); + m_timestamps[i] = new uint64_t[kBucketSize](); + m_top[i] = 0; } const int printTime = controller->config()->printTime(); @@ -79,7 +77,7 @@ double Hashrate::calc(size_t ms) const double result = 0.0; double data; - for (int i = 0; i < m_threads; ++i) { + for (size_t i = 0; i < m_threads; ++i) { data = calc(i, ms); if (isnormal(data)) { result += data; @@ -92,6 +90,8 @@ double Hashrate::calc(size_t ms) const double Hashrate::calc(size_t threadId, size_t ms) const { + assert(threadId < m_threads); + using namespace std::chrono; const uint64_t now = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); diff --git a/src/workers/Hashrate.h b/src/workers/Hashrate.h index 5f4f0eaa..e79c757a 100644 --- a/src/workers/Hashrate.h +++ b/src/workers/Hashrate.h @@ -43,7 +43,7 @@ public: LargeInterval = 900000 }; - Hashrate(int threads, xmrig::Controller *controller); + Hashrate(size_t threads, xmrig::Controller *controller); double calc(size_t ms) const; double calc(size_t threadId, size_t ms) const; void add(size_t threadId, uint64_t count, uint64_t timestamp); @@ -52,7 +52,7 @@ public: void updateHighest(); inline double highest() const { return m_highest; } - inline int threads() const { return m_threads; } + inline size_t threads() const { return m_threads; } private: static void onReport(uv_timer_t *handle); @@ -61,7 +61,7 @@ private: constexpr static size_t kBucketMask = kBucketSize - 1; double m_highest; - int m_threads; + size_t m_threads; uint32_t* m_top; uint64_t** m_counts; uint64_t** m_timestamps; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index e26b2030..068c4258 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -243,10 +243,6 @@ void Workers::onTick(uv_timer_t *handle) if ((m_ticks++ & 0xF) == 0) { m_hashrate->updateHighest(); } - -# ifndef XMRIG_NO_API - Api::tick(m_hashrate); -# endif } diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 81b3411a..0dce78b6 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -59,6 +59,8 @@ public: static inline bool isEnabled() { return m_enabled; } static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; } + static inline Hashrate *hashrate() { return m_hashrate; } + static inline size_t threads() { return m_status.threads; } static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); } static inline void pause() { m_active = false; m_paused = 1; m_sequence++; } static inline void setListener(IJobResultListener *listener) { m_listener = listener; } From c0a72edf9a7a6002947dbee3956f1a2c9935204d Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 17 Apr 2018 10:51:29 +0700 Subject: [PATCH 066/109] Added hashrate information to "GET /1/threads" endpoint. --- src/api/ApiRouter.cpp | 13 +++++++++++-- src/workers/Workers.cpp | 20 ++++++++++++++++++++ src/workers/Workers.h | 3 ++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 08cd9bf6..b8caac9c 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -250,7 +250,7 @@ void ApiRouter::getMiner(rapidjson::Document &doc) const doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator); doc.AddMember("cpu", cpu, allocator); doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algoName()), allocator); - doc.AddMember("hugepages", false, allocator); + doc.AddMember("hugepages", Workers::hugePages() > 0, allocator); doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator); } @@ -283,12 +283,21 @@ void ApiRouter::getThreads(rapidjson::Document &doc) const { doc.SetObject(); auto &allocator = doc.GetAllocator(); + const Hashrate *hr = Workers::hashrate(); const std::vector &threads = m_controller->config()->threads(); rapidjson::Value list(rapidjson::kArrayType); for (const xmrig::IThread *thread : threads) { - list.PushBack(thread->toAPI(doc), allocator); + rapidjson::Value value = thread->toAPI(doc); + + rapidjson::Value hashrate(rapidjson::kArrayType); + hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::ShortInterval)), allocator); + hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::MediumInterval)), allocator); + hashrate.PushBack(normalize(hr->calc(thread->index(), Hashrate::LargeInterval)), allocator); + + value.AddMember("hashrate", hashrate, allocator); + list.PushBack(value, allocator); } doc.AddMember("threads", list, allocator); diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 068c4258..82ad54eb 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -66,6 +66,26 @@ Job Workers::job() } +size_t Workers::hugePages() +{ + uv_mutex_lock(&m_mutex); + const size_t hugePages = m_status.hugePages; + uv_mutex_unlock(&m_mutex); + + return hugePages; +} + + +size_t Workers::threads() +{ + uv_mutex_lock(&m_mutex); + const size_t threads = m_status.threads; + uv_mutex_unlock(&m_mutex); + + return threads; +} + + void Workers::printHashrate(bool detail) { m_hashrate->print(); diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 0dce78b6..f96aa2ca 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -49,6 +49,8 @@ class Workers { public: static Job job(); + static size_t hugePages(); + static size_t threads(); static void printHashrate(bool detail); static void setEnabled(bool enabled); static void setJob(const Job &job, bool donate); @@ -60,7 +62,6 @@ public: static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; } static inline Hashrate *hashrate() { return m_hashrate; } - static inline size_t threads() { return m_status.threads; } static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); } static inline void pause() { m_active = false; m_paused = 1; m_sequence++; } static inline void setListener(IJobResultListener *listener) { m_listener = listener; } From d04a1fcb8f163239ef955ec0bb4263e3d1f938fe Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 17 Apr 2018 14:36:32 +0700 Subject: [PATCH 067/109] Add extra information to threads API. --- src/Cpu_mac.cpp | 9 ++------- src/api/ApiRouter.cpp | 2 ++ src/workers/Workers.cpp | 21 +++++++++++++++++++++ src/workers/Workers.h | 5 +++++ 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/Cpu_mac.cpp b/src/Cpu_mac.cpp index 357e15ef..085148bc 100644 --- a/src/Cpu_mac.cpp +++ b/src/Cpu_mac.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2016 Jay D Dee + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,8 +38,3 @@ void Cpu::init() initCommon(); } - - -void Cpu::setAffinity(int id, uint64_t mask) -{ -} diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index b8caac9c..42256cc9 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -285,6 +285,8 @@ void ApiRouter::getThreads(rapidjson::Document &doc) const auto &allocator = doc.GetAllocator(); const Hashrate *hr = Workers::hashrate(); + Workers::threadsSummary(doc); + const std::vector &threads = m_controller->config()->threads(); rapidjson::Value list(rapidjson::kArrayType); diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 82ad54eb..e1609c0e 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -33,6 +33,7 @@ #include "interfaces/IThread.h" #include "log/Log.h" #include "Mem.h" +#include "rapidjson/document.h" #include "workers/Handle.h" #include "workers/Hashrate.h" #include "workers/MultiWorker.h" @@ -188,6 +189,26 @@ void Workers::submit(const JobResult &result) } +#ifndef XMRIG_NO_API +void Workers::threadsSummary(rapidjson::Document &doc) +{ + uv_mutex_lock(&m_mutex); + const size_t pages[2] = { m_status.hugePages, m_status.pages }; + const size_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo); + uv_mutex_unlock(&m_mutex); + + auto &allocator = doc.GetAllocator(); + + rapidjson::Value hugepages(rapidjson::kArrayType); + hugepages.PushBack(pages[0], allocator); + hugepages.PushBack(pages[1], allocator); + + doc.AddMember("hugepages", hugepages, allocator); + doc.AddMember("memory", memory, allocator); +} +#endif + + void Workers::onReady(void *arg) { auto handle = static_cast(arg); diff --git a/src/workers/Workers.h b/src/workers/Workers.h index f96aa2ca..bbe9a760 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -32,6 +32,7 @@ #include "net/Job.h" #include "net/JobResult.h" +#include "rapidjson/fwd.h" class Handle; @@ -66,6 +67,10 @@ public: static inline void pause() { m_active = false; m_paused = 1; m_sequence++; } static inline void setListener(IJobResultListener *listener) { m_listener = listener; } +# ifndef XMRIG_NO_API + static void threadsSummary(rapidjson::Document &doc); +# endif + private: static void onReady(void *arg); static void onResult(uv_async_t *handle); From bc67216f7f14aac3f7ebfa102ded0f1278f3867e Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 18 Apr 2018 09:58:06 +0700 Subject: [PATCH 068/109] Added API docs and bug fixes. --- CMakeLists.txt | 2 +- doc/API.md | 53 ++++++++++++++++++++++ doc/api/1/config.json | 63 ++++++++++++++++++++++++++ doc/api/1/summary.json | 73 ++++++++++++++++++++++++++++++ doc/api/1/threads.json | 65 ++++++++++++++++++++++++++ src/common/config/CommonConfig.cpp | 2 +- src/core/ConfigLoader_platform.h | 4 +- src/workers/Workers.cpp | 4 +- 8 files changed, 261 insertions(+), 5 deletions(-) create mode 100644 doc/API.md create mode 100644 doc/api/1/config.json create mode 100644 doc/api/1/summary.json create mode 100644 doc/api/1/threads.json diff --git a/CMakeLists.txt b/CMakeLists.txt index ae2a4ed7..c7017b01 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,7 +167,7 @@ endif() add_definitions(/D__STDC_FORMAT_MACROS) add_definitions(/DUNICODE) -add_definitions(/DAPP_DEBUG) +#add_definitions(/DAPP_DEBUG) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") diff --git a/doc/API.md b/doc/API.md new file mode 100644 index 00000000..3357eabb --- /dev/null +++ b/doc/API.md @@ -0,0 +1,53 @@ +# HTTP API + +If you want use API you need choice a port where is internal HTTP server will listen for incoming connections. API will not available if miner built without `libmicrohttpd`. + +Example configuration: + +```json +"api": { + "port": 44444, + "access-token": "TOKEN", + "worker-id": null, + "ipv6": false, + "restricted": false +}, +``` + +* **port** Port for incoming connections `http://:`. +* **access-token** [Bearer](https://gist.github.com/xmrig/c75fdd1f8e0f3bac05500be2ab718f8e#file-api-html-L54) access token to secure access to API. +* **worker-id** Optional worker name, if not set will be detected automatically. +* **ipv6** Enable (`true`) or disable (`false`) IPv6 for API. +* **restricted** Use `false` to allow remote configuration. + +If you prefer use command line options instead of config file, you can use options: `--api-port`, `--api-access-token`, `--api-worker-id`, `--api-ipv6` and `api-no-restricted`. + +## Endpoints + +### GET /1/summary + +Get miner summary information. [Example](api/1/summary.json). + +### GET /1/threads + +Get detailed information about miner threads. [Example](api/1/threads.json). + + +## Restricted endpoints + +All API endpoints below allow access to sensitive information and remote configure miner. You should set `access-token` and allow unrestricted access (`"restricted": false`). + +### GET /1/config + +Get current miner configuration. [Example](api/1/config.json). + + +### PUT /1/config + +Update current miner configuration. Common use case, get current configuration, make changes, and upload it to miner. + +Curl example: + +``` +curl -v --data-binary @config.json -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer SECRET" http://127.0.0.1:44444/1/config +``` \ No newline at end of file diff --git a/doc/api/1/config.json b/doc/api/1/config.json new file mode 100644 index 00000000..2c74cfba --- /dev/null +++ b/doc/api/1/config.json @@ -0,0 +1,63 @@ +{ + "algo": "cryptonight", + "api": { + "port": 44444, + "access-token": "TOKEN", + "worker-id": null, + "ipv6": false, + "restricted": false + }, + "av": 1, + "background": false, + "colors": true, + "cpu-affinity": null, + "cpu-priority": null, + "donate-level": 5, + "huge-pages": true, + "hw-aes": null, + "log-file": null, + "max-cpu-usage": 75, + "pools": [ + { + "url": "pool.monero.hashvault.pro:3333", + "user": "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD", + "pass": "x", + "keepalive": false, + "nicehash": false, + "variant": -1 + }, + { + "url": "pool.supportxmr.com:3333", + "user": "48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD", + "pass": "x", + "keepalive": false, + "nicehash": false, + "variant": -1 + } + ], + "print-time": 60, + "retries": 5, + "retry-pause": 5, + "safe": false, + "threads": [ + { + "low_power_mode": 1, + "affine_to_cpu": 0 + }, + { + "low_power_mode": 1, + "affine_to_cpu": 1 + }, + { + "low_power_mode": 1, + "affine_to_cpu": 2 + }, + { + "low_power_mode": 1, + "affine_to_cpu": 3 + } + ], + "user-agent": null, + "syslog": false, + "watch": false +} \ No newline at end of file diff --git a/doc/api/1/summary.json b/doc/api/1/summary.json new file mode 100644 index 00000000..ed3cd128 --- /dev/null +++ b/doc/api/1/summary.json @@ -0,0 +1,73 @@ +{ + "id": "92f3104f9a2ee78c", + "worker_id": "Ubuntu-1604-xenial-64-minimal", + "version": "2.6.0-beta3", + "kind": "cpu", + "ua": "XMRig/2.6.0-beta3 (Linux x86_64) libuv/1.8.0 gcc/5.4.0", + "cpu": { + "brand": "Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz", + "aes": true, + "x64": true, + "sockets": 1 + }, + "algo": "cryptonight", + "hugepages": true, + "donate_level": 5, + "hashrate": { + "total": [ + 296.24, + 296.23, + 295.97 + ], + "highest": 296.5, + "threads": [ + [ + 73.39, + 73.39, + 73.28 + ], + [ + 74.72, + 74.72, + 74.71 + ], + [ + 74.72, + 74.72, + 74.71 + ], + [ + 73.39, + 73.39, + 73.27 + ] + ] + }, + "results": { + "diff_current": 9990, + "shares_good": 30, + "shares_total": 30, + "avg_time": 31, + "hashes_total": 311833, + "best": [ + 278199, + 181923, + 103717, + 96632, + 56154, + 51580, + 45667, + 33159, + 29581, + 29514 + ], + "error_log": [] + }, + "connection": { + "pool": "pool.monero.hashvault.pro:3333", + "uptime": 953, + "ping": 35, + "failures": 0, + "error_log": [] + } +} \ No newline at end of file diff --git a/doc/api/1/threads.json b/doc/api/1/threads.json new file mode 100644 index 00000000..e536883d --- /dev/null +++ b/doc/api/1/threads.json @@ -0,0 +1,65 @@ +{ + "hugepages": [ + 4, + 4 + ], + "memory": 8388608, + "threads": [ + { + "type": "cpu", + "algo": "cryptonight", + "av": 1, + "low_power_mode": 1, + "affine_to_cpu": 0, + "priority": -1, + "soft_aes": false, + "hashrate": [ + 73.39, + 73.4, + 73.28 + ] + }, + { + "type": "cpu", + "algo": "cryptonight", + "av": 1, + "low_power_mode": 1, + "affine_to_cpu": 1, + "priority": -1, + "soft_aes": false, + "hashrate": [ + 74.72, + 74.72, + 74.7 + ] + }, + { + "type": "cpu", + "algo": "cryptonight", + "av": 1, + "low_power_mode": 1, + "affine_to_cpu": 2, + "priority": -1, + "soft_aes": false, + "hashrate": [ + 74.71, + 74.72, + 74.7 + ] + }, + { + "type": "cpu", + "algo": "cryptonight", + "av": 1, + "low_power_mode": 1, + "affine_to_cpu": 3, + "priority": -1, + "soft_aes": false, + "hashrate": [ + 73.39, + 73.4, + 73.28 + ] + } + ] +} \ No newline at end of file diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp index 2cce845c..22fd348d 100644 --- a/src/common/config/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -205,12 +205,12 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) case SyslogKey: /* --syslog */ case KeepAliveKey: /* --keepalive */ case NicehashKey: /* --nicehash */ + case ApiIPv6Key: /* --api-ipv6 */ return parseBoolean(key, true); case ColorKey: /* --no-color */ case WatchKey: /* --no-watch */ case ApiRestrictedKey: /* --api-no-restricted */ - case ApiIPv6Key: /* --api-no-ipv6 */ return parseBoolean(key, false); case DonateLevelKey: /* --donate-level */ diff --git a/src/core/ConfigLoader_platform.h b/src/core/ConfigLoader_platform.h index 7e1a4baa..d02a9e8f 100644 --- a/src/core/ConfigLoader_platform.h +++ b/src/core/ConfigLoader_platform.h @@ -85,6 +85,8 @@ Options:\n\ --api-port=N port for the miner API\n\ --api-access-token=T access token for API\n\ --api-worker-id=ID custom worker-id for API\n\ + --api-ipv6 enable IPv6 support for API\n\ + --api-no-restricted enable full remote access (only if API token set)\n\ -h, --help display this help and exit\n\ -V, --version output version information and exit\n\ "; @@ -98,7 +100,7 @@ static struct option const options[] = { { "api-access-token", 1, nullptr, xmrig::IConfig::ApiAccessTokenKey }, { "api-port", 1, nullptr, xmrig::IConfig::ApiPort }, { "api-worker-id", 1, nullptr, xmrig::IConfig::ApiWorkerIdKey }, - { "api-no-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key }, + { "api-ipv6", 0, nullptr, xmrig::IConfig::ApiIPv6Key }, { "api-no-restricted", 0, nullptr, xmrig::IConfig::ApiRestrictedKey }, { "av", 1, nullptr, xmrig::IConfig::AVKey }, { "background", 0, nullptr, xmrig::IConfig::BackgroundKey }, diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index e1609c0e..25e1d068 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -193,8 +193,8 @@ void Workers::submit(const JobResult &result) void Workers::threadsSummary(rapidjson::Document &doc) { uv_mutex_lock(&m_mutex); - const size_t pages[2] = { m_status.hugePages, m_status.pages }; - const size_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo); + const uint64_t pages[2] = { m_status.hugePages, m_status.pages }; + const uint64_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo); uv_mutex_unlock(&m_mutex); auto &allocator = doc.GetAllocator(); From ad94e9a7d273df6818e1817b4f04a149b6019e5f Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 19 Apr 2018 11:54:11 +0700 Subject: [PATCH 069/109] Simplify ARM implementation. --- src/Cpu_arm.cpp | 20 ++-- src/Summary.cpp | 33 ++++--- src/crypto/CryptoNight.h | 9 -- src/crypto/CryptoNight_arm.h | 172 +++++++++++------------------------ 4 files changed, 86 insertions(+), 148 deletions(-) diff --git a/src/Cpu_arm.cpp b/src/Cpu_arm.cpp index 1b306789..59ff8421 100644 --- a/src/Cpu_arm.cpp +++ b/src/Cpu_arm.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,16 +28,16 @@ #include "Cpu.h" -char Cpu::m_brand[64] = { 0 }; -int Cpu::m_flags = 0; -int Cpu::m_l2_cache = 0; -int Cpu::m_l3_cache = 0; -int Cpu::m_sockets = 1; -int Cpu::m_totalCores = 0; -int Cpu::m_totalThreads = 0; +char Cpu::m_brand[64] = { 0 }; +int Cpu::m_flags = 0; +int Cpu::m_l2_cache = 0; +int Cpu::m_l3_cache = 0; +int Cpu::m_sockets = 1; +int Cpu::m_totalCores = 0; +size_t Cpu::m_totalThreads = 0; -int Cpu::optimalThreadsCount(xmrig::Algo algo, bool doubleHash, int maxCpuUsage) +size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage) { return m_totalThreads; } diff --git a/src/Summary.cpp b/src/Summary.cpp index a54214e4..32a0e4bb 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -93,21 +93,30 @@ static void print_cpu(xmrig::Config *config) static void print_threads(xmrig::Config *config) { - char buf[32]; - if (config->affinity() != -1L) { - snprintf(buf, 32, ", affinity=0x%" PRIX64, config->affinity()); + if (config->threadsMode() != xmrig::Config::Advanced) { + char buf[32]; + if (config->affinity() != -1L) { + snprintf(buf, 32, ", affinity=0x%" PRIX64, config->affinity()); + } + else { + buf[0] = '\0'; + } + + Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s", + config->threadsCount(), + config->algoName(), + config->algoVariant(), + config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", + config->donateLevel(), + buf); } else { - buf[0] = '\0'; + Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, %sdonate=%d%%" : " * THREADS: %d, %s, %sdonate=%d%%", + config->threadsCount(), + config->algoName(), + config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", + config->donateLevel()); } - - Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s", - config->threadsCount(), - config->algoName(), - config->algoVariant(), - config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", - config->donateLevel(), - buf); } diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index 5a4a266d..e8e86dc4 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -30,15 +30,6 @@ #include -#define AEON_MEMORY 1048576 -#define AEON_MASK 0xFFFF0 -#define AEON_ITER 0x40000 - -#define MONERO_MEMORY 2097152 -#define MONERO_MASK 0x1FFFF0 -#define MONERO_ITER 0x80000 - - struct cryptonight_ctx { alignas(16) uint8_t state[200]; alignas(16) uint8_t* memory; diff --git a/src/crypto/CryptoNight_arm.h b/src/crypto/CryptoNight_arm.h index 101a1f58..fd8c1920 100644 --- a/src/crypto/CryptoNight_arm.h +++ b/src/crypto/CryptoNight_arm.h @@ -73,6 +73,13 @@ static inline __attribute__((always_inline)) __m128i _mm_set_epi64x(const uint64 } +static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey) +{ + alignas(16) const __m128i zero = { 0 }; + return veorq_u8(vaesmcq_u8(vaeseq_u8(v, zero)), rkey ); +} + + /* this one was not implemented yet so here it is */ static inline __attribute__((always_inline)) uint64_t _mm_cvtsi128_si64(__m128i a) { @@ -155,19 +162,19 @@ static inline void aes_genkey(const __m128i* memory, __m128i* k0, __m128i* k1, _ *k0 = xout0; *k1 = xout2; - SOFT_AES ? soft_aes_genkey_sub<0x01>(&xout0, &xout2) : soft_aes_genkey_sub<0x01>(&xout0, &xout2); + soft_aes_genkey_sub<0x01>(&xout0, &xout2); *k2 = xout0; *k3 = xout2; - SOFT_AES ? soft_aes_genkey_sub<0x02>(&xout0, &xout2) : soft_aes_genkey_sub<0x02>(&xout0, &xout2); + soft_aes_genkey_sub<0x02>(&xout0, &xout2); *k4 = xout0; *k5 = xout2; - SOFT_AES ? soft_aes_genkey_sub<0x04>(&xout0, &xout2) : soft_aes_genkey_sub<0x04>(&xout0, &xout2); + soft_aes_genkey_sub<0x04>(&xout0, &xout2); *k6 = xout0; *k7 = xout2; - SOFT_AES ? soft_aes_genkey_sub<0x08>(&xout0, &xout2) : soft_aes_genkey_sub<0x08>(&xout0, &xout2); + soft_aes_genkey_sub<0x08>(&xout0, &xout2); *k8 = xout0; *k9 = xout2; } @@ -186,18 +193,16 @@ static inline void aes_round(__m128i key, __m128i* x0, __m128i* x1, __m128i* x2, *x6 = soft_aesenc((uint32_t*)x6, key); *x7 = soft_aesenc((uint32_t*)x7, key); } -# ifndef XMRIG_ARMv7 else { - *x0 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x0), key)); - *x1 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x1), key)); - *x2 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x2), key)); - *x3 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x3), key)); - *x4 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x4), key)); - *x5 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x5), key)); - *x6 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x6), key)); - *x7 = vaesmcq_u8(vaeseq_u8(*((uint8x16_t *) x7), key)); + *x0 = _mm_aesenc_si128(*x0, key); + *x1 = _mm_aesenc_si128(*x1, key); + *x2 = _mm_aesenc_si128(*x2, key); + *x3 = _mm_aesenc_si128(*x3, key); + *x4 = _mm_aesenc_si128(*x4, key); + *x5 = _mm_aesenc_si128(*x5, key); + *x6 = _mm_aesenc_si128(*x6, key); + *x7 = _mm_aesenc_si128(*x7, key); } -# endif } @@ -234,10 +239,6 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { for (size_t i = 0; i < 16; i++) { - if (!SOFT_AES) { - aes_round(_mm_setzero_si128(), &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - } - aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); @@ -247,30 +248,13 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) aes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - - if (!SOFT_AES) { - xin0 ^= k9; - xin1 ^= k9; - xin2 ^= k9; - xin3 ^= k9; - xin4 ^= k9; - xin5 ^= k9; - xin6 ^= k9; - xin7 ^= k9; - } - else { - aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - } + aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); mix_and_propagate(xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7); } } for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) { - if (!SOFT_AES) { - aes_round(_mm_setzero_si128(), &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - } - aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); @@ -280,20 +264,7 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) aes_round(k6, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k7, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k8, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - - if (!SOFT_AES) { - xin0 ^= k9; - xin1 ^= k9; - xin2 ^= k9; - xin3 ^= k9; - xin4 ^= k9; - xin5 ^= k9; - xin6 ^= k9; - xin7 ^= k9; - } - else { - aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); - } + aes_round(k9, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); _mm_store_si128(output + i + 0, xin0); _mm_store_si128(output + i + 1, xin1); @@ -335,10 +306,6 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6); xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7); - if (!SOFT_AES) { - aes_round(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } - aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); @@ -348,20 +315,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - - if (!SOFT_AES) { - xout0 ^= k9; - xout1 ^= k9; - xout2 ^= k9; - xout3 ^= k9; - xout4 ^= k9; - xout5 ^= k9; - xout6 ^= k9; - xout7 ^= k9; - } - else { - aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } + aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7); @@ -379,10 +333,6 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) xout6 = _mm_xor_si128(_mm_load_si128(input + i + 6), xout6); xout7 = _mm_xor_si128(_mm_load_si128(input + i + 7), xout7); - if (!SOFT_AES) { - aes_round(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } - aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); @@ -392,29 +342,12 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - - if (!SOFT_AES) { - xout0 ^= k9; - xout1 ^= k9; - xout2 ^= k9; - xout3 ^= k9; - xout4 ^= k9; - xout5 ^= k9; - xout6 ^= k9; - xout7 ^= k9; - } - else { - aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } + aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7); } for (size_t i = 0; i < 16; i++) { - if (!SOFT_AES) { - aes_round(_mm_setzero_si128(), &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } - aes_round(k0, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k1, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k2, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); @@ -424,20 +357,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) aes_round(k6, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k7, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - - if (!SOFT_AES) { - xout0 ^= k9; - xout1 ^= k9; - xout2 ^= k9; - xout3 ^= k9; - xout4 ^= k9; - xout5 ^= k9; - xout6 ^= k9; - xout7 ^= k9; - } - else { - aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - } + aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7); } @@ -454,6 +374,21 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) } +static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp) +{ + mem_out[0] = EXTRACT64(tmp); + + uint64_t vh = vgetq_lane_u64(tmp, 1); + + uint8_t x = vh >> 24; + static const uint16_t table = 0x7531; + const uint8_t index = (((x >> 3) & 6) | (x & 1)) << 1; + vh ^= ((table >> index) & 0x3) << 28; + + mem_out[1] = vh; +} + + template inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx) { @@ -489,13 +424,15 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si } else { cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); -# ifndef XMRIG_ARMv7 - cx = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0); -# endif + cx = _mm_aesenc_si128(cx, _mm_set_epi64x(ah0, al0)); + } + + if (VARIANT > 0) { + cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); + } else { + _mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); } - _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); - VARIANT1_1(&l0[idx0 & MASK]); idx0 = EXTRACT64(cx); bx0 = cx; @@ -580,16 +517,17 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si else { cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]); -# ifndef XMRIG_ARMv7 - cx0 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx0, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah0, al0); - cx1 = vreinterpretq_m128i_u8(vaesmcq_u8(vaeseq_u8(cx1, vdupq_n_u8(0)))) ^ _mm_set_epi64x(ah1, al1); -# endif + cx0 = _mm_aesenc_si128(cx0, _mm_set_epi64x(ah0, al0)); + cx1 = _mm_aesenc_si128(cx1, _mm_set_epi64x(ah1, al1)); } - _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); - _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); - VARIANT1_1(&l0[idx0 & MASK]); - VARIANT1_1(&l1[idx1 & MASK]); + if (VARIANT > 0) { + cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); + cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); + } else { + _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); + _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); + }; idx0 = EXTRACT64(cx0); idx1 = EXTRACT64(cx1); From e119f7f40217bc7ef2da412bf1dbd5977b0c95c7 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 19 Apr 2018 13:50:06 +0700 Subject: [PATCH 070/109] Rearrange test vectors, for catch cn-heavy bug. --- src/crypto/CryptoNight_test.h | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/crypto/CryptoNight_test.h b/src/crypto/CryptoNight_test.h index 52dd2965..93cbf23d 100644 --- a/src/crypto/CryptoNight_test.h +++ b/src/crypto/CryptoNight_test.h @@ -27,16 +27,16 @@ const static uint8_t test_input[380] = { - 0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19, - 0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9, - 0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F, - 0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46, - 0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02, 0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00, 0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B, 0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62, 0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92, 0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01, + 0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19, + 0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9, + 0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F, + 0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46, + 0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02, 0x07, 0x07, 0xB4, 0x87, 0xD0, 0xD6, 0x05, 0x26, 0xE0, 0xC6, 0xDD, 0x9B, 0xC7, 0x18, 0xC3, 0xCF, 0x52, 0x04, 0xBD, 0x4F, 0x9B, 0x27, 0xF6, 0x73, 0xB9, 0x3F, 0xEF, 0x7B, 0xB2, 0xF7, 0x2B, 0xBB, 0x3F, 0x3E, 0x9C, 0x3E, 0x9D, 0x33, 0x1E, 0xDE, 0xAD, 0xBE, 0xEF, 0x4E, 0x00, 0x91, 0x81, 0x29, @@ -56,10 +56,10 @@ const static uint8_t test_input[380] = { const static uint8_t test_output_v0[160] = { - 0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66, - 0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F, 0x1A, 0x3F, 0xFB, 0xEE, 0x90, 0x9B, 0x42, 0x0D, 0x91, 0xF7, 0xBE, 0x6E, 0x5F, 0xB5, 0x6D, 0xB7, 0x1B, 0x31, 0x10, 0xD8, 0x86, 0x01, 0x1E, 0x87, 0x7E, 0xE5, 0x78, 0x6A, 0xFD, 0x08, 0x01, 0x00, + 0x1B, 0x60, 0x6A, 0x3F, 0x4A, 0x07, 0xD6, 0x48, 0x9A, 0x1B, 0xCD, 0x07, 0x69, 0x7B, 0xD1, 0x66, + 0x96, 0xB6, 0x1C, 0x8A, 0xE9, 0x82, 0xF6, 0x1A, 0x90, 0x16, 0x0F, 0x4E, 0x52, 0x82, 0x8A, 0x7F, 0xA1, 0xB4, 0xFA, 0xE3, 0xE5, 0x76, 0xCE, 0xCF, 0xB7, 0x9C, 0xAF, 0x3E, 0x29, 0x92, 0xE4, 0xE0, 0x31, 0x24, 0x05, 0x48, 0xBF, 0x8D, 0x5F, 0x7B, 0x11, 0x03, 0x60, 0xAA, 0xD7, 0x50, 0x3F, 0x0C, 0x2D, 0x30, 0xF3, 0x87, 0x4F, 0x86, 0xA1, 0x4A, 0xB5, 0xA2, 0x1A, 0x08, 0xD0, 0x44, 0x2C, 0x9D, @@ -71,10 +71,10 @@ const static uint8_t test_output_v0[160] = { // Monero v7 const static uint8_t test_output_v1[160] = { - 0xC9, 0xFA, 0xE8, 0x42, 0x5D, 0x86, 0x88, 0xDC, 0x23, 0x6B, 0xCD, 0xBC, 0x42, 0xFD, 0xB4, 0x2D, - 0x37, 0x6C, 0x6E, 0xC1, 0x90, 0x50, 0x1A, 0xA8, 0x4B, 0x04, 0xA4, 0xB4, 0xCF, 0x1E, 0xE1, 0x22, 0xF2, 0x2D, 0x3D, 0x62, 0x03, 0xD2, 0xA0, 0x8B, 0x41, 0xD9, 0x02, 0x72, 0x78, 0xD8, 0xBC, 0xC9, - 0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9, + 0x83, 0xAC, 0xAD, 0xA9, 0xB6, 0x8E, 0x52, 0xE3, 0xC6, 0x89, 0x69, 0x2A, 0x50, 0xE9, 0x21, 0xD9, + 0xC9, 0xFA, 0xE8, 0x42, 0x5D, 0x86, 0x88, 0xDC, 0x23, 0x6B, 0xCD, 0xBC, 0x42, 0xFD, 0xB4, 0x2D, + 0x37, 0x6C, 0x6E, 0xC1, 0x90, 0x50, 0x1A, 0xA8, 0x4B, 0x04, 0xA4, 0xB4, 0xCF, 0x1E, 0xE1, 0x22, 0xE7, 0x8C, 0x5A, 0x6E, 0x38, 0x30, 0x68, 0x4A, 0x73, 0xFC, 0x1B, 0xC6, 0x6D, 0xFC, 0x8D, 0x98, 0xB4, 0xC2, 0x23, 0x39, 0xAD, 0xE0, 0x9D, 0xF6, 0x6D, 0x8C, 0x6A, 0xAA, 0xF9, 0xB2, 0xE3, 0x4C, 0xB6, 0x90, 0x6C, 0xE6, 0x15, 0x5E, 0x46, 0x07, 0x9C, 0xB2, 0x6B, 0xAC, 0x3B, 0xAC, 0x1A, 0xDE, @@ -86,10 +86,10 @@ const static uint8_t test_output_v1[160] = { #ifndef XMRIG_NO_AEON const static uint8_t test_output_v0_lite[160] = { - 0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE, - 0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD, 0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E, 0x00, 0x4E, 0xEC, 0xE0, 0x9B, 0x83, 0xA7, 0x2E, 0xF6, 0xBA, 0x98, 0x64, 0xD3, 0x51, 0x0C, 0x88, + 0x28, 0xA2, 0x2B, 0xAD, 0x3F, 0x93, 0xD1, 0x40, 0x8F, 0xCA, 0x47, 0x2E, 0xB5, 0xAD, 0x1C, 0xBE, + 0x75, 0xF2, 0x1D, 0x05, 0x3C, 0x8C, 0xE5, 0xB3, 0xAF, 0x10, 0x5A, 0x57, 0x71, 0x3E, 0x21, 0xDD, 0x38, 0x08, 0xE1, 0x17, 0x0B, 0x99, 0x8D, 0x1A, 0x3C, 0xCE, 0x35, 0xC5, 0xC7, 0x3A, 0x00, 0x2E, 0xCB, 0x54, 0xF0, 0x78, 0x2E, 0x9E, 0xDB, 0xC7, 0xDF, 0x2E, 0x71, 0x9A, 0x16, 0x97, 0xC4, 0x18, 0x4B, 0x97, 0x07, 0xFE, 0x5D, 0x98, 0x9A, 0xD6, 0xD8, 0xE5, 0x92, 0x66, 0x87, 0x7F, 0x19, 0x37, @@ -101,10 +101,10 @@ const static uint8_t test_output_v0_lite[160] = { // AEON v7 const static uint8_t test_output_v1_lite[160] = { - 0x87, 0xC4, 0xE5, 0x70, 0x65, 0x3E, 0xB4, 0xC2, 0xB4, 0x2B, 0x7A, 0x0D, 0x54, 0x65, 0x59, 0x45, - 0x2D, 0xFA, 0xB5, 0x73, 0xB8, 0x2E, 0xC5, 0x2F, 0x15, 0x2B, 0x7F, 0xF9, 0x8E, 0x79, 0x44, 0x6F, 0x6D, 0x8C, 0xDC, 0x44, 0x4E, 0x9B, 0xBB, 0xFD, 0x68, 0xFC, 0x43, 0xFC, 0xD4, 0x85, 0x5B, 0x22, 0x8C, 0x8A, 0x1B, 0xD9, 0x1D, 0x9D, 0x00, 0x28, 0x5B, 0xEC, 0x02, 0xB7, 0xCA, 0x2D, 0x67, 0x41, + 0x87, 0xC4, 0xE5, 0x70, 0x65, 0x3E, 0xB4, 0xC2, 0xB4, 0x2B, 0x7A, 0x0D, 0x54, 0x65, 0x59, 0x45, + 0x2D, 0xFA, 0xB5, 0x73, 0xB8, 0x2E, 0xC5, 0x2F, 0x15, 0x2B, 0x7F, 0xF9, 0x8E, 0x79, 0x44, 0x6F, 0x16, 0x08, 0x74, 0xC7, 0xA2, 0xD2, 0xA3, 0x97, 0x95, 0x76, 0xCA, 0x4D, 0x06, 0x39, 0x7A, 0xAB, 0x6C, 0x87, 0x58, 0x33, 0x4D, 0xC8, 0x5A, 0xAB, 0x04, 0x27, 0xFE, 0x8B, 0x1C, 0x23, 0x2F, 0x32, 0xC0, 0x44, 0xFF, 0x0D, 0xB5, 0x3B, 0x27, 0x96, 0x06, 0x89, 0x7B, 0xA3, 0x0B, 0xD0, 0xCE, 0x9E, @@ -117,10 +117,10 @@ const static uint8_t test_output_v1_lite[160] = { #ifndef XMRIG_NO_SUMO const static uint8_t test_output_heavy[160] = { - 0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A, - 0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D, 0x99, 0x83, 0xF2, 0x1B, 0xDF, 0x20, 0x10, 0xA8, 0xD7, 0x07, 0xBB, 0x2F, 0x14, 0xD7, 0x86, 0x64, 0xBB, 0xE1, 0x18, 0x7F, 0x55, 0x01, 0x4B, 0x39, 0xE5, 0xF3, 0xD6, 0x93, 0x28, 0xE4, 0x8F, 0xC2, + 0x4D, 0x94, 0x7D, 0xD6, 0xDB, 0x6E, 0x07, 0x48, 0x26, 0x4A, 0x51, 0x2E, 0xAC, 0xF3, 0x25, 0x4A, + 0x1F, 0x1A, 0xA2, 0x5B, 0xFC, 0x0A, 0xAD, 0x82, 0xDE, 0xA8, 0x99, 0x96, 0x88, 0x52, 0xD2, 0x7D, 0x3E, 0xE1, 0x23, 0x03, 0x5A, 0x63, 0x7B, 0x66, 0xF6, 0xD7, 0xC2, 0x2A, 0x34, 0x5E, 0x88, 0xE7, 0xFA, 0xC4, 0x25, 0x36, 0x54, 0xCB, 0xD2, 0x5C, 0x2F, 0x80, 0x2A, 0xF9, 0xCC, 0x43, 0xF7, 0xCD, 0xE5, 0x18, 0xA8, 0x05, 0x60, 0x18, 0xA5, 0x73, 0x72, 0x9B, 0x32, 0xDC, 0x69, 0x83, 0xC1, 0xE1, From 14576f599c3e4113704e1457d97badcbbb8bb89e Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 19 Apr 2018 19:44:17 +0700 Subject: [PATCH 071/109] Fix ARMv7 build. --- src/crypto/CryptoNight_arm.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/crypto/CryptoNight_arm.h b/src/crypto/CryptoNight_arm.h index fd8c1920..746de79c 100644 --- a/src/crypto/CryptoNight_arm.h +++ b/src/crypto/CryptoNight_arm.h @@ -73,11 +73,17 @@ static inline __attribute__((always_inline)) __m128i _mm_set_epi64x(const uint64 } +#ifdef XMRIG_ARMv8 static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey) { alignas(16) const __m128i zero = { 0 }; return veorq_u8(vaesmcq_u8(vaeseq_u8(v, zero)), rkey ); } +#else +static inline __attribute__((always_inline)) __m128i _mm_aesenc_si128(__m128i v, __m128i rkey) +{ +} +#endif /* this one was not implemented yet so here it is */ From fe1649a2c13254769cdc6f5e3ce9f7babca89f77 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 19 Apr 2018 20:29:23 +0700 Subject: [PATCH 072/109] Revert old Client::close. --- src/net/Client.cpp | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/src/net/Client.cpp b/src/net/Client.cpp index c4387a7c..436bcd1a 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -120,12 +120,7 @@ void Client::deleteLater() m_listener = nullptr; - if (state() == HostLookupState) { - uv_cancel(reinterpret_cast(&m_resolver)); - return; - } - - if (!disconnect() && m_state != ClosingState) { + if (!disconnect()) { m_storage.remove(m_key); } } @@ -206,28 +201,7 @@ bool Client::close() setState(ClosingState); - uv_stream_t *stream = reinterpret_cast(m_socket); - - if (uv_is_readable(stream) == 1) { - uv_read_stop(stream); - } - - if (uv_is_writable(stream) == 1) { - const int rc = uv_shutdown(new uv_shutdown_t, stream, [](uv_shutdown_t* req, int status) { - if (uv_is_closing(reinterpret_cast(req->handle)) == 0) { - uv_close(reinterpret_cast(req->handle), Client::onClose); - } - - delete req; - }); - - assert(rc == 0); - - if (rc != 0) { - onClose(); - } - } - else { + if (uv_is_closing(reinterpret_cast(m_socket)) == 0) { uv_close(reinterpret_cast(m_socket), Client::onClose); } From 91dd5fe68aa3ed970053227f0e08948c4842214a Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 19 Apr 2018 20:57:23 +0700 Subject: [PATCH 073/109] v2.6.0-beta3 --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index 4ea70a57..c6c42e46 100644 --- a/src/version.h +++ b/src/version.h @@ -27,7 +27,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig CPU miner" -#define APP_VERSION "2.6.0-beta2" +#define APP_VERSION "2.6.0-beta3" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com" @@ -36,7 +36,7 @@ #define APP_VER_MAJOR 2 #define APP_VER_MINOR 6 #define APP_VER_BUILD 0 -#define APP_VER_REV 2 +#define APP_VER_REV 3 #ifdef _MSC_VER # if (_MSC_VER >= 1910) From 3f85b11e12f3c444747bfd84c51a17b1a6330d2a Mon Sep 17 00:00:00 2001 From: xmrig Date: Thu, 19 Apr 2018 21:19:00 +0700 Subject: [PATCH 074/109] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71d4e5b3..63090a26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v2.6.0-beta3 +- [#563](https://github.com/xmrig/xmrig/issues/563) **Added [advanced threads mode](https://github.com/xmrig/xmrig/issues/563), now possible configure each thread individually.** +- [#255](https://github.com/xmrig/xmrig/issues/563) Low power mode extended to **triple**, **quard** and **penta** modes. +- [#519](https://github.com/xmrig/xmrig/issues/519) Fixed high donation levels, improved donation start time randomization. +- [#554](https://github.com/xmrig/xmrig/issues/554) Fixed regression with `print-time` option. + # v2.6.0-beta2 - Improved performance for `cryptonight v7` especially in double hash mode. - [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 disabled for internal HTTP API by default, was causing issues on some systems. From 2d2e60a1971d8a9a608ace74bf88f3a1bc2d3a8f Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 20 Apr 2018 10:14:33 +0700 Subject: [PATCH 075/109] Fix x86 build. --- src/crypto/CryptoNight_x86.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index 3dafe724..e19eb2c9 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -803,10 +803,10 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size __m128i cx3 = _mm_set_epi64x(0, 0); uint64_t idx0, idx1, idx2, idx3; - idx0 = _mm_cvtsi128_si64(ax0); - idx1 = _mm_cvtsi128_si64(ax1); - idx2 = _mm_cvtsi128_si64(ax2); - idx3 = _mm_cvtsi128_si64(ax3); + idx0 = EXTRACT64(ax0); + idx1 = EXTRACT64(ax1); + idx2 = EXTRACT64(ax2); + idx3 = EXTRACT64(ax3); for (size_t i = 0; i < ITERATIONS / 2; i++) { @@ -915,11 +915,11 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz __m128i cx4 = _mm_set_epi64x(0, 0); uint64_t idx0, idx1, idx2, idx3, idx4; - idx0 = _mm_cvtsi128_si64(ax0); - idx1 = _mm_cvtsi128_si64(ax1); - idx2 = _mm_cvtsi128_si64(ax2); - idx3 = _mm_cvtsi128_si64(ax3); - idx4 = _mm_cvtsi128_si64(ax4); + idx0 = EXTRACT64(ax0); + idx1 = EXTRACT64(ax1); + idx2 = EXTRACT64(ax2); + idx3 = EXTRACT64(ax3); + idx4 = EXTRACT64(ax4); for (size_t i = 0; i < ITERATIONS / 2; i++) { From 78e2c122020421b8d9af67df86d632afb406ab58 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 20 Apr 2018 10:36:41 +0700 Subject: [PATCH 076/109] Fix msvc build. --- src/net/Pool.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/net/Pool.cpp b/src/net/Pool.cpp index 4d1d7439..2e167ebd 100644 --- a/src/net/Pool.cpp +++ b/src/net/Pool.cpp @@ -32,7 +32,8 @@ #ifdef _MSC_VER -# define strncasecmp(x,y,z) _strnicmp(x,y,z) +# define strncasecmp _strnicmp +# define strcasecmp _stricmp #endif From a9178bd46808328a522b37a71f316d8200b4a051 Mon Sep 17 00:00:00 2001 From: xmrig Date: Fri, 20 Apr 2018 11:13:00 +0700 Subject: [PATCH 077/109] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 010a03fc..3d438c5a 100644 --- a/README.md +++ b/README.md @@ -124,10 +124,10 @@ Please note performance is highly dependent on system load. The numbers above ar ## Release checksums ### SHA-256 ``` -232af0c5f3b1cdbc2d90b514873a764b434d5621d2790da67954b35c17e44fe3 xmrig-2.6.0-beta2-xenial-amd64.tar.gz/xmrig-2.6.0-beta2/xmrig -2366a06729d4de538ef511862bf11d0c7ad40fd245e7aeab3c1957307d63471a xmrig-2.6.0-beta2-gcc-win32.zip/xmrig.exe -2f6538c765e001d13ca380cbc1558d51efcb97d4bccdfa40993cb872be4e9efd xmrig-2.6.0-beta2-gcc-win64.zip/xmrig.exe -3c0479acb78a3cee8fe416ee438dbff09c786acf50fbaf28a820127fcd0c6e62 xmrig-2.6.0-beta2-msvc-win64.zip/xmrig.exe +6b32fefb356b27caa2180be17755d09639f0654096a1a0c61e8f10f4f2ac1626 xmrig-2.6.0-beta3-xenial-amd64.tar.gz/xmrig-2.6.0-beta3/xmrig +c8b40f4d7aac9d0cc7c3d02cadeac91b0bdb034aae2fb6b415d503272eabb987 xmrig-2.6.0-beta3-gcc-win32.zip/xmrig.exe +32cf7958f97a23296186e38a4addb9cf234adcbd9c7914b15e4209a87fe272e7 xmrig-2.6.0-beta3-gcc-win64.zip/xmrig.exe +4f176ee4c4be52701edc0d573cf9647c4aacbb4ff14975b80b98e6fe63068542 xmrig-2.6.0-beta3-msvc-win64.zip/xmrig.exe ``` ## Contacts From 2d22f2aeffe052b3a13ac95169a0eb737dbb41bb Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 20 Apr 2018 13:44:30 +0700 Subject: [PATCH 078/109] Move shared network code to common folder. --- CMakeLists.txt | 28 +++++++++---------- src/App.cpp | 2 +- src/Summary.cpp | 2 +- src/api/NetworkState.cpp | 6 ++-- src/{ => common}/Console.cpp | 6 ++-- src/{ => common}/Console.h | 4 +-- src/common/config/CommonConfig.cpp | 1 - src/common/config/CommonConfig.h | 2 +- src/common/config/ConfigLoader.cpp | 2 +- src/{ => common}/net/Client.cpp | 2 +- src/{ => common}/net/Client.h | 8 +++--- src/{ => common}/net/Id.h | 0 src/{ => common}/net/Pool.cpp | 2 +- src/{ => common}/net/Pool.h | 0 src/{ => common}/net/Storage.h | 0 src/{ => common}/net/SubmitResult.cpp | 9 +++--- src/{ => common}/net/SubmitResult.h | 9 +++--- .../net/strategies/FailoverStrategy.cpp | 4 +-- .../net/strategies/FailoverStrategy.h | 2 +- .../net/strategies/SinglePoolStrategy.cpp | 4 +-- .../net/strategies/SinglePoolStrategy.h | 0 src/core/Config.cpp | 1 - src/log/Log.cpp | 2 ++ src/net/Job.h | 2 +- src/net/Network.cpp | 12 ++++---- src/net/strategies/DonateStrategy.cpp | 4 +-- src/net/strategies/DonateStrategy.h | 2 +- src/workers/CpuThread.cpp | 2 +- 28 files changed, 60 insertions(+), 58 deletions(-) rename src/{ => common}/Console.cpp (90%) rename src/{ => common}/Console.h (88%) rename src/{ => common}/net/Client.cpp (99%) rename src/{ => common}/net/Client.h (97%) rename src/{ => common}/net/Id.h (100%) rename src/{ => common}/net/Pool.cpp (99%) rename src/{ => common}/net/Pool.h (100%) rename src/{ => common}/net/Storage.h (100%) rename src/{ => common}/net/SubmitResult.cpp (82%) rename src/{ => common}/net/SubmitResult.h (80%) rename src/{ => common}/net/strategies/FailoverStrategy.cpp (97%) rename src/{ => common}/net/strategies/FailoverStrategy.h (98%) rename src/{ => common}/net/strategies/SinglePoolStrategy.cpp (96%) rename src/{ => common}/net/strategies/SinglePoolStrategy.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index c7017b01..e8dc0ba0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,11 +17,18 @@ set(HEADERS src/common/config/CommonConfig.h src/common/config/ConfigLoader.h src/common/config/ConfigWatcher.h + src/common/Console.h + src/common/net/Client.h + src/common/net/Id.h + src/common/net/Pool.h + src/common/net/Storage.h + src/common/net/strategies/FailoverStrategy.h + src/common/net/strategies/SinglePoolStrategy.h + src/common/net/SubmitResult.h src/common/Platform.h src/common/utils/c_str.h src/common/utils/mm_malloc.h src/common/xmrig.h - src/Console.h src/core/Config.cpp src/core/ConfigLoader_platform.h src/core/Controller.h @@ -42,17 +49,10 @@ set(HEADERS src/log/FileLog.h src/log/Log.h src/Mem.h - src/net/Client.h - src/net/Id.h src/net/Job.h src/net/JobResult.h src/net/Network.h - src/net/Pool.h - src/net/Storage.h src/net/strategies/DonateStrategy.h - src/net/strategies/FailoverStrategy.h - src/net/strategies/SinglePoolStrategy.h - src/net/SubmitResult.h src/Summary.h src/version.h src/workers/CpuThread.h @@ -91,22 +91,22 @@ set(SOURCES src/common/config/CommonConfig.cpp src/common/config/ConfigLoader.cpp src/common/config/ConfigWatcher.cpp + src/common/Console.cpp + src/common/net/Client.cpp + src/common/net/Pool.cpp + src/common/net/strategies/FailoverStrategy.cpp + src/common/net/strategies/SinglePoolStrategy.cpp + src/common/net/SubmitResult.cpp src/common/Platform.cpp - src/Console.cpp src/core/Config.cpp src/core/Controller.cpp src/log/ConsoleLog.cpp src/log/FileLog.cpp src/log/Log.cpp src/Mem.cpp - src/net/Client.cpp src/net/Job.cpp src/net/Network.cpp - src/net/Pool.cpp src/net/strategies/DonateStrategy.cpp - src/net/strategies/FailoverStrategy.cpp - src/net/strategies/SinglePoolStrategy.cpp - src/net/SubmitResult.cpp src/Summary.cpp src/workers/CpuThread.cpp src/workers/Handle.cpp diff --git a/src/App.cpp b/src/App.cpp index 78d6b328..e7447634 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -28,8 +28,8 @@ #include "api/Api.h" #include "App.h" +#include "common/Console.h" #include "common/Platform.h" -#include "Console.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" diff --git a/src/Summary.cpp b/src/Summary.cpp index 32a0e4bb..12108d18 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -27,12 +27,12 @@ #include +#include "common/net/Pool.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" #include "log/Log.h" #include "Mem.h" -#include "net/Pool.h" #include "Summary.h" #include "version.h" diff --git a/src/api/NetworkState.cpp b/src/api/NetworkState.cpp index d3ffddd3..0ab80093 100644 --- a/src/api/NetworkState.cpp +++ b/src/api/NetworkState.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,7 +29,7 @@ #include "api/NetworkState.h" -#include "net/SubmitResult.h" +#include "common/net/SubmitResult.h" NetworkState::NetworkState() : diff --git a/src/Console.cpp b/src/common/Console.cpp similarity index 90% rename from src/Console.cpp rename to src/common/Console.cpp index 3d95ada4..350fb139 100644 --- a/src/Console.cpp +++ b/src/common/Console.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,7 +22,7 @@ */ -#include "Console.h" +#include "common/Console.h" #include "interfaces/IConsoleListener.h" diff --git a/src/Console.h b/src/common/Console.h similarity index 88% rename from src/Console.h rename to src/common/Console.h index bde95d7d..7f2e3cc9 100644 --- a/src/Console.h +++ b/src/common/Console.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp index 22fd348d..7327b50c 100644 --- a/src/common/config/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -32,7 +32,6 @@ #include "common/config/CommonConfig.h" #include "donate.h" #include "log/Log.h" -#include "net/Pool.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" diff --git a/src/common/config/CommonConfig.h b/src/common/config/CommonConfig.h index 5a229269..015ba04e 100644 --- a/src/common/config/CommonConfig.h +++ b/src/common/config/CommonConfig.h @@ -28,10 +28,10 @@ #include +#include "common/net/Pool.h" #include "common/utils/c_str.h" #include "common/xmrig.h" #include "interfaces/IConfig.h" -#include "net/Pool.h" namespace xmrig { diff --git a/src/common/config/ConfigLoader.cpp b/src/common/config/ConfigLoader.cpp index 47c6cdf9..cc92213f 100644 --- a/src/common/config/ConfigLoader.cpp +++ b/src/common/config/ConfigLoader.cpp @@ -34,12 +34,12 @@ #include "common/config/ConfigLoader.h" #include "common/config/ConfigWatcher.h" +#include "common/net/Pool.h" #include "common/Platform.h" #include "core/ConfigCreator.h" #include "core/ConfigLoader_platform.h" #include "interfaces/IConfig.h" #include "interfaces/IWatcherListener.h" -#include "net/Pool.h" #include "rapidjson/document.h" #include "rapidjson/error/en.h" #include "rapidjson/filereadstream.h" diff --git a/src/net/Client.cpp b/src/common/net/Client.cpp similarity index 99% rename from src/net/Client.cpp rename to src/common/net/Client.cpp index 436bcd1a..c335634b 100644 --- a/src/net/Client.cpp +++ b/src/common/net/Client.cpp @@ -29,9 +29,9 @@ #include +#include "common/net/Client.h" #include "interfaces/IClientListener.h" #include "log/Log.h" -#include "net/Client.h" #include "rapidjson/document.h" #include "rapidjson/error/en.h" #include "rapidjson/stringbuffer.h" diff --git a/src/net/Client.h b/src/common/net/Client.h similarity index 97% rename from src/net/Client.h rename to src/common/net/Client.h index 0692d38b..502fd4cc 100644 --- a/src/net/Client.h +++ b/src/common/net/Client.h @@ -30,11 +30,11 @@ #include -#include "net/Id.h" +#include "common/net/Id.h" +#include "common/net/Pool.h" +#include "common/net/Storage.h" +#include "common/net/SubmitResult.h" #include "net/Job.h" -#include "net/Storage.h" -#include "net/SubmitResult.h" -#include "net/Pool.h" #include "rapidjson/fwd.h" diff --git a/src/net/Id.h b/src/common/net/Id.h similarity index 100% rename from src/net/Id.h rename to src/common/net/Id.h diff --git a/src/net/Pool.cpp b/src/common/net/Pool.cpp similarity index 99% rename from src/net/Pool.cpp rename to src/common/net/Pool.cpp index 2e167ebd..ddf31031 100644 --- a/src/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -28,7 +28,7 @@ #include -#include "net/Pool.h" +#include "common/net/Pool.h" #ifdef _MSC_VER diff --git a/src/net/Pool.h b/src/common/net/Pool.h similarity index 100% rename from src/net/Pool.h rename to src/common/net/Pool.h diff --git a/src/net/Storage.h b/src/common/net/Storage.h similarity index 100% rename from src/net/Storage.h rename to src/common/net/Storage.h diff --git a/src/net/SubmitResult.cpp b/src/common/net/SubmitResult.cpp similarity index 82% rename from src/net/SubmitResult.cpp rename to src/common/net/SubmitResult.cpp index 2e81017c..251b2bf1 100644 --- a/src/net/SubmitResult.cpp +++ b/src/common/net/SubmitResult.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,10 +25,11 @@ #include -#include "net/SubmitResult.h" +#include "common/net/SubmitResult.h" -SubmitResult::SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff) : +SubmitResult::SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId) : + reqId(reqId), seq(seq), diff(diff), actualDiff(actualDiff), diff --git a/src/net/SubmitResult.h b/src/common/net/SubmitResult.h similarity index 80% rename from src/net/SubmitResult.h rename to src/common/net/SubmitResult.h index 8eddef89..e812cbf8 100644 --- a/src/net/SubmitResult.h +++ b/src/common/net/SubmitResult.h @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,11 +31,12 @@ class SubmitResult { public: - inline SubmitResult() : seq(0), diff(0), actualDiff(0), elapsed(0), start(0) {} - SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff); + inline SubmitResult() : reqId(0), seq(0), diff(0), actualDiff(0), elapsed(0), start(0) {} + SubmitResult(int64_t seq, uint32_t diff, uint64_t actualDiff, int64_t reqId = 0); void done(); + int64_t reqId; int64_t seq; uint32_t diff; uint64_t actualDiff; diff --git a/src/net/strategies/FailoverStrategy.cpp b/src/common/net/strategies/FailoverStrategy.cpp similarity index 97% rename from src/net/strategies/FailoverStrategy.cpp rename to src/common/net/strategies/FailoverStrategy.cpp index cef9da0c..58854498 100644 --- a/src/net/strategies/FailoverStrategy.cpp +++ b/src/common/net/strategies/FailoverStrategy.cpp @@ -22,10 +22,10 @@ */ +#include "common/net/Client.h" +#include "common/net/strategies/FailoverStrategy.h" #include "common/Platform.h" #include "interfaces/IStrategyListener.h" -#include "net/Client.h" -#include "net/strategies/FailoverStrategy.h" FailoverStrategy::FailoverStrategy(const std::vector &urls, int retryPause, int retries, IStrategyListener *listener, bool quiet) : diff --git a/src/net/strategies/FailoverStrategy.h b/src/common/net/strategies/FailoverStrategy.h similarity index 98% rename from src/net/strategies/FailoverStrategy.h rename to src/common/net/strategies/FailoverStrategy.h index a48496fb..f86b366a 100644 --- a/src/net/strategies/FailoverStrategy.h +++ b/src/common/net/strategies/FailoverStrategy.h @@ -28,9 +28,9 @@ #include +#include "common/net/Pool.h" #include "interfaces/IClientListener.h" #include "interfaces/IStrategy.h" -#include "net/Pool.h" class Client; diff --git a/src/net/strategies/SinglePoolStrategy.cpp b/src/common/net/strategies/SinglePoolStrategy.cpp similarity index 96% rename from src/net/strategies/SinglePoolStrategy.cpp rename to src/common/net/strategies/SinglePoolStrategy.cpp index c74a794b..50620ab2 100644 --- a/src/net/strategies/SinglePoolStrategy.cpp +++ b/src/common/net/strategies/SinglePoolStrategy.cpp @@ -22,10 +22,10 @@ */ +#include "common/net/Client.h" +#include "common/net/strategies/SinglePoolStrategy.h" #include "common/Platform.h" #include "interfaces/IStrategyListener.h" -#include "net/Client.h" -#include "net/strategies/SinglePoolStrategy.h" SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, IStrategyListener *listener, bool quiet) : diff --git a/src/net/strategies/SinglePoolStrategy.h b/src/common/net/strategies/SinglePoolStrategy.h similarity index 100% rename from src/net/strategies/SinglePoolStrategy.h rename to src/common/net/strategies/SinglePoolStrategy.h diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 4d48af29..33cd01e8 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -31,7 +31,6 @@ #include "core/ConfigCreator.h" #include "Cpu.h" #include "crypto/CryptoNight_constants.h" -#include "net/Pool.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" diff --git a/src/log/Log.cpp b/src/log/Log.cpp index 131faa54..0e38634d 100644 --- a/src/log/Log.cpp +++ b/src/log/Log.cpp @@ -50,6 +50,8 @@ void Log::message(Log::Level level, const char* fmt, ...) va_end(copy); } + va_end(args); + uv_mutex_unlock(&m_mutex); } diff --git a/src/net/Job.h b/src/net/Job.h index ee4728e3..e632a26d 100644 --- a/src/net/Job.h +++ b/src/net/Job.h @@ -30,8 +30,8 @@ #include +#include "common/net/Id.h" #include "common/xmrig.h" -#include "net/Id.h" class Job diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 98ce7e8d..1fe02a35 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -31,16 +31,16 @@ #include "api/Api.h" +#include "common/net/Client.h" +#include "common/net/strategies/FailoverStrategy.h" +#include "common/net/strategies/SinglePoolStrategy.h" +#include "common/net/SubmitResult.h" +#include "core/Config.h" +#include "core/Controller.h" #include "log/Log.h" -#include "net/Client.h" #include "net/Network.h" #include "net/strategies/DonateStrategy.h" -#include "net/strategies/FailoverStrategy.h" -#include "net/strategies/SinglePoolStrategy.h" -#include "net/SubmitResult.h" #include "workers/Workers.h" -#include "core/Controller.h" -#include "core/Config.h" Network::Network(xmrig::Controller *controller) : diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 27beae33..3176ee52 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -22,13 +22,13 @@ */ +#include "common/net/Client.h" +#include "common/net/strategies/FailoverStrategy.h" #include "common/Platform.h" #include "common/xmrig.h" #include "interfaces/IStrategyListener.h" -#include "net/Client.h" #include "net/Job.h" #include "net/strategies/DonateStrategy.h" -#include "net/strategies/FailoverStrategy.h" extern "C" diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index cad360b1..edb15c8f 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -29,10 +29,10 @@ #include +#include "common/net/Pool.h" #include "interfaces/IClientListener.h" #include "interfaces/IStrategy.h" #include "interfaces/IStrategyListener.h" -#include "net/Pool.h" class Client; diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 3632e193..be24b2d5 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -24,7 +24,7 @@ #include -#include "net/Pool.h" +#include "common/net/Pool.h" #include "rapidjson/document.h" #include "workers/CpuThread.h" From 98e7308597f6fae8a44ac3024a2171b9f1b99cf0 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 20 Apr 2018 14:45:51 +0700 Subject: [PATCH 079/109] Move keccak to common code. --- CMakeLists.txt | 4 +- src/api/ApiRouter.cpp | 9 +--- .../c_keccak.c => common/crypto/keccak.cpp} | 50 ++++++++++++++----- src/common/crypto/keccak.h | 49 ++++++++++++++++++ src/crypto/CryptoNight_x86.h | 26 +++++----- src/crypto/c_keccak.h | 26 ---------- src/net/strategies/DonateStrategy.cpp | 9 +--- 7 files changed, 105 insertions(+), 68 deletions(-) rename src/{crypto/c_keccak.c => common/crypto/keccak.cpp} (74%) create mode 100644 src/common/crypto/keccak.h delete mode 100644 src/crypto/c_keccak.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e8dc0ba0..06f0bef9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ set(HEADERS src/common/config/ConfigLoader.h src/common/config/ConfigWatcher.h src/common/Console.h + src/common/crypto/keccak.h src/common/net/Client.h src/common/net/Id.h src/common/net/Pool.h @@ -67,7 +68,6 @@ set(HEADERS_CRYPTO src/crypto/c_blake256.h src/crypto/c_groestl.h src/crypto/c_jh.h - src/crypto/c_keccak.h src/crypto/c_skein.h src/crypto/CryptoNight.h src/crypto/CryptoNight_constants.h @@ -92,6 +92,7 @@ set(SOURCES src/common/config/ConfigLoader.cpp src/common/config/ConfigWatcher.cpp src/common/Console.cpp + src/common/crypto/keccak.cpp src/common/net/Client.cpp src/common/net/Pool.cpp src/common/net/strategies/FailoverStrategy.cpp @@ -118,7 +119,6 @@ set(SOURCES ) set(SOURCES_CRYPTO - src/crypto/c_keccak.c src/crypto/c_groestl.c src/crypto/c_blake256.c src/crypto/c_jh.c diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 42256cc9..cfe5ed9f 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -35,6 +35,7 @@ #include "api/ApiRouter.h" #include "common/api/HttpReply.h" #include "common/api/HttpRequest.h" +#include "common/crypto/keccak.h" #include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" @@ -50,12 +51,6 @@ #include "workers/Workers.h" -extern "C" -{ -#include "crypto/c_keccak.h" -} - - static inline double normalize(double d) { if (!isnormal(d)) { @@ -171,7 +166,7 @@ void ApiRouter::genId() memcpy(input, interfaces[i].phys_addr, addrSize); memcpy(input + addrSize, APP_KIND, strlen(APP_KIND)); - keccak(input, static_cast(inSize), hash, sizeof(hash)); + xmrig::keccak(input, inSize, hash); Job::toHex(hash, 8, m_id); delete [] input; diff --git a/src/crypto/c_keccak.c b/src/common/crypto/keccak.cpp similarity index 74% rename from src/crypto/c_keccak.c rename to src/common/crypto/keccak.cpp index 997db241..ecfe7700 100644 --- a/src/crypto/c_keccak.c +++ b/src/common/crypto/keccak.cpp @@ -1,10 +1,35 @@ -// keccak.c -// 19-Nov-11 Markku-Juhani O. Saarinen -// A baseline Keccak (3rd round) implementation. +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2011 Markku-Juhani O. Saarinen + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include #include + +#include "common/crypto/keccak.h" + + #define HASH_DATA_AREA 136 #define KECCAK_ROUNDS 24 @@ -26,7 +51,7 @@ const uint64_t keccakf_rndc[24] = // update the state with given number of rounds -void keccakf(uint64_t st[25], int rounds) +void xmrig::keccakf(uint64_t st[25], int rounds) { int i, j, round; uint64_t t, bc[5]; @@ -139,7 +164,8 @@ void keccakf(uint64_t st[25], int rounds) // compute a keccak hash (md) of given byte length from "in" typedef uint64_t state_t[25]; -void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen) + +void xmrig::keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen) { state_t st; uint8_t temp[144]; @@ -151,9 +177,11 @@ void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen) memset(st, 0, sizeof(st)); for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) { - for (i = 0; i < rsizw; i++) + for (i = 0; i < rsizw; i++) { st[i] ^= ((uint64_t *) in)[i]; - keccakf(st, KECCAK_ROUNDS); + } + + xmrig::keccakf(st, KECCAK_ROUNDS); } // last block and padding @@ -162,15 +190,11 @@ void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen) memset(temp + inlen, 0, rsiz - inlen); temp[rsiz - 1] |= 0x80; - for (i = 0; i < rsizw; i++) + for (i = 0; i < rsizw; i++) { st[i] ^= ((uint64_t *) temp)[i]; + } keccakf(st, KECCAK_ROUNDS); memcpy(md, st, mdlen); } - -void keccak1600(const uint8_t *in, int inlen, uint8_t *md) -{ - keccak(in, inlen, md, sizeof(state_t)); -} diff --git a/src/common/crypto/keccak.h b/src/common/crypto/keccak.h new file mode 100644 index 00000000..0413ec2d --- /dev/null +++ b/src/common/crypto/keccak.h @@ -0,0 +1,49 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2011 Markku-Juhani O. Saarinen + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#ifndef KECCAK_H_ +#define KECCAK_H_ + +#include +#include + + +namespace xmrig { + +// compute a keccak hash (md) of given byte length from "in" +void keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen); + + +inline void keccak(const uint8_t *in, size_t inlen, uint8_t *md) +{ + keccak(in, static_cast(inlen), md, 200); +} + +// update the state +void keccakf(uint64_t st[25], int norounds); + +} /* namespace xmrig */ + +#endif /* KECCAK_H_ */ diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index e19eb2c9..a1651cc3 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -34,6 +34,7 @@ #endif +#include "common/crypto/keccak.h" #include "crypto/CryptoNight.h" #include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_monero.h" @@ -42,7 +43,6 @@ extern "C" { -#include "crypto/c_keccak.h" #include "crypto/c_groestl.h" #include "crypto/c_blake256.h" #include "crypto/c_jh.h" @@ -414,7 +414,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si return; } - keccak(input, (int) size, ctx[0]->state, 200); + xmrig::keccak(input, size, ctx[0]->state); VARIANT1_INIT(0) @@ -478,7 +478,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); - keccakf(h0, 24); + xmrig::keccakf(h0, 24); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); } @@ -495,8 +495,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si return; } - keccak(input, (int) size, ctx[0]->state, 200); - keccak(input + size, (int) size, ctx[1]->state, 200); + xmrig::keccak(input, size, ctx[0]->state); + xmrig::keccak(input + size, size, ctx[1]->state); VARIANT1_INIT(0); VARIANT1_INIT(1); @@ -603,8 +603,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); - keccakf(h0, 24); - keccakf(h1, 24); + xmrig::keccakf(h0, 24); + xmrig::keccakf(h1, 24); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); @@ -681,7 +681,7 @@ inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t si } for (size_t i = 0; i < 3; i++) { - keccak(input + size * i, static_cast(size), ctx[i]->state, 200); + xmrig::keccak(input + size * i, size, ctx[i]->state); cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); } @@ -752,7 +752,7 @@ inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t si for (size_t i = 0; i < 3; i++) { cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); - keccakf(reinterpret_cast(ctx[i]->state), 24); + xmrig::keccakf(reinterpret_cast(ctx[i]->state), 24); extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); } } @@ -771,7 +771,7 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size } for (size_t i = 0; i < 4; i++) { - keccak(input + size * i, static_cast(size), ctx[i]->state, 200); + xmrig::keccak(input + size * i, size, ctx[i]->state); cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); } @@ -858,7 +858,7 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size for (size_t i = 0; i < 4; i++) { cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); - keccakf(reinterpret_cast(ctx[i]->state), 24); + xmrig::keccakf(reinterpret_cast(ctx[i]->state), 24); extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); } } @@ -877,7 +877,7 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz } for (size_t i = 0; i < 5; i++) { - keccak(input + size * i, static_cast(size), ctx[i]->state, 200); + xmrig::keccak(input + size * i, size, ctx[i]->state); cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); } @@ -979,7 +979,7 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz for (size_t i = 0; i < 5; i++) { cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); - keccakf(reinterpret_cast(ctx[i]->state), 24); + xmrig::keccakf(reinterpret_cast(ctx[i]->state), 24); extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); } } diff --git a/src/crypto/c_keccak.h b/src/crypto/c_keccak.h deleted file mode 100644 index 4f7f8572..00000000 --- a/src/crypto/c_keccak.h +++ /dev/null @@ -1,26 +0,0 @@ -// keccak.h -// 19-Nov-11 Markku-Juhani O. Saarinen - -#ifndef KECCAK_H -#define KECCAK_H - -#include -#include - -#ifndef KECCAK_ROUNDS -#define KECCAK_ROUNDS 24 -#endif - -#ifndef ROTL64 -#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) -#endif - -// compute a keccak hash (md) of given byte length from "in" -int keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen); - -// update the state -void keccakf(uint64_t st[25], int norounds); - -void keccak1600(const uint8_t *in, int inlen, uint8_t *md); - -#endif diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 3176ee52..9b4a60c7 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -22,6 +22,7 @@ */ +#include "common/crypto/keccak.h" #include "common/net/Client.h" #include "common/net/strategies/FailoverStrategy.h" #include "common/Platform.h" @@ -31,12 +32,6 @@ #include "net/strategies/DonateStrategy.h" -extern "C" -{ -#include "crypto/c_keccak.h" -} - - const static char *kDonatePool1 = "miner.fee.xmrig.com"; const static char *kDonatePool2 = "emergency.fee.xmrig.com"; @@ -56,7 +51,7 @@ DonateStrategy::DonateStrategy(int level, const char *user, int algo, IStrategyL uint8_t hash[200]; char userId[65] = { 0 }; - keccak(reinterpret_cast(user), static_cast(strlen(user)), hash, sizeof(hash)); + xmrig::keccak(reinterpret_cast(user), strlen(user), hash); Job::toHex(hash, 32, userId); if (algo == xmrig::CRYPTONIGHT) { From 36a612af9a2972174ff3c4bc68317369bc389d71 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 20 Apr 2018 18:54:58 +0700 Subject: [PATCH 080/109] Move logging code to common folder. --- CMakeLists.txt | 14 +++++++------- src/App.cpp | 4 +--- src/Mem_win.cpp | 2 +- src/Summary.cpp | 2 +- src/common/api/Httpd.cpp | 2 +- src/common/config/CommonConfig.cpp | 2 +- src/common/config/ConfigWatcher.cpp | 2 +- src/common/crypto/keccak.cpp | 2 +- src/{ => common}/log/ConsoleLog.cpp | 4 ++-- src/{ => common}/log/ConsoleLog.h | 0 src/{ => common}/log/FileLog.cpp | 2 +- src/{ => common}/log/FileLog.h | 0 src/{ => common}/log/Log.cpp | 2 +- src/{ => common}/log/Log.h | 0 src/{ => common}/log/SysLog.cpp | 2 +- src/{ => common}/log/SysLog.h | 0 src/common/net/Client.cpp | 2 +- src/common/net/Storage.h | 3 ++- src/core/Controller.cpp | 6 +++--- src/net/Network.cpp | 2 +- src/workers/Hashrate.cpp | 2 +- src/workers/Workers.cpp | 2 +- 22 files changed, 28 insertions(+), 29 deletions(-) rename src/{ => common}/log/ConsoleLog.cpp (98%) rename src/{ => common}/log/ConsoleLog.h (100%) rename src/{ => common}/log/FileLog.cpp (98%) rename src/{ => common}/log/FileLog.h (100%) rename src/{ => common}/log/Log.cpp (98%) rename src/{ => common}/log/Log.h (100%) rename src/{ => common}/log/SysLog.cpp (97%) rename src/{ => common}/log/SysLog.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 06f0bef9..e6c2d2d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,9 +46,9 @@ set(HEADERS src/interfaces/IThread.h src/interfaces/IWatcherListener.h src/interfaces/IWorker.h - src/log/ConsoleLog.h - src/log/FileLog.h - src/log/Log.h + src/common/log/ConsoleLog.h + src/common/log/FileLog.h + src/common/log/Log.h src/Mem.h src/net/Job.h src/net/JobResult.h @@ -101,9 +101,9 @@ set(SOURCES src/common/Platform.cpp src/core/Config.cpp src/core/Controller.cpp - src/log/ConsoleLog.cpp - src/log/FileLog.cpp - src/log/Log.cpp + src/common/log/ConsoleLog.cpp + src/common/log/FileLog.cpp + src/common/log/Log.cpp src/Mem.cpp src/net/Job.cpp src/net/Network.cpp @@ -194,7 +194,7 @@ endif() CHECK_INCLUDE_FILE (syslog.h HAVE_SYSLOG_H) if (HAVE_SYSLOG_H) add_definitions(/DHAVE_SYSLOG_H) - set(SOURCES_SYSLOG src/log/SysLog.h src/log/SysLog.cpp) + set(SOURCES_SYSLOG src/common/log/SysLog.h src/common/log/SysLog.cpp) endif() if (NOT WITH_AEON) diff --git a/src/App.cpp b/src/App.cpp index e7447634..adcc5752 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -29,14 +29,12 @@ #include "api/Api.h" #include "App.h" #include "common/Console.h" +#include "common/log/Log.h" #include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" #include "crypto/CryptoNight.h" -#include "log/ConsoleLog.h" -#include "log/FileLog.h" -#include "log/Log.h" #include "Mem.h" #include "net/Network.h" #include "Summary.h" diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index 9a81b039..2bfcc3b0 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -29,11 +29,11 @@ #include +#include "common/log/Log.h" #include "common/utils/mm_malloc.h" #include "common/xmrig.h" #include "crypto/CryptoNight.h" #include "crypto/CryptoNight_constants.h" -#include "log/Log.h" #include "Mem.h" diff --git a/src/Summary.cpp b/src/Summary.cpp index 12108d18..38ceac8e 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -27,11 +27,11 @@ #include +#include "common/log/Log.h" #include "common/net/Pool.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" -#include "log/Log.h" #include "Mem.h" #include "Summary.h" #include "version.h" diff --git a/src/common/api/Httpd.cpp b/src/common/api/Httpd.cpp index 135ac7c9..0cab01bf 100644 --- a/src/common/api/Httpd.cpp +++ b/src/common/api/Httpd.cpp @@ -30,7 +30,7 @@ #include "common/api/Httpd.h" #include "common/api/HttpReply.h" #include "common/api/HttpRequest.h" -#include "log/Log.h" +#include "common/log/Log.h" Httpd::Httpd(int port, const char *accessToken, bool IPv6, bool restricted) : diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp index 7327b50c..75906621 100644 --- a/src/common/config/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -30,8 +30,8 @@ #include "common/config/CommonConfig.h" +#include "common/log/Log.h" #include "donate.h" -#include "log/Log.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" diff --git a/src/common/config/ConfigWatcher.cpp b/src/common/config/ConfigWatcher.cpp index 21d73188..a08b2be7 100644 --- a/src/common/config/ConfigWatcher.cpp +++ b/src/common/config/ConfigWatcher.cpp @@ -27,9 +27,9 @@ #include "common/config/ConfigLoader.h" #include "common/config/ConfigWatcher.h" +#include "common/log/Log.h" #include "core/ConfigCreator.h" #include "interfaces/IWatcherListener.h" -#include "log/Log.h" xmrig::ConfigWatcher::ConfigWatcher(const char *path, IConfigCreator *creator, IWatcherListener *listener) : diff --git a/src/common/crypto/keccak.cpp b/src/common/crypto/keccak.cpp index ecfe7700..0219ce36 100644 --- a/src/common/crypto/keccak.cpp +++ b/src/common/crypto/keccak.cpp @@ -183,7 +183,7 @@ void xmrig::keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen) xmrig::keccakf(st, KECCAK_ROUNDS); } - + // last block and padding memcpy(temp, in, inlen); temp[inlen++] = 1; diff --git a/src/log/ConsoleLog.cpp b/src/common/log/ConsoleLog.cpp similarity index 98% rename from src/log/ConsoleLog.cpp rename to src/common/log/ConsoleLog.cpp index eeed7355..b7d187d1 100644 --- a/src/log/ConsoleLog.cpp +++ b/src/common/log/ConsoleLog.cpp @@ -34,10 +34,10 @@ #endif +#include "common/log/ConsoleLog.h" +#include "common/log/Log.h" #include "core/Config.h" #include "core/Controller.h" -#include "log/ConsoleLog.h" -#include "log/Log.h" ConsoleLog::ConsoleLog(xmrig::Controller *controller) : diff --git a/src/log/ConsoleLog.h b/src/common/log/ConsoleLog.h similarity index 100% rename from src/log/ConsoleLog.h rename to src/common/log/ConsoleLog.h diff --git a/src/log/FileLog.cpp b/src/common/log/FileLog.cpp similarity index 98% rename from src/log/FileLog.cpp rename to src/common/log/FileLog.cpp index 5eeb252c..c8eaf5f7 100644 --- a/src/log/FileLog.cpp +++ b/src/common/log/FileLog.cpp @@ -29,7 +29,7 @@ #include -#include "log/FileLog.h" +#include "common/log/FileLog.h" FileLog::FileLog(const char *fileName) diff --git a/src/log/FileLog.h b/src/common/log/FileLog.h similarity index 100% rename from src/log/FileLog.h rename to src/common/log/FileLog.h diff --git a/src/log/Log.cpp b/src/common/log/Log.cpp similarity index 98% rename from src/log/Log.cpp rename to src/common/log/Log.cpp index 0e38634d..03237f03 100644 --- a/src/log/Log.cpp +++ b/src/common/log/Log.cpp @@ -29,8 +29,8 @@ #include +#include "common/log/Log.h" #include "interfaces/ILogBackend.h" -#include "log/Log.h" Log *Log::m_self = nullptr; diff --git a/src/log/Log.h b/src/common/log/Log.h similarity index 100% rename from src/log/Log.h rename to src/common/log/Log.h diff --git a/src/log/SysLog.cpp b/src/common/log/SysLog.cpp similarity index 97% rename from src/log/SysLog.cpp rename to src/common/log/SysLog.cpp index f9b16cca..70879c33 100644 --- a/src/log/SysLog.cpp +++ b/src/common/log/SysLog.cpp @@ -25,7 +25,7 @@ #include -#include "log/SysLog.h" +#include "common/log/SysLog.h" #include "version.h" diff --git a/src/log/SysLog.h b/src/common/log/SysLog.h similarity index 100% rename from src/log/SysLog.h rename to src/common/log/SysLog.h diff --git a/src/common/net/Client.cpp b/src/common/net/Client.cpp index c335634b..2c28c89a 100644 --- a/src/common/net/Client.cpp +++ b/src/common/net/Client.cpp @@ -29,9 +29,9 @@ #include +#include "common/log/Log.h" #include "common/net/Client.h" #include "interfaces/IClientListener.h" -#include "log/Log.h" #include "rapidjson/document.h" #include "rapidjson/error/en.h" #include "rapidjson/stringbuffer.h" diff --git a/src/common/net/Storage.h b/src/common/net/Storage.h index 105547ec..752e9512 100644 --- a/src/common/net/Storage.h +++ b/src/common/net/Storage.h @@ -28,7 +28,8 @@ #include #include -#include "log/Log.h" + +#include "common/log/Log.h" namespace xmrig { diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 5f0a9bb3..d0babe47 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -26,14 +26,14 @@ #include "common/config/ConfigLoader.h" +#include "common/log/ConsoleLog.h" +#include "common/log/FileLog.h" +#include "common/log/Log.h" #include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" #include "interfaces/IControllerListener.h" -#include "log/ConsoleLog.h" -#include "log/FileLog.h" -#include "log/Log.h" #include "net/Network.h" diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 1fe02a35..5f6d73ee 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -31,13 +31,13 @@ #include "api/Api.h" +#include "common/log/Log.h" #include "common/net/Client.h" #include "common/net/strategies/FailoverStrategy.h" #include "common/net/strategies/SinglePoolStrategy.h" #include "common/net/SubmitResult.h" #include "core/Config.h" #include "core/Controller.h" -#include "log/Log.h" #include "net/Network.h" #include "net/strategies/DonateStrategy.h" #include "workers/Workers.h" diff --git a/src/workers/Hashrate.cpp b/src/workers/Hashrate.cpp index 7d2e6a4c..60d3a6a2 100644 --- a/src/workers/Hashrate.cpp +++ b/src/workers/Hashrate.cpp @@ -29,9 +29,9 @@ #include +#include "common/log/Log.h" #include "core/Config.h" #include "core/Controller.h" -#include "log/Log.h" #include "workers/Hashrate.h" diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 25e1d068..1d2c1739 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -26,12 +26,12 @@ #include "api/Api.h" +#include "common/log/Log.h" #include "core/Config.h" #include "core/Controller.h" #include "crypto/CryptoNight_constants.h" #include "interfaces/IJobResultListener.h" #include "interfaces/IThread.h" -#include "log/Log.h" #include "Mem.h" #include "rapidjson/document.h" #include "workers/Handle.h" From 8fe264bbd79251ed2f62f2ade40fdb5f707723d2 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 20 Apr 2018 23:44:32 +0700 Subject: [PATCH 081/109] Move Job to common. --- CMakeLists.txt | 16 ++++----- src/api/ApiRouter.cpp | 2 +- src/common/net/Client.cpp | 19 ++-------- src/common/net/Client.h | 2 +- src/{ => common}/net/Job.cpp | 37 +++++++++---------- src/{ => common}/net/Job.h | 51 ++++++++++++++++----------- src/net/JobResult.h | 2 +- src/net/strategies/DonateStrategy.cpp | 2 +- src/workers/MultiWorker.h | 2 +- src/workers/Workers.h | 2 +- 10 files changed, 63 insertions(+), 72 deletions(-) rename src/{ => common}/net/Job.cpp (90%) rename src/{ => common}/net/Job.h (57%) diff --git a/CMakeLists.txt b/CMakeLists.txt index e6c2d2d3..21d0726b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,8 +19,12 @@ set(HEADERS src/common/config/ConfigWatcher.h src/common/Console.h src/common/crypto/keccak.h + src/common/log/ConsoleLog.h + src/common/log/FileLog.h + src/common/log/Log.h src/common/net/Client.h src/common/net/Id.h + src/common/net/Job.h src/common/net/Pool.h src/common/net/Storage.h src/common/net/strategies/FailoverStrategy.h @@ -46,11 +50,7 @@ set(HEADERS src/interfaces/IThread.h src/interfaces/IWatcherListener.h src/interfaces/IWorker.h - src/common/log/ConsoleLog.h - src/common/log/FileLog.h - src/common/log/Log.h src/Mem.h - src/net/Job.h src/net/JobResult.h src/net/Network.h src/net/strategies/DonateStrategy.h @@ -93,7 +93,11 @@ set(SOURCES src/common/config/ConfigWatcher.cpp src/common/Console.cpp src/common/crypto/keccak.cpp + src/common/log/ConsoleLog.cpp + src/common/log/FileLog.cpp + src/common/log/Log.cpp src/common/net/Client.cpp + src/common/net/Job.cpp src/common/net/Pool.cpp src/common/net/strategies/FailoverStrategy.cpp src/common/net/strategies/SinglePoolStrategy.cpp @@ -101,11 +105,7 @@ set(SOURCES src/common/Platform.cpp src/core/Config.cpp src/core/Controller.cpp - src/common/log/ConsoleLog.cpp - src/common/log/FileLog.cpp - src/common/log/Log.cpp src/Mem.cpp - src/net/Job.cpp src/net/Network.cpp src/net/strategies/DonateStrategy.cpp src/Summary.cpp diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index cfe5ed9f..a9e32b18 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -36,13 +36,13 @@ #include "common/api/HttpReply.h" #include "common/api/HttpRequest.h" #include "common/crypto/keccak.h" +#include "common/net/Job.h" #include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" #include "Cpu.h" #include "interfaces/IThread.h" #include "Mem.h" -#include "net/Job.h" #include "rapidjson/document.h" #include "rapidjson/prettywriter.h" #include "rapidjson/stringbuffer.h" diff --git a/src/common/net/Client.cpp b/src/common/net/Client.cpp index 2c28c89a..a110b2ce 100644 --- a/src/common/net/Client.cpp +++ b/src/common/net/Client.cpp @@ -32,19 +32,13 @@ #include "common/log/Log.h" #include "common/net/Client.h" #include "interfaces/IClientListener.h" +#include "net/JobResult.h" #include "rapidjson/document.h" #include "rapidjson/error/en.h" #include "rapidjson/stringbuffer.h" #include "rapidjson/writer.h" -#ifdef XMRIG_PROXY_PROJECT -# include "proxy/JobResult.h" -#else -# include "net/JobResult.h" -#endif - - #ifdef _MSC_VER # define strncasecmp(x,y,z) _strnicmp(x,y,z) #endif @@ -238,12 +232,7 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } -# ifdef XMRIG_PROXY_PROJECT - Job job(m_id, m_pool.variant()); - job.setClientId(m_rpcId); -# else - Job job(m_id, m_nicehash, m_pool.algo(), m_pool.variant()); -# endif + Job job(m_id, m_nicehash, m_pool.algo(), m_pool.variant(), m_rpcId); if (!job.setId(params["job_id"].GetString())) { *code = 3; @@ -260,10 +249,6 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } - if (params.HasMember("coin")) { - job.setCoin(params["coin"].GetString()); - } - if (params.HasMember("variant")) { job.setVariant(params["variant"].GetInt()); } diff --git a/src/common/net/Client.h b/src/common/net/Client.h index 502fd4cc..651f97b5 100644 --- a/src/common/net/Client.h +++ b/src/common/net/Client.h @@ -31,10 +31,10 @@ #include "common/net/Id.h" +#include "common/net/Job.h" #include "common/net/Pool.h" #include "common/net/Storage.h" #include "common/net/SubmitResult.h" -#include "net/Job.h" #include "rapidjson/fwd.h" diff --git a/src/net/Job.cpp b/src/common/net/Job.cpp similarity index 90% rename from src/net/Job.cpp rename to src/common/net/Job.cpp index 1434c87f..c5f9902c 100644 --- a/src/net/Job.cpp +++ b/src/common/net/Job.cpp @@ -27,7 +27,7 @@ #include -#include "net/Job.h" +#include "common/net/Job.h" static inline unsigned char hf_hex2bin(char c, bool &err) @@ -59,31 +59,30 @@ static inline char hf_bin2hex(unsigned char c) Job::Job() : m_nicehash(false), - m_coin(), - m_algo(xmrig::CRYPTONIGHT), m_poolId(-2), m_threadId(-1), m_size(0), m_diff(0), m_target(0), m_blob(), + m_algo(xmrig::INVALID_ALGO), m_variant(xmrig::VARIANT_AUTO) { } -Job::Job(int poolId, bool nicehash, int algo, int variant) : +Job::Job(int poolId, bool nicehash, xmrig::Algo algo, xmrig::Variant variant, const xmrig::Id &clientId) : m_nicehash(nicehash), - m_coin(), - m_algo(algo), m_poolId(poolId), m_threadId(-1), m_size(0), m_diff(0), m_target(0), - m_blob() + m_blob(), + m_algo(algo), + m_clientId(clientId), + m_variant(variant) { - setVariant(variant); } @@ -116,6 +115,11 @@ bool Job::setBlob(const char *blob) m_nicehash = true; } +# ifdef XMRIG_PROXY_PROJECT + memset(m_rawBlob, 0, sizeof(m_rawBlob)); + memcpy(m_rawBlob, blob, m_size * 2); +# endif + return true; } @@ -152,23 +156,16 @@ bool Job::setTarget(const char *target) return false; } +# ifdef XMRIG_PROXY_PROJECT + memset(m_rawTarget, 0, sizeof(m_rawTarget)); + memcpy(m_rawTarget, target, len); +# endif + m_diff = toDiff(m_target); return true; } -void Job::setCoin(const char *coin) -{ - if (!coin || strlen(coin) > 4) { - memset(m_coin, 0, sizeof(m_coin)); - return; - } - - strncpy(m_coin, coin, sizeof(m_coin)); - m_algo = strcmp(m_coin, "AEON") == 0 ? xmrig::CRYPTONIGHT_LITE : xmrig::CRYPTONIGHT; -} - - void Job::setVariant(int variant) { switch (variant) { diff --git a/src/net/Job.h b/src/common/net/Job.h similarity index 57% rename from src/net/Job.h rename to src/common/net/Job.h index e632a26d..4eb7018e 100644 --- a/src/net/Job.h +++ b/src/common/net/Job.h @@ -38,31 +38,35 @@ class Job { public: Job(); - Job(int poolId, bool nicehash, int algo, int variant); + Job(int poolId, bool nicehash, xmrig::Algo algo, xmrig::Variant variant, const xmrig::Id &clientId); ~Job(); bool setBlob(const char *blob); bool setTarget(const char *target); - void setCoin(const char *coin); void setVariant(int variant); - inline bool isNicehash() const { return m_nicehash; } - inline bool isValid() const { return m_size > 0 && m_diff > 0; } - inline bool setId(const char *id) { return m_id.setId(id); } - inline const char *coin() const { return m_coin; } - inline const uint32_t *nonce() const { return reinterpret_cast(m_blob + 39); } - inline const uint8_t *blob() const { return m_blob; } - inline const xmrig::Id &id() const { return m_id; } - inline int poolId() const { return m_poolId; } - inline int threadId() const { return m_threadId; } - inline size_t size() const { return m_size; } - inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } - inline uint32_t diff() const { return (uint32_t) m_diff; } - inline uint64_t target() const { return m_target; } - inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } - inline void setPoolId(int poolId) { m_poolId = poolId; } - inline void setThreadId(int threadId) { m_threadId = threadId; } - inline xmrig::Variant variant() const { return (m_variant == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? xmrig::VARIANT_V1 : xmrig::VARIANT_NONE) : m_variant); } + inline bool isNicehash() const { return m_nicehash; } + inline bool isValid() const { return m_size > 0 && m_diff > 0; } + inline bool setId(const char *id) { return m_id.setId(id); } + inline const uint32_t *nonce() const { return reinterpret_cast(m_blob + 39); } + inline const uint8_t *blob() const { return m_blob; } + inline const xmrig::Id &clientId() const { return m_clientId; } + inline const xmrig::Id &id() const { return m_id; } + inline int poolId() const { return m_poolId; } + inline int threadId() const { return m_threadId; } + inline size_t size() const { return m_size; } + inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } + inline uint32_t diff() const { return static_cast(m_diff); } + inline uint64_t target() const { return m_target; } + inline void setClientId(const xmrig::Id &id) { m_clientId = id; } + inline void setPoolId(int poolId) { m_poolId = poolId; } + inline void setThreadId(int threadId) { m_threadId = threadId; } + inline xmrig::Variant variant() const { return (m_variant == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? xmrig::VARIANT_V1 : xmrig::VARIANT_NONE) : m_variant); } + +# ifdef XMRIG_PROXY_PROJECT + inline char *rawBlob() { return m_rawBlob; } + inline const char *rawTarget() const { return m_rawTarget; } +# endif static bool fromHex(const char* in, unsigned int len, unsigned char* out); static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast(blob + 39); } @@ -78,16 +82,21 @@ public: private: bool m_nicehash; - char m_coin[5]; - int m_algo; int m_poolId; int m_threadId; size_t m_size; uint64_t m_diff; uint64_t m_target; uint8_t m_blob[96]; // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk. + xmrig::Algo m_algo; + xmrig::Id m_clientId; xmrig::Id m_id; xmrig::Variant m_variant; + +# ifdef XMRIG_PROXY_PROJECT + char m_rawBlob[176]; + char m_rawTarget[24]; +# endif }; #endif /* __JOB_H__ */ diff --git a/src/net/JobResult.h b/src/net/JobResult.h index e3282584..68afc862 100644 --- a/src/net/JobResult.h +++ b/src/net/JobResult.h @@ -29,7 +29,7 @@ #include -#include "Job.h" +#include "common/net/Job.h" class JobResult diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 9b4a60c7..2efe4977 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -24,11 +24,11 @@ #include "common/crypto/keccak.h" #include "common/net/Client.h" +#include "common/net/Job.h" #include "common/net/strategies/FailoverStrategy.h" #include "common/Platform.h" #include "common/xmrig.h" #include "interfaces/IStrategyListener.h" -#include "net/Job.h" #include "net/strategies/DonateStrategy.h" diff --git a/src/workers/MultiWorker.h b/src/workers/MultiWorker.h index 2c231e8d..d89bbb33 100644 --- a/src/workers/MultiWorker.h +++ b/src/workers/MultiWorker.h @@ -26,8 +26,8 @@ #define __MULTIWORKER_H__ +#include "common/net/Job.h" #include "Mem.h" -#include "net/Job.h" #include "net/JobResult.h" #include "workers/Worker.h" diff --git a/src/workers/Workers.h b/src/workers/Workers.h index bbe9a760..ca01e698 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -30,7 +30,7 @@ #include #include -#include "net/Job.h" +#include "common/net/Job.h" #include "net/JobResult.h" #include "rapidjson/fwd.h" From 274992e50ddbd6dffc41d6f426047a7711daedda Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 21 Apr 2018 00:19:33 +0700 Subject: [PATCH 082/109] Basic cryptonight-ipbc definition. --- CMakeLists.txt | 5 +++++ src/common/net/Pool.cpp | 22 ++++++++++++++++------ src/common/net/Pool.h | 2 +- src/common/xmrig.h | 1 + src/crypto/CryptoNight_constants.h | 16 ++++++++++++++++ 5 files changed, 39 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 21d0726b..25c20409 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ project(xmrig) option(WITH_LIBCPUID "Use Libcpuid" ON) option(WITH_AEON "CryptoNight-Lite support" ON) option(WITH_SUMO "CryptoNight-Heavy support" ON) +option(WITH_IPBC "CryptoNight-IPBC support" ON) option(WITH_HTTPD "HTTP REST API" ON) option(BUILD_STATIC "Build static binary" OFF) @@ -205,6 +206,10 @@ if (NOT WITH_SUMO) add_definitions(/DXMRIG_NO_SUMO) endif() +if (NOT WITH_IPBC) + add_definitions(/DXMRIG_NO_IPBC) +endif() + if (WITH_HTTPD) find_package(MHD) diff --git a/src/common/net/Pool.cpp b/src/common/net/Pool.cpp index ddf31031..22f2a647 100644 --- a/src/common/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -45,9 +45,14 @@ static const char *algoNames[] = { nullptr, # endif # ifndef XMRIG_NO_SUMO - "cryptonight-heavy" + "cryptonight-heavy", # else - nullptr + nullptr, +# endif +# ifndef XMRIG_NO_IPBC + "cryptonight-ipbc", +# else + nullptr, # endif }; @@ -60,9 +65,14 @@ static const char *algoNamesShort[] = { nullptr, # endif # ifndef XMRIG_NO_SUMO - "cn-heavy" + "cn-heavy", # else - nullptr + nullptr, +# endif +# ifndef XMRIG_NO_IPBC + "cn-ipbc", +# else + nullptr, # endif }; @@ -119,9 +129,9 @@ Pool::Pool(const char *host, uint16_t port, const char *user, const char *passwo } -const char *Pool::algoName(xmrig::Algo algorithm) +const char *Pool::algoName(xmrig::Algo algorithm, bool shortName) { - return algoNames[algorithm]; + return (shortName ? algoNamesShort : algoNames)[algorithm]; } diff --git a/src/common/net/Pool.h b/src/common/net/Pool.h index ecce865a..62c80185 100644 --- a/src/common/net/Pool.h +++ b/src/common/net/Pool.h @@ -51,7 +51,7 @@ public: xmrig::Variant variant = xmrig::VARIANT_AUTO ); - static const char *algoName(xmrig::Algo algorithm); + static const char *algoName(xmrig::Algo algorithm, bool shortName = false); static xmrig::Algo algorithm(const char *algo); inline bool isNicehash() const { return m_nicehash; } diff --git a/src/common/xmrig.h b/src/common/xmrig.h index 0aa6b842..6bef4186 100644 --- a/src/common/xmrig.h +++ b/src/common/xmrig.h @@ -34,6 +34,7 @@ enum Algo { CRYPTONIGHT, /* CryptoNight (Monero) */ CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ CRYPTONIGHT_HEAVY, /* CryptoNight-Heavy (SUMO) */ + CRYPTONIGHT_IPBC /* CryptoNight-IPBC (IPBC) */ }; diff --git a/src/crypto/CryptoNight_constants.h b/src/crypto/CryptoNight_constants.h index 3c746d47..6004edbd 100644 --- a/src/crypto/CryptoNight_constants.h +++ b/src/crypto/CryptoNight_constants.h @@ -47,11 +47,16 @@ constexpr const size_t CRYPTONIGHT_HEAVY_MEMORY = 4 * 1024 * 1024; constexpr const uint32_t CRYPTONIGHT_HEAVY_MASK = 0x3FFFF0; constexpr const uint32_t CRYPTONIGHT_HEAVY_ITER = 0x40000; +constexpr const size_t CRYPTONIGHT_IPBC_MEMORY = 1 * 1024 * 1024; +constexpr const uint32_t CRYPTONIGHT_IPBC_MASK = 0xFFFF0; +constexpr const uint32_t CRYPTONIGHT_IPBC_ITER = 0x40000; + template inline constexpr size_t cn_select_memory() { return 0; } template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_MEMORY; } template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_LITE_MEMORY; } template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_HEAVY_MEMORY; } +template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_IPBC_MEMORY; } inline size_t cn_select_memory(Algo algorithm) { @@ -66,6 +71,9 @@ inline size_t cn_select_memory(Algo algorithm) case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_MEMORY; + case CRYPTONIGHT_IPBC: + return CRYPTONIGHT_IPBC_MEMORY; + default: break; } @@ -78,6 +86,7 @@ template inline constexpr uint32_t cn_select_mask() { retur template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_MASK; } template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_LITE_MASK; } template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_HEAVY_MASK; } +template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_IPBC_MASK; } inline uint32_t cn_select_mask(Algo algorithm) { @@ -92,6 +101,9 @@ inline uint32_t cn_select_mask(Algo algorithm) case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_MASK; + case CRYPTONIGHT_IPBC: + return CRYPTONIGHT_IPBC_MASK; + default: break; } @@ -104,6 +116,7 @@ template inline constexpr uint32_t cn_select_iter() { retur template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_LITE_ITER; } template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_HEAVY_ITER; } +template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_IPBC_ITER; } inline uint32_t cn_select_iter(Algo algorithm) { @@ -118,6 +131,9 @@ inline uint32_t cn_select_iter(Algo algorithm) case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_ITER; + case CRYPTONIGHT_IPBC: + return CRYPTONIGHT_IPBC_ITER; + default: break; } From f9dbd7bc78a93a659b3b4b749bff597c4ee0b015 Mon Sep 17 00:00:00 2001 From: Ange Date: Sat, 21 Apr 2018 00:36:58 +0200 Subject: [PATCH 083/109] valgrind showed some conditional jumps when printing the hashrate --- src/workers/Hashrate.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/workers/Hashrate.cpp b/src/workers/Hashrate.cpp index 7d2e6a4c..71aa9cc6 100644 --- a/src/workers/Hashrate.cpp +++ b/src/workers/Hashrate.cpp @@ -151,10 +151,10 @@ void Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp) void Hashrate::print() { - char num1[8]; - char num2[8]; - char num3[8]; - char num4[8]; + char num1[8] = { 0 }; + char num2[8] = { 0 }; + char num3[8] = { 0 }; + char num4[8] = { 0 }; LOG_INFO(m_controller->config()->isColors() ? "\x1B[01;37mspeed\x1B[0m 2.5s/60s/15m \x1B[01;36m%s \x1B[22;36m%s %s \x1B[01;36mH/s\x1B[0m max: \x1B[01;36m%s H/s" : "speed 2.5s/60s/15m %s %s %s H/s max: %s H/s", format(calc(ShortInterval), num1, sizeof(num1)), From 45e8a0525cac390bd086e136cecff60788d99ec0 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 21 Apr 2018 19:55:51 +0700 Subject: [PATCH 084/109] Prepare for per pool and per job algorithms. --- src/common/config/CommonConfig.cpp | 10 +---- src/common/config/CommonConfig.h | 1 - src/common/log/Log.h | 6 +++ src/common/net/Client.cpp | 2 +- src/common/net/Job.cpp | 6 +-- src/common/net/Job.h | 5 ++- src/common/net/Pool.cpp | 57 +++++++++++++++++------- src/common/net/Pool.h | 13 +++--- src/common/xmrig.h | 2 +- src/net/Network.cpp | 9 ++-- src/net/strategies/DonateStrategy.cpp | 19 ++++++-- src/net/strategies/DonateStrategy.h | 2 +- src/workers/CpuThread.cpp | 64 +++++++++++++-------------- src/workers/MultiWorker.cpp | 4 +- 14 files changed, 116 insertions(+), 84 deletions(-) diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp index 75906621..431eff1d 100644 --- a/src/common/config/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -141,7 +141,7 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) { switch (key) { case AlgorithmKey: /* --algo */ - setAlgo(arg); + m_algorithm = Pool::algorithm(arg); break; case UserpassKey: /* --userpass */ @@ -204,7 +204,7 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) case SyslogKey: /* --syslog */ case KeepAliveKey: /* --keepalive */ case NicehashKey: /* --nicehash */ - case ApiIPv6Key: /* --api-ipv6 */ + case ApiIPv6Key: /* --api-ipv6 */ return parseBoolean(key, true); case ColorKey: /* --no-color */ @@ -322,9 +322,3 @@ bool xmrig::CommonConfig::parseInt(int key, int arg) return true; } - - -void xmrig::CommonConfig::setAlgo(const char *algo) -{ - m_algorithm = Pool::algorithm(algo); -} diff --git a/src/common/config/CommonConfig.h b/src/common/config/CommonConfig.h index 015ba04e..ebeb41fe 100644 --- a/src/common/config/CommonConfig.h +++ b/src/common/config/CommonConfig.h @@ -96,7 +96,6 @@ protected: private: bool parseInt(int key, int arg); - void setAlgo(const char *algo); }; diff --git a/src/common/log/Log.h b/src/common/log/Log.h index f8c6a401..8434d779 100644 --- a/src/common/log/Log.h +++ b/src/common/log/Log.h @@ -80,6 +80,12 @@ private: }; +#define MAGENTA_BOLD(x) "\e[1;35m" x "\e[0m" +#define MAGENTA(x) "\e[0;35m" x "\e[0m" +#define WHITE_BOLD(x) "\e[1;37m" x "\e[0m" +#define WHITE(x) "\e[0;37m" x "\e[0m" + + #define LOG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__) #define LOG_WARN(x, ...) Log::i()->message(Log::WARNING, x, ##__VA_ARGS__) #define LOG_NOTICE(x, ...) Log::i()->message(Log::NOTICE, x, ##__VA_ARGS__) diff --git a/src/common/net/Client.cpp b/src/common/net/Client.cpp index a110b2ce..d7e88cbf 100644 --- a/src/common/net/Client.cpp +++ b/src/common/net/Client.cpp @@ -232,7 +232,7 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } - Job job(m_id, m_nicehash, m_pool.algo(), m_pool.variant(), m_rpcId); + Job job(m_id, m_nicehash, m_pool.algorithm(), m_pool.variant(), m_rpcId); if (!job.setId(params["job_id"].GetString())) { *code = 3; diff --git a/src/common/net/Job.cpp b/src/common/net/Job.cpp index c5f9902c..ec5279bf 100644 --- a/src/common/net/Job.cpp +++ b/src/common/net/Job.cpp @@ -65,7 +65,7 @@ Job::Job() : m_diff(0), m_target(0), m_blob(), - m_algo(xmrig::INVALID_ALGO), + m_algorithm(xmrig::INVALID_ALGO), m_variant(xmrig::VARIANT_AUTO) { } @@ -79,7 +79,7 @@ Job::Job(int poolId, bool nicehash, xmrig::Algo algo, xmrig::Variant variant, co m_diff(0), m_target(0), m_blob(), - m_algo(algo), + m_algorithm(algo), m_clientId(clientId), m_variant(variant) { @@ -170,7 +170,7 @@ void Job::setVariant(int variant) { switch (variant) { case xmrig::VARIANT_AUTO: - case xmrig::VARIANT_NONE: + case xmrig::VARIANT_V0: case xmrig::VARIANT_V1: m_variant = static_cast(variant); break; diff --git a/src/common/net/Job.h b/src/common/net/Job.h index 4eb7018e..0e2951f3 100644 --- a/src/common/net/Job.h +++ b/src/common/net/Job.h @@ -61,7 +61,8 @@ public: inline void setClientId(const xmrig::Id &id) { m_clientId = id; } inline void setPoolId(int poolId) { m_poolId = poolId; } inline void setThreadId(int threadId) { m_threadId = threadId; } - inline xmrig::Variant variant() const { return (m_variant == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? xmrig::VARIANT_V1 : xmrig::VARIANT_NONE) : m_variant); } + inline xmrig::Algo algorithm() const { return m_algorithm; } + inline xmrig::Variant variant() const { return (m_variant == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? xmrig::VARIANT_V1 : xmrig::VARIANT_V0) : m_variant); } # ifdef XMRIG_PROXY_PROJECT inline char *rawBlob() { return m_rawBlob; } @@ -88,7 +89,7 @@ private: uint64_t m_diff; uint64_t m_target; uint8_t m_blob[96]; // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk. - xmrig::Algo m_algo; + xmrig::Algo m_algorithm; xmrig::Id m_clientId; xmrig::Id m_id; xmrig::Variant m_variant; diff --git a/src/common/net/Pool.cpp b/src/common/net/Pool.cpp index 22f2a647..f1dd1352 100644 --- a/src/common/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -81,7 +81,7 @@ Pool::Pool() : m_nicehash(false), m_keepAlive(0), m_port(kDefaultPort), - m_algo(xmrig::CRYPTONIGHT), + m_algorithm(xmrig::INVALID_ALGO), m_variant(xmrig::VARIANT_AUTO) { } @@ -102,7 +102,7 @@ Pool::Pool(const char *url) : m_nicehash(false), m_keepAlive(0), m_port(kDefaultPort), - m_algo(xmrig::CRYPTONIGHT), + m_algorithm(xmrig::INVALID_ALGO), m_variant(xmrig::VARIANT_AUTO) { parse(url); @@ -113,11 +113,11 @@ Pool::Pool(const char *host, uint16_t port, const char *user, const char *passwo m_nicehash(nicehash), m_keepAlive(keepAlive), m_port(port), - m_algo(xmrig::CRYPTONIGHT), + m_algorithm(xmrig::INVALID_ALGO), m_host(host), m_password(password), m_user(user), - m_variant(variant) + m_variant(variant) { const size_t size = m_host.size() + 8; assert(size > 8); @@ -131,6 +131,10 @@ Pool::Pool(const char *host, uint16_t port, const char *user, const char *passwo const char *Pool::algoName(xmrig::Algo algorithm, bool shortName) { + if (algorithm == xmrig::INVALID_ALGO) { + return "invalid"; + } + return (shortName ? algoNamesShort : algoNames)[algorithm]; } @@ -160,6 +164,20 @@ xmrig::Algo Pool::algorithm(const char *algo) } +bool Pool::isEqual(const Pool &other) const +{ + return (m_nicehash == other.m_nicehash + && m_keepAlive == other.m_keepAlive + && m_port == other.m_port + && m_algorithm == other.m_algorithm + && m_host == other.m_host + && m_password == other.m_password + && m_url == other.m_url + && m_user == other.m_user + && m_variant == other.m_variant); +} + + bool Pool::parse(const char *url) { assert(url != nullptr); @@ -218,13 +236,15 @@ bool Pool::setUserpass(const char *userpass) } -void Pool::adjust(xmrig::Algo algo) +void Pool::adjust(xmrig::Algo algorithm) { if (!isValid()) { return; } - m_algo = algo; + if (m_algorithm == xmrig::INVALID_ALGO) { + m_algorithm = algorithm; + } if (strstr(m_host.data(), ".nicehash.com")) { m_keepAlive = false; @@ -241,7 +261,7 @@ void Pool::setVariant(int variant) { switch (variant) { case xmrig::VARIANT_AUTO: - case xmrig::VARIANT_NONE: + case xmrig::VARIANT_V0: case xmrig::VARIANT_V1: m_variant = static_cast(variant); break; @@ -253,17 +273,20 @@ void Pool::setVariant(int variant) } -bool Pool::isEqual(const Pool &other) const +xmrig::Variant Pool::variant() const { - return (m_nicehash == other.m_nicehash - && m_keepAlive == other.m_keepAlive - && m_port == other.m_port - && m_algo == other.m_algo - && m_host == other.m_host - && m_password == other.m_password - && m_url == other.m_url - && m_user == other.m_user - && m_variant == other.m_variant); + switch (m_algorithm) { + case xmrig::CRYPTONIGHT_HEAVY: + return xmrig::VARIANT_V0; + + case xmrig::CRYPTONIGHT_IPBC: + return xmrig::VARIANT_V1; + + default: + break; + } + + return m_variant; } diff --git a/src/common/net/Pool.h b/src/common/net/Pool.h index 62c80185..a7e1ca8b 100644 --- a/src/common/net/Pool.h +++ b/src/common/net/Pool.h @@ -62,22 +62,23 @@ public: inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; } inline int keepAlive() const { return m_keepAlive; } inline uint16_t port() const { return m_port; } + inline void setAlgo(const char *algo) { m_algorithm = algorithm(algo); } + inline void setAlgo(xmrig::Algo algorithm) { m_algorithm = algorithm; } inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } inline void setPassword(const char *password) { m_password = password; } inline void setUser(const char *user) { m_user = user; } - inline xmrig::Algo algo() const { return m_algo; } - inline xmrig::Variant variant() const { return m_variant; } + inline xmrig::Algo algorithm() const { return m_algorithm; } inline bool operator!=(const Pool &other) const { return !isEqual(other); } inline bool operator==(const Pool &other) const { return isEqual(other); } + bool isEqual(const Pool &other) const; bool parse(const char *url); bool setUserpass(const char *userpass); - void adjust(xmrig::Algo algo); + void adjust(xmrig::Algo algorithm); void setVariant(int variant); - - bool isEqual(const Pool &other) const; + xmrig::Variant variant() const; private: bool parseIPv6(const char *addr); @@ -85,7 +86,7 @@ private: bool m_nicehash; int m_keepAlive; uint16_t m_port; - xmrig::Algo m_algo; + xmrig::Algo m_algorithm; xmrig::c_str m_host; xmrig::c_str m_password; xmrig::c_str m_url; diff --git a/src/common/xmrig.h b/src/common/xmrig.h index 6bef4186..2de1a798 100644 --- a/src/common/xmrig.h +++ b/src/common/xmrig.h @@ -60,7 +60,7 @@ enum AlgoVariant { enum Variant { VARIANT_AUTO = -1, // Autodetect - VARIANT_NONE = 0, // Original CryptoNight + VARIANT_V0 = 0, // Original CryptoNight or CryptoNight-Heavy VARIANT_V1 = 1 // Monero v7 PoW }; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 5f6d73ee..4101245e 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -166,12 +166,9 @@ bool Network::isColors() const void Network::setJob(Client *client, const Job &job, bool donate) { - if (isColors()) { - LOG_INFO("\x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d", client->host(), client->port(), job.diff()); - } - else { - LOG_INFO("new job from %s:%d diff %d", client->host(), client->port(), job.diff()); - } + LOG_INFO(isColors() ? MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%d") " algo " WHITE_BOLD("%s/%d") + : "new job from %s:%d diff %d algo %s/%d", + client->host(), client->port(), job.diff(), Pool::algoName(job.algorithm(), true), static_cast(job.variant())); m_state.diff = job.diff(); Workers::setJob(job, donate); diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 2efe4977..ad8e88c0 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -26,6 +26,7 @@ #include "common/net/Client.h" #include "common/net/Job.h" #include "common/net/strategies/FailoverStrategy.h" +#include "common/net/strategies/SinglePoolStrategy.h" #include "common/Platform.h" #include "common/xmrig.h" #include "interfaces/IStrategyListener.h" @@ -41,7 +42,7 @@ static inline float randomf(float min, float max) { } -DonateStrategy::DonateStrategy(int level, const char *user, int algo, IStrategyListener *listener) : +DonateStrategy::DonateStrategy(int level, const char *user, xmrig::Algo algo, IStrategyListener *listener) : m_active(false), m_donateTime(level * 60 * 1000), m_idleTime((100 - level) * 60 * 1000), @@ -61,14 +62,24 @@ DonateStrategy::DonateStrategy(int level, const char *user, int algo, IStrategyL } else if (algo == xmrig::CRYPTONIGHT_HEAVY) { m_pools.push_back(Pool(kDonatePool1, 8888, userId, nullptr, false, true)); - m_pools.push_back(Pool(kDonatePool1, 8889, userId, nullptr, false, true)); + } + else if (algo == xmrig::CRYPTONIGHT_IPBC) { + m_pools.push_back(Pool(kDonatePool1, 13333, userId, nullptr, false, true)); } else { m_pools.push_back(Pool(kDonatePool1, 5555, userId, nullptr, false, true)); - m_pools.push_back(Pool(kDonatePool1, 7777, userId, nullptr, false, true)); } - m_strategy = new FailoverStrategy(m_pools, 1, 1, this, true); + for (Pool &pool : m_pools) { + pool.setAlgo(algo); + } + + if (m_pools.size() > 1) { + m_strategy = new FailoverStrategy(m_pools, 1, 2, this, true); + } + else { + m_strategy = new SinglePoolStrategy(m_pools.front(), 1, this, true); + } m_timer.data = this; uv_timer_init(uv_default_loop(), &m_timer); diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index edb15c8f..66c0375c 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -43,7 +43,7 @@ class Url; class DonateStrategy : public IStrategy, public IStrategyListener { public: - DonateStrategy(int level, const char *user, int algo, IStrategyListener *listener); + DonateStrategy(int level, const char *user, xmrig::Algo algo, IStrategyListener *listener); ~DonateStrategy(); public: diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index be24b2d5..5c0e8c0b 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -62,19 +62,19 @@ bool xmrig::CpuThread::isSoftAES(AlgoVariant av) xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant) { - assert(variant == VARIANT_NONE || variant == VARIANT_V1); + assert(variant == VARIANT_V0 || variant == VARIANT_V1); static const cn_hash_fun func_table[50] = { - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, cryptonight_single_hash, cryptonight_double_hash, @@ -88,16 +88,16 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a cryptonight_penta_hash, # ifndef XMRIG_NO_AEON - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, cryptonight_single_hash, cryptonight_double_hash, @@ -115,16 +115,16 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a # endif # ifndef XMRIG_NO_SUMO - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, # else nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, # endif @@ -132,7 +132,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a # ifndef XMRIG_NO_SUMO if (algorithm == CRYPTONIGHT_HEAVY) { - variant = VARIANT_NONE; + variant = VARIANT_V0; } # endif diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index 09dd568f..33f5864d 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -50,11 +50,11 @@ MultiWorker::~MultiWorker() template bool MultiWorker::selfTest() { - if (m_thread->fn(xmrig::VARIANT_NONE) == nullptr) { + if (m_thread->fn(xmrig::VARIANT_V0) == nullptr) { return false; } - m_thread->fn(xmrig::VARIANT_NONE)(test_input, 76, m_hash, m_ctx); + m_thread->fn(xmrig::VARIANT_V0)(test_input, 76, m_hash, m_ctx); if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_hash, test_output_v0, sizeof m_hash) == 0) { m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); From 259a1774caaced0ca011bb160691f0d485ff1508 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 21 Apr 2018 21:41:39 +0700 Subject: [PATCH 085/109] Fix Linux build. --- src/App_unix.cpp | 2 +- src/Mem_unix.cpp | 2 +- src/common/net/Job.h | 1 + src/core/Controller.cpp | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/App_unix.cpp b/src/App_unix.cpp index f739e42e..45f73d2d 100644 --- a/src/App_unix.cpp +++ b/src/App_unix.cpp @@ -29,9 +29,9 @@ #include "App.h" +#include "common/log/Log.h" #include "core/Config.h" #include "core/Controller.h" -#include "log/Log.h" void App::background() diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index 229a0d46..c1aa0fb1 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -27,10 +27,10 @@ #include +#include "common/log/Log.h" #include "common/utils/mm_malloc.h" #include "common/xmrig.h" #include "crypto/CryptoNight.h" -#include "log/Log.h" #include "Mem.h" diff --git a/src/common/net/Job.h b/src/common/net/Job.h index 0e2951f3..c235072e 100644 --- a/src/common/net/Job.h +++ b/src/common/net/Job.h @@ -58,6 +58,7 @@ public: inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } inline uint32_t diff() const { return static_cast(m_diff); } inline uint64_t target() const { return m_target; } + inline void reset() { m_size = 0; m_diff = 0; } inline void setClientId(const xmrig::Id &id) { m_clientId = id; } inline void setPoolId(int poolId) { m_poolId = poolId; } inline void setThreadId(int threadId) { m_threadId = threadId; } diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index d0babe47..b1e03f32 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -38,7 +38,7 @@ #ifdef HAVE_SYSLOG_H -# include "log/SysLog.h" +# include "common/log/SysLog.h" #endif From 6d40f2dd1a09a949f145f1ebded9d1c983c248a6 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 23 Apr 2018 00:59:58 +0700 Subject: [PATCH 086/109] Sync changes with proxy. --- src/common/Platform_unix.cpp | 4 ++-- src/common/api/Httpd.cpp | 7 +++++++ src/common/net/Pool.cpp | 20 ++++++++++++++++++++ src/common/net/Pool.h | 4 ++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/common/Platform_unix.cpp b/src/common/Platform_unix.cpp index 624594e9..63cd1c8b 100644 --- a/src/common/Platform_unix.cpp +++ b/src/common/Platform_unix.cpp @@ -4,8 +4,8 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/common/api/Httpd.cpp b/src/common/api/Httpd.cpp index 0cab01bf..eb6a4ba6 100644 --- a/src/common/api/Httpd.cpp +++ b/src/common/api/Httpd.cpp @@ -81,7 +81,12 @@ bool Httpd::start() return false; } +# if MHD_VERSION >= 0x00093900 uv_timer_start(&m_timer, Httpd::onTimer, kIdleInterval, kIdleInterval); +# else + uv_timer_start(&m_timer, Httpd::onTimer, kActiveInterval, kActiveInterval); +# endif + return true; } @@ -107,6 +112,7 @@ void Httpd::run() { MHD_run(m_daemon); +# if MHD_VERSION >= 0x00093900 const MHD_DaemonInfo *info = MHD_get_daemon_info(m_daemon, MHD_DAEMON_INFO_CURRENT_CONNECTIONS); if (m_idle && info->num_connections) { uv_timer_set_repeat(&m_timer, kActiveInterval); @@ -116,6 +122,7 @@ void Httpd::run() uv_timer_set_repeat(&m_timer, kIdleInterval); m_idle = true; } +# endif } diff --git a/src/common/net/Pool.cpp b/src/common/net/Pool.cpp index f1dd1352..3be491fb 100644 --- a/src/common/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -31,6 +31,11 @@ #include "common/net/Pool.h" +#ifdef APP_DEBUG +# include "common/log/Log.h" +#endif + + #ifdef _MSC_VER # define strncasecmp _strnicmp # define strcasecmp _stricmp @@ -290,6 +295,21 @@ xmrig::Variant Pool::variant() const } +#ifdef APP_DEBUG +void Pool::print() const +{ + LOG_NOTICE("url: %s", m_url.data()); + LOG_DEBUG ("host: %s", m_host.data()); + LOG_DEBUG ("port: %d", static_cast(m_port)); + LOG_DEBUG ("user: %s", m_user.data()); + LOG_DEBUG ("pass: %s", m_password.data()); + LOG_DEBUG ("algo: %s/%d", algoName(m_algorithm), static_cast(variant())); + LOG_DEBUG ("nicehash: %d", static_cast(m_nicehash)); + LOG_DEBUG ("keepAlive: %d", m_keepAlive); +} +#endif + + bool Pool::parseIPv6(const char *addr) { const char *end = strchr(addr, ']'); diff --git a/src/common/net/Pool.h b/src/common/net/Pool.h index a7e1ca8b..df8578bc 100644 --- a/src/common/net/Pool.h +++ b/src/common/net/Pool.h @@ -80,6 +80,10 @@ public: void setVariant(int variant); xmrig::Variant variant() const; +# ifdef APP_DEBUG + void print() const; +# endif + private: bool parseIPv6(const char *addr); From b9fec2fcc4dff2866c3ecb0d596b27015da8ef5d Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 23 Apr 2018 13:20:43 +0700 Subject: [PATCH 087/109] Added support for "rig id" protocol extension. --- src/Summary.cpp | 4 ++-- src/common/config/CommonConfig.cpp | 4 ++++ src/common/log/Log.h | 4 ++++ src/common/net/Client.cpp | 4 ++++ src/common/net/Pool.cpp | 7 +++++++ src/common/net/Pool.h | 3 +++ src/core/Config.cpp | 1 + src/core/ConfigLoader_platform.h | 3 +++ src/interfaces/IConfig.h | 13 +++++++------ src/workers/Workers.cpp | 6 +++--- 10 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/Summary.cpp b/src/Summary.cpp index 38ceac8e..a52b7945 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -132,8 +132,8 @@ static void print_pools(xmrig::Config *config) } # ifdef APP_DEBUG - for (size_t i = 0; i < pools.size(); ++i) { - Log::i()->text("%s:%d, user: %s, pass: %s, ka: %d, nicehash: %d", pools[i].host(), pools[i].port(), pools[i].user(), pools[i].password(), pools[i].keepAlive(), pools[i].isNicehash()); + for (const Pool &pool : pools) { + pool.print(); } # endif } diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp index 431eff1d..baf5a729 100644 --- a/src/common/config/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -177,6 +177,10 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) m_pools.back().setPassword(arg); break; + case RigIdKey: /* --rig-id */ + m_pools.back().setRigId(arg); + break; + case LogFileKey: /* --log-file */ m_logFile = arg; break; diff --git a/src/common/log/Log.h b/src/common/log/Log.h index 8434d779..0b333272 100644 --- a/src/common/log/Log.h +++ b/src/common/log/Log.h @@ -80,8 +80,12 @@ private: }; +#define GREEN_BOLD(x) "\e[1;32m" x "\e[0m" +#define GREEN(x) "\e[0;32m" x "\e[0m" #define MAGENTA_BOLD(x) "\e[1;35m" x "\e[0m" #define MAGENTA(x) "\e[0;35m" x "\e[0m" +#define CYAN_BOLD(x) "\e[1;36m" x "\e[0m" +#define CYAN(x) "\e[0;36m" x "\e[0m" #define WHITE_BOLD(x) "\e[1;37m" x "\e[0m" #define WHITE(x) "\e[0;37m" x "\e[0m" diff --git a/src/common/net/Client.cpp b/src/common/net/Client.cpp index d7e88cbf..de56b315 100644 --- a/src/common/net/Client.cpp +++ b/src/common/net/Client.cpp @@ -397,6 +397,10 @@ void Client::login() params.AddMember("pass", rapidjson::StringRef(m_pool.password()), allocator); params.AddMember("agent", rapidjson::StringRef(m_agent), allocator); + if (m_pool.rigId()) { + params.AddMember("rigid", rapidjson::StringRef(m_pool.rigId()), allocator); + } + doc.AddMember("params", params, allocator); rapidjson::StringBuffer buffer(0, 512); diff --git a/src/common/net/Pool.cpp b/src/common/net/Pool.cpp index 3be491fb..4675876a 100644 --- a/src/common/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -177,6 +177,7 @@ bool Pool::isEqual(const Pool &other) const && m_algorithm == other.m_algorithm && m_host == other.m_host && m_password == other.m_password + && m_rigId == other.m_rigId && m_url == other.m_url && m_user == other.m_user && m_variant == other.m_variant); @@ -254,9 +255,14 @@ void Pool::adjust(xmrig::Algo algorithm) if (strstr(m_host.data(), ".nicehash.com")) { m_keepAlive = false; m_nicehash = true; + + if (strstr(m_host.data(), "cryptonightv7.")) { + m_variant = xmrig::VARIANT_V1; + } } if (strstr(m_host.data(), ".minergate.com")) { + m_variant = xmrig::VARIANT_V1; m_keepAlive = false; } } @@ -303,6 +309,7 @@ void Pool::print() const LOG_DEBUG ("port: %d", static_cast(m_port)); LOG_DEBUG ("user: %s", m_user.data()); LOG_DEBUG ("pass: %s", m_password.data()); + LOG_DEBUG ("rig_id %s", m_rigId.data()); LOG_DEBUG ("algo: %s/%d", algoName(m_algorithm), static_cast(variant())); LOG_DEBUG ("nicehash: %d", static_cast(m_nicehash)); LOG_DEBUG ("keepAlive: %d", m_keepAlive); diff --git a/src/common/net/Pool.h b/src/common/net/Pool.h index df8578bc..b1b93507 100644 --- a/src/common/net/Pool.h +++ b/src/common/net/Pool.h @@ -58,6 +58,7 @@ public: inline bool isValid() const { return !m_host.isNull() && m_port > 0; } inline const char *host() const { return m_host.data(); } inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; } + inline const char *rigId() const { return m_rigId.data(); } inline const char *url() const { return m_url.data(); } inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; } inline int keepAlive() const { return m_keepAlive; } @@ -67,6 +68,7 @@ public: inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } inline void setPassword(const char *password) { m_password = password; } + inline void setRigId(const char *rigId) { m_rigId = rigId; } inline void setUser(const char *user) { m_user = user; } inline xmrig::Algo algorithm() const { return m_algorithm; } @@ -93,6 +95,7 @@ private: xmrig::Algo m_algorithm; xmrig::c_str m_host; xmrig::c_str m_password; + xmrig::c_str m_rigId; xmrig::c_str m_url; xmrig::c_str m_user; xmrig::Variant m_variant; diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 33cd01e8..43abbbbd 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -108,6 +108,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const obj.AddMember("url", StringRef(pool.url()), allocator); obj.AddMember("user", StringRef(pool.user()), allocator); obj.AddMember("pass", StringRef(pool.password()), allocator); + obj.AddMember("rig-id", pool.rigId() ? Value(StringRef(pool.rigId())).Move() : Value(kNullType).Move(), allocator); if (pool.keepAlive() == 0 || pool.keepAlive() == Pool::kKeepAliveTimeout) { obj.AddMember("keepalive", pool.keepAlive() > 0, allocator); diff --git a/src/core/ConfigLoader_platform.h b/src/core/ConfigLoader_platform.h index d02a9e8f..9704d5e3 100644 --- a/src/core/ConfigLoader_platform.h +++ b/src/core/ConfigLoader_platform.h @@ -58,6 +58,7 @@ Options:\n\ -O, --userpass=U:P username:password pair for mining server\n\ -u, --user=USERNAME username for mining server\n\ -p, --pass=PASSWORD password for mining server\n\ + --rig-id=ID rig identifier for pool-side statistics (needs pool support)\n\ -t, --threads=N number of miner threads\n\ -v, --av=N algorithm variation, 0 auto select\n\ -k, --keepalive send keepalived for prevent timeout (need pool support)\n\ @@ -128,6 +129,7 @@ static struct option const options[] = { { "user", 1, nullptr, xmrig::IConfig::UserKey }, { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, { "userpass", 1, nullptr, xmrig::IConfig::UserpassKey }, + { "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey }, { "version", 0, nullptr, xmrig::IConfig::VersionKey }, { 0, 0, 0, 0 } }; @@ -165,6 +167,7 @@ static struct option const pool_options[] = { { "nicehash", 0, nullptr, xmrig::IConfig::NicehashKey }, { "keepalive", 2, nullptr, xmrig::IConfig::KeepAliveKey }, { "variant", 1, nullptr, xmrig::IConfig::VariantKey }, + { "rig-id", 1, nullptr, xmrig::IConfig::RigIdKey }, { 0, 0, 0, 0 } }; diff --git a/src/interfaces/IConfig.h b/src/interfaces/IConfig.h index f7433d7f..cf4f0d23 100644 --- a/src/interfaces/IConfig.h +++ b/src/interfaces/IConfig.h @@ -36,30 +36,31 @@ public: enum Keys { // common AlgorithmKey = 'a', - ApiPort = 4000, ApiAccessTokenKey = 4001, - ApiWorkerIdKey = 4002, ApiIPv6Key = 4003, + ApiPort = 4000, ApiRestrictedKey = 4004, + ApiWorkerIdKey = 4002, BackgroundKey = 'B', + ColorKey = 1002, ConfigKey = 'c', DonateLevelKey = 1003, HelpKey = 'h', KeepAliveKey = 'k', LogFileKey = 'l', - ColorKey = 1002, - WatchKey = 1105, PasswordKey = 'p', RetriesKey = 'r', RetryPauseKey = 'R', + RigIdKey = 1012, SyslogKey = 'S', UrlKey = 'o', - UserKey = 'u', UserAgentKey = 1008, + UserKey = 'u', UserpassKey = 'O', + VariantKey = 1010, VerboseKey = 1100, VersionKey = 'V', - VariantKey = 1010, + WatchKey = 1105, // xmrig common CPUPriorityKey = 1021, diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 1d2c1739..67b2973d 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -133,7 +133,7 @@ void Workers::start(xmrig::Controller *controller) { const std::vector &threads = controller->config()->threads(); m_status.algo = controller->config()->algorithm(); - m_status.colors = controller->config()->isHugePages(); + m_status.colors = controller->config()->isColors(); m_status.threads = threads.size(); for (const xmrig::IThread *thread : threads) { @@ -301,9 +301,9 @@ void Workers::start(IWorker *worker) const size_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo) / 1048576; if (m_status.colors) { - LOG_INFO("\x1B[01;32mREADY (CPU)\x1B[0m threads \x1B[01;36m%zu(%zu)\x1B[0m huge pages %s%zu/%zu %1.0f%%\x1B[0m memory \x1B[01;36m%zu.0 MB", + LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\e[0m memory " CYAN_BOLD("%zu.0 MB") "", m_status.threads, m_status.ways, - (m_status.hugePages == m_status.pages ? "\x1B[01;32m" : (m_status.hugePages == 0 ? "\x1B[01;31m" : "\x1B[01;33m")), + (m_status.hugePages == m_status.pages ? "\e[1;32m" : (m_status.hugePages == 0 ? "\e[1;31m" : "\e[1;33m")), m_status.hugePages, m_status.pages, percent, memory); } else { From ca149d2eed8f3d278bd0f322b191824f3c5b7796 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 25 Apr 2018 14:48:32 +0700 Subject: [PATCH 088/109] Sync changes with proxy. --- CMakeLists.txt | 2 + src/Summary.cpp | 4 +- src/api/ApiRouter.cpp | 2 +- src/common/config/CommonConfig.cpp | 18 ++- src/common/config/CommonConfig.h | 5 +- src/common/crypto/Algorithm.cpp | 158 +++++++++++++++++++++++ src/common/crypto/Algorithm.h | 76 +++++++++++ src/common/net/Client.cpp | 4 +- src/common/net/Job.cpp | 28 +--- src/common/net/Job.h | 51 ++++---- src/common/net/Pool.cpp | 178 ++++++++------------------ src/common/net/Pool.h | 48 +++---- src/common/net/Storage.h | 3 - src/common/utils/c_str.h | 2 +- src/common/xmrig.h | 9 +- src/core/Config.cpp | 29 +---- src/crypto/CryptoNight_constants.h | 19 +-- src/net/Network.cpp | 8 +- src/net/strategies/DonateStrategy.cpp | 5 +- src/workers/CpuThread.cpp | 105 ++++++++------- src/workers/MultiWorker.cpp | 8 +- src/workers/Workers.cpp | 2 +- 22 files changed, 436 insertions(+), 328 deletions(-) create mode 100644 src/common/crypto/Algorithm.cpp create mode 100644 src/common/crypto/Algorithm.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 25c20409..b26b1d93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ set(HEADERS src/common/config/ConfigLoader.h src/common/config/ConfigWatcher.h src/common/Console.h + src/common/crypto/Algorithm.h src/common/crypto/keccak.h src/common/log/ConsoleLog.h src/common/log/FileLog.h @@ -93,6 +94,7 @@ set(SOURCES src/common/config/ConfigLoader.cpp src/common/config/ConfigWatcher.cpp src/common/Console.cpp + src/common/crypto/Algorithm.cpp src/common/crypto/keccak.cpp src/common/log/ConsoleLog.cpp src/common/log/FileLog.cpp diff --git a/src/Summary.cpp b/src/Summary.cpp index a52b7945..e960dd8d 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -104,7 +104,7 @@ static void print_threads(xmrig::Config *config) Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, av=%d, %sdonate=%d%%%s" : " * THREADS: %d, %s, av=%d, %sdonate=%d%%%s", config->threadsCount(), - config->algoName(), + config->algorithm().name(), config->algoVariant(), config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", config->donateLevel(), @@ -113,7 +113,7 @@ static void print_threads(xmrig::Config *config) else { Log::i()->text(config->isColors() ? "\x1B[01;32m * \x1B[01;37mTHREADS: \x1B[01;36m%d\x1B[01;37m, %s, %sdonate=%d%%" : " * THREADS: %d, %s, %sdonate=%d%%", config->threadsCount(), - config->algoName(), + config->algorithm().name(), config->isColors() && config->donateLevel() == 0 ? "\x1B[01;31m" : "", config->donateLevel()); } diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index a9e32b18..07e425f1 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -244,7 +244,7 @@ void ApiRouter::getMiner(rapidjson::Document &doc) const doc.AddMember("kind", APP_KIND, allocator); doc.AddMember("ua", rapidjson::StringRef(Platform::userAgent()), allocator); doc.AddMember("cpu", cpu, allocator); - doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algoName()), allocator); + doc.AddMember("algo", rapidjson::StringRef(m_controller->config()->algorithm().name()), allocator); doc.AddMember("hugepages", Workers::hugePages() > 0, allocator); doc.AddMember("donate_level", m_controller->config()->donateLevel(), allocator); } diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp index baf5a729..5bad4af5 100644 --- a/src/common/config/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -38,7 +38,6 @@ xmrig::CommonConfig::CommonConfig() : - m_algorithm(CRYPTONIGHT), m_adjusted(false), m_apiIPv6(false), m_apiRestricted(true), @@ -80,8 +79,12 @@ bool xmrig::CommonConfig::adjust() m_adjusted = true; + if (!m_algorithm.isValid()) { + m_algorithm.setAlgo(CRYPTONIGHT); + } + for (Pool &pool : m_pools) { - pool.adjust(algorithm()); + pool.adjust(m_algorithm.algo()); } return true; @@ -90,7 +93,7 @@ bool xmrig::CommonConfig::adjust() bool xmrig::CommonConfig::isValid() const { - return m_pools[0].isValid() && m_algorithm != INVALID_ALGO; + return m_pools[0].isValid() && m_algorithm.isValid(); } @@ -141,7 +144,7 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) { switch (key) { case AlgorithmKey: /* --algo */ - m_algorithm = Pool::algorithm(arg); + m_algorithm.parseAlgorithm(arg); break; case UserpassKey: /* --userpass */ @@ -181,6 +184,10 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) m_pools.back().setRigId(arg); break; + case VariantKey: /* --variant */ + m_pools.back().algorithm().parseVariant(arg); + break; + case LogFileKey: /* --log-file */ m_logFile = arg; break; @@ -199,7 +206,6 @@ bool xmrig::CommonConfig::parseString(int key, const char *arg) case RetriesKey: /* --retries */ case RetryPauseKey: /* --retry-pause */ - case VariantKey: /* --variant */ case ApiPort: /* --api-port */ case PrintTimeKey: /* --cpu-priority */ return parseUint64(key, strtol(arg, nullptr, 10)); @@ -299,7 +305,7 @@ bool xmrig::CommonConfig::parseInt(int key, int arg) break; case VariantKey: /* --variant */ - m_pools.back().setVariant(arg); + m_pools.back().algorithm().parseVariant(arg); break; case DonateLevelKey: /* --donate-level */ diff --git a/src/common/config/CommonConfig.h b/src/common/config/CommonConfig.h index ebeb41fe..b04de6eb 100644 --- a/src/common/config/CommonConfig.h +++ b/src/common/config/CommonConfig.h @@ -43,13 +43,12 @@ public: CommonConfig(); ~CommonConfig(); - inline Algo algorithm() const { return m_algorithm; } inline bool isApiIPv6() const { return m_apiIPv6; } inline bool isApiRestricted() const { return m_apiRestricted; } inline bool isBackground() const { return m_background; } inline bool isColors() const { return m_colors; } inline bool isSyslog() const { return m_syslog; } - inline const char *algoName() const { return Pool::algoName(m_algorithm); } + inline const Algorithm &algorithm() const { return m_algorithm; } inline const char *apiToken() const { return m_apiToken.data(); } inline const char *apiWorkerId() const { return m_apiWorkerId.data(); } inline const char *logFile() const { return m_logFile.data(); } @@ -74,7 +73,7 @@ protected: bool save() override; void setFileName(const char *fileName) override; - Algo m_algorithm; + Algorithm m_algorithm; bool m_adjusted; bool m_apiIPv6; bool m_apiRestricted; diff --git a/src/common/crypto/Algorithm.cpp b/src/common/crypto/Algorithm.cpp new file mode 100644 index 00000000..2e13fffd --- /dev/null +++ b/src/common/crypto/Algorithm.cpp @@ -0,0 +1,158 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include +#include +#include + + +#include "common/crypto/Algorithm.h" + + +#ifdef _MSC_VER +# define strncasecmp _strnicmp +# define strcasecmp _stricmp +#endif + + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + + +struct AlgoData +{ + const char *name; + const char *shortName; + xmrig::Algo algo; + xmrig::Variant variant; +}; + + +static AlgoData const algorithms[] = { + { "cryptonight", "cn", xmrig::CRYPTONIGHT, xmrig::VARIANT_AUTO }, + { "cryptonight/0", "cn/0", xmrig::CRYPTONIGHT, xmrig::VARIANT_0 }, + { "cryptonight/1", "cn/1", xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, + { "cryptonight/xtl", "cn/xtl", xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL }, + +# ifndef XMRIG_NO_AEON + { "cryptonight-lite", "cn-lite", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO }, + { "cryptonight-lite/0", "cn-lite/0", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 }, + { "cryptonight-lite/1", "cn-lite/1", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, + { "cryptonight-lite/ipbc", "cn-lite/ipbc", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_IBPC }, +# endif + +# ifndef XMRIG_NO_SUMO + { "cryptonight-heavy", "cn-heavy", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_0 }, +# endif +}; + + +static const char *variants[] = { + "0", + "1", + "ipbc", + "xtl" +}; + + +const char *xmrig::Algorithm::variantName() const +{ + if (m_variant == VARIANT_AUTO) { + return "auto"; + } + + return variants[m_variant]; +} + + +void xmrig::Algorithm::parseAlgorithm(const char *algo) +{ + m_algo = INVALID_ALGO; + m_variant = VARIANT_AUTO; + + for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) { + if ((strcasecmp(algo, algorithms[i].name) == 0) || (strcasecmp(algo, algorithms[i].shortName) == 0)) { + m_algo = algorithms[i].algo; + m_variant = algorithms[i].variant; + break; + } + } + + if (m_algo == INVALID_ALGO) { + assert(false); + } +} + + +void xmrig::Algorithm::parseVariant(const char *variant) +{ + if (m_algo == CRYPTONIGHT_HEAVY) { + return; + } + + m_variant = VARIANT_AUTO; + + for (size_t i = 0; i < ARRAY_SIZE(variants); i++) { + if (strcasecmp(variant, variants[i]) == 0) { + m_variant = static_cast(i); + break; + } + } +} + + +void xmrig::Algorithm::parseVariant(int variant) +{ + if (variant >= VARIANT_AUTO && variant <= VARIANT_XTL) { + m_variant = static_cast(variant); + } + else { + assert(false); + } +} + + +void xmrig::Algorithm::setAlgo(Algo algo) +{ + m_algo = algo; + + if (m_algo == CRYPTONIGHT_HEAVY) { + m_variant = VARIANT_0; + } +} + + +const char *xmrig::Algorithm::name(bool shortName) const +{ + for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) { + if (algorithms[i].algo == m_algo && algorithms[i].variant == m_variant) { + return shortName ? algorithms[i].shortName : algorithms[i].name; + } + } + + return "invalid"; +} diff --git a/src/common/crypto/Algorithm.h b/src/common/crypto/Algorithm.h new file mode 100644 index 00000000..bbabb40f --- /dev/null +++ b/src/common/crypto/Algorithm.h @@ -0,0 +1,76 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2016-2018 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __ALGORITHM_H__ +#define __ALGORITHM_H__ + + +#include "common/xmrig.h" + + +namespace xmrig { + + +class Algorithm +{ +public: + inline Algorithm() : + m_algo(INVALID_ALGO), + m_variant(VARIANT_AUTO) + {} + + inline Algorithm(Algo algo, Variant variant) : + m_variant(variant) + { + setAlgo(algo); + } + + bool isEqual(const Algorithm &other) const { return m_algo == other.m_algo && m_variant == other.m_variant; } + inline Algo algo() const { return m_algo; } + inline bool isValid() const { return m_algo != INVALID_ALGO; } + inline const char *name() const { return name(false); } + inline const char *shortName() const { return name(true); } + inline Variant variant() const { return m_variant; } + inline void setVariant(Variant variant) { m_variant = variant; } + + inline bool operator!=(const Algorithm &other) const { return !isEqual(other); } + inline bool operator==(const Algorithm &other) const { return isEqual(other); } + + const char *variantName() const; + void parseAlgorithm(const char *algo); + void parseVariant(const char *variant); + void parseVariant(int variant); + void setAlgo(Algo algo); + +private: + const char *name(bool shortName) const; + + Algo m_algo; + Variant m_variant; +}; + + +} /* namespace xmrig */ + +#endif /* __ALGORITHM_H__ */ diff --git a/src/common/net/Client.cpp b/src/common/net/Client.cpp index de56b315..0576854b 100644 --- a/src/common/net/Client.cpp +++ b/src/common/net/Client.cpp @@ -232,7 +232,7 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } - Job job(m_id, m_nicehash, m_pool.algorithm(), m_pool.variant(), m_rpcId); + Job job(m_id, m_nicehash, m_pool.algorithm(), m_rpcId); if (!job.setId(params["job_id"].GetString())) { *code = 3; @@ -250,7 +250,7 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) } if (params.HasMember("variant")) { - job.setVariant(params["variant"].GetInt()); + job.algorithm().parseVariant(params["variant"].GetInt()); } if (m_job != job) { diff --git a/src/common/net/Job.cpp b/src/common/net/Job.cpp index ec5279bf..34aab326 100644 --- a/src/common/net/Job.cpp +++ b/src/common/net/Job.cpp @@ -64,14 +64,12 @@ Job::Job() : m_size(0), m_diff(0), m_target(0), - m_blob(), - m_algorithm(xmrig::INVALID_ALGO), - m_variant(xmrig::VARIANT_AUTO) + m_blob() { } -Job::Job(int poolId, bool nicehash, xmrig::Algo algo, xmrig::Variant variant, const xmrig::Id &clientId) : +Job::Job(int poolId, bool nicehash, xmrig::Algorithm algorithm, const xmrig::Id &clientId) : m_nicehash(nicehash), m_poolId(poolId), m_threadId(-1), @@ -79,9 +77,8 @@ Job::Job(int poolId, bool nicehash, xmrig::Algo algo, xmrig::Variant variant, co m_diff(0), m_target(0), m_blob(), - m_algorithm(algo), - m_clientId(clientId), - m_variant(variant) + m_algorithm(algorithm), + m_clientId(clientId) { } @@ -166,23 +163,6 @@ bool Job::setTarget(const char *target) } -void Job::setVariant(int variant) -{ - switch (variant) { - case xmrig::VARIANT_AUTO: - case xmrig::VARIANT_V0: - case xmrig::VARIANT_V1: - m_variant = static_cast(variant); - break; - - default: - assert(false); - m_variant = xmrig::VARIANT_AUTO; - break; - } -} - - bool Job::fromHex(const char* in, unsigned int len, unsigned char* out) { bool error = false; diff --git a/src/common/net/Job.h b/src/common/net/Job.h index c235072e..08d5ae82 100644 --- a/src/common/net/Job.h +++ b/src/common/net/Job.h @@ -30,40 +30,44 @@ #include +#include "common/crypto/Algorithm.h" #include "common/net/Id.h" -#include "common/xmrig.h" class Job { public: Job(); - Job(int poolId, bool nicehash, xmrig::Algo algo, xmrig::Variant variant, const xmrig::Id &clientId); + Job(int poolId, bool nicehash, xmrig::Algorithm algorithm, const xmrig::Id &clientId); ~Job(); bool setBlob(const char *blob); bool setTarget(const char *target); - void setVariant(int variant); - inline bool isNicehash() const { return m_nicehash; } - inline bool isValid() const { return m_size > 0 && m_diff > 0; } - inline bool setId(const char *id) { return m_id.setId(id); } - inline const uint32_t *nonce() const { return reinterpret_cast(m_blob + 39); } - inline const uint8_t *blob() const { return m_blob; } - inline const xmrig::Id &clientId() const { return m_clientId; } - inline const xmrig::Id &id() const { return m_id; } - inline int poolId() const { return m_poolId; } - inline int threadId() const { return m_threadId; } - inline size_t size() const { return m_size; } - inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } - inline uint32_t diff() const { return static_cast(m_diff); } - inline uint64_t target() const { return m_target; } - inline void reset() { m_size = 0; m_diff = 0; } - inline void setClientId(const xmrig::Id &id) { m_clientId = id; } - inline void setPoolId(int poolId) { m_poolId = poolId; } - inline void setThreadId(int threadId) { m_threadId = threadId; } - inline xmrig::Algo algorithm() const { return m_algorithm; } - inline xmrig::Variant variant() const { return (m_variant == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? xmrig::VARIANT_V1 : xmrig::VARIANT_V0) : m_variant); } + inline bool isNicehash() const { return m_nicehash; } + inline bool isValid() const { return m_size > 0 && m_diff > 0; } + inline bool setId(const char *id) { return m_id.setId(id); } + inline const uint32_t *nonce() const { return reinterpret_cast(m_blob + 39); } + inline const uint8_t *blob() const { return m_blob; } + inline const xmrig::Algorithm &algorithm() const { return m_algorithm; } + inline const xmrig::Id &clientId() const { return m_clientId; } + inline const xmrig::Id &id() const { return m_id; } + inline int poolId() const { return m_poolId; } + inline int threadId() const { return m_threadId; } + inline size_t size() const { return m_size; } + inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } + inline uint32_t diff() const { return static_cast(m_diff); } + inline uint64_t target() const { return m_target; } + inline void reset() { m_size = 0; m_diff = 0; } + inline void setClientId(const xmrig::Id &id) { m_clientId = id; } + inline void setPoolId(int poolId) { m_poolId = poolId; } + inline void setThreadId(int threadId) { m_threadId = threadId; } + inline xmrig::Algorithm &algorithm() { return m_algorithm; } + + inline xmrig::Variant variant() const + { + return (m_algorithm.variant() == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? xmrig::VARIANT_1 : xmrig::VARIANT_0) : m_algorithm.variant()); + } # ifdef XMRIG_PROXY_PROJECT inline char *rawBlob() { return m_rawBlob; } @@ -90,10 +94,9 @@ private: uint64_t m_diff; uint64_t m_target; uint8_t m_blob[96]; // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk. - xmrig::Algo m_algorithm; + xmrig::Algorithm m_algorithm; xmrig::Id m_clientId; xmrig::Id m_id; - xmrig::Variant m_variant; # ifdef XMRIG_PROXY_PROJECT char m_rawBlob[176]; diff --git a/src/common/net/Pool.cpp b/src/common/net/Pool.cpp index 4675876a..d3c15056 100644 --- a/src/common/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -29,6 +29,7 @@ #include "common/net/Pool.h" +#include "rapidjson/document.h" #ifdef APP_DEBUG @@ -42,52 +43,10 @@ #endif -static const char *algoNames[] = { - "cryptonight", -# ifndef XMRIG_NO_AEON - "cryptonight-lite", -# else - nullptr, -# endif -# ifndef XMRIG_NO_SUMO - "cryptonight-heavy", -# else - nullptr, -# endif -# ifndef XMRIG_NO_IPBC - "cryptonight-ipbc", -# else - nullptr, -# endif -}; - - -static const char *algoNamesShort[] = { - "cn", -# ifndef XMRIG_NO_AEON - "cn-lite", -# else - nullptr, -# endif -# ifndef XMRIG_NO_SUMO - "cn-heavy", -# else - nullptr, -# endif -# ifndef XMRIG_NO_IPBC - "cn-ipbc", -# else - nullptr, -# endif -}; - - Pool::Pool() : m_nicehash(false), m_keepAlive(0), - m_port(kDefaultPort), - m_algorithm(xmrig::INVALID_ALGO), - m_variant(xmrig::VARIANT_AUTO) + m_port(kDefaultPort) { } @@ -106,23 +65,19 @@ Pool::Pool() : Pool::Pool(const char *url) : m_nicehash(false), m_keepAlive(0), - m_port(kDefaultPort), - m_algorithm(xmrig::INVALID_ALGO), - m_variant(xmrig::VARIANT_AUTO) + m_port(kDefaultPort) { parse(url); } -Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, xmrig::Variant variant) : +Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash) : m_nicehash(nicehash), m_keepAlive(keepAlive), m_port(port), - m_algorithm(xmrig::INVALID_ALGO), m_host(host), m_password(password), - m_user(user), - m_variant(variant) + m_user(user) { const size_t size = m_host.size() + 8; assert(size > 8); @@ -134,41 +89,6 @@ Pool::Pool(const char *host, uint16_t port, const char *user, const char *passwo } -const char *Pool::algoName(xmrig::Algo algorithm, bool shortName) -{ - if (algorithm == xmrig::INVALID_ALGO) { - return "invalid"; - } - - return (shortName ? algoNamesShort : algoNames)[algorithm]; -} - - -xmrig::Algo Pool::algorithm(const char *algo) -{ -# ifndef XMRIG_NO_AEON - if (strcasecmp(algo, "cryptonight-light") == 0) { - fprintf(stderr, "Algorithm \"cryptonight-light\" is deprecated, use \"cryptonight-lite\" instead\n"); - - return xmrig::CRYPTONIGHT_LITE; - } -# endif - - const size_t size = sizeof(algoNames) / sizeof(algoNames[0]); - - assert(size == (sizeof(algoNamesShort) / sizeof(algoNamesShort[0]))); - - for (size_t i = 0; i < size; i++) { - if ((algoNames[i] && strcasecmp(algo, algoNames[i]) == 0) || (algoNamesShort[i] && strcasecmp(algo, algoNamesShort[i]) == 0)) { - return static_cast(i); - } - } - - fprintf(stderr, "Unknown algorithm \"%s\" specified.\n", algo); - return xmrig::INVALID_ALGO; -} - - bool Pool::isEqual(const Pool &other) const { return (m_nicehash == other.m_nicehash @@ -179,8 +99,7 @@ bool Pool::isEqual(const Pool &other) const && m_password == other.m_password && m_rigId == other.m_rigId && m_url == other.m_url - && m_user == other.m_user - && m_variant == other.m_variant); + && m_user == other.m_user); } @@ -242,14 +161,54 @@ bool Pool::setUserpass(const char *userpass) } +rapidjson::Value Pool::toJSON(rapidjson::Document &doc) const +{ + using namespace rapidjson; + + auto &allocator = doc.GetAllocator(); + + Value obj(kObjectType); + + obj.AddMember("url", StringRef(url()), allocator); + obj.AddMember("user", StringRef(user()), allocator); + obj.AddMember("pass", StringRef(password()), allocator); + obj.AddMember("rig-id", rigId() ? Value(StringRef(rigId())).Move() : Value(kNullType).Move(), allocator); + +# ifndef XMRIG_PROXY_PROJECT + obj.AddMember("nicehash", isNicehash(), allocator); +# endif + + if (m_keepAlive == 0 || m_keepAlive == kKeepAliveTimeout) { + obj.AddMember("keepalive", m_keepAlive > 0, allocator); + } + else { + obj.AddMember("keepalive", m_keepAlive, allocator); + } + + switch (m_algorithm.variant()) { + case xmrig::VARIANT_AUTO: + case xmrig::VARIANT_0: + case xmrig::VARIANT_1: + obj.AddMember("variant", m_algorithm.variant(), allocator); + break; + + default: + obj.AddMember("variant", StringRef(m_algorithm.variantName()), allocator); + break; + } + + return obj; +} + + void Pool::adjust(xmrig::Algo algorithm) { if (!isValid()) { return; } - if (m_algorithm == xmrig::INVALID_ALGO) { - m_algorithm = algorithm; + if (!m_algorithm.isValid()) { + m_algorithm.setAlgo(algorithm); } if (strstr(m_host.data(), ".nicehash.com")) { @@ -257,50 +216,17 @@ void Pool::adjust(xmrig::Algo algorithm) m_nicehash = true; if (strstr(m_host.data(), "cryptonightv7.")) { - m_variant = xmrig::VARIANT_V1; + m_algorithm.setVariant(xmrig::VARIANT_1); } } if (strstr(m_host.data(), ".minergate.com")) { - m_variant = xmrig::VARIANT_V1; m_keepAlive = false; + m_algorithm.setVariant(xmrig::VARIANT_1); } } -void Pool::setVariant(int variant) -{ - switch (variant) { - case xmrig::VARIANT_AUTO: - case xmrig::VARIANT_V0: - case xmrig::VARIANT_V1: - m_variant = static_cast(variant); - break; - - default: - assert(false); - break; - } -} - - -xmrig::Variant Pool::variant() const -{ - switch (m_algorithm) { - case xmrig::CRYPTONIGHT_HEAVY: - return xmrig::VARIANT_V0; - - case xmrig::CRYPTONIGHT_IPBC: - return xmrig::VARIANT_V1; - - default: - break; - } - - return m_variant; -} - - #ifdef APP_DEBUG void Pool::print() const { @@ -309,8 +235,8 @@ void Pool::print() const LOG_DEBUG ("port: %d", static_cast(m_port)); LOG_DEBUG ("user: %s", m_user.data()); LOG_DEBUG ("pass: %s", m_password.data()); - LOG_DEBUG ("rig_id %s", m_rigId.data()); - LOG_DEBUG ("algo: %s/%d", algoName(m_algorithm), static_cast(variant())); + LOG_DEBUG ("rig-id %s", m_rigId.data()); + LOG_DEBUG ("algo: %s", m_algorithm.name()); LOG_DEBUG ("nicehash: %d", static_cast(m_nicehash)); LOG_DEBUG ("keepAlive: %d", m_keepAlive); } diff --git a/src/common/net/Pool.h b/src/common/net/Pool.h index b1b93507..670924f2 100644 --- a/src/common/net/Pool.h +++ b/src/common/net/Pool.h @@ -28,8 +28,9 @@ #include +#include "common/crypto/Algorithm.h" #include "common/utils/c_str.h" -#include "common/xmrig.h" +#include "rapidjson/fwd.h" class Pool @@ -47,30 +48,25 @@ public: const char *user = nullptr, const char *password = nullptr, int keepAlive = 0, - bool nicehash = false, - xmrig::Variant variant = xmrig::VARIANT_AUTO + bool nicehash = false ); - static const char *algoName(xmrig::Algo algorithm, bool shortName = false); - static xmrig::Algo algorithm(const char *algo); - - inline bool isNicehash() const { return m_nicehash; } - inline bool isValid() const { return !m_host.isNull() && m_port > 0; } - inline const char *host() const { return m_host.data(); } - inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; } - inline const char *rigId() const { return m_rigId.data(); } - inline const char *url() const { return m_url.data(); } - inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; } - inline int keepAlive() const { return m_keepAlive; } - inline uint16_t port() const { return m_port; } - inline void setAlgo(const char *algo) { m_algorithm = algorithm(algo); } - inline void setAlgo(xmrig::Algo algorithm) { m_algorithm = algorithm; } - inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } - inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } - inline void setPassword(const char *password) { m_password = password; } - inline void setRigId(const char *rigId) { m_rigId = rigId; } - inline void setUser(const char *user) { m_user = user; } - inline xmrig::Algo algorithm() const { return m_algorithm; } + inline bool isNicehash() const { return m_nicehash; } + inline bool isValid() const { return !m_host.isNull() && m_port > 0; } + inline const char *host() const { return m_host.data(); } + inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; } + inline const char *rigId() const { return m_rigId.data(); } + inline const char *url() const { return m_url.data(); } + inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; } + inline const xmrig::Algorithm &algorithm() const { return m_algorithm; } + inline int keepAlive() const { return m_keepAlive; } + inline uint16_t port() const { return m_port; } + inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } + inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } + inline void setPassword(const char *password) { m_password = password; } + inline void setRigId(const char *rigId) { m_rigId = rigId; } + inline void setUser(const char *user) { m_user = user; } + inline xmrig::Algorithm &algorithm() { return m_algorithm; } inline bool operator!=(const Pool &other) const { return !isEqual(other); } inline bool operator==(const Pool &other) const { return isEqual(other); } @@ -78,9 +74,8 @@ public: bool isEqual(const Pool &other) const; bool parse(const char *url); bool setUserpass(const char *userpass); + rapidjson::Value toJSON(rapidjson::Document &doc) const; void adjust(xmrig::Algo algorithm); - void setVariant(int variant); - xmrig::Variant variant() const; # ifdef APP_DEBUG void print() const; @@ -92,13 +87,12 @@ private: bool m_nicehash; int m_keepAlive; uint16_t m_port; - xmrig::Algo m_algorithm; + xmrig::Algorithm m_algorithm; xmrig::c_str m_host; xmrig::c_str m_password; xmrig::c_str m_rigId; xmrig::c_str m_url; xmrig::c_str m_user; - xmrig::Variant m_variant; }; #endif /* __POOL_H__ */ diff --git a/src/common/net/Storage.h b/src/common/net/Storage.h index 752e9512..f36ce594 100644 --- a/src/common/net/Storage.h +++ b/src/common/net/Storage.h @@ -29,9 +29,6 @@ #include -#include "common/log/Log.h" - - namespace xmrig { diff --git a/src/common/utils/c_str.h b/src/common/utils/c_str.h index 9a11ade6..3cc4d326 100644 --- a/src/common/utils/c_str.h +++ b/src/common/utils/c_str.h @@ -68,7 +68,7 @@ public: inline bool isEqual(const char *str) const { - return (m_data != nullptr && str != nullptr && strcmp(m_data, str)) || (m_data == nullptr && m_data == nullptr); + return (m_data != nullptr && str != nullptr && strcmp(m_data, str) == 0) || (m_data == nullptr && m_data == nullptr); } diff --git a/src/common/xmrig.h b/src/common/xmrig.h index 2de1a798..3349d3b6 100644 --- a/src/common/xmrig.h +++ b/src/common/xmrig.h @@ -33,8 +33,7 @@ enum Algo { INVALID_ALGO = -1, CRYPTONIGHT, /* CryptoNight (Monero) */ CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ - CRYPTONIGHT_HEAVY, /* CryptoNight-Heavy (SUMO) */ - CRYPTONIGHT_IPBC /* CryptoNight-IPBC (IPBC) */ + CRYPTONIGHT_HEAVY /* CryptoNight-Heavy (SUMO) */ }; @@ -60,8 +59,10 @@ enum AlgoVariant { enum Variant { VARIANT_AUTO = -1, // Autodetect - VARIANT_V0 = 0, // Original CryptoNight or CryptoNight-Heavy - VARIANT_V1 = 1 // Monero v7 PoW + VARIANT_0 = 0, // Original CryptoNight or CryptoNight-Heavy + VARIANT_1 = 1, // CryptoNight variant 1 also known as Monero7 and CryptoNightV7 + VARIANT_IBPC = 2, // CryptoNight Lite variant 1 with XOR (IPBC only) + VARIANT_XTL = 3 // CryptoNight variant 1 (Stellite only) }; diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 43abbbbd..329d595a 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -71,7 +71,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const auto &allocator = doc.GetAllocator(); - doc.AddMember("algo", StringRef(algoName()), allocator); + doc.AddMember("algo", StringRef(algorithm().name()), allocator); Value api(kObjectType); api.AddMember("port", apiPort(), allocator); @@ -103,24 +103,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const Value pools(kArrayType); for (const Pool &pool : m_pools) { - Value obj(kObjectType); - - obj.AddMember("url", StringRef(pool.url()), allocator); - obj.AddMember("user", StringRef(pool.user()), allocator); - obj.AddMember("pass", StringRef(pool.password()), allocator); - obj.AddMember("rig-id", pool.rigId() ? Value(StringRef(pool.rigId())).Move() : Value(kNullType).Move(), allocator); - - if (pool.keepAlive() == 0 || pool.keepAlive() == Pool::kKeepAliveTimeout) { - obj.AddMember("keepalive", pool.keepAlive() > 0, allocator); - } - else { - obj.AddMember("keepalive", pool.keepAlive(), allocator); - } - - obj.AddMember("nicehash", pool.isNicehash(), allocator); - obj.AddMember("variant", pool.variant(), allocator); - - pools.PushBack(obj, allocator); + pools.PushBack(pool.toJSON(doc), allocator); } doc.AddMember("pools", pools, allocator); @@ -169,7 +152,7 @@ bool xmrig::Config::adjust() const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; for (size_t i = 0; i < m_threads.cpu.size(); ++i) { - m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm, m_threads.cpu[i], m_priority, softAES)); + m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES)); } return true; @@ -178,7 +161,7 @@ bool xmrig::Config::adjust() m_algoVariant = getAlgoVariant(); m_threads.mode = m_threads.count ? Simple : Automatic; - const size_t size = CpuThread::multiway(m_algoVariant) * cn_select_memory(m_algorithm) / 1024; + const size_t size = CpuThread::multiway(m_algoVariant) * cn_select_memory(m_algorithm.algo()) / 1024; if (!m_threads.count) { m_threads.count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); @@ -191,7 +174,7 @@ bool xmrig::Config::adjust() } for (size_t i = 0; i < m_threads.count; ++i) { - m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm, m_algoVariant, m_threads.mask, m_priority)); + m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), m_algoVariant, m_threads.mask, m_priority)); } return true; @@ -351,7 +334,7 @@ bool xmrig::Config::parseInt(int key, int arg) xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const { # ifndef XMRIG_NO_AEON - if (m_algorithm == xmrig::CRYPTONIGHT_LITE) { + if (m_algorithm.algo() == xmrig::CRYPTONIGHT_LITE) { return getAlgoVariantLite(); } # endif diff --git a/src/crypto/CryptoNight_constants.h b/src/crypto/CryptoNight_constants.h index 6004edbd..7e6627fd 100644 --- a/src/crypto/CryptoNight_constants.h +++ b/src/crypto/CryptoNight_constants.h @@ -47,16 +47,12 @@ constexpr const size_t CRYPTONIGHT_HEAVY_MEMORY = 4 * 1024 * 1024; constexpr const uint32_t CRYPTONIGHT_HEAVY_MASK = 0x3FFFF0; constexpr const uint32_t CRYPTONIGHT_HEAVY_ITER = 0x40000; -constexpr const size_t CRYPTONIGHT_IPBC_MEMORY = 1 * 1024 * 1024; -constexpr const uint32_t CRYPTONIGHT_IPBC_MASK = 0xFFFF0; -constexpr const uint32_t CRYPTONIGHT_IPBC_ITER = 0x40000; - template inline constexpr size_t cn_select_memory() { return 0; } template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_MEMORY; } template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_LITE_MEMORY; } template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_HEAVY_MEMORY; } -template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_IPBC_MEMORY; } + inline size_t cn_select_memory(Algo algorithm) { @@ -71,9 +67,6 @@ inline size_t cn_select_memory(Algo algorithm) case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_MEMORY; - case CRYPTONIGHT_IPBC: - return CRYPTONIGHT_IPBC_MEMORY; - default: break; } @@ -86,7 +79,7 @@ template inline constexpr uint32_t cn_select_mask() { retur template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_MASK; } template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_LITE_MASK; } template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_HEAVY_MASK; } -template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_IPBC_MASK; } + inline uint32_t cn_select_mask(Algo algorithm) { @@ -101,9 +94,6 @@ inline uint32_t cn_select_mask(Algo algorithm) case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_MASK; - case CRYPTONIGHT_IPBC: - return CRYPTONIGHT_IPBC_MASK; - default: break; } @@ -116,7 +106,7 @@ template inline constexpr uint32_t cn_select_iter() { retur template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_LITE_ITER; } template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_HEAVY_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_IPBC_ITER; } + inline uint32_t cn_select_iter(Algo algorithm) { @@ -131,9 +121,6 @@ inline uint32_t cn_select_iter(Algo algorithm) case CRYPTONIGHT_HEAVY: return CRYPTONIGHT_HEAVY_ITER; - case CRYPTONIGHT_IPBC: - return CRYPTONIGHT_IPBC_ITER; - default: break; } diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 4101245e..bcd13ee1 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -61,7 +61,7 @@ Network::Network(xmrig::Controller *controller) : } if (controller->config()->donateLevel() > 0) { - m_donate = new DonateStrategy(controller->config()->donateLevel(), controller->config()->pools().front().user(), controller->config()->algorithm(), this); + m_donate = new DonateStrategy(controller->config()->donateLevel(), controller->config()->pools().front().user(), controller->config()->algorithm().algo(), this); } m_timer.data = this; @@ -166,9 +166,9 @@ bool Network::isColors() const void Network::setJob(Client *client, const Job &job, bool donate) { - LOG_INFO(isColors() ? MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%d") " algo " WHITE_BOLD("%s/%d") - : "new job from %s:%d diff %d algo %s/%d", - client->host(), client->port(), job.diff(), Pool::algoName(job.algorithm(), true), static_cast(job.variant())); + LOG_INFO(isColors() ? MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%d") " algo " WHITE_BOLD("%s") + : "new job from %s:%d diff %d algo %s", + client->host(), client->port(), job.diff(), job.algorithm().shortName()); m_state.diff = job.diff(); Workers::setJob(job, donate); diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index ad8e88c0..3bb5caa2 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -63,15 +63,12 @@ DonateStrategy::DonateStrategy(int level, const char *user, xmrig::Algo algo, IS else if (algo == xmrig::CRYPTONIGHT_HEAVY) { m_pools.push_back(Pool(kDonatePool1, 8888, userId, nullptr, false, true)); } - else if (algo == xmrig::CRYPTONIGHT_IPBC) { - m_pools.push_back(Pool(kDonatePool1, 13333, userId, nullptr, false, true)); - } else { m_pools.push_back(Pool(kDonatePool1, 5555, userId, nullptr, false, true)); } for (Pool &pool : m_pools) { - pool.setAlgo(algo); + pool.algorithm().setAlgo(algo); } if (m_pools.size() > 1) { diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 5c0e8c0b..758eb982 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -62,69 +62,69 @@ bool xmrig::CpuThread::isSoftAES(AlgoVariant av) xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant) { - assert(variant == VARIANT_V0 || variant == VARIANT_V1); + assert(variant == VARIANT_0 || variant == VARIANT_1); static const cn_hash_fun func_table[50] = { - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, # ifndef XMRIG_NO_AEON - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, # else nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, # endif # ifndef XMRIG_NO_SUMO - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, # else nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, # endif @@ -132,7 +132,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a # ifndef XMRIG_NO_SUMO if (algorithm == CRYPTONIGHT_HEAVY) { - variant = VARIANT_V0; + variant = VARIANT_0; } # endif @@ -252,7 +252,6 @@ rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const auto &allocator = doc.GetAllocator(); obj.AddMember("type", "cpu", allocator); - obj.AddMember("algo", rapidjson::StringRef(Pool::algoName(algorithm())), allocator); obj.AddMember("av", m_av, allocator); obj.AddMember("low_power_mode", multiway(), allocator); obj.AddMember("affine_to_cpu", affinity(), allocator); diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index 33f5864d..c3cd9782 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -50,21 +50,21 @@ MultiWorker::~MultiWorker() template bool MultiWorker::selfTest() { - if (m_thread->fn(xmrig::VARIANT_V0) == nullptr) { + if (m_thread->fn(xmrig::VARIANT_0) == nullptr) { return false; } - m_thread->fn(xmrig::VARIANT_V0)(test_input, 76, m_hash, m_ctx); + m_thread->fn(xmrig::VARIANT_0)(test_input, 76, m_hash, m_ctx); if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_hash, test_output_v0, sizeof m_hash) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); + m_thread->fn(xmrig::VARIANT_1)(test_input, 76, m_hash, m_ctx); return memcmp(m_hash, test_output_v1, sizeof m_hash) == 0; } # ifndef XMRIG_NO_AEON if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_hash, test_output_v0_lite, sizeof m_hash) == 0) { - m_thread->fn(xmrig::VARIANT_V1)(test_input, 76, m_hash, m_ctx); + m_thread->fn(xmrig::VARIANT_1)(test_input, 76, m_hash, m_ctx); return memcmp(m_hash, test_output_v1_lite, sizeof m_hash) == 0; } diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 67b2973d..497e3060 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -132,7 +132,7 @@ void Workers::setJob(const Job &job, bool donate) void Workers::start(xmrig::Controller *controller) { const std::vector &threads = controller->config()->threads(); - m_status.algo = controller->config()->algorithm(); + m_status.algo = controller->config()->algorithm().algo(); m_status.colors = controller->config()->isColors(); m_status.threads = threads.size(); From ba5f92c6dd07b1cdd9a21e74fbee563b6e5bf42d Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 25 Apr 2018 18:31:18 +0700 Subject: [PATCH 089/109] Added support for cn-lite/ipbc. --- src/crypto/CryptoNight_test.h | 15 +++++++++ src/crypto/CryptoNight_x86.h | 59 ++++++++++++++++++++++++++--------- src/workers/CpuThread.cpp | 34 ++++++++++++++++++-- src/workers/MultiWorker.cpp | 6 +++- 4 files changed, 96 insertions(+), 18 deletions(-) diff --git a/src/crypto/CryptoNight_test.h b/src/crypto/CryptoNight_test.h index 93cbf23d..66630393 100644 --- a/src/crypto/CryptoNight_test.h +++ b/src/crypto/CryptoNight_test.h @@ -112,6 +112,21 @@ const static uint8_t test_output_v1_lite[160] = { 0x8C, 0x2B, 0xA4, 0x1F, 0x60, 0x76, 0x39, 0xD7, 0xF6, 0x46, 0x77, 0x18, 0x20, 0xAD, 0xD4, 0xC9, 0x87, 0xF7, 0x37, 0xDA, 0xFD, 0xBA, 0xBA, 0xD2, 0xF2, 0x68, 0xDC, 0x26, 0x8D, 0x1B, 0x08, 0xC6 }; + + +// IPBC +const static uint8_t test_output_ipbc_lite[160] = { + 0xE4, 0x93, 0x8C, 0xAA, 0x59, 0x8D, 0x02, 0x8A, 0xB8, 0x6F, 0x25, 0xD2, 0xB1, 0x23, 0xD0, 0xD5, + 0x33, 0xE3, 0x9F, 0x37, 0xAC, 0xE5, 0xF8, 0xEB, 0x7A, 0xE8, 0x40, 0xEB, 0x5D, 0xB1, 0x35, 0x5F, + 0xB2, 0x47, 0x86, 0xF0, 0x7F, 0x6F, 0x4B, 0x55, 0x3E, 0xA1, 0xBB, 0xE8, 0xA1, 0x75, 0x00, 0x2D, + 0x07, 0x9A, 0x21, 0x0E, 0xBD, 0x06, 0x6A, 0xB0, 0xFD, 0x96, 0x9E, 0xE6, 0xE4, 0x69, 0x67, 0xBB, + 0x88, 0x45, 0x0B, 0x91, 0x0B, 0x7B, 0xCB, 0x21, 0x3C, 0x3C, 0x09, 0x30, 0x07, 0x71, 0x07, 0xD5, + 0xB8, 0x2D, 0x83, 0x09, 0xAF, 0x7E, 0xB2, 0xA8, 0xAC, 0x25, 0xDC, 0x10, 0xF8, 0x63, 0x6A, 0xBC, + 0x73, 0x01, 0x4E, 0xA8, 0x1C, 0xDA, 0x9A, 0x86, 0x17, 0xEC, 0xA8, 0xFB, 0xAA, 0x23, 0x23, 0x17, + 0xE1, 0x32, 0x68, 0x9C, 0x4C, 0xF4, 0x08, 0xED, 0xB0, 0x15, 0xC3, 0xA9, 0x0F, 0xF0, 0xA2, 0x7E, + 0xD9, 0xE4, 0x23, 0xA7, 0x9E, 0x91, 0xD8, 0x73, 0x94, 0xD6, 0x6C, 0x70, 0x9B, 0x8B, 0x72, 0x92, + 0xA3, 0xA4, 0x0A, 0xE2, 0x3C, 0x0A, 0x34, 0x88, 0xA1, 0x6D, 0xFE, 0x02, 0x44, 0x60, 0x7B, 0x3D +}; #endif diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index a1651cc3..75246b6e 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -457,13 +457,22 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si al0 += hi; ah0 += lo; - VARIANT1_2(ah0, 0); ((uint64_t*)&l0[idx0 & MASK])[0] = al0; - ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; - VARIANT1_2(ah0, 0); - ah0 ^= ch; + if (VARIANT > 0) { + if (VARIANT == xmrig::VARIANT_IBPC) { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; + } + else { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; + } + } + else { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; + } + al0 ^= cl; + ah0 ^= ch; idx0 = al0; if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { @@ -556,13 +565,22 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si al0 += hi; ah0 += lo; - VARIANT1_2(ah0, 0); - ((uint64_t*) &l0[idx0 & MASK])[0] = al0; - ((uint64_t*) &l0[idx0 & MASK])[1] = ah0; - VARIANT1_2(ah0, 0); + ((uint64_t*)&l0[idx0 & MASK])[0] = al0; + + if (VARIANT > 0) { + if (VARIANT == xmrig::VARIANT_IBPC) { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; + } + else { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; + } + } + else { + ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; + } - ah0 ^= ch; al0 ^= cl; + ah0 ^= ch; idx0 = al0; if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { @@ -581,13 +599,22 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si al1 += hi; ah1 += lo; - VARIANT1_2(ah1, 1); - ((uint64_t*) &l1[idx1 & MASK])[0] = al1; - ((uint64_t*) &l1[idx1 & MASK])[1] = ah1; - VARIANT1_2(ah1, 1); + ((uint64_t*)&l1[idx1 & MASK])[0] = al1; + + if (VARIANT > 0) { + if (VARIANT == xmrig::VARIANT_IBPC) { + ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1 ^ al1; + } + else { + ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1; + } + } + else { + ((uint64_t*)&l1[idx1 & MASK])[1] = ah1; + } - ah1 ^= ch; al1 ^= cl; + ah1 ^= ch; idx1 = al1; if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { @@ -644,6 +671,10 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si \ if (VARIANT > 0) { \ _mm_store_si128(ptr, _mm_xor_si128(a, mc)); \ + \ + if (VARIANT == xmrig::VARIANT_IBPC) { \ + ((uint64_t*)ptr)[1] ^= ((uint64_t*)ptr)[0]; \ + } \ } else { \ _mm_store_si128(ptr, a); \ } \ diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 758eb982..e08ffecd 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -62,9 +62,9 @@ bool xmrig::CpuThread::isSoftAES(AlgoVariant av) xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant) { - assert(variant == VARIANT_0 || variant == VARIANT_1); + assert(variant == VARIANT_0 || variant == VARIANT_1 || variant == VARIANT_IBPC || variant == VARIANT_XTL); - static const cn_hash_fun func_table[50] = { + static const cn_hash_fun func_table[90] = { cryptonight_single_hash, cryptonight_double_hash, cryptonight_single_hash, @@ -87,6 +87,19 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a cryptonight_quad_hash, cryptonight_penta_hash, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + # ifndef XMRIG_NO_AEON cryptonight_single_hash, cryptonight_double_hash, @@ -109,9 +122,24 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a cryptonight_triple_hash, cryptonight_quad_hash, cryptonight_penta_hash, + + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, # else nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, # endif # ifndef XMRIG_NO_SUMO @@ -136,7 +164,7 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a } # endif - return func_table[20 * algorithm + 10 * variant + av - 1]; + return func_table[40 * algorithm + 10 * variant + av - 1]; } diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index c3cd9782..012876a3 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -65,8 +65,12 @@ bool MultiWorker::selfTest() # ifndef XMRIG_NO_AEON if (m_thread->algorithm() == xmrig::CRYPTONIGHT_LITE && memcmp(m_hash, test_output_v0_lite, sizeof m_hash) == 0) { m_thread->fn(xmrig::VARIANT_1)(test_input, 76, m_hash, m_ctx); + if (memcmp(m_hash, test_output_v1_lite, sizeof m_hash) != 0) { + return false; + } - return memcmp(m_hash, test_output_v1_lite, sizeof m_hash) == 0; + m_thread->fn(xmrig::VARIANT_IBPC)(test_input, 76, m_hash, m_ctx); + return memcmp(m_hash, test_output_ipbc_lite, sizeof m_hash) == 0; } # endif From a9cc5c52582298c18f5b62b299d391aebc8a543a Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 25 Apr 2018 19:09:08 +0700 Subject: [PATCH 090/109] Basic algo selection from pool/proxy. --- src/common/net/Client.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/common/net/Client.cpp b/src/common/net/Client.cpp index 0576854b..9a2b8b1b 100644 --- a/src/common/net/Client.cpp +++ b/src/common/net/Client.cpp @@ -249,6 +249,10 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } + if (params.HasMember("algo")) { + job.algorithm().parseAlgorithm(params["algo"].GetString()); + } + if (params.HasMember("variant")) { job.algorithm().parseVariant(params["variant"].GetInt()); } From 230962230f40a22f9364d24fad636ba8185c5426 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 25 Apr 2018 22:03:26 +0700 Subject: [PATCH 091/109] Better algorithm validation. --- src/common/crypto/Algorithm.cpp | 16 ++++++++++++++++ src/common/crypto/Algorithm.h | 2 +- src/workers/CpuThread.cpp | 13 ++++++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/common/crypto/Algorithm.cpp b/src/common/crypto/Algorithm.cpp index 2e13fffd..8d95acde 100644 --- a/src/common/crypto/Algorithm.cpp +++ b/src/common/crypto/Algorithm.cpp @@ -79,6 +79,22 @@ static const char *variants[] = { }; +bool xmrig::Algorithm::isValid() const +{ + if (m_algo == INVALID_ALGO) { + return false; + } + + for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) { + if (algorithms[i].algo == m_algo && algorithms[i].variant == m_variant) { + return true; + } + } + + return false; +} + + const char *xmrig::Algorithm::variantName() const { if (m_variant == VARIANT_AUTO) { diff --git a/src/common/crypto/Algorithm.h b/src/common/crypto/Algorithm.h index bbabb40f..aff7a8c8 100644 --- a/src/common/crypto/Algorithm.h +++ b/src/common/crypto/Algorithm.h @@ -48,7 +48,6 @@ public: bool isEqual(const Algorithm &other) const { return m_algo == other.m_algo && m_variant == other.m_variant; } inline Algo algo() const { return m_algo; } - inline bool isValid() const { return m_algo != INVALID_ALGO; } inline const char *name() const { return name(false); } inline const char *shortName() const { return name(true); } inline Variant variant() const { return m_variant; } @@ -57,6 +56,7 @@ public: inline bool operator!=(const Algorithm &other) const { return !isEqual(other); } inline bool operator==(const Algorithm &other) const { return isEqual(other); } + bool isValid() const; const char *variantName() const; void parseAlgorithm(const char *algo); void parseVariant(const char *variant); diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index e08ffecd..86699afc 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -164,7 +164,18 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a } # endif - return func_table[40 * algorithm + 10 * variant + av - 1]; + const size_t index = 40 * algorithm + 10 * variant + av - 1; + +# ifndef NDEBUG + cn_hash_fun func = func_table[index]; + + assert(index < sizeof(func_table) / sizeof(func_table[0])); + assert(func != nullptr); + + return func; +# else + return func_table[index]; +# endif } From bc2660f509ba384087f1b86cdffe61daace9a3df Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 25 Apr 2018 23:17:27 +0700 Subject: [PATCH 092/109] Add support for skip invalid pools. --- src/common/config/CommonConfig.cpp | 31 +++++++++++++++++++---------- src/common/config/CommonConfig.h | 13 +++++++++--- src/common/config/ConfigLoader.cpp | 11 +++++----- src/common/config/ConfigWatcher.cpp | 2 +- src/core/Config.cpp | 8 ++++++-- src/core/Config.h | 2 +- src/interfaces/IConfig.h | 3 +-- 7 files changed, 45 insertions(+), 25 deletions(-) diff --git a/src/common/config/CommonConfig.cpp b/src/common/config/CommonConfig.cpp index 5bad4af5..5eaf68fd 100644 --- a/src/common/config/CommonConfig.cpp +++ b/src/common/config/CommonConfig.cpp @@ -55,7 +55,8 @@ xmrig::CommonConfig::CommonConfig() : m_donateLevel(kDefaultDonateLevel), m_printTime(60), m_retries(5), - m_retryPause(5) + m_retryPause(5), + m_state(NoneState) { m_pools.push_back(Pool()); @@ -71,13 +72,15 @@ xmrig::CommonConfig::~CommonConfig() } -bool xmrig::CommonConfig::adjust() +bool xmrig::CommonConfig::finalize() { - if (m_adjusted) { - return false; + if (m_state == ReadyState) { + return true; } - m_adjusted = true; + if (m_state == ErrorState) { + return false; + } if (!m_algorithm.isValid()) { m_algorithm.setAlgo(CRYPTONIGHT); @@ -85,18 +88,24 @@ bool xmrig::CommonConfig::adjust() for (Pool &pool : m_pools) { pool.adjust(m_algorithm.algo()); + + if (pool.isValid() && pool.algorithm().isValid()) { + m_activePools.push_back(std::move(pool)); + } } + m_pools.clear(); + + if (m_activePools.empty()) { + m_state = ErrorState; + return false; + } + + m_state = ReadyState; return true; } -bool xmrig::CommonConfig::isValid() const -{ - return m_pools[0].isValid() && m_algorithm.isValid(); -} - - bool xmrig::CommonConfig::parseBoolean(int key, bool enable) { switch (key) { diff --git a/src/common/config/CommonConfig.h b/src/common/config/CommonConfig.h index b04de6eb..d54afe3a 100644 --- a/src/common/config/CommonConfig.h +++ b/src/common/config/CommonConfig.h @@ -53,7 +53,7 @@ public: inline const char *apiWorkerId() const { return m_apiWorkerId.data(); } inline const char *logFile() const { return m_logFile.data(); } inline const char *userAgent() const { return m_userAgent.data(); } - inline const std::vector &pools() const { return m_pools; } + inline const std::vector &pools() const { return m_activePools; } inline int apiPort() const { return m_apiPort; } inline int donateLevel() const { return m_donateLevel; } inline int printTime() const { return m_printTime; } @@ -65,8 +65,13 @@ public: inline const char *fileName() const override { return m_fileName.data(); } protected: - bool adjust() override; - bool isValid() const override; + 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; @@ -86,6 +91,8 @@ protected: int m_printTime; int m_retries; int m_retryPause; + State m_state; + std::vector m_activePools; std::vector m_pools; xmrig::c_str m_apiToken; xmrig::c_str m_apiWorkerId; diff --git a/src/common/config/ConfigLoader.cpp b/src/common/config/ConfigLoader.cpp index cc92213f..919ff00c 100644 --- a/src/common/config/ConfigLoader.cpp +++ b/src/common/config/ConfigLoader.cpp @@ -108,9 +108,8 @@ bool xmrig::ConfigLoader::loadFromJSON(xmrig::IConfig *config, const rapidjson:: } config->parseJSON(doc); - config->adjust(); - return config->isValid(); + return config->finalize(); } @@ -163,11 +162,14 @@ xmrig::IConfig *xmrig::ConfigLoader::load(int argc, char **argv, IConfigCreator return nullptr; } - if (!config->isValid()) { + if (!config->finalize()) { + delete config; + + config = m_creator->create(); loadFromFile(config, Platform::defaultConfigName()); } - if (!config->isValid()) { + if (!config->finalize()) { fprintf(stderr, "No valid configuration found. Exiting.\n"); delete config; return nullptr; @@ -177,7 +179,6 @@ xmrig::IConfig *xmrig::ConfigLoader::load(int argc, char **argv, IConfigCreator m_watcher = new xmrig::ConfigWatcher(config->fileName(), creator, listener); } - config->adjust(); return config; } diff --git a/src/common/config/ConfigWatcher.cpp b/src/common/config/ConfigWatcher.cpp index a08b2be7..bde35f23 100644 --- a/src/common/config/ConfigWatcher.cpp +++ b/src/common/config/ConfigWatcher.cpp @@ -83,7 +83,7 @@ void xmrig::ConfigWatcher::reload() IConfig *config = m_creator->create(); ConfigLoader::loadFromFile(config, m_path.data()); - if (!config->isValid()) { + if (!config->finalize()) { LOG_ERR("reloading failed"); delete config; diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 329d595a..a27dc917 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -141,9 +141,13 @@ xmrig::Config *xmrig::Config::load(int argc, char **argv, IWatcherListener *list } -bool xmrig::Config::adjust() +bool xmrig::Config::finalize() { - if (!CommonConfig::adjust()) { + if (m_state != NoneState) { + return CommonConfig::finalize(); + } + + if (!CommonConfig::finalize()) { return false; } diff --git a/src/core/Config.h b/src/core/Config.h index 13320a80..0c6a2173 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -88,7 +88,7 @@ public: static Config *load(int argc, char **argv, IWatcherListener *listener); protected: - bool adjust() override; + 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; diff --git a/src/interfaces/IConfig.h b/src/interfaces/IConfig.h index cf4f0d23..2422b891 100644 --- a/src/interfaces/IConfig.h +++ b/src/interfaces/IConfig.h @@ -91,8 +91,7 @@ public: virtual ~IConfig() {} - virtual bool adjust() = 0; - virtual bool isValid() const = 0; + 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; From 41e8c4f887be3c0c1d4fae0faf80230a472238a7 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 26 Apr 2018 15:02:01 +0700 Subject: [PATCH 093/109] Send supported algorithms to pool in login request. --- src/common/crypto/Algorithm.cpp | 2 +- src/common/crypto/Algorithm.h | 6 ++++++ src/common/net/Client.cpp | 24 ++++++++++++++-------- src/common/net/Pool.cpp | 30 +++++++++++++++++++++++++++ src/common/net/Pool.h | 36 +++++++++++++++++---------------- src/common/xmrig.h | 2 +- src/crypto/CryptoNight_x86.h | 8 ++++---- src/workers/CpuThread.cpp | 22 ++++++++++---------- src/workers/MultiWorker.cpp | 2 +- 9 files changed, 89 insertions(+), 43 deletions(-) diff --git a/src/common/crypto/Algorithm.cpp b/src/common/crypto/Algorithm.cpp index 8d95acde..3123c361 100644 --- a/src/common/crypto/Algorithm.cpp +++ b/src/common/crypto/Algorithm.cpp @@ -62,7 +62,7 @@ static AlgoData const algorithms[] = { { "cryptonight-lite", "cn-lite", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO }, { "cryptonight-lite/0", "cn-lite/0", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 }, { "cryptonight-lite/1", "cn-lite/1", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, - { "cryptonight-lite/ipbc", "cn-lite/ipbc", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_IBPC }, + { "cryptonight-lite/ipbc", "cn-lite/ipbc", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_IPBC }, # endif # ifndef XMRIG_NO_SUMO diff --git a/src/common/crypto/Algorithm.h b/src/common/crypto/Algorithm.h index aff7a8c8..a34d5c07 100644 --- a/src/common/crypto/Algorithm.h +++ b/src/common/crypto/Algorithm.h @@ -26,6 +26,9 @@ #define __ALGORITHM_H__ +#include + + #include "common/xmrig.h" @@ -71,6 +74,9 @@ private: }; +typedef std::vector Algorithms; + + } /* namespace xmrig */ #endif /* __ALGORITHM_H__ */ diff --git a/src/common/net/Client.cpp b/src/common/net/Client.cpp index 9a2b8b1b..c7cdd358 100644 --- a/src/common/net/Client.cpp +++ b/src/common/net/Client.cpp @@ -385,9 +385,10 @@ void Client::connect(sockaddr *addr) void Client::login() { + using namespace rapidjson; m_results.clear(); - rapidjson::Document doc; + Document doc; doc.SetObject(); auto &allocator = doc.GetAllocator(); @@ -396,19 +397,26 @@ void Client::login() doc.AddMember("jsonrpc", "2.0", allocator); doc.AddMember("method", "login", allocator); - rapidjson::Value params(rapidjson::kObjectType); - params.AddMember("login", rapidjson::StringRef(m_pool.user()), allocator); - params.AddMember("pass", rapidjson::StringRef(m_pool.password()), allocator); - params.AddMember("agent", rapidjson::StringRef(m_agent), allocator); + Value params(kObjectType); + params.AddMember("login", StringRef(m_pool.user()), allocator); + params.AddMember("pass", StringRef(m_pool.password()), allocator); + params.AddMember("agent", StringRef(m_agent), allocator); if (m_pool.rigId()) { - params.AddMember("rigid", rapidjson::StringRef(m_pool.rigId()), allocator); + params.AddMember("rigid", StringRef(m_pool.rigId()), allocator); } + Value algo(kArrayType); + + for (const auto &a : m_pool.algorithms()) { + algo.PushBack(StringRef(a.shortName()), allocator); + } + + params.AddMember("algo", algo, allocator); doc.AddMember("params", params, allocator); - rapidjson::StringBuffer buffer(0, 512); - rapidjson::Writer writer(buffer); + StringBuffer buffer(0, 512); + Writer writer(buffer); doc.Accept(writer); const size_t size = buffer.GetSize(); diff --git a/src/common/net/Pool.cpp b/src/common/net/Pool.cpp index d3c15056..aa1fa651 100644 --- a/src/common/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -37,6 +37,9 @@ #endif +#define ADD_VARIANT(variant) m_algorithms.push_back(xmrig::Algorithm(m_algorithm.algo(), variant)); + + #ifdef _MSC_VER # define strncasecmp _strnicmp # define strcasecmp _stricmp @@ -224,6 +227,33 @@ void Pool::adjust(xmrig::Algo algorithm) m_keepAlive = false; m_algorithm.setVariant(xmrig::VARIANT_1); } + +# ifndef XMRIG_PROXY_PROJECT + switch (m_algorithm.algo()) { + case xmrig::CRYPTONIGHT: + ADD_VARIANT(xmrig::VARIANT_AUTO); + ADD_VARIANT(xmrig::VARIANT_0); + ADD_VARIANT(xmrig::VARIANT_1); + ADD_VARIANT(xmrig::VARIANT_XTL); + break; + + case xmrig::CRYPTONIGHT_LITE: + ADD_VARIANT(xmrig::VARIANT_AUTO); + ADD_VARIANT(xmrig::VARIANT_0); + ADD_VARIANT(xmrig::VARIANT_1); + ADD_VARIANT(xmrig::VARIANT_IPBC); + break; + + case xmrig::CRYPTONIGHT_HEAVY: + ADD_VARIANT(xmrig::VARIANT_0); + break; + + default: + break; + } +# else + m_algorithms.push_back(m_algorithm); +# endif } diff --git a/src/common/net/Pool.h b/src/common/net/Pool.h index 670924f2..eb926b3b 100644 --- a/src/common/net/Pool.h +++ b/src/common/net/Pool.h @@ -25,7 +25,7 @@ #define __POOL_H__ -#include +#include #include "common/crypto/Algorithm.h" @@ -51,22 +51,23 @@ public: bool nicehash = false ); - inline bool isNicehash() const { return m_nicehash; } - inline bool isValid() const { return !m_host.isNull() && m_port > 0; } - inline const char *host() const { return m_host.data(); } - inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; } - inline const char *rigId() const { return m_rigId.data(); } - inline const char *url() const { return m_url.data(); } - inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; } - inline const xmrig::Algorithm &algorithm() const { return m_algorithm; } - inline int keepAlive() const { return m_keepAlive; } - inline uint16_t port() const { return m_port; } - inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } - inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } - inline void setPassword(const char *password) { m_password = password; } - inline void setRigId(const char *rigId) { m_rigId = rigId; } - inline void setUser(const char *user) { m_user = user; } - inline xmrig::Algorithm &algorithm() { return m_algorithm; } + inline bool isNicehash() const { return m_nicehash; } + inline bool isValid() const { return !m_host.isNull() && m_port > 0; } + inline const char *host() const { return m_host.data(); } + inline const char *password() const { return !m_password.isNull() ? m_password.data() : kDefaultPassword; } + inline const char *rigId() const { return m_rigId.data(); } + inline const char *url() const { return m_url.data(); } + inline const char *user() const { return !m_user.isNull() ? m_user.data() : kDefaultUser; } + inline const xmrig::Algorithm &algorithm() const { return m_algorithm; } + inline const xmrig::Algorithms &algorithms() const { return m_algorithms; } + inline int keepAlive() const { return m_keepAlive; } + inline uint16_t port() const { return m_port; } + inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } + inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } + inline void setPassword(const char *password) { m_password = password; } + inline void setRigId(const char *rigId) { m_rigId = rigId; } + inline void setUser(const char *user) { m_user = user; } + inline xmrig::Algorithm &algorithm() { return m_algorithm; } inline bool operator!=(const Pool &other) const { return !isEqual(other); } inline bool operator==(const Pool &other) const { return isEqual(other); } @@ -88,6 +89,7 @@ private: int m_keepAlive; uint16_t m_port; xmrig::Algorithm m_algorithm; + xmrig::Algorithms m_algorithms; xmrig::c_str m_host; xmrig::c_str m_password; xmrig::c_str m_rigId; diff --git a/src/common/xmrig.h b/src/common/xmrig.h index 3349d3b6..a6fda9fc 100644 --- a/src/common/xmrig.h +++ b/src/common/xmrig.h @@ -61,7 +61,7 @@ enum Variant { VARIANT_AUTO = -1, // Autodetect VARIANT_0 = 0, // Original CryptoNight or CryptoNight-Heavy VARIANT_1 = 1, // CryptoNight variant 1 also known as Monero7 and CryptoNightV7 - VARIANT_IBPC = 2, // CryptoNight Lite variant 1 with XOR (IPBC only) + VARIANT_IPBC = 2, // CryptoNight Lite variant 1 with XOR (IPBC only) VARIANT_XTL = 3 // CryptoNight variant 1 (Stellite only) }; diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index 75246b6e..75778053 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -460,7 +460,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si ((uint64_t*)&l0[idx0 & MASK])[0] = al0; if (VARIANT > 0) { - if (VARIANT == xmrig::VARIANT_IBPC) { + if (VARIANT == xmrig::VARIANT_IPBC) { ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; } else { @@ -568,7 +568,7 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si ((uint64_t*)&l0[idx0 & MASK])[0] = al0; if (VARIANT > 0) { - if (VARIANT == xmrig::VARIANT_IBPC) { + if (VARIANT == xmrig::VARIANT_IPBC) { ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; } else { @@ -602,7 +602,7 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si ((uint64_t*)&l1[idx1 & MASK])[0] = al1; if (VARIANT > 0) { - if (VARIANT == xmrig::VARIANT_IBPC) { + if (VARIANT == xmrig::VARIANT_IPBC) { ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1 ^ al1; } else { @@ -672,7 +672,7 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si if (VARIANT > 0) { \ _mm_store_si128(ptr, _mm_xor_si128(a, mc)); \ \ - if (VARIANT == xmrig::VARIANT_IBPC) { \ + if (VARIANT == xmrig::VARIANT_IPBC) { \ ((uint64_t*)ptr)[1] ^= ((uint64_t*)ptr)[0]; \ } \ } else { \ diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 86699afc..e42139c0 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -62,7 +62,7 @@ bool xmrig::CpuThread::isSoftAES(AlgoVariant av) xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant) { - assert(variant == VARIANT_0 || variant == VARIANT_1 || variant == VARIANT_IBPC || variant == VARIANT_XTL); + assert(variant == VARIANT_0 || variant == VARIANT_1 || variant == VARIANT_IPBC || variant == VARIANT_XTL); static const cn_hash_fun func_table[90] = { cryptonight_single_hash, @@ -123,16 +123,16 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a cryptonight_quad_hash, cryptonight_penta_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_single_hash, + cryptonight_double_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, + cryptonight_triple_hash, + cryptonight_quad_hash, + cryptonight_penta_hash, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, # else diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index 012876a3..b3b384f6 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -69,7 +69,7 @@ bool MultiWorker::selfTest() return false; } - m_thread->fn(xmrig::VARIANT_IBPC)(test_input, 76, m_hash, m_ctx); + m_thread->fn(xmrig::VARIANT_IPBC)(test_input, 76, m_hash, m_ctx); return memcmp(m_hash, test_output_ipbc_lite, sizeof m_hash) == 0; } # endif From 2ddac1ce6802a61d8bc463809b31d0bf607785d0 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 26 Apr 2018 15:28:33 +0700 Subject: [PATCH 094/109] Silence primary pool errors if failover active. --- src/common/net/Client.cpp | 23 ++++++++++--------- src/common/net/Client.h | 4 ++++ .../net/strategies/FailoverStrategy.cpp | 1 + .../net/strategies/SinglePoolStrategy.cpp | 3 ++- .../net/strategies/SinglePoolStrategy.h | 2 +- src/net/Network.cpp | 2 +- src/net/strategies/DonateStrategy.cpp | 2 +- 7 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/common/net/Client.cpp b/src/common/net/Client.cpp index c7cdd358..f141af66 100644 --- a/src/common/net/Client.cpp +++ b/src/common/net/Client.cpp @@ -55,6 +55,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) : m_agent(agent), m_listener(listener), m_id(id), + m_retries(5), m_retryPause(5000), m_failures(0), m_recvBufPos(0), @@ -267,7 +268,7 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } - if (!m_quiet) { + if (!isQuiet()) { LOG_WARN("[%s] duplicate job received, reconnect", m_pool.url()); } @@ -311,7 +312,7 @@ int Client::resolve(const char *host) const int r = uv_getaddrinfo(uv_default_loop(), &m_resolver, Client::onResolved, host, nullptr, &m_hints); if (r) { - if (!m_quiet) { + if (!isQuiet()) { LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host, m_pool.port(), uv_strerror(r)); } return 1; @@ -453,7 +454,7 @@ void Client::parse(char *line, size_t len) LOG_DEBUG("[%s] received (%d bytes): \"%s\"", m_pool.url(), len, line); if (len < 32 || line[0] != '{') { - if (!m_quiet) { + if (!isQuiet()) { LOG_ERR("[%s] JSON decode failed", m_pool.url()); } @@ -462,7 +463,7 @@ void Client::parse(char *line, size_t len) rapidjson::Document doc; if (doc.ParseInsitu(line).HasParseError()) { - if (!m_quiet) { + if (!isQuiet()) { LOG_ERR("[%s] JSON decode failed: \"%s\"", m_pool.url(), rapidjson::GetParseError_En(doc.GetParseError())); } @@ -504,7 +505,7 @@ void Client::parseExtensions(const rapidjson::Value &value) void Client::parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error) { if (error.IsObject()) { - if (!m_quiet) { + if (!isQuiet()) { LOG_ERR("[%s] error: \"%s\", code: %d", m_pool.url(), error["message"].GetString(), error["code"].GetInt()); } return; @@ -538,7 +539,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap m_listener->onResultAccepted(this, it->second, message); m_results.erase(it); } - else if (!m_quiet) { + else if (!isQuiet()) { LOG_ERR("[%s] error: \"%s\", code: %d", m_pool.url(), message, error["code"].GetInt()); } @@ -556,7 +557,7 @@ void Client::parseResponse(int64_t id, const rapidjson::Value &result, const rap if (id == 1) { int code = -1; if (!parseLogin(result, &code)) { - if (!m_quiet) { + if (!isQuiet()) { LOG_ERR("[%s] login error code: %d", m_pool.url(), code); } @@ -661,7 +662,7 @@ void Client::onConnect(uv_connect_t *req, int status) } if (status < 0) { - if (!client->m_quiet) { + if (!client->isQuiet()) { LOG_ERR("[%s] connect error: \"%s\"", client->m_pool.url(), uv_strerror(status)); } @@ -689,7 +690,7 @@ void Client::onRead(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) } if (nread < 0) { - if (nread != UV_EOF && !client->m_quiet) { + if (nread != UV_EOF && !client->isQuiet()) { LOG_ERR("[%s] read error: \"%s\"", client->m_pool.url(), uv_strerror((int) nread)); } @@ -749,7 +750,7 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) } if (status < 0) { - if (!client->m_quiet) { + if (!client->isQuiet()) { LOG_ERR("[%s] DNS error: \"%s\"", client->m_pool.url(), uv_strerror(status)); } @@ -773,7 +774,7 @@ void Client::onResolved(uv_getaddrinfo_t *req, int status, struct addrinfo *res) } if (ipv4.empty() && ipv6.empty()) { - if (!client->m_quiet) { + if (!client->isQuiet()) { LOG_ERR("[%s] DNS error: \"No IPv4 (A) or IPv6 (AAAA) records found\"", client->m_pool.url()); } diff --git a/src/common/net/Client.h b/src/common/net/Client.h index 651f97b5..97bf16a5 100644 --- a/src/common/net/Client.h +++ b/src/common/net/Client.h @@ -74,6 +74,7 @@ public: inline SocketState state() const { return m_state; } inline uint16_t port() const { return m_pool.port(); } inline void setQuiet(bool quiet) { m_quiet = quiet; } + inline void setRetries(int retries) { m_retries = retries; } inline void setRetryPause(int ms) { m_retryPause = ms; } private: @@ -96,6 +97,8 @@ private: void setState(SocketState state); void startTimeout(); + inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; } + static void onAllocBuffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf); static void onClose(uv_handle_t *handle); static void onConnect(uv_connect_t *req, int status); @@ -114,6 +117,7 @@ private: const char *m_agent; IClientListener *m_listener; int m_id; + int m_retries; int m_retryPause; int64_t m_failures; Job m_job; diff --git a/src/common/net/strategies/FailoverStrategy.cpp b/src/common/net/strategies/FailoverStrategy.cpp index 58854498..295b4335 100644 --- a/src/common/net/strategies/FailoverStrategy.cpp +++ b/src/common/net/strategies/FailoverStrategy.cpp @@ -157,6 +157,7 @@ void FailoverStrategy::add(const Pool &pool) { Client *client = new Client((int) m_pools.size(), Platform::userAgent(), this); client->setPool(pool); + client->setRetries(m_retries); client->setRetryPause(m_retryPause * 1000); client->setQuiet(m_quiet); diff --git a/src/common/net/strategies/SinglePoolStrategy.cpp b/src/common/net/strategies/SinglePoolStrategy.cpp index 50620ab2..21ce7b34 100644 --- a/src/common/net/strategies/SinglePoolStrategy.cpp +++ b/src/common/net/strategies/SinglePoolStrategy.cpp @@ -28,12 +28,13 @@ #include "interfaces/IStrategyListener.h" -SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, IStrategyListener *listener, bool quiet) : +SinglePoolStrategy::SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet) : m_active(false), m_listener(listener) { m_client = new Client(0, Platform::userAgent(), this); m_client->setPool(pool); + m_client->setRetries(retries); m_client->setRetryPause(retryPause * 1000); m_client->setQuiet(quiet); } diff --git a/src/common/net/strategies/SinglePoolStrategy.h b/src/common/net/strategies/SinglePoolStrategy.h index ce3d0f7f..41d90e34 100644 --- a/src/common/net/strategies/SinglePoolStrategy.h +++ b/src/common/net/strategies/SinglePoolStrategy.h @@ -37,7 +37,7 @@ class Url; class SinglePoolStrategy : public IStrategy, public IClientListener { public: - SinglePoolStrategy(const Pool &pool, int retryPause, IStrategyListener *listener, bool quiet = false); + SinglePoolStrategy(const Pool &pool, int retryPause, int retries, IStrategyListener *listener, bool quiet = false); ~SinglePoolStrategy(); public: diff --git a/src/net/Network.cpp b/src/net/Network.cpp index bcd13ee1..7293a0ac 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -57,7 +57,7 @@ Network::Network(xmrig::Controller *controller) : m_strategy = new FailoverStrategy(pools, controller->config()->retryPause(), controller->config()->retries(), this); } else { - m_strategy = new SinglePoolStrategy(pools.front(), controller->config()->retryPause(), this); + m_strategy = new SinglePoolStrategy(pools.front(), controller->config()->retryPause(), controller->config()->retries(), this); } if (controller->config()->donateLevel() > 0) { diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 3bb5caa2..b4b41938 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -75,7 +75,7 @@ DonateStrategy::DonateStrategy(int level, const char *user, xmrig::Algo algo, IS m_strategy = new FailoverStrategy(m_pools, 1, 2, this, true); } else { - m_strategy = new SinglePoolStrategy(m_pools.front(), 1, this, true); + m_strategy = new SinglePoolStrategy(m_pools.front(), 1, 2, this, true); } m_timer.data = this; From 85f9bd97f14eaba2432d5012772949500eb30621 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 26 Apr 2018 23:27:53 +0700 Subject: [PATCH 095/109] Verify & send algorithm name. --- src/common/net/Client.cpp | 108 ++++++++++++++++++++++++++++-------- src/common/net/Client.h | 8 +++ src/common/net/Pool.cpp | 12 ++++ src/common/net/Pool.h | 1 + src/net/JobResult.h | 22 +------- src/workers/MultiWorker.cpp | 2 +- 6 files changed, 109 insertions(+), 44 deletions(-) diff --git a/src/common/net/Client.cpp b/src/common/net/Client.cpp index f141af66..c53397a3 100644 --- a/src/common/net/Client.cpp +++ b/src/common/net/Client.cpp @@ -54,6 +54,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) : m_quiet(false), m_agent(agent), m_listener(listener), + m_extensions(0), m_id(id), m_retries(5), m_retryPause(5000), @@ -161,12 +162,14 @@ bool Client::disconnect() int64_t Client::submit(const JobResult &result) { + using namespace rapidjson; + # ifdef XMRIG_PROXY_PROJECT const char *nonce = result.nonce; const char *data = result.result; # else - char nonce[9]; - char data[65]; + char *nonce = m_sendBuf; + char *data = m_sendBuf + 16; Job::toHex(reinterpret_cast(&result.nonce), 4, nonce); nonce[8] = '\0'; @@ -175,8 +178,24 @@ int64_t Client::submit(const JobResult &result) data[64] = '\0'; # endif - const size_t size = snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRIu64 ",\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n", - m_sequence, m_rpcId.data(), result.jobId.data(), nonce, data); + Document doc(kObjectType); + auto &allocator = doc.GetAllocator(); + + doc.AddMember("id", m_sequence, allocator); + doc.AddMember("jsonrpc", "2.0", allocator); + doc.AddMember("method", "submit", allocator); + + Value params(kObjectType); + params.AddMember("id", StringRef(m_rpcId.data()), allocator); + params.AddMember("job_id", StringRef(result.jobId.data()), allocator); + params.AddMember("nonce", StringRef(nonce), allocator); + params.AddMember("result", StringRef(data), allocator); + + if (m_extensions & AlgoExt) { + params.AddMember("algo", StringRef(result.algorithm.shortName()), allocator); + } + + doc.AddMember("params", params, allocator); # ifdef XMRIG_PROXY_PROJECT m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id); @@ -184,7 +203,7 @@ int64_t Client::submit(const JobResult &result) m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff()); # endif - return send(size); + return send(doc); } @@ -258,6 +277,13 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) job.algorithm().parseVariant(params["variant"].GetInt()); } + if (!verifyAlgorithm(job.algorithm())) { + *code = 6; + + close(); + return false; + } + if (m_job != job) { m_jobs++; m_job = std::move(job); @@ -284,9 +310,7 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code) return false; } -# ifndef XMRIG_PROXY_PROJECT m_nicehash = m_pool.isNicehash(); -# endif if (result.HasMember("extensions")) { parseExtensions(result["extensions"]); @@ -299,6 +323,27 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code) } +bool Client::verifyAlgorithm(const xmrig::Algorithm &algorithm) const +{ + if (m_pool.isCompatible(algorithm)) { + return true; + } + + if (isQuiet()) { + return false; + } + + if (algorithm.isValid()) { + LOG_ERR("Incompatible algorithm \"%s\" detected, reconnect", algorithm.name()); + } + else { + LOG_ERR("Unknown/unsupported algorithm detected, reconnect"); + } + + return false; +} + + int Client::resolve(const char *host) { setState(HostLookupState); @@ -322,6 +367,27 @@ int Client::resolve(const char *host) } +int64_t Client::send(const rapidjson::Document &doc) +{ + using namespace rapidjson; + + StringBuffer buffer(0, 512); + Writer writer(buffer); + doc.Accept(writer); + + const size_t size = buffer.GetSize(); + if (size > (sizeof(m_buf) - 2)) { + return -1; + } + + memcpy(m_sendBuf, buffer.GetString(), size); + m_sendBuf[size] = '\n'; + m_sendBuf[size + 1] = '\0'; + + return send(size + 1); +} + + int64_t Client::send(size_t size) { LOG_DEBUG("[%s] send (%d bytes): \"%s\"", m_pool.url(), size, m_sendBuf); @@ -389,9 +455,7 @@ void Client::login() using namespace rapidjson; m_results.clear(); - Document doc; - doc.SetObject(); - + Document doc(kObjectType); auto &allocator = doc.GetAllocator(); doc.AddMember("id", 1, allocator); @@ -416,20 +480,7 @@ void Client::login() params.AddMember("algo", algo, allocator); doc.AddMember("params", params, allocator); - StringBuffer buffer(0, 512); - Writer writer(buffer); - doc.Accept(writer); - - const size_t size = buffer.GetSize(); - if (size > (sizeof(m_buf) - 2)) { - return; - } - - memcpy(m_sendBuf, buffer.GetString(), size); - m_sendBuf[size] = '\n'; - m_sendBuf[size + 1] = '\0'; - - send(size + 1); + send(doc); } @@ -486,6 +537,8 @@ void Client::parse(char *line, size_t len) void Client::parseExtensions(const rapidjson::Value &value) { + m_extensions = 0; + if (!value.IsArray()) { return; } @@ -495,8 +548,15 @@ void Client::parseExtensions(const rapidjson::Value &value) continue; } + if (strcmp(ext.GetString(), "algo") == 0) { + m_extensions |= AlgoExt; + continue; + } + if (strcmp(ext.GetString(), "nicehash") == 0) { + m_extensions |= NicehashExt; m_nicehash = true; + continue; } } } diff --git a/src/common/net/Client.h b/src/common/net/Client.h index 97bf16a5..27273092 100644 --- a/src/common/net/Client.h +++ b/src/common/net/Client.h @@ -78,11 +78,18 @@ public: inline void setRetryPause(int ms) { m_retryPause = ms; } private: + enum Extensions { + NicehashExt = 1, + AlgoExt = 2 + }; + bool close(); bool isCriticalError(const char *message); bool parseJob(const rapidjson::Value ¶ms, int *code); bool parseLogin(const rapidjson::Value &result, int *code); + bool verifyAlgorithm(const xmrig::Algorithm &algorithm) const; int resolve(const char *host); + int64_t send(const rapidjson::Document &doc); int64_t send(size_t size); void connect(const std::vector &ipv4, const std::vector &ipv6); void connect(sockaddr *addr); @@ -116,6 +123,7 @@ private: char m_sendBuf[768]; const char *m_agent; IClientListener *m_listener; + int m_extensions; int m_id; int m_retries; int m_retryPause; diff --git a/src/common/net/Pool.cpp b/src/common/net/Pool.cpp index aa1fa651..ab3bdea7 100644 --- a/src/common/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -92,6 +92,18 @@ Pool::Pool(const char *host, uint16_t port, const char *user, const char *passwo } +bool Pool::isCompatible(const xmrig::Algorithm &algorithm) const +{ + for (const auto &a : m_algorithms) { + if (algorithm == a) { + return true; + } + } + + return false; +} + + bool Pool::isEqual(const Pool &other) const { return (m_nicehash == other.m_nicehash diff --git a/src/common/net/Pool.h b/src/common/net/Pool.h index eb926b3b..5475e10d 100644 --- a/src/common/net/Pool.h +++ b/src/common/net/Pool.h @@ -72,6 +72,7 @@ public: inline bool operator!=(const Pool &other) const { return !isEqual(other); } inline bool operator==(const Pool &other) const { return isEqual(other); } + bool isCompatible(const xmrig::Algorithm &algorithm) const; bool isEqual(const Pool &other) const; bool parse(const char *url); bool setUserpass(const char *userpass); diff --git a/src/net/JobResult.h b/src/net/JobResult.h index 68afc862..4a920ca0 100644 --- a/src/net/JobResult.h +++ b/src/net/JobResult.h @@ -36,34 +36,17 @@ class JobResult { public: inline JobResult() : poolId(0), diff(0), nonce(0) {} - inline JobResult(int poolId, const xmrig::Id &jobId, uint32_t nonce, const uint8_t *result, uint32_t diff) : + inline JobResult(int poolId, const xmrig::Id &jobId, uint32_t nonce, const uint8_t *result, uint32_t diff, const xmrig::Algorithm &algorithm) : poolId(poolId), diff(diff), nonce(nonce), + algorithm(algorithm), jobId(jobId) { memcpy(this->result, result, sizeof(this->result)); } - inline JobResult(const Job &job) : poolId(0), diff(0), nonce(0) - { - jobId = job.id(); - poolId = job.poolId(); - diff = job.diff(); - nonce = *job.nonce(); - } - - - inline JobResult &operator=(const Job &job) { - jobId = job.id(); - poolId = job.poolId(); - diff = job.diff(); - - return *this; - } - - inline uint64_t actualDiff() const { return Job::toDiff(reinterpret_cast(result)[3]); @@ -74,6 +57,7 @@ public: uint32_t diff; uint32_t nonce; uint8_t result[32]; + xmrig::Algorithm algorithm; xmrig::Id jobId; }; diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index b3b384f6..d4d5992c 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -108,7 +108,7 @@ void MultiWorker::start() for (size_t i = 0; i < N; ++i) { if (*reinterpret_cast(m_hash + (i * 32) + 24) < m_state.job.target()) { - Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash + (i * 32), m_state.job.diff())); + Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash + (i * 32), m_state.job.diff(), m_state.job.algorithm())); } *nonce(i) += 1; From 3df99fbcedb0d736e7c16e51b5d988e92518fe6d Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 27 Apr 2018 00:28:52 +0700 Subject: [PATCH 096/109] Add Stellite (XTL) support as cn/xtl. --- src/crypto/CryptoNight_test.h | 15 +++++++++++++++ src/crypto/CryptoNight_x86.h | 11 ++++++----- src/workers/MultiWorker.cpp | 6 +++++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/crypto/CryptoNight_test.h b/src/crypto/CryptoNight_test.h index 66630393..bf6013e8 100644 --- a/src/crypto/CryptoNight_test.h +++ b/src/crypto/CryptoNight_test.h @@ -84,6 +84,21 @@ const static uint8_t test_output_v1[160] = { }; +// Stellite (XTL) +const static uint8_t test_output_xtl[160] = { + 0x8F, 0xE5, 0xF0, 0x5F, 0x02, 0x2A, 0x61, 0x7D, 0xE5, 0x3F, 0x79, 0x36, 0x4B, 0x25, 0xCB, 0xC3, + 0xC0, 0x8E, 0x0E, 0x1F, 0xE3, 0xBE, 0x48, 0x57, 0x07, 0x03, 0xFE, 0xE1, 0xEC, 0x0E, 0xB0, 0xB1, + 0x21, 0x26, 0xFF, 0x98, 0xE6, 0x86, 0x08, 0x5B, 0xC9, 0x96, 0x44, 0xA3, 0xB8, 0x4E, 0x28, 0x90, + 0x76, 0xED, 0xAD, 0xB9, 0xAA, 0xAC, 0x01, 0x94, 0x1D, 0xBE, 0x3E, 0xEA, 0xAD, 0xEE, 0xB2, 0xCF, + 0xB0, 0x43, 0x4B, 0x88, 0xFC, 0xB2, 0xF3, 0x82, 0x9D, 0xD7, 0xDF, 0x51, 0x97, 0x2C, 0x5A, 0xE3, + 0xC7, 0x16, 0x0B, 0xC8, 0x7C, 0xB7, 0x2F, 0x1C, 0x55, 0x33, 0xCA, 0xE1, 0xEE, 0x08, 0xA4, 0x86, + 0x60, 0xED, 0x6E, 0x9D, 0x2D, 0x05, 0x0D, 0x7D, 0x02, 0x49, 0x23, 0x39, 0x7C, 0xC3, 0x6D, 0x3D, + 0x05, 0x51, 0x28, 0xF1, 0x9B, 0x3C, 0xDF, 0xC4, 0xEA, 0x8A, 0xA6, 0x6A, 0x3C, 0x8B, 0xE2, 0xAF, + 0x47, 0x00, 0xFC, 0x36, 0xED, 0x50, 0xBB, 0xD2, 0x2E, 0x63, 0x4B, 0x93, 0x11, 0x0C, 0xA7, 0xBA, + 0x32, 0x6E, 0x47, 0x4D, 0xCE, 0xCC, 0x82, 0x54, 0x1D, 0x06, 0xF8, 0x06, 0x86, 0xBD, 0x22, 0x48 +}; + + #ifndef XMRIG_NO_AEON const static uint8_t test_output_v0_lite[160] = { 0x36, 0x95, 0xB4, 0xB5, 0x3B, 0xB0, 0x03, 0x58, 0xB0, 0xAD, 0x38, 0xDC, 0x16, 0x0F, 0xEB, 0x9E, diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index 75778053..66bcf8b5 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -386,6 +386,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) } +template static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp) { mem_out[0] = EXTRACT64(tmp); @@ -395,7 +396,7 @@ static inline void cryptonight_monero_tweak(uint64_t* mem_out, __m128i tmp) uint8_t x = vh >> 24; static const uint16_t table = 0x7531; - const uint8_t index = (((x >> 3) & 6) | (x & 1)) << 1; + const uint8_t index = (((x >> SHIFT) & 6) | (x & 1)) << 1; vh ^= ((table >> index) & 0x3) << 28; mem_out[1] = vh; @@ -441,7 +442,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si } if (VARIANT > 0) { - cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); + cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); } else { _mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); } @@ -544,8 +545,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si } if (VARIANT > 0) { - cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); - cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); + cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); + cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); } else { _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx0, cx0)); _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx1, cx1)); @@ -653,7 +654,7 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si b = _mm_xor_si128(b, c); \ \ if (VARIANT > 0) { \ - cryptonight_monero_tweak(reinterpret_cast(ptr), b); \ + cryptonight_monero_tweak(reinterpret_cast(ptr), b); \ } else { \ _mm_store_si128(ptr, b); \ } diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index d4d5992c..c0f88446 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -58,8 +58,12 @@ bool MultiWorker::selfTest() if (m_thread->algorithm() == xmrig::CRYPTONIGHT && memcmp(m_hash, test_output_v0, sizeof m_hash) == 0) { m_thread->fn(xmrig::VARIANT_1)(test_input, 76, m_hash, m_ctx); + if (memcmp(m_hash, test_output_v1, sizeof m_hash) != 0) { + return false; + } - return memcmp(m_hash, test_output_v1, sizeof m_hash) == 0; + m_thread->fn(xmrig::VARIANT_XTL)(test_input, 76, m_hash, m_ctx); + return memcmp(m_hash, test_output_xtl, sizeof m_hash) == 0; } # ifndef XMRIG_NO_AEON From be232fa1f26b0e73f92146668c42bd3fae8e0172 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 27 Apr 2018 00:40:22 +0700 Subject: [PATCH 097/109] Also support variant received as string. --- src/common/crypto/Algorithm.cpp | 1 + src/common/net/Client.cpp | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/common/crypto/Algorithm.cpp b/src/common/crypto/Algorithm.cpp index 3123c361..168468f4 100644 --- a/src/common/crypto/Algorithm.cpp +++ b/src/common/crypto/Algorithm.cpp @@ -127,6 +127,7 @@ void xmrig::Algorithm::parseAlgorithm(const char *algo) void xmrig::Algorithm::parseVariant(const char *variant) { if (m_algo == CRYPTONIGHT_HEAVY) { + m_variant = VARIANT_0; return; } diff --git a/src/common/net/Client.cpp b/src/common/net/Client.cpp index c53397a3..921fa618 100644 --- a/src/common/net/Client.cpp +++ b/src/common/net/Client.cpp @@ -274,7 +274,14 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) } if (params.HasMember("variant")) { - job.algorithm().parseVariant(params["variant"].GetInt()); + const rapidjson::Value &variant = params["variant"]; + + if (variant.IsInt()) { + job.algorithm().parseVariant(variant.GetInt()); + } + else if (variant.IsString()){ + job.algorithm().parseVariant(variant.GetString()); + } } if (!verifyAlgorithm(job.algorithm())) { From 2b0309e1591a4a804b666af5d9d105f509028ad5 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 29 Apr 2018 14:24:44 +0700 Subject: [PATCH 098/109] Sync changes with proxy. --- src/common/crypto/Algorithm.cpp | 34 +++++++++++++++++++++++++++++++++ src/common/crypto/Algorithm.h | 9 +++++++++ src/common/log/Log.h | 2 ++ src/core/Config.cpp | 2 +- 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/common/crypto/Algorithm.cpp b/src/common/crypto/Algorithm.cpp index 168468f4..f3e9b23d 100644 --- a/src/common/crypto/Algorithm.cpp +++ b/src/common/crypto/Algorithm.cpp @@ -71,6 +71,19 @@ static AlgoData const algorithms[] = { }; +#ifdef XMRIG_PROXY_PROJECT +static AlgoData const xmrStakAlgorithms[] = { + { "cryptonight-monerov7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, + { "cryptonight_v7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, + { "cryptonight_v7_stellite", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL }, + { "cryptonight_lite", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 }, + { "cryptonight-aeonv7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, + { "cryptonight_lite_v7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, + { "cryptonight_lite_v7_xor", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_IPBC }, +}; +#endif + + static const char *variants[] = { "0", "1", @@ -163,6 +176,27 @@ void xmrig::Algorithm::setAlgo(Algo algo) } +#ifdef XMRIG_PROXY_PROJECT +void xmrig::Algorithm::parseXmrStakAlgorithm(const char *algo) +{ + m_algo = INVALID_ALGO; + m_variant = VARIANT_AUTO; + + for (size_t i = 0; i < ARRAY_SIZE(xmrStakAlgorithms); i++) { + if (strcasecmp(algo, xmrStakAlgorithms[i].name) == 0) { + m_algo = xmrStakAlgorithms[i].algo; + m_variant = xmrStakAlgorithms[i].variant; + break; + } + } + + if (m_algo == INVALID_ALGO) { + assert(false); + } +} +#endif + + const char *xmrig::Algorithm::name(bool shortName) const { for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) { diff --git a/src/common/crypto/Algorithm.h b/src/common/crypto/Algorithm.h index a34d5c07..bcf029d8 100644 --- a/src/common/crypto/Algorithm.h +++ b/src/common/crypto/Algorithm.h @@ -49,6 +49,11 @@ public: setAlgo(algo); } + inline Algorithm(const char *algo) + { + parseAlgorithm(algo); + } + bool isEqual(const Algorithm &other) const { return m_algo == other.m_algo && m_variant == other.m_variant; } inline Algo algo() const { return m_algo; } inline const char *name() const { return name(false); } @@ -66,6 +71,10 @@ public: void parseVariant(int variant); void setAlgo(Algo algo); +# ifdef XMRIG_PROXY_PROJECT + void parseXmrStakAlgorithm(const char *algo); +# endif + private: const char *name(bool shortName) const; diff --git a/src/common/log/Log.h b/src/common/log/Log.h index 0b333272..463c2248 100644 --- a/src/common/log/Log.h +++ b/src/common/log/Log.h @@ -80,6 +80,8 @@ private: }; +#define RED_BOLD(x) "\e[1;31m" x "\e[0m" +#define RED(x) "\e[0;31m" x "\e[0m" #define GREEN_BOLD(x) "\e[1;32m" x "\e[0m" #define GREEN(x) "\e[0;32m" x "\e[0m" #define MAGENTA_BOLD(x) "\e[1;35m" x "\e[0m" diff --git a/src/core/Config.cpp b/src/core/Config.cpp index a27dc917..0c4ce779 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -102,7 +102,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const Value pools(kArrayType); - for (const Pool &pool : m_pools) { + for (const Pool &pool : m_activePools) { pools.PushBack(pool.toJSON(doc), allocator); } From 9c2318617234dadf0117f10ae05c55008c53e35d Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 30 Apr 2018 18:17:07 +0700 Subject: [PATCH 099/109] Sync changes with proxy. --- src/common/crypto/Algorithm.cpp | 10 +++++++ src/common/net/Pool.cpp | 47 +++++++++++++-------------------- src/common/net/Pool.h | 4 +++ 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/common/crypto/Algorithm.cpp b/src/common/crypto/Algorithm.cpp index f3e9b23d..fce4d7b8 100644 --- a/src/common/crypto/Algorithm.cpp +++ b/src/common/crypto/Algorithm.cpp @@ -123,6 +123,11 @@ void xmrig::Algorithm::parseAlgorithm(const char *algo) m_algo = INVALID_ALGO; m_variant = VARIANT_AUTO; + assert(algo != nullptr); + if (algo == nullptr) { + return; + } + for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) { if ((strcasecmp(algo, algorithms[i].name) == 0) || (strcasecmp(algo, algorithms[i].shortName) == 0)) { m_algo = algorithms[i].algo; @@ -182,6 +187,11 @@ void xmrig::Algorithm::parseXmrStakAlgorithm(const char *algo) m_algo = INVALID_ALGO; m_variant = VARIANT_AUTO; + assert(algo != nullptr); + if (algo == nullptr) { + return; + } + for (size_t i = 0; i < ARRAY_SIZE(xmrStakAlgorithms); i++) { if (strcasecmp(algo, xmrStakAlgorithms[i].name) == 0) { m_algo = xmrStakAlgorithms[i].algo; diff --git a/src/common/net/Pool.cpp b/src/common/net/Pool.cpp index ab3bdea7..25d99097 100644 --- a/src/common/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -37,9 +37,6 @@ #endif -#define ADD_VARIANT(variant) m_algorithms.push_back(xmrig::Algorithm(m_algorithm.algo(), variant)); - - #ifdef _MSC_VER # define strncasecmp _strnicmp # define strcasecmp _stricmp @@ -240,32 +237,15 @@ void Pool::adjust(xmrig::Algo algorithm) m_algorithm.setVariant(xmrig::VARIANT_1); } -# ifndef XMRIG_PROXY_PROJECT - switch (m_algorithm.algo()) { - case xmrig::CRYPTONIGHT: - ADD_VARIANT(xmrig::VARIANT_AUTO); - ADD_VARIANT(xmrig::VARIANT_0); - ADD_VARIANT(xmrig::VARIANT_1); - ADD_VARIANT(xmrig::VARIANT_XTL); - break; - - case xmrig::CRYPTONIGHT_LITE: - ADD_VARIANT(xmrig::VARIANT_AUTO); - ADD_VARIANT(xmrig::VARIANT_0); - ADD_VARIANT(xmrig::VARIANT_1); - ADD_VARIANT(xmrig::VARIANT_IPBC); - break; - - case xmrig::CRYPTONIGHT_HEAVY: - ADD_VARIANT(xmrig::VARIANT_0); - break; - - default: - break; - } -# else m_algorithms.push_back(m_algorithm); -# endif + + if (m_algorithm.algo() != xmrig::CRYPTONIGHT_HEAVY) { + addVariant(xmrig::VARIANT_1); + addVariant(xmrig::VARIANT_0); + addVariant(xmrig::VARIANT_XTL); + addVariant(xmrig::VARIANT_IPBC); + addVariant(xmrig::VARIANT_AUTO); + } } @@ -306,3 +286,14 @@ bool Pool::parseIPv6(const char *addr) return true; } + + +void Pool::addVariant(xmrig::Variant variant) +{ + const xmrig::Algorithm algorithm(m_algorithm.algo(), variant); + if (!algorithm.isValid() || m_algorithm == algorithm) { + return; + } + + m_algorithms.push_back(algorithm); +} diff --git a/src/common/net/Pool.h b/src/common/net/Pool.h index 5475e10d..ad015bf2 100644 --- a/src/common/net/Pool.h +++ b/src/common/net/Pool.h @@ -85,6 +85,7 @@ public: private: bool parseIPv6(const char *addr); + void addVariant(xmrig::Variant variant); bool m_nicehash; int m_keepAlive; @@ -98,4 +99,7 @@ private: xmrig::c_str m_user; }; + +typedef std::vector Pools; + #endif /* __POOL_H__ */ From 3ca7f3eece5215d99f3cf41e1b8dc081cbb4efde Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 3 May 2018 00:37:01 +0700 Subject: [PATCH 100/109] Sync changes with proxy. --- src/common/net/Pool.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/net/Pool.cpp b/src/common/net/Pool.cpp index 25d99097..8c0de46a 100644 --- a/src/common/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -239,6 +239,7 @@ void Pool::adjust(xmrig::Algo algorithm) m_algorithms.push_back(m_algorithm); +# ifndef XMRIG_PROXY_PROJECT if (m_algorithm.algo() != xmrig::CRYPTONIGHT_HEAVY) { addVariant(xmrig::VARIANT_1); addVariant(xmrig::VARIANT_0); @@ -246,6 +247,7 @@ void Pool::adjust(xmrig::Algo algorithm) addVariant(xmrig::VARIANT_IPBC); addVariant(xmrig::VARIANT_AUTO); } +# endif } From b533644f3fcdc9b389e61adc2f26f9e7213ba49a Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 3 May 2018 04:12:53 +0700 Subject: [PATCH 101/109] v2.6.1-dev --- res/app.rc | 4 ++-- src/version.h | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/res/app.rc b/res/app.rc index 800ce2dd..037d842a 100644 --- a/res/app.rc +++ b/res/app.rc @@ -4,8 +4,8 @@ IDI_ICON1 ICON DISCARDABLE "app.ico" VS_VERSION_INFO VERSIONINFO - FILEVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_BUILD,APP_VER_REV - PRODUCTVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_BUILD,APP_VER_REV + FILEVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_PATCH,0 + PRODUCTVERSION APP_VER_MAJOR,APP_VER_MINOR,APP_VER_PATCH,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG diff --git a/src/version.h b/src/version.h index c6c42e46..b0e4d2a5 100644 --- a/src/version.h +++ b/src/version.h @@ -27,7 +27,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig CPU miner" -#define APP_VERSION "2.6.0-beta3" +#define APP_VERSION "2.6.1-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2018 xmrig.com" @@ -35,8 +35,7 @@ #define APP_VER_MAJOR 2 #define APP_VER_MINOR 6 -#define APP_VER_BUILD 0 -#define APP_VER_REV 3 +#define APP_VER_PATCH 1 #ifdef _MSC_VER # if (_MSC_VER >= 1910) From 3da58239057f66d56a2cda8088bd843acfd11533 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 3 May 2018 04:15:36 +0700 Subject: [PATCH 102/109] Remove obsolete tests. --- test/CMakeLists.txt | 9 - test/autoconf/CMakeLists.txt | 16 - test/autoconf/autoconf.c | 152 --- test/cryptonight/CMakeLists.txt | 28 - test/cryptonight/cryptonight.c | 136 -- test/cryptonight_lite/CMakeLists.txt | 27 - test/cryptonight_lite/cryptonight_lite.c | 124 -- test/unity/CMakeLists.txt | 2 - test/unity/unity.c | 1446 ---------------------- test/unity/unity.h | 293 ----- test/unity/unity_internals.h | 749 ----------- 11 files changed, 2982 deletions(-) delete mode 100644 test/CMakeLists.txt delete mode 100644 test/autoconf/CMakeLists.txt delete mode 100644 test/autoconf/autoconf.c delete mode 100644 test/cryptonight/CMakeLists.txt delete mode 100644 test/cryptonight/cryptonight.c delete mode 100644 test/cryptonight_lite/CMakeLists.txt delete mode 100644 test/cryptonight_lite/cryptonight_lite.c delete mode 100644 test/unity/CMakeLists.txt delete mode 100644 test/unity/unity.c delete mode 100644 test/unity/unity.h delete mode 100644 test/unity/unity_internals.h diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt deleted file mode 100644 index b30cfb0b..00000000 --- a/test/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -project("xmrig-test" C) -cmake_minimum_required(VERSION 3.0) - -include(CTest) - -add_subdirectory(unity) -add_subdirectory(cryptonight) -add_subdirectory(cryptonight_lite) -add_subdirectory(autoconf) \ No newline at end of file diff --git a/test/autoconf/CMakeLists.txt b/test/autoconf/CMakeLists.txt deleted file mode 100644 index b956a9de..00000000 --- a/test/autoconf/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -set(SOURCES - autoconf.c - ../../cpu.h - ../../cpu.c - ) - -add_executable(autoconf_app ${SOURCES}) -target_link_libraries(autoconf_app unity) - -include_directories(../..) - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-strict-aliasing") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2") -add_definitions(-DBUILD_TEST) - -add_test(autoconf_test autoconf_app) diff --git a/test/autoconf/autoconf.c b/test/autoconf/autoconf.c deleted file mode 100644 index 86ced5f0..00000000 --- a/test/autoconf/autoconf.c +++ /dev/null @@ -1,152 +0,0 @@ -#include - -#include "cpu.h" -#include "options.h" - -struct cpu_info cpu_info = { 0 }; - - -static void set_cpu_info(int total_logical_cpus, int l2_cache, int l3_cache) { - cpu_info.total_cores = total_logical_cpus; - cpu_info.total_logical_cpus = total_logical_cpus; - cpu_info.l2_cache = l2_cache; - cpu_info.l3_cache = l3_cache; -} - - -void test_autoconf_should_GetOptimalThreadsCounti7(void) { - set_cpu_info(8, 1024, 8192); // 4C/8T 8 MB (Generic i7 CPU) - - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100)); - TEST_ASSERT_EQUAL_INT(2, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100)); - - TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100)); - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100)); - - TEST_ASSERT_EQUAL_INT(6, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75)); - TEST_ASSERT_EQUAL_INT(5, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 60)); - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 50)); - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 35)); - TEST_ASSERT_EQUAL_INT(2, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 20)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 5)); -} - - -void test_autoconf_should_GetOptimalThreadsCounti5(void) { - set_cpu_info(4, 1024, 6144); // 2C/4T 6 MB (Generic i5 CPU) - - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100)); - - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75)); - - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100)); - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100)); - - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75)); - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75)); -} - - -void test_autoconf_should_GetOptimalThreadsCounti3(void) { - set_cpu_info(4, 512, 3072); // 2C/4T 3 MB (Generic i3 CPU) - - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100)); - - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75)); - - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100)); - - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75)); -} - - -void test_autoconf_should_GetOptimalThreadsCountR7(void) { - set_cpu_info(16, 4096, 16384); // 8C/16T 16 MB (AMD Ryzen 7) - - TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100)); - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100)); - - TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75)); - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75)); - - TEST_ASSERT_EQUAL_INT(16, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100)); - TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100)); - - TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75)); - TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75)); -} - - -void test_autoconf_should_GetOptimalThreadsCountTwoE5620(void) { - set_cpu_info(16, 2048, 24576); // 8C/16T 24 MB (Two E5620) - - TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100)); - TEST_ASSERT_EQUAL_INT(6, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100)); - - TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75)); - TEST_ASSERT_EQUAL_INT(6, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75)); - - TEST_ASSERT_EQUAL_INT(16, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100)); - TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100)); - - TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75)); - TEST_ASSERT_EQUAL_INT(12, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75)); -} - - -void test_autoconf_should_GetOptimalThreadsCountVCPU(void) { - set_cpu_info(1, 1024, 15360); // 1C/1T 15 MB (Single core Virtual CPU) - - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100)); - - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 75)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 75)); - - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100)); - - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 75)); -} - - -void test_autoconf_should_GetOptimalThreadsCountNoL3(void) { - set_cpu_info(8, 8192, 0); // 4C/8T (Multi core Virtual CPU without L3 cache) - - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT, false, 100)); - TEST_ASSERT_EQUAL_INT(2, get_optimal_threads_count(ALGO_CRYPTONIGHT, true, 100)); - - TEST_ASSERT_EQUAL_INT(8, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 100)); - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, true, 100)); - - TEST_ASSERT_EQUAL_INT(6, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 75)); - TEST_ASSERT_EQUAL_INT(5, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 60)); - TEST_ASSERT_EQUAL_INT(4, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 50)); - TEST_ASSERT_EQUAL_INT(3, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 35)); - TEST_ASSERT_EQUAL_INT(2, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 20)); - TEST_ASSERT_EQUAL_INT(1, get_optimal_threads_count(ALGO_CRYPTONIGHT_LITE, false, 5)); -} - - -int main(void) -{ - UNITY_BEGIN(); - - RUN_TEST(test_autoconf_should_GetOptimalThreadsCounti7); - RUN_TEST(test_autoconf_should_GetOptimalThreadsCounti5); - RUN_TEST(test_autoconf_should_GetOptimalThreadsCounti3); - RUN_TEST(test_autoconf_should_GetOptimalThreadsCountR7); - RUN_TEST(test_autoconf_should_GetOptimalThreadsCountR7); - RUN_TEST(test_autoconf_should_GetOptimalThreadsCountTwoE5620); - RUN_TEST(test_autoconf_should_GetOptimalThreadsCountVCPU); - RUN_TEST(test_autoconf_should_GetOptimalThreadsCountNoL3); - - return UNITY_END(); -} diff --git a/test/cryptonight/CMakeLists.txt b/test/cryptonight/CMakeLists.txt deleted file mode 100644 index 4ebbbcc9..00000000 --- a/test/cryptonight/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -set(SOURCES - cryptonight.c - ../../options.h - ../../algo/cryptonight/cryptonight.h - ../../algo/cryptonight/cryptonight.c - ../../algo/cryptonight/cryptonight_av1_aesni.c - ../../algo/cryptonight/cryptonight_av2_aesni_double.c - ../../algo/cryptonight/cryptonight_av3_softaes.c - ../../algo/cryptonight/cryptonight_av4_softaes_double.c - ../../crypto/c_keccak.c - ../../crypto/c_blake256.c - ../../crypto/c_groestl.c - ../../crypto/c_jh.c - ../../crypto/c_skein.c - ../../crypto/soft_aes.c - ) - -add_executable(cryptonight_app ${SOURCES}) -target_link_libraries(cryptonight_app unity) - -include_directories(../..) - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -fno-strict-aliasing") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2") -add_definitions(-DBUILD_TEST) -add_definitions(-DXMRIG_NO_AEON) - -add_test(cryptonight_test cryptonight_app) diff --git a/test/cryptonight/cryptonight.c b/test/cryptonight/cryptonight.c deleted file mode 100644 index bcc0db30..00000000 --- a/test/cryptonight/cryptonight.c +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include -#include -#include -#include - -#include "options.h" -#include "algo/cryptonight/cryptonight.h" - -bool opt_double_hash = false; - -const static char input1[152] = { - 0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00, - 0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B, - 0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62, - 0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92, - 0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01, - 0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19, - 0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9, - 0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F, - 0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46, - 0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02, -}; - -const static char input2[] = "This is a test"; -const static char input3[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus pellentesque metus."; - - -void cryptonight_av1_aesni(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_av2_aesni_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_av3_softaes(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_av4_softaes_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); - - -static char hash[64]; -#define RESULT1 "1a3ffbee909b420d91f7be6e5fb56db71b3110d886011e877ee5786afd080100" -#define RESULT1_DOUBLE "1a3ffbee909b420d91f7be6e5fb56db71b3110d886011e877ee5786afd0801001b606a3f4a07d6489a1bcd07697bd16696b61c8ae982f61a90160f4e52828a7f" -#define RESULT2 "a084f01d1437a09c6985401b60d43554ae105802c5f5d8a9b3253649c0be6605" -#define RESULT3 "0bbe54bd26caa92a1d436eec71cbef02560062fa689fe14d7efcf42566b411cf" - - -static char *bin2hex(const unsigned char *p, size_t len) -{ - char *s = malloc((len * 2) + 1); - if (!s) { - return NULL; - } - - for (int i = 0; i < len; i++) { - sprintf(s + (i * 2), "%02x", (unsigned int) p[i]); - } - - return s; -} - - -static void * create_ctx(int ratio) { - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16); - ctx->memory = (uint8_t *) _mm_malloc(MEMORY * ratio, 16); - - return ctx; -} - - -static void free_ctx(struct cryptonight_ctx *ctx) { - _mm_free(ctx->memory); - _mm_free(ctx); -} - - -void test_cryptonight_av1_should_CalcHash(void) { - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(1); - - cryptonight_av1_aesni(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1, bin2hex(hash, 32)); - - cryptonight_av1_aesni(input2, strlen(input2), &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT2, bin2hex(hash, 32)); - - cryptonight_av1_aesni(input3, strlen(input3), &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT3, bin2hex(hash, 32)); - - free_ctx(ctx); -} - - -void test_cryptonight_av2_should_CalcHash(void) -{ - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(2); - - cryptonight_av2_aesni_double(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1_DOUBLE, bin2hex(hash, 64)); - - free_ctx(ctx); -} - - -void test_cryptonight_av3_should_CalcHash(void) -{ - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(1); - - cryptonight_av3_softaes(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1, bin2hex(hash, 32)); - - cryptonight_av3_softaes(input2, strlen(input2), &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT2, bin2hex(hash, 32)); - - cryptonight_av3_softaes(input3, strlen(input3), &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT3, bin2hex(hash, 32)); - - free_ctx(ctx); -} - - -void test_cryptonight_av4_should_CalcHash(void) -{ - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(2); - - cryptonight_av4_softaes_double(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1_DOUBLE, bin2hex(hash, 64)); - - free_ctx(ctx); -} - - -int main(void) -{ - UNITY_BEGIN(); - - RUN_TEST(test_cryptonight_av1_should_CalcHash); - RUN_TEST(test_cryptonight_av2_should_CalcHash); - RUN_TEST(test_cryptonight_av3_should_CalcHash); - RUN_TEST(test_cryptonight_av4_should_CalcHash); - - return UNITY_END(); -} diff --git a/test/cryptonight_lite/CMakeLists.txt b/test/cryptonight_lite/CMakeLists.txt deleted file mode 100644 index 9a83ecbc..00000000 --- a/test/cryptonight_lite/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -set(SOURCES - cryptonight_lite.c - ../../options.h - ../../algo/cryptonight/cryptonight.h - ../../algo/cryptonight/cryptonight.c - ../../algo/cryptonight-lite/cryptonight_lite_av1_aesni.c - ../../algo/cryptonight-lite/cryptonight_lite_av2_aesni_double.c - ../../algo/cryptonight-lite/cryptonight_lite_av3_softaes.c - ../../algo/cryptonight-lite/cryptonight_lite_av4_softaes_double.c - ../../crypto/c_keccak.c - ../../crypto/c_blake256.c - ../../crypto/c_groestl.c - ../../crypto/c_jh.c - ../../crypto/c_skein.c - ../../crypto/soft_aes.c - ) - -add_executable(cryptonight_lite_app ${SOURCES}) -target_link_libraries(cryptonight_lite_app unity) - -include_directories(../..) - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -fno-strict-aliasing") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2") -add_definitions(-DBUILD_TEST) - -add_test(cryptonight_lite_test cryptonight_lite_app) diff --git a/test/cryptonight_lite/cryptonight_lite.c b/test/cryptonight_lite/cryptonight_lite.c deleted file mode 100644 index a6d5b554..00000000 --- a/test/cryptonight_lite/cryptonight_lite.c +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include -#include -#include - -#include "options.h" -#include "algo/cryptonight/cryptonight.h" - -bool opt_double_hash = false; -enum mining_algo opt_algo = ALGO_CRYPTONIGHT_LITE; - -const static char input1[152] = { - 0x03, 0x05, 0xA0, 0xDB, 0xD6, 0xBF, 0x05, 0xCF, 0x16, 0xE5, 0x03, 0xF3, 0xA6, 0x6F, 0x78, 0x00, - 0x7C, 0xBF, 0x34, 0x14, 0x43, 0x32, 0xEC, 0xBF, 0xC2, 0x2E, 0xD9, 0x5C, 0x87, 0x00, 0x38, 0x3B, - 0x30, 0x9A, 0xCE, 0x19, 0x23, 0xA0, 0x96, 0x4B, 0x00, 0x00, 0x00, 0x08, 0xBA, 0x93, 0x9A, 0x62, - 0x72, 0x4C, 0x0D, 0x75, 0x81, 0xFC, 0xE5, 0x76, 0x1E, 0x9D, 0x8A, 0x0E, 0x6A, 0x1C, 0x3F, 0x92, - 0x4F, 0xDD, 0x84, 0x93, 0xD1, 0x11, 0x56, 0x49, 0xC0, 0x5E, 0xB6, 0x01, - 0x01, 0x00, 0xFB, 0x8E, 0x8A, 0xC8, 0x05, 0x89, 0x93, 0x23, 0x37, 0x1B, 0xB7, 0x90, 0xDB, 0x19, - 0x21, 0x8A, 0xFD, 0x8D, 0xB8, 0xE3, 0x75, 0x5D, 0x8B, 0x90, 0xF3, 0x9B, 0x3D, 0x55, 0x06, 0xA9, - 0xAB, 0xCE, 0x4F, 0xA9, 0x12, 0x24, 0x45, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x81, 0x46, 0xD4, 0x9F, - 0xA9, 0x3E, 0xE7, 0x24, 0xDE, 0xB5, 0x7D, 0x12, 0xCB, 0xC6, 0xC6, 0xF3, 0xB9, 0x24, 0xD9, 0x46, - 0x12, 0x7C, 0x7A, 0x97, 0x41, 0x8F, 0x93, 0x48, 0x82, 0x8F, 0x0F, 0x02, -}; - - -void cryptonight_av1_aesni(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx) {} -void cryptonight_av2_aesni_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx) {} -void cryptonight_av3_softaes(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx) {} -void cryptonight_av4_softaes_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx) {} - -void cryptonight_lite_av1_aesni(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_lite_av2_aesni_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_lite_av3_softaes(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); -void cryptonight_lite_av4_softaes_double(const void* input, size_t size, void* output, struct cryptonight_ctx* ctx); - - -static char hash[64]; -#define RESULT1 "3695b4b53bb00358b0ad38dc160feb9e004eece09b83a72ef6ba9864d3510c88" -#define RESULT1_DOUBLE "3695b4b53bb00358b0ad38dc160feb9e004eece09b83a72ef6ba9864d3510c8828a22bad3f93d1408fca472eb5ad1cbe75f21d053c8ce5b3af105a57713e21dd" - - -static char *bin2hex(const unsigned char *p, size_t len) -{ - char *s = malloc((len * 2) + 1); - if (!s) { - return NULL; - } - - for (int i = 0; i < len; i++) { - sprintf(s + (i * 2), "%02x", (unsigned int) p[i]); - } - - return s; -} - - -static void * create_ctx(int ratio) { - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) _mm_malloc(sizeof(struct cryptonight_ctx), 16); - ctx->memory = (uint8_t *) _mm_malloc(MEMORY_LITE * ratio, 16); - - return ctx; -} - - -static void free_ctx(struct cryptonight_ctx *ctx) { - _mm_free(ctx->memory); - _mm_free(ctx); -} - - -void test_cryptonight_lite_av1_should_CalcHash(void) { - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(1); - - cryptonight_lite_av1_aesni(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1, bin2hex(hash, 32)); - - free_ctx(ctx); -} - - -void test_cryptonight_lite_av2_should_CalcHash(void) -{ - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(2); - - cryptonight_lite_av2_aesni_double(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1_DOUBLE, bin2hex(hash, 64)); - - free_ctx(ctx); -} - - -void test_cryptonight_lite_av3_should_CalcHash(void) { - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(1); - - cryptonight_lite_av3_softaes(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1, bin2hex(hash, 32)); - - free_ctx(ctx); -} - - -void test_cryptonight_lite_av4_should_CalcHash(void) -{ - struct cryptonight_ctx *ctx = (struct cryptonight_ctx*) create_ctx(2); - - cryptonight_lite_av4_softaes_double(input1, 76, &hash, ctx); - TEST_ASSERT_EQUAL_STRING(RESULT1_DOUBLE, bin2hex(hash, 64)); - - free_ctx(ctx); -} - - -int main(void) -{ - UNITY_BEGIN(); - - RUN_TEST(test_cryptonight_lite_av1_should_CalcHash); - RUN_TEST(test_cryptonight_lite_av2_should_CalcHash); - RUN_TEST(test_cryptonight_lite_av3_should_CalcHash); - RUN_TEST(test_cryptonight_lite_av4_should_CalcHash); - - return UNITY_END(); -} diff --git a/test/unity/CMakeLists.txt b/test/unity/CMakeLists.txt deleted file mode 100644 index 6e350179..00000000 --- a/test/unity/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_library(unity STATIC unity.c) -target_include_directories(unity PUBLIC .) diff --git a/test/unity/unity.c b/test/unity/unity.c deleted file mode 100644 index a43e33e1..00000000 --- a/test/unity/unity.c +++ /dev/null @@ -1,1446 +0,0 @@ -/* ========================================================================= - Unity Project - A Test Framework for C - Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -============================================================================ */ - -#include "unity.h" -#include - -/* If omitted from header, declare overrideable prototypes here so they're ready for use */ -#ifdef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION -void UNITY_OUTPUT_CHAR(int); -#endif - -/* Helpful macros for us to use here */ -#define UNITY_FAIL_AND_BAIL { Unity.CurrentTestFailed = 1; longjmp(Unity.AbortFrame, 1); } -#define UNITY_IGNORE_AND_BAIL { Unity.CurrentTestIgnored = 1; longjmp(Unity.AbortFrame, 1); } - -/* return prematurely if we are already in failure or ignore state */ -#define UNITY_SKIP_EXECUTION { if ((Unity.CurrentTestFailed != 0) || (Unity.CurrentTestIgnored != 0)) {return;} } - -struct _Unity Unity; - -static const char UnityStrOk[] = "OK"; -static const char UnityStrPass[] = "PASS"; -static const char UnityStrFail[] = "FAIL"; -static const char UnityStrIgnore[] = "IGNORE"; -static const char UnityStrNull[] = "NULL"; -static const char UnityStrSpacer[] = ". "; -static const char UnityStrExpected[] = " Expected "; -static const char UnityStrWas[] = " Was "; -static const char UnityStrElement[] = " Element "; -static const char UnityStrByte[] = " Byte "; -static const char UnityStrMemory[] = " Memory Mismatch."; -static const char UnityStrDelta[] = " Values Not Within Delta "; -static const char UnityStrPointless[] = " You Asked Me To Compare Nothing, Which Was Pointless."; -static const char UnityStrNullPointerForExpected[] = " Expected pointer to be NULL"; -static const char UnityStrNullPointerForActual[] = " Actual pointer was NULL"; -#ifndef UNITY_EXCLUDE_FLOAT -static const char UnityStrNot[] = "Not "; -static const char UnityStrInf[] = "Infinity"; -static const char UnityStrNegInf[] = "Negative Infinity"; -static const char UnityStrNaN[] = "NaN"; -static const char UnityStrDet[] = "Determinate"; -static const char UnityStrInvalidFloatTrait[] = "Invalid Float Trait"; -#endif -const char UnityStrErrFloat[] = "Unity Floating Point Disabled"; -const char UnityStrErrDouble[] = "Unity Double Precision Disabled"; -const char UnityStrErr64[] = "Unity 64-bit Support Disabled"; -static const char UnityStrBreaker[] = "-----------------------"; -static const char UnityStrResultsTests[] = " Tests "; -static const char UnityStrResultsFailures[] = " Failures "; -static const char UnityStrResultsIgnored[] = " Ignored "; -static const char UnityStrDetail1Name[] = UNITY_DETAIL1_NAME " "; -static const char UnityStrDetail2Name[] = " " UNITY_DETAIL2_NAME " "; - -/* compiler-generic print formatting masks */ -static const _U_UINT UnitySizeMask[] = -{ - 255u, /* 0xFF */ - 65535u, /* 0xFFFF */ - 65535u, - 4294967295u, /* 0xFFFFFFFF */ - 4294967295u, - 4294967295u, - 4294967295u -#ifdef UNITY_SUPPORT_64 - ,0xFFFFFFFFFFFFFFFF -#endif -}; - -/*----------------------------------------------- - * Pretty Printers & Test Result Output Handlers - *-----------------------------------------------*/ - -void UnityPrint(const char* string) -{ - const char* pch = string; - - if (pch != NULL) - { - while (*pch) - { - /* printable characters plus CR & LF are printed */ - if ((*pch <= 126) && (*pch >= 32)) - { - UNITY_OUTPUT_CHAR(*pch); - } - /* write escaped carriage returns */ - else if (*pch == 13) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('r'); - } - /* write escaped line feeds */ - else if (*pch == 10) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('n'); - } - /* unprintable characters are shown as codes */ - else - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('x'); - UnityPrintNumberHex((_U_UINT)*pch, 2); - } - pch++; - } - } -} - -void UnityPrintLen(const char* string, const _UU32 length); -void UnityPrintLen(const char* string, const _UU32 length) -{ - const char* pch = string; - - if (pch != NULL) - { - while (*pch && (_UU32)(pch - string) < length) - { - /* printable characters plus CR & LF are printed */ - if ((*pch <= 126) && (*pch >= 32)) - { - UNITY_OUTPUT_CHAR(*pch); - } - /* write escaped carriage returns */ - else if (*pch == 13) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('r'); - } - /* write escaped line feeds */ - else if (*pch == 10) - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('n'); - } - /* unprintable characters are shown as codes */ - else - { - UNITY_OUTPUT_CHAR('\\'); - UNITY_OUTPUT_CHAR('x'); - UnityPrintNumberHex((_U_UINT)*pch, 2); - } - pch++; - } - } -} - -/*-----------------------------------------------*/ -void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style) -{ - if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) - { - UnityPrintNumber(number); - } - else if ((style & UNITY_DISPLAY_RANGE_UINT) == UNITY_DISPLAY_RANGE_UINT) - { - UnityPrintNumberUnsigned( (_U_UINT)number & UnitySizeMask[((_U_UINT)style & (_U_UINT)0x0F) - 1] ); - } - else - { - UNITY_OUTPUT_CHAR('0'); - UNITY_OUTPUT_CHAR('x'); - UnityPrintNumberHex((_U_UINT)number, (char)((style & 0x000F) << 1)); - } -} - -/*-----------------------------------------------*/ -void UnityPrintNumber(const _U_SINT number_to_print) -{ - _U_UINT number = (_U_UINT)number_to_print; - - if (number_to_print < 0) - { - /* A negative number, including MIN negative */ - UNITY_OUTPUT_CHAR('-'); - number = (_U_UINT)(-number_to_print); - } - UnityPrintNumberUnsigned(number); -} - -/*----------------------------------------------- - * basically do an itoa using as little ram as possible */ -void UnityPrintNumberUnsigned(const _U_UINT number) -{ - _U_UINT divisor = 1; - - /* figure out initial divisor */ - while (number / divisor > 9) - { - divisor *= 10; - } - - /* now mod and print, then divide divisor */ - do - { - UNITY_OUTPUT_CHAR((char)('0' + (number / divisor % 10))); - divisor /= 10; - } - while (divisor > 0); -} - -/*-----------------------------------------------*/ -void UnityPrintNumberHex(const _U_UINT number, const char nibbles_to_print) -{ - _U_UINT nibble; - char nibbles = nibbles_to_print; - - while (nibbles > 0) - { - nibble = (number >> (--nibbles << 2)) & 0x0000000F; - if (nibble <= 9) - { - UNITY_OUTPUT_CHAR((char)('0' + nibble)); - } - else - { - UNITY_OUTPUT_CHAR((char)('A' - 10 + nibble)); - } - } -} - -/*-----------------------------------------------*/ -void UnityPrintMask(const _U_UINT mask, const _U_UINT number) -{ - _U_UINT current_bit = (_U_UINT)1 << (UNITY_INT_WIDTH - 1); - _US32 i; - - for (i = 0; i < UNITY_INT_WIDTH; i++) - { - if (current_bit & mask) - { - if (current_bit & number) - { - UNITY_OUTPUT_CHAR('1'); - } - else - { - UNITY_OUTPUT_CHAR('0'); - } - } - else - { - UNITY_OUTPUT_CHAR('X'); - } - current_bit = current_bit >> 1; - } -} - -/*-----------------------------------------------*/ -#ifdef UNITY_FLOAT_VERBOSE -#include - -#ifndef UNITY_VERBOSE_NUMBER_MAX_LENGTH -# ifdef UNITY_DOUBLE_VERBOSE -# define UNITY_VERBOSE_NUMBER_MAX_LENGTH 317 -# else -# define UNITY_VERBOSE_NUMBER_MAX_LENGTH 47 -# endif -#endif - -void UnityPrintFloat(_UD number) -{ - char TempBuffer[UNITY_VERBOSE_NUMBER_MAX_LENGTH + 1]; - snprintf(TempBuffer, sizeof(TempBuffer), "%.6f", number); - UnityPrint(TempBuffer); -} -#endif - -/*-----------------------------------------------*/ - -void UnityPrintFail(void); -void UnityPrintFail(void) -{ - UnityPrint(UnityStrFail); -} - -void UnityPrintOk(void); -void UnityPrintOk(void) -{ - UnityPrint(UnityStrOk); -} - -/*-----------------------------------------------*/ -static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line); -static void UnityTestResultsBegin(const char* file, const UNITY_LINE_TYPE line) -{ -#ifndef UNITY_FIXTURES - UnityPrint(file); - UNITY_OUTPUT_CHAR(':'); - UnityPrintNumber((_U_SINT)line); - UNITY_OUTPUT_CHAR(':'); - UnityPrint(Unity.CurrentTestName); - UNITY_OUTPUT_CHAR(':'); -#else - UNITY_UNUSED(file); - UNITY_UNUSED(line); -#endif -} - -/*-----------------------------------------------*/ -static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line); -static void UnityTestResultsFailBegin(const UNITY_LINE_TYPE line) -{ -#ifndef UNITY_FIXTURES - UnityTestResultsBegin(Unity.TestFile, line); -#else - UNITY_UNUSED(line); -#endif - UnityPrint(UnityStrFail); - UNITY_OUTPUT_CHAR(':'); -} - -/*-----------------------------------------------*/ -void UnityConcludeTest(void) -{ - if (Unity.CurrentTestIgnored) - { - Unity.TestIgnores++; - } - else if (!Unity.CurrentTestFailed) - { - UnityTestResultsBegin(Unity.TestFile, Unity.CurrentTestLineNumber); - UnityPrint(UnityStrPass); - } - else - { - Unity.TestFailures++; - } - - Unity.CurrentTestFailed = 0; - Unity.CurrentTestIgnored = 0; - UNITY_PRINT_EOL(); - UNITY_FLUSH_CALL(); -} - -/*-----------------------------------------------*/ -static void UnityAddMsgIfSpecified(const char* msg); -static void UnityAddMsgIfSpecified(const char* msg) -{ - if (msg) - { - UnityPrint(UnityStrSpacer); -#ifndef UNITY_EXCLUDE_DETAILS - if (Unity.CurrentDetail1) - { - UnityPrint(UnityStrDetail1Name); - UnityPrint(Unity.CurrentDetail1); - if (Unity.CurrentDetail2) - { - UnityPrint(UnityStrDetail2Name); - UnityPrint(Unity.CurrentDetail2); - } - UnityPrint(UnityStrSpacer); - } -#endif - UnityPrint(msg); - } -} - -/*-----------------------------------------------*/ -static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual); -static void UnityPrintExpectedAndActualStrings(const char* expected, const char* actual) -{ - UnityPrint(UnityStrExpected); - if (expected != NULL) - { - UNITY_OUTPUT_CHAR('\''); - UnityPrint(expected); - UNITY_OUTPUT_CHAR('\''); - } - else - { - UnityPrint(UnityStrNull); - } - UnityPrint(UnityStrWas); - if (actual != NULL) - { - UNITY_OUTPUT_CHAR('\''); - UnityPrint(actual); - UNITY_OUTPUT_CHAR('\''); - } - else - { - UnityPrint(UnityStrNull); - } -} - -/*-----------------------------------------------*/ -static void UnityPrintExpectedAndActualStringsLen(const char* expected, const char* actual, const _UU32 length) -{ - UnityPrint(UnityStrExpected); - if (expected != NULL) - { - UNITY_OUTPUT_CHAR('\''); - UnityPrintLen(expected, length); - UNITY_OUTPUT_CHAR('\''); - } - else - { - UnityPrint(UnityStrNull); - } - UnityPrint(UnityStrWas); - if (actual != NULL) - { - UNITY_OUTPUT_CHAR('\''); - UnityPrintLen(actual, length); - UNITY_OUTPUT_CHAR('\''); - } - else - { - UnityPrint(UnityStrNull); - } -} - - - -/*----------------------------------------------- - * Assertion & Control Helpers - *-----------------------------------------------*/ - -static int UnityCheckArraysForNull(UNITY_INTERNAL_PTR expected, UNITY_INTERNAL_PTR actual, const UNITY_LINE_TYPE lineNumber, const char* msg) -{ - /* return true if they are both NULL */ - if ((expected == NULL) && (actual == NULL)) - return 1; - - /* throw error if just expected is NULL */ - if (expected == NULL) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrNullPointerForExpected); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - /* throw error if just actual is NULL */ - if (actual == NULL) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrNullPointerForActual); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - - /* return false if neither is NULL */ - return 0; -} - -/*----------------------------------------------- - * Assertion Functions - *-----------------------------------------------*/ - -void UnityAssertBits(const _U_SINT mask, - const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - UNITY_SKIP_EXECUTION; - - if ((mask & expected) != (mask & actual)) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - UnityPrintMask((_U_UINT)mask, (_U_UINT)expected); - UnityPrint(UnityStrWas); - UnityPrintMask((_U_UINT)mask, (_U_UINT)actual); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -/*-----------------------------------------------*/ -void UnityAssertEqualNumber(const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style) -{ - UNITY_SKIP_EXECUTION; - - if (expected != actual) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(expected, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(actual, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -#define UnityPrintPointlessAndBail() \ -{ \ - UnityTestResultsFailBegin(lineNumber); \ - UnityPrint(UnityStrPointless); \ - UnityAddMsgIfSpecified(msg); \ - UNITY_FAIL_AND_BAIL; } - -/*-----------------------------------------------*/ -void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, - UNITY_INTERNAL_PTR actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style) -{ - _UU32 elements = num_elements; - UNITY_INTERNAL_PTR ptr_exp = (UNITY_INTERNAL_PTR)expected; - UNITY_INTERNAL_PTR ptr_act = (UNITY_INTERNAL_PTR)actual; - - UNITY_SKIP_EXECUTION; - - if (elements == 0) - { - UnityPrintPointlessAndBail(); - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - /* If style is UNITY_DISPLAY_STYLE_INT, we'll fall into the default case rather than the INT16 or INT32 (etc) case - * as UNITY_DISPLAY_STYLE_INT includes a flag for UNITY_DISPLAY_RANGE_AUTO, which the width-specific - * variants do not. Therefore remove this flag. */ - switch(style & (UNITY_DISPLAY_STYLE_T)(~UNITY_DISPLAY_RANGE_AUTO)) - { - case UNITY_DISPLAY_STYLE_HEX8: - case UNITY_DISPLAY_STYLE_INT8: - case UNITY_DISPLAY_STYLE_UINT8: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US8*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(num_elements - elements - 1); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US8*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 1); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 1); - } - break; - case UNITY_DISPLAY_STYLE_HEX16: - case UNITY_DISPLAY_STYLE_INT16: - case UNITY_DISPLAY_STYLE_UINT16: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(num_elements - elements - 1); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US16*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 2); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 2); - } - break; -#ifdef UNITY_SUPPORT_64 - case UNITY_DISPLAY_STYLE_HEX64: - case UNITY_DISPLAY_STYLE_INT64: - case UNITY_DISPLAY_STYLE_UINT64: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(num_elements - elements - 1); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US64*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 8); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 8); - } - break; -#endif - default: - while (elements--) - { - if (*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp != *(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(num_elements - elements - 1); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_exp, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*(UNITY_PTR_ATTRIBUTE const _US32*)ptr_act, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 4); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 4); - } - break; - } -} - -/*-----------------------------------------------*/ -/* Wrap this define in a function with variable types as float or double */ -#define UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff) \ - if (isinf(expected) && isinf(actual) && (isneg(expected) == isneg(actual))) return 1; \ - if (isnan(expected) && isnan(actual)) return 1; \ - diff = actual - expected; \ - if (diff < 0.0f) diff = 0.0f - diff; \ - if (delta < 0.0f) delta = 0.0f - delta; \ - return !(isnan(diff) || isinf(diff) || (delta < diff)); - /* This first part of this condition will catch any NaN or Infinite values */ - -#ifndef UNITY_EXCLUDE_FLOAT -static int UnityFloatsWithin(_UF delta, _UF expected, _UF actual) -{ - _UF diff; - UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); -} - -void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected, - UNITY_PTR_ATTRIBUTE const _UF* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 elements = num_elements; - UNITY_PTR_ATTRIBUTE const _UF* ptr_expected = expected; - UNITY_PTR_ATTRIBUTE const _UF* ptr_actual = actual; - - UNITY_SKIP_EXECUTION; - - if (elements == 0) - { - UnityPrintPointlessAndBail(); - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - while (elements--) - { - if (!UnityFloatsWithin(*ptr_expected * UNITY_FLOAT_PRECISION, *ptr_expected, *ptr_actual)) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(num_elements - elements - 1); -#ifdef UNITY_FLOAT_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat(*ptr_expected); - UnityPrint(UnityStrWas); - UnityPrintFloat(*ptr_actual); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_expected++; - ptr_actual++; - } -} - -/*-----------------------------------------------*/ -void UnityAssertFloatsWithin(const _UF delta, - const _UF expected, - const _UF actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - UNITY_SKIP_EXECUTION; - - - if (!UnityFloatsWithin(delta, expected, actual)) - { - UnityTestResultsFailBegin(lineNumber); -#ifdef UNITY_FLOAT_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat(expected); - UnityPrint(UnityStrWas); - UnityPrintFloat(actual); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -/*-----------------------------------------------*/ -void UnityAssertFloatSpecial(const _UF actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_FLOAT_TRAIT_T style) -{ - const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet }; - _U_SINT should_be_trait = ((_U_SINT)style & 1); - _U_SINT is_trait = !should_be_trait; - _U_SINT trait_index = (_U_SINT)(style >> 1); - - UNITY_SKIP_EXECUTION; - - switch(style) - { - case UNITY_FLOAT_IS_INF: - case UNITY_FLOAT_IS_NOT_INF: - is_trait = isinf(actual) & ispos(actual); - break; - case UNITY_FLOAT_IS_NEG_INF: - case UNITY_FLOAT_IS_NOT_NEG_INF: - is_trait = isinf(actual) & isneg(actual); - break; - - case UNITY_FLOAT_IS_NAN: - case UNITY_FLOAT_IS_NOT_NAN: - is_trait = isnan(actual); - break; - - /* A determinate number is non infinite and not NaN. (therefore the opposite of the two above) */ - case UNITY_FLOAT_IS_DET: - case UNITY_FLOAT_IS_NOT_DET: - if (isinf(actual) | isnan(actual)) - is_trait = 0; - else - is_trait = 1; - break; - - default: - trait_index = 0; - trait_names[0] = UnityStrInvalidFloatTrait; - break; - } - - if (is_trait != should_be_trait) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - if (!should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); - UnityPrint(UnityStrWas); -#ifdef UNITY_FLOAT_VERBOSE - UnityPrintFloat(actual); -#else - if (should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -#endif /* not UNITY_EXCLUDE_FLOAT */ - -/*-----------------------------------------------*/ -#ifndef UNITY_EXCLUDE_DOUBLE -static int UnityDoublesWithin(_UD delta, _UD expected, _UD actual) -{ - _UD diff; - UNITY_FLOAT_OR_DOUBLE_WITHIN(delta, expected, actual, diff); -} - -void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected, - UNITY_PTR_ATTRIBUTE const _UD* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 elements = num_elements; - UNITY_PTR_ATTRIBUTE const _UD* ptr_expected = expected; - UNITY_PTR_ATTRIBUTE const _UD* ptr_actual = actual; - - UNITY_SKIP_EXECUTION; - - if (elements == 0) - { - UnityPrintPointlessAndBail(); - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - while (elements--) - { - if (!UnityDoublesWithin(*ptr_expected * UNITY_DOUBLE_PRECISION, *ptr_expected, *ptr_actual)) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(num_elements - elements - 1); -#ifdef UNITY_DOUBLE_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat((float)(*ptr_expected)); - UnityPrint(UnityStrWas); - UnityPrintFloat((float)(*ptr_actual)); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_expected++; - ptr_actual++; - } -} - -/*-----------------------------------------------*/ -void UnityAssertDoublesWithin(const _UD delta, - const _UD expected, - const _UD actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - UNITY_SKIP_EXECUTION; - - if (!UnityDoublesWithin(delta, expected, actual)) - { - UnityTestResultsFailBegin(lineNumber); -#ifdef UNITY_DOUBLE_VERBOSE - UnityPrint(UnityStrExpected); - UnityPrintFloat((float)expected); - UnityPrint(UnityStrWas); - UnityPrintFloat((float)actual); -#else - UnityPrint(UnityStrDelta); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -/*-----------------------------------------------*/ - -void UnityAssertDoubleSpecial(const _UD actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_FLOAT_TRAIT_T style) -{ - const char* trait_names[] = { UnityStrInf, UnityStrNegInf, UnityStrNaN, UnityStrDet }; - _U_SINT should_be_trait = ((_U_SINT)style & 1); - _U_SINT is_trait = !should_be_trait; - _U_SINT trait_index = (_U_SINT)(style >> 1); - - UNITY_SKIP_EXECUTION; - - switch(style) - { - case UNITY_FLOAT_IS_INF: - case UNITY_FLOAT_IS_NOT_INF: - is_trait = isinf(actual) & ispos(actual); - break; - case UNITY_FLOAT_IS_NEG_INF: - case UNITY_FLOAT_IS_NOT_NEG_INF: - is_trait = isinf(actual) & isneg(actual); - break; - - case UNITY_FLOAT_IS_NAN: - case UNITY_FLOAT_IS_NOT_NAN: - is_trait = isnan(actual); - break; - - /* A determinate number is non infinite and not NaN. (therefore the opposite of the two above) */ - case UNITY_FLOAT_IS_DET: - case UNITY_FLOAT_IS_NOT_DET: - if (isinf(actual) | isnan(actual)) - is_trait = 0; - else - is_trait = 1; - break; - - default: - trait_index = 0; - trait_names[0] = UnityStrInvalidFloatTrait; - break; - } - - if (is_trait != should_be_trait) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrExpected); - if (!should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); - UnityPrint(UnityStrWas); -#ifdef UNITY_DOUBLE_VERBOSE - UnityPrintFloat(actual); -#else - if (should_be_trait) - UnityPrint(UnityStrNot); - UnityPrint(trait_names[trait_index]); -#endif - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - - -#endif /* not UNITY_EXCLUDE_DOUBLE */ - -/*-----------------------------------------------*/ -void UnityAssertNumbersWithin( const _U_UINT delta, - const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style) -{ - UNITY_SKIP_EXECUTION; - - if ((style & UNITY_DISPLAY_RANGE_INT) == UNITY_DISPLAY_RANGE_INT) - { - if (actual > expected) - Unity.CurrentTestFailed = ((_U_UINT)(actual - expected) > delta); - else - Unity.CurrentTestFailed = ((_U_UINT)(expected - actual) > delta); - } - else - { - if ((_U_UINT)actual > (_U_UINT)expected) - Unity.CurrentTestFailed = ((_U_UINT)(actual - expected) > delta); - else - Unity.CurrentTestFailed = ((_U_UINT)(expected - actual) > delta); - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrDelta); - UnityPrintNumberByStyle((_U_SINT)delta, style); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(expected, style); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(actual, style); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -/*-----------------------------------------------*/ -void UnityAssertEqualString(const char* expected, - const char* actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 i; - - UNITY_SKIP_EXECUTION; - - /* if both pointers not null compare the strings */ - if (expected && actual) - { - for (i = 0; expected[i] || actual[i]; i++) - { - if (expected[i] != actual[i]) - { - Unity.CurrentTestFailed = 1; - break; - } - } - } - else - { /* handle case of one pointers being null (if both null, test should pass) */ - if (expected != actual) - { - Unity.CurrentTestFailed = 1; - } - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrintExpectedAndActualStrings(expected, actual); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - -/*-----------------------------------------------*/ -void UnityAssertEqualStringLen(const char* expected, - const char* actual, - const _UU32 length, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 i; - - UNITY_SKIP_EXECUTION; - - /* if both pointers not null compare the strings */ - if (expected && actual) - { - for (i = 0; (i < length) && (expected[i] || actual[i]); i++) - { - if (expected[i] != actual[i]) - { - Unity.CurrentTestFailed = 1; - break; - } - } - } - else - { /* handle case of one pointers being null (if both null, test should pass) */ - if (expected != actual) - { - Unity.CurrentTestFailed = 1; - } - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrintExpectedAndActualStringsLen(expected, actual, length); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } -} - - -/*-----------------------------------------------*/ -void UnityAssertEqualStringArray( const char** expected, - const char** actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - _UU32 i, j = 0; - - UNITY_SKIP_EXECUTION; - - /* if no elements, it's an error */ - if (num_elements == 0) - { - UnityPrintPointlessAndBail(); - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - do - { - /* if both pointers not null compare the strings */ - if (expected[j] && actual[j]) - { - for (i = 0; expected[j][i] || actual[j][i]; i++) - { - if (expected[j][i] != actual[j][i]) - { - Unity.CurrentTestFailed = 1; - break; - } - } - } - else - { /* handle case of one pointers being null (if both null, test should pass) */ - if (expected[j] != actual[j]) - { - Unity.CurrentTestFailed = 1; - } - } - - if (Unity.CurrentTestFailed) - { - UnityTestResultsFailBegin(lineNumber); - if (num_elements > 1) - { - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(j); - } - UnityPrintExpectedAndActualStrings((const char*)(expected[j]), (const char*)(actual[j])); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - } while (++j < num_elements); -} - -/*-----------------------------------------------*/ -void UnityAssertEqualMemory( UNITY_INTERNAL_PTR expected, - UNITY_INTERNAL_PTR actual, - const _UU32 length, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber) -{ - UNITY_PTR_ATTRIBUTE const unsigned char* ptr_exp = (UNITY_PTR_ATTRIBUTE const unsigned char*)expected; - UNITY_PTR_ATTRIBUTE const unsigned char* ptr_act = (UNITY_PTR_ATTRIBUTE const unsigned char*)actual; - _UU32 elements = num_elements; - _UU32 bytes; - - UNITY_SKIP_EXECUTION; - - if ((elements == 0) || (length == 0)) - { - UnityPrintPointlessAndBail(); - } - - if (UnityCheckArraysForNull((UNITY_INTERNAL_PTR)expected, (UNITY_INTERNAL_PTR)actual, lineNumber, msg) == 1) - return; - - while (elements--) - { - bytes = length; - while (bytes--) - { - if (*ptr_exp != *ptr_act) - { - UnityTestResultsFailBegin(lineNumber); - UnityPrint(UnityStrMemory); - if (num_elements > 1) - { - UnityPrint(UnityStrElement); - UnityPrintNumberUnsigned(num_elements - elements - 1); - } - UnityPrint(UnityStrByte); - UnityPrintNumberUnsigned(length - bytes - 1); - UnityPrint(UnityStrExpected); - UnityPrintNumberByStyle(*ptr_exp, UNITY_DISPLAY_STYLE_HEX8); - UnityPrint(UnityStrWas); - UnityPrintNumberByStyle(*ptr_act, UNITY_DISPLAY_STYLE_HEX8); - UnityAddMsgIfSpecified(msg); - UNITY_FAIL_AND_BAIL; - } - ptr_exp = (UNITY_INTERNAL_PTR)((_UP)ptr_exp + 1); - ptr_act = (UNITY_INTERNAL_PTR)((_UP)ptr_act + 1); - } - } -} - -/*----------------------------------------------- - * Control Functions - *-----------------------------------------------*/ - -void UnityFail(const char* msg, const UNITY_LINE_TYPE line) -{ - UNITY_SKIP_EXECUTION; - - UnityTestResultsBegin(Unity.TestFile, line); - UnityPrintFail(); - if (msg != NULL) - { - UNITY_OUTPUT_CHAR(':'); - -#ifndef UNITY_EXCLUDE_DETAILS - if (Unity.CurrentDetail1) - { - UnityPrint(UnityStrDetail1Name); - UnityPrint(Unity.CurrentDetail1); - if (Unity.CurrentDetail2) - { - UnityPrint(UnityStrDetail2Name); - UnityPrint(Unity.CurrentDetail2); - } - UnityPrint(UnityStrSpacer); - } -#endif - if (msg[0] != ' ') - { - UNITY_OUTPUT_CHAR(' '); - } - UnityPrint(msg); - } - - UNITY_FAIL_AND_BAIL; -} - -/*-----------------------------------------------*/ -void UnityIgnore(const char* msg, const UNITY_LINE_TYPE line) -{ - UNITY_SKIP_EXECUTION; - - UnityTestResultsBegin(Unity.TestFile, line); - UnityPrint(UnityStrIgnore); - if (msg != NULL) - { - UNITY_OUTPUT_CHAR(':'); - UNITY_OUTPUT_CHAR(' '); - UnityPrint(msg); - } - UNITY_IGNORE_AND_BAIL; -} - -/*-----------------------------------------------*/ -#if defined(UNITY_WEAK_ATTRIBUTE) - UNITY_WEAK_ATTRIBUTE void setUp(void) { } - UNITY_WEAK_ATTRIBUTE void tearDown(void) { } -#elif defined(UNITY_WEAK_PRAGMA) -# pragma weak setUp - void setUp(void) { } -# pragma weak tearDown - void tearDown(void) { } -#endif -/*-----------------------------------------------*/ -void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum) -{ - Unity.CurrentTestName = FuncName; - Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)FuncLineNum; - Unity.NumberOfTests++; - UNITY_CLR_DETAILS(); - if (TEST_PROTECT()) - { - setUp(); - Func(); - } - if (TEST_PROTECT() && !(Unity.CurrentTestIgnored)) - { - tearDown(); - } - UnityConcludeTest(); -} - -/*-----------------------------------------------*/ -void UnityBegin(const char* filename) -{ - Unity.TestFile = filename; - Unity.CurrentTestName = NULL; - Unity.CurrentTestLineNumber = 0; - Unity.NumberOfTests = 0; - Unity.TestFailures = 0; - Unity.TestIgnores = 0; - Unity.CurrentTestFailed = 0; - Unity.CurrentTestIgnored = 0; - - UNITY_CLR_DETAILS(); - UNITY_OUTPUT_START(); -} - -/*-----------------------------------------------*/ -int UnityEnd(void) -{ - UNITY_PRINT_EOL(); - UnityPrint(UnityStrBreaker); - UNITY_PRINT_EOL(); - UnityPrintNumber((_U_SINT)(Unity.NumberOfTests)); - UnityPrint(UnityStrResultsTests); - UnityPrintNumber((_U_SINT)(Unity.TestFailures)); - UnityPrint(UnityStrResultsFailures); - UnityPrintNumber((_U_SINT)(Unity.TestIgnores)); - UnityPrint(UnityStrResultsIgnored); - UNITY_PRINT_EOL(); - if (Unity.TestFailures == 0U) - { - UnityPrintOk(); - } - else - { - UnityPrintFail(); -#ifdef UNITY_DIFFERENTIATE_FINAL_FAIL - UNITY_OUTPUT_CHAR('E'); UNITY_OUTPUT_CHAR('D'); -#endif - } - UNITY_PRINT_EOL(); - UNITY_FLUSH_CALL(); - UNITY_OUTPUT_COMPLETE(); - return (int)(Unity.TestFailures); -} - -/*----------------------------------------------- - * Command Line Argument Support - *-----------------------------------------------*/ -#ifdef UNITY_USE_COMMAND_LINE_ARGS - -char* UnityOptionIncludeNamed = NULL; -char* UnityOptionExcludeNamed = NULL; -int UnityVerbosity = 1; - -int UnityParseOptions(int argc, char** argv) -{ - UnityOptionIncludeNamed = NULL; - UnityOptionExcludeNamed = NULL; - - for (int i = 1; i < argc; i++) - { - if (argv[i][0] == '-') - { - switch(argv[i][1]) - { - case 'l': /* list tests */ - return -1; - case 'n': /* include tests with name including this string */ - case 'f': /* an alias for -n */ - if (argv[i][2] == '=') - UnityOptionIncludeNamed = &argv[i][3]; - else if (++i < argc) - UnityOptionIncludeNamed = argv[i]; - else - { - UnityPrint("ERROR: No Test String to Include Matches For"); - UNITY_PRINT_EOL(); - return 1; - } - break; - case 'q': /* quiet */ - UnityVerbosity = 0; - break; - case 'v': /* verbose */ - UnityVerbosity = 2; - break; - case 'x': /* exclude tests with name including this string */ - if (argv[i][2] == '=') - UnityOptionExcludeNamed = &argv[i][3]; - else if (++i < argc) - UnityOptionExcludeNamed = argv[i]; - else - { - UnityPrint("ERROR: No Test String to Exclude Matches For"); - UNITY_PRINT_EOL(); - return 1; - } - break; - default: - UnityPrint("ERROR: Unknown Option "); - UNITY_OUTPUT_CHAR(argv[i][1]); - UNITY_PRINT_EOL(); - return 1; - } - } - } - - return 0; -} - -int IsStringInBiggerString(const char* longstring, const char* shortstring) -{ - char* lptr = (char*)longstring; - char* sptr = (char*)shortstring; - char* lnext = lptr; - - if (*sptr == '*') - return 1; - - while (*lptr) - { - lnext = lptr + 1; - - /* If they current bytes match, go on to the next bytes */ - while (*lptr && *sptr && (*lptr == *sptr)) - { - lptr++; - sptr++; - - /* We're done if we match the entire string or up to a wildcard */ - if (*sptr == '*') - return 1; - if (*sptr == ',') - return 1; - if (*sptr == '"') - return 1; - if (*sptr == '\'') - return 1; - if (*sptr == ':') - return 2; - if (*sptr == 0) - return 1; - } - - /* Otherwise we start in the long pointer 1 character further and try again */ - lptr = lnext; - sptr = (char*)shortstring; - } - return 0; -} - -int UnityStringArgumentMatches(const char* str) -{ - int retval; - const char* ptr1; - const char* ptr2; - const char* ptrf; - - /* Go through the options and get the substrings for matching one at a time */ - ptr1 = str; - while (ptr1[0] != 0) - { - if ((ptr1[0] == '"') || (ptr1[0] == '\'')) - ptr1++; - - /* look for the start of the next partial */ - ptr2 = ptr1; - ptrf = 0; - do { - ptr2++; - if ((ptr2[0] == ':') && (ptr2[1] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')) - ptrf = &ptr2[1]; - } while ((ptr2[0] != 0) && (ptr2[0] != '\'') && (ptr2[0] != '"') && (ptr2[0] != ',')); - while ((ptr2[0] != 0) && ((ptr2[0] == ':') || (ptr2[0] == '\'') || (ptr2[0] == '"') || (ptr2[0] == ','))) - ptr2++; - - /* done if complete filename match */ - retval = IsStringInBiggerString(Unity.TestFile, ptr1); - if (retval == 1) - return retval; - - /* done if testname match after filename partial match */ - if ((retval == 2) && (ptrf != 0)) - { - if (IsStringInBiggerString(Unity.CurrentTestName, ptrf)) - return 1; - } - - /* done if complete testname match */ - if (IsStringInBiggerString(Unity.CurrentTestName, ptr1) == 1) - return 1; - - ptr1 = ptr2; - } - - /* we couldn't find a match for any substrings */ - return 0; -} - -int UnityTestMatches(void) -{ - /* Check if this test name matches the included test pattern */ - int retval; - if (UnityOptionIncludeNamed) - { - retval = UnityStringArgumentMatches(UnityOptionIncludeNamed); - } - else - retval = 1; - - /* Check if this test name matches the excluded test pattern */ - if (UnityOptionExcludeNamed) - { - if (UnityStringArgumentMatches(UnityOptionExcludeNamed)) - retval = 0; - } - return retval; -} - -#endif /* UNITY_USE_COMMAND_LINE_ARGS */ -/*-----------------------------------------------*/ diff --git a/test/unity/unity.h b/test/unity/unity.h deleted file mode 100644 index 031ccc92..00000000 --- a/test/unity/unity.h +++ /dev/null @@ -1,293 +0,0 @@ -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#ifndef UNITY_FRAMEWORK_H -#define UNITY_FRAMEWORK_H -#define UNITY - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "unity_internals.h" - -void setUp(void); -void tearDown(void); - -/*------------------------------------------------------- - * Configuration Options - *------------------------------------------------------- - * All options described below should be passed as a compiler flag to all files using Unity. If you must add #defines, place them BEFORE the #include above. - - * Integers/longs/pointers - * - Unity attempts to automatically discover your integer sizes - * - define UNITY_EXCLUDE_STDINT_H to stop attempting to look in - * - define UNITY_EXCLUDE_LIMITS_H to stop attempting to look in - * - If you cannot use the automatic methods above, you can force Unity by using these options: - * - define UNITY_SUPPORT_64 - * - set UNITY_INT_WIDTH - * - set UNITY_LONG_WIDTH - * - set UNITY_POINTER_WIDTH - - * Floats - * - define UNITY_EXCLUDE_FLOAT to disallow floating point comparisons - * - define UNITY_FLOAT_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_FLOAT - * - define UNITY_FLOAT_TYPE to specify doubles instead of single precision floats - * - define UNITY_FLOAT_VERBOSE to print floating point values in errors (uses sprintf) - * - define UNITY_INCLUDE_DOUBLE to allow double floating point comparisons - * - define UNITY_EXCLUDE_DOUBLE to disallow double floating point comparisons (default) - * - define UNITY_DOUBLE_PRECISION to specify the precision to use when doing TEST_ASSERT_EQUAL_DOUBLE - * - define UNITY_DOUBLE_TYPE to specify something other than double - * - define UNITY_DOUBLE_VERBOSE to print floating point values in errors (uses sprintf) - * - define UNITY_VERBOSE_NUMBER_MAX_LENGTH to change maximum length of printed numbers (used by sprintf) - - * Output - * - by default, Unity prints to standard out with putchar. define UNITY_OUTPUT_CHAR(a) with a different function if desired - * - define UNITY_DIFFERENTIATE_FINAL_FAIL to print FAILED (vs. FAIL) at test end summary - for automated search for failure - - * Optimization - * - by default, line numbers are stored in unsigned shorts. Define UNITY_LINE_TYPE with a different type if your files are huge - * - by default, test and failure counters are unsigned shorts. Define UNITY_COUNTER_TYPE with a different type if you want to save space or have more than 65535 Tests. - - * Test Cases - * - define UNITY_SUPPORT_TEST_CASES to include the TEST_CASE macro, though really it's mostly about the runner generator script - - * Parameterized Tests - * - you'll want to create a define of TEST_CASE(...) which basically evaluates to nothing - - * Tests with Arguments - * - you'll want to define UNITY_USE_COMMAND_LINE_ARGS if you have the test runner passing arguments to Unity - - *------------------------------------------------------- - * Basic Fail and Ignore - *-------------------------------------------------------*/ - -#define TEST_FAIL_MESSAGE(message) UNITY_TEST_FAIL(__LINE__, (message)) -#define TEST_FAIL() UNITY_TEST_FAIL(__LINE__, NULL) -#define TEST_IGNORE_MESSAGE(message) UNITY_TEST_IGNORE(__LINE__, (message)) -#define TEST_IGNORE() UNITY_TEST_IGNORE(__LINE__, NULL) -#define TEST_ONLY() - -/* It is not necessary for you to call PASS. A PASS condition is assumed if nothing fails. - * This method allows you to abort a test immediately with a PASS state, ignoring the remainder of the test. */ -#define TEST_PASS() longjmp(Unity.AbortFrame, 1) - -/*------------------------------------------------------- - * Test Asserts (simple) - *-------------------------------------------------------*/ - -/* Boolean */ -#define TEST_ASSERT(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expression Evaluated To FALSE") -#define TEST_ASSERT_TRUE(condition) UNITY_TEST_ASSERT( (condition), __LINE__, " Expected TRUE Was FALSE") -#define TEST_ASSERT_UNLESS(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expression Evaluated To TRUE") -#define TEST_ASSERT_FALSE(condition) UNITY_TEST_ASSERT( !(condition), __LINE__, " Expected FALSE Was TRUE") -#define TEST_ASSERT_NULL(pointer) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, " Expected NULL") -#define TEST_ASSERT_NOT_NULL(pointer) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, " Expected Non-NULL") - -/* Integers (of all sizes) */ -#define TEST_ASSERT_EQUAL_INT(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL(expected, actual) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_NOT_EQUAL(expected, actual) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, " Expected Not-Equal") -#define TEST_ASSERT_EQUAL_UINT(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT8(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT16(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT32(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT64(expected, actual) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX8(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX16(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX32(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX64(expected, actual) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_BITS(mask, expected, actual) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_BITS_HIGH(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(-1), (actual), __LINE__, NULL) -#define TEST_ASSERT_BITS_LOW(mask, actual) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(0), (actual), __LINE__, NULL) -#define TEST_ASSERT_BIT_HIGH(bit, actual) UNITY_TEST_ASSERT_BITS(((_UU32)1 << (bit)), (_UU32)(-1), (actual), __LINE__, NULL) -#define TEST_ASSERT_BIT_LOW(bit, actual) UNITY_TEST_ASSERT_BITS(((_UU32)1 << (bit)), (_UU32)(0), (actual), __LINE__, NULL) - -/* Integer Ranges (of all sizes) */ -#define TEST_ASSERT_INT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_INT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_INT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_INT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_INT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_UINT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_UINT8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_UINT16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_UINT32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_UINT64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_HEX_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_HEX8_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_HEX16_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_HEX32_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_HEX64_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, NULL) - -/* Structs and Strings */ -#define TEST_ASSERT_EQUAL_PTR(expected, actual) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_STRING(expected, actual) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_MEMORY(expected, actual, len) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, NULL) - -/* Arrays */ -#define TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, NULL) - -/* Floating Point (If Enabled) */ -#define TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_FLOAT(expected, actual) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NOT_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, NULL) -#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, NULL) - -/* Double (If Enabled) */ -#define TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_DOUBLE(expected, actual) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, NULL) -#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NOT_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, NULL) -#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, NULL) - -/*------------------------------------------------------- - * Test Asserts (with additional messages) - *-------------------------------------------------------*/ - -/* Boolean */ -#define TEST_ASSERT_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message)) -#define TEST_ASSERT_TRUE_MESSAGE(condition, message) UNITY_TEST_ASSERT( (condition), __LINE__, (message)) -#define TEST_ASSERT_UNLESS_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message)) -#define TEST_ASSERT_FALSE_MESSAGE(condition, message) UNITY_TEST_ASSERT( !(condition), __LINE__, (message)) -#define TEST_ASSERT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NULL( (pointer), __LINE__, (message)) -#define TEST_ASSERT_NOT_NULL_MESSAGE(pointer, message) UNITY_TEST_ASSERT_NOT_NULL((pointer), __LINE__, (message)) - -/* Integers (of all sizes) */ -#define TEST_ASSERT_EQUAL_INT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT8((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT16((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT32((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT64((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_INT((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_NOT_EQUAL_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT(((expected) != (actual)), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT( (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT8( (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT16( (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT32( (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_UINT64( (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX8_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX8( (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX16_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX16((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX32_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX32((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX64_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_HEX64((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_BITS_MESSAGE(mask, expected, actual, message) UNITY_TEST_ASSERT_BITS((mask), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_BITS_HIGH_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(-1), (actual), __LINE__, (message)) -#define TEST_ASSERT_BITS_LOW_MESSAGE(mask, actual, message) UNITY_TEST_ASSERT_BITS((mask), (_UU32)(0), (actual), __LINE__, (message)) -#define TEST_ASSERT_BIT_HIGH_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((_UU32)1 << (bit)), (_UU32)(-1), (actual), __LINE__, (message)) -#define TEST_ASSERT_BIT_LOW_MESSAGE(bit, actual, message) UNITY_TEST_ASSERT_BITS(((_UU32)1 << (bit)), (_UU32)(0), (actual), __LINE__, (message)) - -/* Integer Ranges (of all sizes) */ -#define TEST_ASSERT_INT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_INT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT8_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_INT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_INT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_INT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_INT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_UINT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_UINT8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT8_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_UINT16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT16_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_UINT32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT32_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_UINT64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_UINT64_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_HEX_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_HEX8_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX8_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_HEX16_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX16_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_HEX32_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX32_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_HEX64_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_HEX64_WITHIN((delta), (expected), (actual), __LINE__, (message)) - -/* Structs and Strings */ -#define TEST_ASSERT_EQUAL_PTR_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_PTR((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_STRING_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_STRING((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_STRING_LEN_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_STRING_LEN((expected), (actual), (len), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_MEMORY_MESSAGE(expected, actual, len, message) UNITY_TEST_ASSERT_EQUAL_MEMORY((expected), (actual), (len), __LINE__, (message)) - -/* Arrays */ -#define TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_INT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_UINT64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX8_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX16_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX32_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_HEX64_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_PTR_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_STRING_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_MEMORY_ARRAY_MESSAGE(expected, actual, len, num_elements, message) UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY((expected), (actual), (len), (num_elements), __LINE__, (message)) - -/* Floating Point (If Enabled) */ -#define TEST_ASSERT_FLOAT_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_FLOAT_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_FLOAT((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_FLOAT_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NAN((actual), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE((actual), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN((actual), __LINE__, (message)) -#define TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE((actual), __LINE__, (message)) - -/* Double (If Enabled) */ -#define TEST_ASSERT_DOUBLE_WITHIN_MESSAGE(delta, expected, actual, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((delta), (expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_DOUBLE_MESSAGE(expected, actual, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE((expected), (actual), __LINE__, (message)) -#define TEST_ASSERT_EQUAL_DOUBLE_ARRAY_MESSAGE(expected, actual, num_elements, message) UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY((expected), (actual), (num_elements), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NAN((actual), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE((actual), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_NOT_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF((actual), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_NOT_NAN_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN((actual), __LINE__, (message)) -#define TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE_MESSAGE(actual, message) UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE((actual), __LINE__, (message)) - -/* end of UNITY_FRAMEWORK_H */ -#ifdef __cplusplus -} -#endif -#endif diff --git a/test/unity/unity_internals.h b/test/unity/unity_internals.h deleted file mode 100644 index 8ccd66d5..00000000 --- a/test/unity/unity_internals.h +++ /dev/null @@ -1,749 +0,0 @@ -/* ========================================== - Unity Project - A Test Framework for C - Copyright (c) 2007-14 Mike Karlesky, Mark VanderVoord, Greg Williams - [Released under MIT License. Please refer to license.txt for details] -========================================== */ - -#ifndef UNITY_INTERNALS_H -#define UNITY_INTERNALS_H - -#ifdef UNITY_INCLUDE_CONFIG_H -#include "unity_config.h" -#endif - -#include - -#ifndef UNITY_EXCLUDE_MATH_H -#include -#endif - -/* Unity Attempts to Auto-Detect Integer Types - * Attempt 1: UINT_MAX, ULONG_MAX in , or default to 32 bits - * Attempt 2: UINTPTR_MAX in , or default to same size as long - * The user may override any of these derived constants: - * UNITY_INT_WIDTH, UNITY_LONG_WIDTH, UNITY_POINTER_WIDTH */ -#ifndef UNITY_EXCLUDE_STDINT_H -#include -#endif - -#ifndef UNITY_EXCLUDE_LIMITS_H -#include -#endif - -/*------------------------------------------------------- - * Guess Widths If Not Specified - *-------------------------------------------------------*/ - -/* Determine the size of an int, if not already specified. - * We cannot use sizeof(int), because it is not yet defined - * at this stage in the translation of the C program. - * Therefore, infer it from UINT_MAX if possible. */ -#ifndef UNITY_INT_WIDTH - #ifdef UINT_MAX - #if (UINT_MAX == 0xFFFF) - #define UNITY_INT_WIDTH (16) - #elif (UINT_MAX == 0xFFFFFFFF) - #define UNITY_INT_WIDTH (32) - #elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF) - #define UNITY_INT_WIDTH (64) - #endif - #else /* Set to default */ - #define UNITY_INT_WIDTH (32) - #endif /* UINT_MAX */ -#endif - -/* Determine the size of a long, if not already specified. */ -#ifndef UNITY_LONG_WIDTH - #ifdef ULONG_MAX - #if (ULONG_MAX == 0xFFFF) - #define UNITY_LONG_WIDTH (16) - #elif (ULONG_MAX == 0xFFFFFFFF) - #define UNITY_LONG_WIDTH (32) - #elif (ULONG_MAX == 0xFFFFFFFFFFFFFFFF) - #define UNITY_LONG_WIDTH (64) - #endif - #else /* Set to default */ - #define UNITY_LONG_WIDTH (32) - #endif /* ULONG_MAX */ -#endif - -/* Determine the size of a pointer, if not already specified. */ -#ifndef UNITY_POINTER_WIDTH - #ifdef UINTPTR_MAX - #if (UINTPTR_MAX <= 0xFFFF) - #define UNITY_POINTER_WIDTH (16) - #elif (UINTPTR_MAX <= 0xFFFFFFFF) - #define UNITY_POINTER_WIDTH (32) - #elif (UINTPTR_MAX <= 0xFFFFFFFFFFFFFFFF) - #define UNITY_POINTER_WIDTH (64) - #endif - #else /* Set to default */ - #define UNITY_POINTER_WIDTH UNITY_LONG_WIDTH - #endif /* UINTPTR_MAX */ -#endif - -/*------------------------------------------------------- - * Int Support (Define types based on detected sizes) - *-------------------------------------------------------*/ - -#if (UNITY_INT_WIDTH == 32) - typedef unsigned char _UU8; - typedef unsigned short _UU16; - typedef unsigned int _UU32; - typedef signed char _US8; - typedef signed short _US16; - typedef signed int _US32; -#elif (UNITY_INT_WIDTH == 16) - typedef unsigned char _UU8; - typedef unsigned int _UU16; - typedef unsigned long _UU32; - typedef signed char _US8; - typedef signed int _US16; - typedef signed long _US32; -#else - #error Invalid UNITY_INT_WIDTH specified! (16 or 32 are supported) -#endif - -/*------------------------------------------------------- - * 64-bit Support - *-------------------------------------------------------*/ - -#ifndef UNITY_SUPPORT_64 - #if UNITY_LONG_WIDTH == 64 || UNITY_POINTER_WIDTH == 64 - #define UNITY_SUPPORT_64 - #endif -#endif - -#ifndef UNITY_SUPPORT_64 - /* No 64-bit Support */ - typedef _UU32 _U_UINT; - typedef _US32 _U_SINT; -#else - - /* 64-bit Support */ - #if (UNITY_LONG_WIDTH == 32) - typedef unsigned long long _UU64; - typedef signed long long _US64; - #elif (UNITY_LONG_WIDTH == 64) - typedef unsigned long _UU64; - typedef signed long _US64; - #else - #error Invalid UNITY_LONG_WIDTH specified! (32 or 64 are supported) - #endif - typedef _UU64 _U_UINT; - typedef _US64 _U_SINT; - -#endif - -/*------------------------------------------------------- - * Pointer Support - *-------------------------------------------------------*/ - -#if (UNITY_POINTER_WIDTH == 32) - typedef _UU32 _UP; -#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX32 -#elif (UNITY_POINTER_WIDTH == 64) - typedef _UU64 _UP; -#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX64 -#elif (UNITY_POINTER_WIDTH == 16) - typedef _UU16 _UP; -#define UNITY_DISPLAY_STYLE_POINTER UNITY_DISPLAY_STYLE_HEX16 -#else - #error Invalid UNITY_POINTER_WIDTH specified! (16, 32 or 64 are supported) -#endif - -#ifndef UNITY_PTR_ATTRIBUTE -#define UNITY_PTR_ATTRIBUTE -#endif - -#ifndef UNITY_INTERNAL_PTR -#define UNITY_INTERNAL_PTR UNITY_PTR_ATTRIBUTE const void* -/* #define UNITY_INTERNAL_PTR UNITY_PTR_ATTRIBUTE const _UU8* */ -#endif - -/*------------------------------------------------------- - * Float Support - *-------------------------------------------------------*/ - -#ifdef UNITY_EXCLUDE_FLOAT - -/* No Floating Point Support */ -#undef UNITY_INCLUDE_FLOAT -#undef UNITY_FLOAT_PRECISION -#undef UNITY_FLOAT_TYPE -#undef UNITY_FLOAT_VERBOSE - -#else - -#ifndef UNITY_INCLUDE_FLOAT -#define UNITY_INCLUDE_FLOAT -#endif - -/* Floating Point Support */ -#ifndef UNITY_FLOAT_PRECISION -#define UNITY_FLOAT_PRECISION (0.00001f) -#endif -#ifndef UNITY_FLOAT_TYPE -#define UNITY_FLOAT_TYPE float -#endif -typedef UNITY_FLOAT_TYPE _UF; - -#ifndef isinf -/* The value of Inf - Inf is NaN */ -#define isinf(n) (isnan((n) - (n)) && !isnan(n)) -#endif - -#ifndef isnan -/* NaN is the only floating point value that does NOT equal itself. - * Therefore if n != n, then it is NaN. */ -#define isnan(n) ((n != n) ? 1 : 0) -#endif - -#ifndef isneg -#define isneg(n) ((n < 0.0f) ? 1 : 0) -#endif - -#ifndef ispos -#define ispos(n) ((n > 0.0f) ? 1 : 0) -#endif - -#endif - -/*------------------------------------------------------- - * Double Float Support - *-------------------------------------------------------*/ - -/* unlike FLOAT, we DON'T include by default */ -#ifndef UNITY_EXCLUDE_DOUBLE - #ifndef UNITY_INCLUDE_DOUBLE - #define UNITY_EXCLUDE_DOUBLE - #endif -#endif - -#ifdef UNITY_EXCLUDE_DOUBLE - - /* No Floating Point Support */ - #undef UNITY_DOUBLE_PRECISION - #undef UNITY_DOUBLE_TYPE - #undef UNITY_DOUBLE_VERBOSE - - #ifdef UNITY_INCLUDE_DOUBLE - #undef UNITY_INCLUDE_DOUBLE - #endif - - #ifdef UNITY_FLOAT_VERBOSE - typedef _UF _UD; - /* For parameter in UnityPrintFloat, double promotion required */ - #endif - -#else - - /* Double Floating Point Support */ - #ifndef UNITY_DOUBLE_PRECISION - #define UNITY_DOUBLE_PRECISION (1e-12f) - #endif - - #ifndef UNITY_DOUBLE_TYPE - #define UNITY_DOUBLE_TYPE double - #endif - typedef UNITY_DOUBLE_TYPE _UD; - -#endif - -#ifdef UNITY_DOUBLE_VERBOSE -#ifndef UNITY_FLOAT_VERBOSE -#define UNITY_FLOAT_VERBOSE -#endif -#endif - -/*------------------------------------------------------- - * Output Method: stdout (DEFAULT) - *-------------------------------------------------------*/ -#ifndef UNITY_OUTPUT_CHAR -/* Default to using putchar, which is defined in stdio.h */ -#include -#define UNITY_OUTPUT_CHAR(a) (void)putchar(a) -#else - /* If defined as something else, make sure we declare it here so it's ready for use */ - #ifndef UNITY_OMIT_OUTPUT_CHAR_HEADER_DECLARATION -extern void UNITY_OUTPUT_CHAR(int); - #endif -#endif - -#ifndef UNITY_OUTPUT_FLUSH -/* Default to using fflush, which is defined in stdio.h */ -#include -#define UNITY_OUTPUT_FLUSH (void)fflush(stdout) -#else - /* If defined as something else, make sure we declare it here so it's ready for use */ - #ifndef UNITY_OMIT_OUTPUT_FLUSH_HEADER_DECLARATION -extern void UNITY_OUTPUT_FLUSH(void); - #endif -#endif - -#ifndef UNITY_OUTPUT_FLUSH -#define UNITY_FLUSH_CALL() -#else -#define UNITY_FLUSH_CALL() UNITY_OUTPUT_FLUSH -#endif - -#ifndef UNITY_PRINT_EOL -#define UNITY_PRINT_EOL() UNITY_OUTPUT_CHAR('\n') -#endif - -#ifndef UNITY_OUTPUT_START -#define UNITY_OUTPUT_START() -#endif - -#ifndef UNITY_OUTPUT_COMPLETE -#define UNITY_OUTPUT_COMPLETE() -#endif - -/*------------------------------------------------------- - * Footprint - *-------------------------------------------------------*/ - -#ifndef UNITY_LINE_TYPE -#define UNITY_LINE_TYPE _U_UINT -#endif - -#ifndef UNITY_COUNTER_TYPE -#define UNITY_COUNTER_TYPE _U_UINT -#endif - -/*------------------------------------------------------- - * Language Features Available - *-------------------------------------------------------*/ -#if !defined(UNITY_WEAK_ATTRIBUTE) && !defined(UNITY_WEAK_PRAGMA) -# ifdef __GNUC__ /* includes clang */ -# if !(defined(__WIN32__) && defined(__clang__)) && !defined(__TMS470__) -# define UNITY_WEAK_ATTRIBUTE __attribute__((weak)) -# endif -# endif -#endif - -#ifdef UNITY_NO_WEAK -# undef UNITY_WEAK_ATTRIBUTE -# undef UNITY_WEAK_PRAGMA -#endif - - -/*------------------------------------------------------- - * Internal Structs Needed - *-------------------------------------------------------*/ - -typedef void (*UnityTestFunction)(void); - -#define UNITY_DISPLAY_RANGE_INT (0x10) -#define UNITY_DISPLAY_RANGE_UINT (0x20) -#define UNITY_DISPLAY_RANGE_HEX (0x40) -#define UNITY_DISPLAY_RANGE_AUTO (0x80) - -typedef enum -{ -UNITY_DISPLAY_STYLE_INT = sizeof(int)+ UNITY_DISPLAY_RANGE_INT + UNITY_DISPLAY_RANGE_AUTO, - UNITY_DISPLAY_STYLE_INT8 = 1 + UNITY_DISPLAY_RANGE_INT, - UNITY_DISPLAY_STYLE_INT16 = 2 + UNITY_DISPLAY_RANGE_INT, - UNITY_DISPLAY_STYLE_INT32 = 4 + UNITY_DISPLAY_RANGE_INT, -#ifdef UNITY_SUPPORT_64 - UNITY_DISPLAY_STYLE_INT64 = 8 + UNITY_DISPLAY_RANGE_INT, -#endif - -UNITY_DISPLAY_STYLE_UINT = sizeof(unsigned) + UNITY_DISPLAY_RANGE_UINT + UNITY_DISPLAY_RANGE_AUTO, - UNITY_DISPLAY_STYLE_UINT8 = 1 + UNITY_DISPLAY_RANGE_UINT, - UNITY_DISPLAY_STYLE_UINT16 = 2 + UNITY_DISPLAY_RANGE_UINT, - UNITY_DISPLAY_STYLE_UINT32 = 4 + UNITY_DISPLAY_RANGE_UINT, -#ifdef UNITY_SUPPORT_64 - UNITY_DISPLAY_STYLE_UINT64 = 8 + UNITY_DISPLAY_RANGE_UINT, -#endif - - UNITY_DISPLAY_STYLE_HEX8 = 1 + UNITY_DISPLAY_RANGE_HEX, - UNITY_DISPLAY_STYLE_HEX16 = 2 + UNITY_DISPLAY_RANGE_HEX, - UNITY_DISPLAY_STYLE_HEX32 = 4 + UNITY_DISPLAY_RANGE_HEX, -#ifdef UNITY_SUPPORT_64 - UNITY_DISPLAY_STYLE_HEX64 = 8 + UNITY_DISPLAY_RANGE_HEX, -#endif - - UNITY_DISPLAY_STYLE_UNKNOWN -} UNITY_DISPLAY_STYLE_T; - -#ifndef UNITY_EXCLUDE_FLOAT -typedef enum _UNITY_FLOAT_TRAIT_T -{ - UNITY_FLOAT_IS_NOT_INF = 0, - UNITY_FLOAT_IS_INF, - UNITY_FLOAT_IS_NOT_NEG_INF, - UNITY_FLOAT_IS_NEG_INF, - UNITY_FLOAT_IS_NOT_NAN, - UNITY_FLOAT_IS_NAN, - UNITY_FLOAT_IS_NOT_DET, - UNITY_FLOAT_IS_DET, - UNITY_FLOAT_INVALID_TRAIT -} UNITY_FLOAT_TRAIT_T; -#endif - -struct _Unity -{ - const char* TestFile; - const char* CurrentTestName; -#ifndef UNITY_EXCLUDE_DETAILS - const char* CurrentDetail1; - const char* CurrentDetail2; -#endif - UNITY_LINE_TYPE CurrentTestLineNumber; - UNITY_COUNTER_TYPE NumberOfTests; - UNITY_COUNTER_TYPE TestFailures; - UNITY_COUNTER_TYPE TestIgnores; - UNITY_COUNTER_TYPE CurrentTestFailed; - UNITY_COUNTER_TYPE CurrentTestIgnored; - jmp_buf AbortFrame; -}; - -extern struct _Unity Unity; - -/*------------------------------------------------------- - * Test Suite Management - *-------------------------------------------------------*/ - -void UnityBegin(const char* filename); -int UnityEnd(void); -void UnityConcludeTest(void); -void UnityDefaultTestRun(UnityTestFunction Func, const char* FuncName, const int FuncLineNum); - -/*------------------------------------------------------- - * Details Support - *-------------------------------------------------------*/ - -#ifdef UNITY_EXCLUDE_DETAILS -#define UNITY_CLR_DETAILS() -#define UNITY_SET_DETAIL(d1) -#define UNITY_SET_DETAILS(d1,d2) -#else -#define UNITY_CLR_DETAILS() { Unity.CurrentDetail1 = 0; Unity.CurrentDetail2 = 0; } -#define UNITY_SET_DETAIL(d1) { Unity.CurrentDetail1 = d1; Unity.CurrentDetail2 = 0; } -#define UNITY_SET_DETAILS(d1,d2) { Unity.CurrentDetail1 = d1; Unity.CurrentDetail2 = d2; } - -#ifndef UNITY_DETAIL1_NAME -#define UNITY_DETAIL1_NAME "Function" -#endif - -#ifndef UNITY_DETAIL2_NAME -#define UNITY_DETAIL2_NAME "Argument" -#endif -#endif - -/*------------------------------------------------------- - * Test Output - *-------------------------------------------------------*/ - -void UnityPrint(const char* string); -void UnityPrintMask(const _U_UINT mask, const _U_UINT number); -void UnityPrintNumberByStyle(const _U_SINT number, const UNITY_DISPLAY_STYLE_T style); -void UnityPrintNumber(const _U_SINT number); -void UnityPrintNumberUnsigned(const _U_UINT number); -void UnityPrintNumberHex(const _U_UINT number, const char nibbles); - -#ifdef UNITY_FLOAT_VERBOSE -void UnityPrintFloat(const _UD number); -#endif - -/*------------------------------------------------------- - * Test Assertion Functions - *------------------------------------------------------- - * Use the macros below this section instead of calling - * these directly. The macros have a consistent naming - * convention and will pull in file and line information - * for you. */ - -void UnityAssertEqualNumber(const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style); - -void UnityAssertEqualIntArray(UNITY_INTERNAL_PTR expected, - UNITY_INTERNAL_PTR actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style); - -void UnityAssertBits(const _U_SINT mask, - const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualString(const char* expected, - const char* actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualStringLen(const char* expected, - const char* actual, - const _UU32 length, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualStringArray( const char** expected, - const char** actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualMemory( UNITY_INTERNAL_PTR expected, - UNITY_INTERNAL_PTR actual, - const _UU32 length, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertNumbersWithin(const _U_UINT delta, - const _U_SINT expected, - const _U_SINT actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_DISPLAY_STYLE_T style); - -void UnityFail(const char* message, const UNITY_LINE_TYPE line); - -void UnityIgnore(const char* message, const UNITY_LINE_TYPE line); - -#ifndef UNITY_EXCLUDE_FLOAT -void UnityAssertFloatsWithin(const _UF delta, - const _UF expected, - const _UF actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualFloatArray(UNITY_PTR_ATTRIBUTE const _UF* expected, - UNITY_PTR_ATTRIBUTE const _UF* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertFloatSpecial(const _UF actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_FLOAT_TRAIT_T style); -#endif - -#ifndef UNITY_EXCLUDE_DOUBLE -void UnityAssertDoublesWithin(const _UD delta, - const _UD expected, - const _UD actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertEqualDoubleArray(UNITY_PTR_ATTRIBUTE const _UD* expected, - UNITY_PTR_ATTRIBUTE const _UD* actual, - const _UU32 num_elements, - const char* msg, - const UNITY_LINE_TYPE lineNumber); - -void UnityAssertDoubleSpecial(const _UD actual, - const char* msg, - const UNITY_LINE_TYPE lineNumber, - const UNITY_FLOAT_TRAIT_T style); -#endif - -/*------------------------------------------------------- - * Error Strings We Might Need - *-------------------------------------------------------*/ - -extern const char UnityStrErrFloat[]; -extern const char UnityStrErrDouble[]; -extern const char UnityStrErr64[]; - -/*------------------------------------------------------- - * Test Running Macros - *-------------------------------------------------------*/ - -#define TEST_PROTECT() (setjmp(Unity.AbortFrame) == 0) - -#define TEST_ABORT() {longjmp(Unity.AbortFrame, 1);} - -/* This tricky series of macros gives us an optional line argument to treat it as RUN_TEST(func, num=__LINE__) */ -#ifndef RUN_TEST -#ifdef __STDC_VERSION__ -#if __STDC_VERSION__ >= 199901L -#define RUN_TEST(...) UnityDefaultTestRun(RUN_TEST_FIRST(__VA_ARGS__), RUN_TEST_SECOND(__VA_ARGS__)) -#define RUN_TEST_FIRST(...) RUN_TEST_FIRST_HELPER(__VA_ARGS__, throwaway) -#define RUN_TEST_FIRST_HELPER(first, ...) (first), #first -#define RUN_TEST_SECOND(...) RUN_TEST_SECOND_HELPER(__VA_ARGS__, __LINE__, throwaway) -#define RUN_TEST_SECOND_HELPER(first, second, ...) (second) -#endif -#endif -#endif - -/* If we can't do the tricky version, we'll just have to require them to always include the line number */ -#ifndef RUN_TEST -#ifdef CMOCK -#define RUN_TEST(func, num) UnityDefaultTestRun(func, #func, num) -#else -#define RUN_TEST(func) UnityDefaultTestRun(func, #func, __LINE__) -#endif -#endif - -#define TEST_LINE_NUM (Unity.CurrentTestLineNumber) -#define TEST_IS_IGNORED (Unity.CurrentTestIgnored) -#define UNITY_NEW_TEST(a) \ - Unity.CurrentTestName = (a); \ - Unity.CurrentTestLineNumber = (UNITY_LINE_TYPE)(__LINE__); \ - Unity.NumberOfTests++; - -#ifndef UNITY_BEGIN -#define UNITY_BEGIN() UnityBegin(__FILE__) -#endif - -#ifndef UNITY_END -#define UNITY_END() UnityEnd() -#endif - -#define UNITY_UNUSED(x) (void)(sizeof(x)) - -/*----------------------------------------------- - * Command Line Argument Support - *-----------------------------------------------*/ - -#ifdef UNITY_USE_COMMAND_LINE_ARGS -int UnityParseOptions(int argc, char** argv); -int UnityTestMatches(void); -#endif - -/*------------------------------------------------------- - * Basic Fail and Ignore - *-------------------------------------------------------*/ - -#define UNITY_TEST_FAIL(line, message) UnityFail( (message), (UNITY_LINE_TYPE)(line)) -#define UNITY_TEST_IGNORE(line, message) UnityIgnore( (message), (UNITY_LINE_TYPE)(line)) - -/*------------------------------------------------------- - * Test Asserts - *-------------------------------------------------------*/ - -#define UNITY_TEST_ASSERT(condition, line, message) if (condition) {} else {UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), (message));} -#define UNITY_TEST_ASSERT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) == NULL), (UNITY_LINE_TYPE)(line), (message)) -#define UNITY_TEST_ASSERT_NOT_NULL(pointer, line, message) UNITY_TEST_ASSERT(((pointer) != NULL), (UNITY_LINE_TYPE)(line), (message)) - -#define UNITY_TEST_ASSERT_EQUAL_INT(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) -#define UNITY_TEST_ASSERT_EQUAL_INT8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) -#define UNITY_TEST_ASSERT_EQUAL_INT16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) -#define UNITY_TEST_ASSERT_EQUAL_INT32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) -#define UNITY_TEST_ASSERT_EQUAL_UINT(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) -#define UNITY_TEST_ASSERT_EQUAL_UINT8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU8 )(expected), (_U_SINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) -#define UNITY_TEST_ASSERT_EQUAL_UINT16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU16)(expected), (_U_SINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) -#define UNITY_TEST_ASSERT_EQUAL_UINT32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UU32)(expected), (_U_SINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) -#define UNITY_TEST_ASSERT_EQUAL_HEX8(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) -#define UNITY_TEST_ASSERT_EQUAL_HEX16(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) -#define UNITY_TEST_ASSERT_EQUAL_HEX32(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) -#define UNITY_TEST_ASSERT_BITS(mask, expected, actual, line, message) UnityAssertBits((_U_SINT)(mask), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line)) - -#define UNITY_TEST_ASSERT_INT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) -#define UNITY_TEST_ASSERT_INT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU8 )(delta), (_U_SINT)(_US8 )(expected), (_U_SINT)(_US8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) -#define UNITY_TEST_ASSERT_INT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU16)(delta), (_U_SINT)(_US16)(expected), (_U_SINT)(_US16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) -#define UNITY_TEST_ASSERT_INT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU32)(delta), (_U_SINT)(_US32)(expected), (_U_SINT)(_US32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) -#define UNITY_TEST_ASSERT_UINT_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) -#define UNITY_TEST_ASSERT_UINT8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU8 )(delta), (_U_SINT)(_U_UINT)(_UU8 )(expected), (_U_SINT)(_U_UINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) -#define UNITY_TEST_ASSERT_UINT16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU16)(delta), (_U_SINT)(_U_UINT)(_UU16)(expected), (_U_SINT)(_U_UINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) -#define UNITY_TEST_ASSERT_UINT32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU32)(delta), (_U_SINT)(_U_UINT)(_UU32)(expected), (_U_SINT)(_U_UINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) -#define UNITY_TEST_ASSERT_HEX8_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU8 )(delta), (_U_SINT)(_U_UINT)(_UU8 )(expected), (_U_SINT)(_U_UINT)(_UU8 )(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) -#define UNITY_TEST_ASSERT_HEX16_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU16)(delta), (_U_SINT)(_U_UINT)(_UU16)(expected), (_U_SINT)(_U_UINT)(_UU16)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) -#define UNITY_TEST_ASSERT_HEX32_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((_UU32)(delta), (_U_SINT)(_U_UINT)(_UU32)(expected), (_U_SINT)(_U_UINT)(_UU32)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) - -#define UNITY_TEST_ASSERT_EQUAL_PTR(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(_UP)(expected), (_U_SINT)(_UP)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER) -#define UNITY_TEST_ASSERT_EQUAL_STRING(expected, actual, line, message) UnityAssertEqualString((const char*)(expected), (const char*)(actual), (message), (UNITY_LINE_TYPE)(line)) -#define UNITY_TEST_ASSERT_EQUAL_STRING_LEN(expected, actual, len, line, message) UnityAssertEqualStringLen((const char*)(expected), (const char*)(actual), (_UU32)(len), (message), (UNITY_LINE_TYPE)(line)) -#define UNITY_TEST_ASSERT_EQUAL_MEMORY(expected, actual, len, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(len), 1, (message), (UNITY_LINE_TYPE)(line)) - -#define UNITY_TEST_ASSERT_EQUAL_INT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT) -#define UNITY_TEST_ASSERT_EQUAL_INT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT8) -#define UNITY_TEST_ASSERT_EQUAL_INT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT16) -#define UNITY_TEST_ASSERT_EQUAL_INT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT32) -#define UNITY_TEST_ASSERT_EQUAL_UINT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT) -#define UNITY_TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT8) -#define UNITY_TEST_ASSERT_EQUAL_UINT16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT16) -#define UNITY_TEST_ASSERT_EQUAL_UINT32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT32) -#define UNITY_TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX8) -#define UNITY_TEST_ASSERT_EQUAL_HEX16_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX16) -#define UNITY_TEST_ASSERT_EQUAL_HEX32_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX32) -#define UNITY_TEST_ASSERT_EQUAL_PTR_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(_UP*)(expected), (UNITY_INTERNAL_PTR)(_UP*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_POINTER) -#define UNITY_TEST_ASSERT_EQUAL_STRING_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualStringArray((const char**)(expected), (const char**)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line)) -#define UNITY_TEST_ASSERT_EQUAL_MEMORY_ARRAY(expected, actual, len, num_elements, line, message) UnityAssertEqualMemory((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(len), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line)) - -#ifdef UNITY_SUPPORT_64 -#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) -#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) -#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UnityAssertEqualNumber((_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) -#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) -#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) -#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualIntArray((UNITY_INTERNAL_PTR)(expected), (UNITY_INTERNAL_PTR)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) -#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_INT64) -#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_UINT64) -#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UnityAssertNumbersWithin((delta), (_U_SINT)(expected), (_U_SINT)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_DISPLAY_STYLE_HEX64) -#else -#define UNITY_TEST_ASSERT_EQUAL_INT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_UINT64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_HEX64(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_INT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_UINT64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_EQUAL_HEX64_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_INT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_UINT64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#define UNITY_TEST_ASSERT_HEX64_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErr64) -#endif - -#ifdef UNITY_EXCLUDE_FLOAT -#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrFloat) -#else -#define UNITY_TEST_ASSERT_FLOAT_WITHIN(delta, expected, actual, line, message) UnityAssertFloatsWithin((_UF)(delta), (_UF)(expected), (_UF)(actual), (message), (UNITY_LINE_TYPE)(line)) -#define UNITY_TEST_ASSERT_EQUAL_FLOAT(expected, actual, line, message) UNITY_TEST_ASSERT_FLOAT_WITHIN((_UF)(expected) * (_UF)UNITY_FLOAT_PRECISION, (_UF)(expected), (_UF)(actual), (UNITY_LINE_TYPE)(line), (message)) -#define UNITY_TEST_ASSERT_EQUAL_FLOAT_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualFloatArray((_UF*)(expected), (_UF*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)(line)) -#define UNITY_TEST_ASSERT_FLOAT_IS_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) -#define UNITY_TEST_ASSERT_FLOAT_IS_NEG_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) -#define UNITY_TEST_ASSERT_FLOAT_IS_NAN(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) -#define UNITY_TEST_ASSERT_FLOAT_IS_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_DET) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_INF) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NEG_INF(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NEG_INF) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_NAN(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NAN) -#define UNITY_TEST_ASSERT_FLOAT_IS_NOT_DETERMINATE(actual, line, message) UnityAssertFloatSpecial((_UF)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET) -#endif - -#ifdef UNITY_EXCLUDE_DOUBLE -#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UNITY_TEST_FAIL((UNITY_LINE_TYPE)(line), UnityStrErrDouble) -#else -#define UNITY_TEST_ASSERT_DOUBLE_WITHIN(delta, expected, actual, line, message) UnityAssertDoublesWithin((_UD)(delta), (_UD)(expected), (_UD)(actual), (message), (UNITY_LINE_TYPE)line) -#define UNITY_TEST_ASSERT_EQUAL_DOUBLE(expected, actual, line, message) UNITY_TEST_ASSERT_DOUBLE_WITHIN((_UD)(expected) * (_UD)UNITY_DOUBLE_PRECISION, (_UD)expected, (_UD)actual, (UNITY_LINE_TYPE)(line), message) -#define UNITY_TEST_ASSERT_EQUAL_DOUBLE_ARRAY(expected, actual, num_elements, line, message) UnityAssertEqualDoubleArray((_UD*)(expected), (_UD*)(actual), (_UU32)(num_elements), (message), (UNITY_LINE_TYPE)line) -#define UNITY_TEST_ASSERT_DOUBLE_IS_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_INF) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NEG_INF) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NAN(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NAN) -#define UNITY_TEST_ASSERT_DOUBLE_IS_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_DET) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_INF) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NEG_INF(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NEG_INF) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_NAN(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_NAN) -#define UNITY_TEST_ASSERT_DOUBLE_IS_NOT_DETERMINATE(actual, line, message) UnityAssertDoubleSpecial((_UD)(actual), (message), (UNITY_LINE_TYPE)(line), UNITY_FLOAT_IS_NOT_DET) -#endif - -/* End of UNITY_INTERNALS_H */ -#endif From 1ab0829ab3db39600b5e0d06935f19bf4199894d Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 3 May 2018 19:31:54 +0700 Subject: [PATCH 103/109] Added doc/ALGORITHMS.md. --- doc/ALGORITHMS.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 doc/ALGORITHMS.md diff --git a/doc/ALGORITHMS.md b/doc/ALGORITHMS.md new file mode 100644 index 00000000..3e1718d3 --- /dev/null +++ b/doc/ALGORITHMS.md @@ -0,0 +1,43 @@ +# Algorithms + +XMRig uses a different way to specify algorithms, compared to other miners. + +Algorithm selection splitted to 2 parts: + + * Global base algorithm per miner or proxy instance, `algo` option. Possible values: `cryptonight`, `cryptonight-lite`, `cryptonight-heavy`. + * Algorithm variant specified separately for each pool, `variant` option. + +Possible variants for `cryptonight`: + + * `0` Original cryptonight. + * `1` cryptonight variant 1, also known as cryptonight v7 or monero7. + * `"xtl"` Stellite coin variant. + +Possible variants for `cryptonight-lite`: + + * `0` Original cryptonight-lite. + * `1` cryptonight-lite variant 1, also known as cryptonight-lite v7 or aeon7. + * `"ipbc"` IPBC coin variant. + +For `cryptonight-heavy` currently no variants. + + +### Cheatsheet + +You mine **Sumokoin** or **Haven Protocol**? +Your algorithm is `cryptonight-heavy` no variant option need. + +You mine **Aeon**, **TurtleCoin** or **IPBC**?. +Your base algorithm is `cryptonight-lite`: +Variants: + * Aeon: `-1` autodetect. `0` right now, `1` after fork. + * TurtleCoin: `1`. + * IPBC: `"ipbc"`. + +In all other cases base algorithm is `cryptonight`. + +### Mining algorithm negotiation +If your pool support [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/issues/168) miner will choice proper variant automaticaly and if you choice wrong base algorithm you will see error message. + +Pools with mining algorithm negotiation support. + * [www.hashvault.pro](https://www.hashvault.pro/) \ No newline at end of file From 734c0dbce1637feabf677083dbcaeea215a7db09 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 3 May 2018 20:16:42 +0700 Subject: [PATCH 104/109] Use block version to detect proper XTL variant and use variant 1 by default for cryptonight. --- src/common/net/Job.cpp | 22 ++++++++++++++++++++++ src/common/net/Job.h | 6 +----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/common/net/Job.cpp b/src/common/net/Job.cpp index 34aab326..81c3b8f8 100644 --- a/src/common/net/Job.cpp +++ b/src/common/net/Job.cpp @@ -163,6 +163,28 @@ bool Job::setTarget(const char *target) } +xmrig::Variant Job::variant() const +{ + if (m_algorithm.algo() == xmrig::CRYPTONIGHT_HEAVY) { + return xmrig::VARIANT_0; + } + + if (m_algorithm.variant() == xmrig::VARIANT_XTL && m_blob[0] < 4) { + return xmrig::VARIANT_1; + } + + if (m_algorithm.variant() == xmrig::VARIANT_AUTO) { + if (m_algorithm.algo() == xmrig::CRYPTONIGHT) { + return xmrig::VARIANT_1; + } + + return (m_blob[0] > 6 ? xmrig::VARIANT_1 : xmrig::VARIANT_0); + } + + return m_algorithm.variant(); +} + + bool Job::fromHex(const char* in, unsigned int len, unsigned char* out) { bool error = false; diff --git a/src/common/net/Job.h b/src/common/net/Job.h index 08d5ae82..049eb7d4 100644 --- a/src/common/net/Job.h +++ b/src/common/net/Job.h @@ -43,6 +43,7 @@ public: bool setBlob(const char *blob); bool setTarget(const char *target); + xmrig::Variant variant() const; inline bool isNicehash() const { return m_nicehash; } inline bool isValid() const { return m_size > 0 && m_diff > 0; } @@ -64,11 +65,6 @@ public: inline void setThreadId(int threadId) { m_threadId = threadId; } inline xmrig::Algorithm &algorithm() { return m_algorithm; } - inline xmrig::Variant variant() const - { - return (m_algorithm.variant() == xmrig::VARIANT_AUTO ? (m_blob[0] > 6 ? xmrig::VARIANT_1 : xmrig::VARIANT_0) : m_algorithm.variant()); - } - # ifdef XMRIG_PROXY_PROJECT inline char *rawBlob() { return m_rawBlob; } inline const char *rawTarget() const { return m_rawTarget; } From b98d44ce10613968ca240e570462d24ab668766c Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 3 May 2018 22:17:40 +0700 Subject: [PATCH 105/109] Update CHANGELOG.md. --- CHANGELOG.md | 342 ++++++++++++++++++++++++++------------------------- 1 file changed, 175 insertions(+), 167 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53e24f85..e905725e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,167 +1,175 @@ -# v2.6.0-beta3 -- [#563](https://github.com/xmrig/xmrig/issues/563) **Added [advanced threads mode](https://github.com/xmrig/xmrig/issues/563), now possible configure each thread individually.** -- [#255](https://github.com/xmrig/xmrig/issues/563) Low power mode extended to **triple**, **quard** and **penta** modes. -- [#519](https://github.com/xmrig/xmrig/issues/519) Fixed high donation levels, improved donation start time randomization. -- [#554](https://github.com/xmrig/xmrig/issues/554) Fixed regression with `print-time` option. - -# v2.6.0-beta2 -- Improved performance for `cryptonight v7` especially in double hash mode. -- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 disabled for internal HTTP API by default, was causing issues on some systems. -- Added short aliases for algorithm names: `cn`, `cn-lite` and `cn-heavy`. -- Fixed regressions (v2.6.0-beta1 affected) - - [#494](https://github.com/xmrig/xmrig/issues/494) Command line option `--donate-level` was broken. - - [#502](https://github.com/xmrig/xmrig/issues/502) Build without libmicrohttpd was broken. - - Fixed nonce calculation for `--av 4` (software AES, double hash) was causing reduction of effective hashrate and rejected shares on nicehash. - -# v2.6.0-beta1 - - [#476](https://github.com/xmrig/xmrig/issues/476) **Added Cryptonight-Heavy support for Sumokoin ASIC resistance fork.** - - HTTP server now runs in main loop, it make possible easy extend API without worry about thread synchronization. - - Added initial graceful reload support, miner will reload configuration if config file changed, disabled by default until it will be fully implemented and tested. - - Added API endpoint `PUT /1/config` to update current config. - - Added API endpoint `GET /1/config` to get current active config. - - Added API endpoint `GET /1/threads` to get current active threads configuration. - - API endpoint `GET /` now deprecated, use `GET /1/summary` instead. - - Added `--api-no-ipv6` and similar config option to disable IPv6 support for HTTP API. - - Added `--api-no-restricted` to enable full access to api, this option has no effect if `--api-access-token` not specified. - -# v2.5.3 -- Fixed critical bug, in some cases miner was can't recovery connection and switch to failover pool, version 2.5.2 affected. If you use v2.6.0-beta3 this issue doesn't concern you. -- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 support disabled for internal HTTP API. -- Added workaround for nicehash.com if you use `cryptonightv7..nicehash.com` option `variant=1` will be set automatically. - -# v2.5.2 -- [#448](https://github.com/xmrig/xmrig/issues/478) Fixed broken reconnect. - -# v2.5.1 -- [#454](https://github.com/xmrig/xmrig/issues/454) Fixed build with libmicrohttpd version below v0.9.35. -- [#456](https://github.com/xmrig/xmrig/issues/459) Verbose errors related to donation pool was not fully silenced. -- [#459](https://github.com/xmrig/xmrig/issues/459) Fixed regression (version 2.5.0 affected) with connection to **xmr.f2pool.com**. - -# v2.5.0 -- [#434](https://github.com/xmrig/xmrig/issues/434) **Added support for Monero v7 PoW, scheduled on April 6.** -- Added full IPv6 support. -- Added protocol extension, when use the miner with xmrig-proxy 2.5+ no more need manually specify `nicehash` option. -- [#123](https://github.com/xmrig/xmrig-proxy/issues/123) Fixed regression (all versions since 2.4 affected) fragmented responses from pool/proxy was parsed incorrectly. -- [#428](https://github.com/xmrig/xmrig/issues/428) Fixed regression (version 2.4.5 affected) with CPU cache size detection. - -# v2.4.5 -- [#324](https://github.com/xmrig/xmrig/pull/324) Fixed build without libmicrohttpd (CMake cache issue). -- [#341](https://github.com/xmrig/xmrig/issues/341) Fixed wrong exit code and added command line option `--dry-run`. -- [#385](https://github.com/xmrig/xmrig/pull/385) Up to 20% performance increase for non-AES CPU and fixed Intel Core 2 cache detection. - -# v2.4.4 - - Added libmicrohttpd version to --version output. - - Fixed bug in singal handler, in some cases miner wasn't shutdown properly. - - Fixed recent MSVC 2017 version detection. - - [#279](https://github.com/xmrig/xmrig/pull/279) Fixed build on some macOS versions. - -# v2.4.3 - - [#94](https://github.com/xmrig/xmrig/issues/94#issuecomment-342019257) [#216](https://github.com/xmrig/xmrig/issues/216) Added **ARMv8** and **ARMv7** support. Hardware AES supported, thanks [Imran Yusuff](https://github.com/imranyusuff). - - [#157](https://github.com/xmrig/xmrig/issues/157) [#196](https://github.com/xmrig/xmrig/issues/196) Fixed Linux compile issues. - - [#184](https://github.com/xmrig/xmrig/issues/184) Fixed cache size detection for CPUs with disabled Hyper-Threading. - - [#200](https://github.com/xmrig/xmrig/issues/200) In some cases miner was doesn't write log to stdout. - -# v2.4.2 - - [#60](https://github.com/xmrig/xmrig/issues/60) Added FreeBSD support, thanks [vcambur](https://github.com/vcambur). - - [#153](https://github.com/xmrig/xmrig/issues/153) Fixed issues with dwarfpool.com. - -# v2.4.1 - - [#147](https://github.com/xmrig/xmrig/issues/147) Fixed comparability with monero-stratum. - -# v2.4.0 - - Added [HTTP API](https://github.com/xmrig/xmrig/wiki/API). - - Added comments support in config file. - - libjansson replaced to rapidjson. - - [#98](https://github.com/xmrig/xmrig/issues/98) Ignore `keepalive` option with minergate.com and nicehash.com. - - [#101](https://github.com/xmrig/xmrig/issues/101) Fixed MSVC 2017 (15.3) compile time version detection. - - [#108](https://github.com/xmrig/xmrig/issues/108) Silently ignore invalid values for `donate-level` option. - - [#111](https://github.com/xmrig/xmrig/issues/111) Fixed build without AEON support. - -# v2.3.1 -- [#68](https://github.com/xmrig/xmrig/issues/68) Fixed compatibility with Docker containers, was nothing print on console. - -# v2.3.0 -- Added `--cpu-priority` option (0 idle, 2 normal to 5 highest). -- Added `--user-agent` option, to set custom user-agent string for pool. For example `cpuminer-multi/0.1`. -- Added `--no-huge-pages` option, to disable huge pages support. -- [#62](https://github.com/xmrig/xmrig/issues/62) Don't send the login to the dev pool. -- Force reconnect if pool block miner IP address. helps switch to backup pool. -- Fixed: failed open default config file if path contains non English characters. -- Fixed: error occurred if try use unavailable stdin or stdout, regression since version 2.2.0. -- Fixed: message about huge pages support successfully enabled on Windows was not shown in release builds. - -# v2.2.1 -- Fixed [terminal issues](https://github.com/xmrig/xmrig-proxy/issues/2#issuecomment-319914085) after exit on Linux and OS X. - -# v2.2.0 -- [#46](https://github.com/xmrig/xmrig/issues/46) Restored config file support. Now possible use multiple config files and combine with command line options also added support for default config. -- Improved colors support on Windows, now used uv_tty, legacy code removed. -- QuickEdit Mode now disabled on Windows. -- Added interactive commands in console window:: **h**ashrate, **p**ause, **r**esume. -- Fixed autoconf mode for AMD FX CPUs. - -# v2.1.0 -- [#40](https://github.com/xmrig/xmrig/issues/40) -Improved miner shutdown, fixed crash on exit for Linux and OS X. -- Fixed, login request was contain malformed JSON if username or password has some special characters for example `\`. -- [#220](https://github.com/fireice-uk/xmr-stak-cpu/pull/220) Better support for Round Robin DNS, IP address now always chosen randomly instead of stuck on first one. -- Changed donation address, new [xmrig-proxy](https://github.com/xmrig/xmrig-proxy) is coming soon. - -# v2.0.2 -- Better deal with possible duplicate jobs from pool, show warning and ignore duplicates. -- For Windows builds libuv updated to version 1.13.1 and gcc to 7.1.0. - -# v2.0.1 - - [#27](https://github.com/xmrig/xmrig/issues/27) Fixed possibility crash on 32bit systems. - -# v2.0.0 - - Option `--backup-url` removed, instead now possibility specify multiple pools for example: `-o example1.com:3333 -u user1 -p password1 -k -o example2.com:5555 -u user2 -o example3.com:4444 -u user3` - - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-l, --log-file=FILE` to write log to file. - - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-S, --syslog` to use syslog for logging, Linux only. - - [#18](https://github.com/xmrig/xmrig/issues/18) Added nice messages for accepted/rejected shares with diff and network latency. - - [#20](https://github.com/xmrig/xmrig/issues/20) Fixed `--cpu-affinity` for more than 32 threads. - - Fixed Windows XP support. - - Fixed regression, option `--no-color` was not fully disable colored output. - - Show resolved pool IP address in miner output. - -# v1.0.1 -- Fix broken software AES implementation, app has crashed if CPU not support AES-NI, only version 1.0.0 affected. - -# v1.0.0 -- Miner complete rewritten in C++ with libuv. -- This version should be fully compatible (except config file) with previos versions, many new nice features will come in next versions. -- This is still beta. If you found regression, stability or perfomance issues or have an idea for new feature please fell free to open new [issue](https://github.com/xmrig/xmrig/issues/new). -- Added new option `--print-time=N`, print hashrate report every N seconds. -- New hashrate reports, by default every 60 secons. -- Added Microsoft Visual C++ 2015 and 2017 support. -- Removed dependency on libcurl. -- To compile this version from source please switch to [dev](https://github.com/xmrig/xmrig/tree/dev) branch. - -# v0.8.2 -- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). - -# v0.8.2 -- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). -- Fixed gcc 7.1 support. - -# v0.8.1 -- Added nicehash support, detects automaticaly by pool URL, for example `cryptonight.eu.nicehash.com:3355` or manually via option `--nicehash`. - -# v0.8.0 -- Added double hash mode, also known as lower power mode. `--av=2` and `--av=4`. -- Added smart automatic CPU configuration. Default threads count now depends on size of the L3 cache of CPU. -- Added CryptoNight-Lite support for AEON `-a cryptonight-lite`. -- Added `--max-cpu-usage` option for auto CPU configuration mode. -- Added `--safe` option for adjust threads and algorithm variations to current CPU. -- No more manual steps to enable huge pages on Windows. XMRig will do it automatically. -- Removed BMI2 algorithm variation. -- Removed default pool URL. - -# v0.6.0 -- Added automatic cryptonight self test. -- New software AES algorithm variation. Will be automatically selected if cpu not support AES-NI. -- Added 32 bit builds. -- Documented [algorithm variations](https://github.com/xmrig/xmrig#algorithm-variations). - -# v0.5.0 -- Initial public release. +# v2.6.1-beta + - [#168](https://github.com/xmrig/xmrig-proxy/issues/168) Added support for [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/blob/dev/doc/STRATUM_EXT.md#1-mining-algorithm-negotiation). + - Added IPBC coin support, base algorithm `cn-lite` variant `ipbc`. + - [#581](https://github.com/xmrig/xmrig/issues/581) Added support for upcoming Stellite (XTL) fork, base algorithm `cn` variant `xtl`, variant can set now, no need do it after fork. + - Added support for **rig-id** stratum protocol extensions, compatible with xmr-stak. + - Changed behavior for option `variant=-1` for `cryptonight`, now variant is `1` by default, if you mine old coins need change `variant` to `0`. + - A lot of small fixes and better unification with proxy code. + +# v2.6.0-beta3 +- [#563](https://github.com/xmrig/xmrig/issues/563) **Added [advanced threads mode](https://github.com/xmrig/xmrig/issues/563), now possible configure each thread individually.** +- [#255](https://github.com/xmrig/xmrig/issues/563) Low power mode extended to **triple**, **quard** and **penta** modes. +- [#519](https://github.com/xmrig/xmrig/issues/519) Fixed high donation levels, improved donation start time randomization. +- [#554](https://github.com/xmrig/xmrig/issues/554) Fixed regression with `print-time` option. + +# v2.6.0-beta2 +- Improved performance for `cryptonight v7` especially in double hash mode. +- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 disabled for internal HTTP API by default, was causing issues on some systems. +- Added short aliases for algorithm names: `cn`, `cn-lite` and `cn-heavy`. +- Fixed regressions (v2.6.0-beta1 affected) + - [#494](https://github.com/xmrig/xmrig/issues/494) Command line option `--donate-level` was broken. + - [#502](https://github.com/xmrig/xmrig/issues/502) Build without libmicrohttpd was broken. + - Fixed nonce calculation for `--av 4` (software AES, double hash) was causing reduction of effective hashrate and rejected shares on nicehash. + +# v2.6.0-beta1 + - [#476](https://github.com/xmrig/xmrig/issues/476) **Added Cryptonight-Heavy support for Sumokoin ASIC resistance fork.** + - HTTP server now runs in main loop, it make possible easy extend API without worry about thread synchronization. + - Added initial graceful reload support, miner will reload configuration if config file changed, disabled by default until it will be fully implemented and tested. + - Added API endpoint `PUT /1/config` to update current config. + - Added API endpoint `GET /1/config` to get current active config. + - Added API endpoint `GET /1/threads` to get current active threads configuration. + - API endpoint `GET /` now deprecated, use `GET /1/summary` instead. + - Added `--api-no-ipv6` and similar config option to disable IPv6 support for HTTP API. + - Added `--api-no-restricted` to enable full access to api, this option has no effect if `--api-access-token` not specified. + +# v2.5.3 +- Fixed critical bug, in some cases miner was can't recovery connection and switch to failover pool, version 2.5.2 affected. If you use v2.6.0-beta3 this issue doesn't concern you. +- [#499](https://github.com/xmrig/xmrig/issues/499) IPv6 support disabled for internal HTTP API. +- Added workaround for nicehash.com if you use `cryptonightv7..nicehash.com` option `variant=1` will be set automatically. + +# v2.5.2 +- [#448](https://github.com/xmrig/xmrig/issues/478) Fixed broken reconnect. + +# v2.5.1 +- [#454](https://github.com/xmrig/xmrig/issues/454) Fixed build with libmicrohttpd version below v0.9.35. +- [#456](https://github.com/xmrig/xmrig/issues/459) Verbose errors related to donation pool was not fully silenced. +- [#459](https://github.com/xmrig/xmrig/issues/459) Fixed regression (version 2.5.0 affected) with connection to **xmr.f2pool.com**. + +# v2.5.0 +- [#434](https://github.com/xmrig/xmrig/issues/434) **Added support for Monero v7 PoW, scheduled on April 6.** +- Added full IPv6 support. +- Added protocol extension, when use the miner with xmrig-proxy 2.5+ no more need manually specify `nicehash` option. +- [#123](https://github.com/xmrig/xmrig-proxy/issues/123) Fixed regression (all versions since 2.4 affected) fragmented responses from pool/proxy was parsed incorrectly. +- [#428](https://github.com/xmrig/xmrig/issues/428) Fixed regression (version 2.4.5 affected) with CPU cache size detection. + +# v2.4.5 +- [#324](https://github.com/xmrig/xmrig/pull/324) Fixed build without libmicrohttpd (CMake cache issue). +- [#341](https://github.com/xmrig/xmrig/issues/341) Fixed wrong exit code and added command line option `--dry-run`. +- [#385](https://github.com/xmrig/xmrig/pull/385) Up to 20% performance increase for non-AES CPU and fixed Intel Core 2 cache detection. + +# v2.4.4 + - Added libmicrohttpd version to --version output. + - Fixed bug in singal handler, in some cases miner wasn't shutdown properly. + - Fixed recent MSVC 2017 version detection. + - [#279](https://github.com/xmrig/xmrig/pull/279) Fixed build on some macOS versions. + +# v2.4.3 + - [#94](https://github.com/xmrig/xmrig/issues/94#issuecomment-342019257) [#216](https://github.com/xmrig/xmrig/issues/216) Added **ARMv8** and **ARMv7** support. Hardware AES supported, thanks [Imran Yusuff](https://github.com/imranyusuff). + - [#157](https://github.com/xmrig/xmrig/issues/157) [#196](https://github.com/xmrig/xmrig/issues/196) Fixed Linux compile issues. + - [#184](https://github.com/xmrig/xmrig/issues/184) Fixed cache size detection for CPUs with disabled Hyper-Threading. + - [#200](https://github.com/xmrig/xmrig/issues/200) In some cases miner was doesn't write log to stdout. + +# v2.4.2 + - [#60](https://github.com/xmrig/xmrig/issues/60) Added FreeBSD support, thanks [vcambur](https://github.com/vcambur). + - [#153](https://github.com/xmrig/xmrig/issues/153) Fixed issues with dwarfpool.com. + +# v2.4.1 + - [#147](https://github.com/xmrig/xmrig/issues/147) Fixed comparability with monero-stratum. + +# v2.4.0 + - Added [HTTP API](https://github.com/xmrig/xmrig/wiki/API). + - Added comments support in config file. + - libjansson replaced to rapidjson. + - [#98](https://github.com/xmrig/xmrig/issues/98) Ignore `keepalive` option with minergate.com and nicehash.com. + - [#101](https://github.com/xmrig/xmrig/issues/101) Fixed MSVC 2017 (15.3) compile time version detection. + - [#108](https://github.com/xmrig/xmrig/issues/108) Silently ignore invalid values for `donate-level` option. + - [#111](https://github.com/xmrig/xmrig/issues/111) Fixed build without AEON support. + +# v2.3.1 +- [#68](https://github.com/xmrig/xmrig/issues/68) Fixed compatibility with Docker containers, was nothing print on console. + +# v2.3.0 +- Added `--cpu-priority` option (0 idle, 2 normal to 5 highest). +- Added `--user-agent` option, to set custom user-agent string for pool. For example `cpuminer-multi/0.1`. +- Added `--no-huge-pages` option, to disable huge pages support. +- [#62](https://github.com/xmrig/xmrig/issues/62) Don't send the login to the dev pool. +- Force reconnect if pool block miner IP address. helps switch to backup pool. +- Fixed: failed open default config file if path contains non English characters. +- Fixed: error occurred if try use unavailable stdin or stdout, regression since version 2.2.0. +- Fixed: message about huge pages support successfully enabled on Windows was not shown in release builds. + +# v2.2.1 +- Fixed [terminal issues](https://github.com/xmrig/xmrig-proxy/issues/2#issuecomment-319914085) after exit on Linux and OS X. + +# v2.2.0 +- [#46](https://github.com/xmrig/xmrig/issues/46) Restored config file support. Now possible use multiple config files and combine with command line options also added support for default config. +- Improved colors support on Windows, now used uv_tty, legacy code removed. +- QuickEdit Mode now disabled on Windows. +- Added interactive commands in console window:: **h**ashrate, **p**ause, **r**esume. +- Fixed autoconf mode for AMD FX CPUs. + +# v2.1.0 +- [#40](https://github.com/xmrig/xmrig/issues/40) +Improved miner shutdown, fixed crash on exit for Linux and OS X. +- Fixed, login request was contain malformed JSON if username or password has some special characters for example `\`. +- [#220](https://github.com/fireice-uk/xmr-stak-cpu/pull/220) Better support for Round Robin DNS, IP address now always chosen randomly instead of stuck on first one. +- Changed donation address, new [xmrig-proxy](https://github.com/xmrig/xmrig-proxy) is coming soon. + +# v2.0.2 +- Better deal with possible duplicate jobs from pool, show warning and ignore duplicates. +- For Windows builds libuv updated to version 1.13.1 and gcc to 7.1.0. + +# v2.0.1 + - [#27](https://github.com/xmrig/xmrig/issues/27) Fixed possibility crash on 32bit systems. + +# v2.0.0 + - Option `--backup-url` removed, instead now possibility specify multiple pools for example: `-o example1.com:3333 -u user1 -p password1 -k -o example2.com:5555 -u user2 -o example3.com:4444 -u user3` + - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-l, --log-file=FILE` to write log to file. + - [#15](https://github.com/xmrig/xmrig/issues/15) Added option `-S, --syslog` to use syslog for logging, Linux only. + - [#18](https://github.com/xmrig/xmrig/issues/18) Added nice messages for accepted/rejected shares with diff and network latency. + - [#20](https://github.com/xmrig/xmrig/issues/20) Fixed `--cpu-affinity` for more than 32 threads. + - Fixed Windows XP support. + - Fixed regression, option `--no-color` was not fully disable colored output. + - Show resolved pool IP address in miner output. + +# v1.0.1 +- Fix broken software AES implementation, app has crashed if CPU not support AES-NI, only version 1.0.0 affected. + +# v1.0.0 +- Miner complete rewritten in C++ with libuv. +- This version should be fully compatible (except config file) with previos versions, many new nice features will come in next versions. +- This is still beta. If you found regression, stability or perfomance issues or have an idea for new feature please fell free to open new [issue](https://github.com/xmrig/xmrig/issues/new). +- Added new option `--print-time=N`, print hashrate report every N seconds. +- New hashrate reports, by default every 60 secons. +- Added Microsoft Visual C++ 2015 and 2017 support. +- Removed dependency on libcurl. +- To compile this version from source please switch to [dev](https://github.com/xmrig/xmrig/tree/dev) branch. + +# v0.8.2 +- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). + +# v0.8.2 +- Fixed L2 cache size detection for AMD CPUs (Bulldozer/Piledriver/Steamroller/Excavator architecture). +- Fixed gcc 7.1 support. + +# v0.8.1 +- Added nicehash support, detects automaticaly by pool URL, for example `cryptonight.eu.nicehash.com:3355` or manually via option `--nicehash`. + +# v0.8.0 +- Added double hash mode, also known as lower power mode. `--av=2` and `--av=4`. +- Added smart automatic CPU configuration. Default threads count now depends on size of the L3 cache of CPU. +- Added CryptoNight-Lite support for AEON `-a cryptonight-lite`. +- Added `--max-cpu-usage` option for auto CPU configuration mode. +- Added `--safe` option for adjust threads and algorithm variations to current CPU. +- No more manual steps to enable huge pages on Windows. XMRig will do it automatically. +- Removed BMI2 algorithm variation. +- Removed default pool URL. + +# v0.6.0 +- Added automatic cryptonight self test. +- New software AES algorithm variation. Will be automatically selected if cpu not support AES-NI. +- Added 32 bit builds. +- Documented [algorithm variations](https://github.com/xmrig/xmrig#algorithm-variations). + +# v0.5.0 +- Initial public release. From 68e953345f818bf97e367dc6f7991d570cdae30b Mon Sep 17 00:00:00 2001 From: xmrig Date: Thu, 3 May 2018 22:20:36 +0700 Subject: [PATCH 106/109] Update ALGORITHMS.md --- doc/ALGORITHMS.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/ALGORITHMS.md b/doc/ALGORITHMS.md index 3e1718d3..d9a34a16 100644 --- a/doc/ALGORITHMS.md +++ b/doc/ALGORITHMS.md @@ -27,8 +27,9 @@ For `cryptonight-heavy` currently no variants. You mine **Sumokoin** or **Haven Protocol**? Your algorithm is `cryptonight-heavy` no variant option need. -You mine **Aeon**, **TurtleCoin** or **IPBC**?. +You mine **Aeon**, **TurtleCoin** or **IPBC**? Your base algorithm is `cryptonight-lite`: + Variants: * Aeon: `-1` autodetect. `0` right now, `1` after fork. * TurtleCoin: `1`. @@ -40,4 +41,4 @@ In all other cases base algorithm is `cryptonight`. If your pool support [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/issues/168) miner will choice proper variant automaticaly and if you choice wrong base algorithm you will see error message. Pools with mining algorithm negotiation support. - * [www.hashvault.pro](https://www.hashvault.pro/) \ No newline at end of file + * [www.hashvault.pro](https://www.hashvault.pro/) From dfe20e116b0e136f079b2da74d987467e3c04c02 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 4 May 2018 01:01:05 +0700 Subject: [PATCH 107/109] Fix color issues. --- src/common/log/Log.h | 20 ++++++++++---------- src/workers/Workers.cpp | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/common/log/Log.h b/src/common/log/Log.h index 463c2248..31600dc6 100644 --- a/src/common/log/Log.h +++ b/src/common/log/Log.h @@ -80,16 +80,16 @@ private: }; -#define RED_BOLD(x) "\e[1;31m" x "\e[0m" -#define RED(x) "\e[0;31m" x "\e[0m" -#define GREEN_BOLD(x) "\e[1;32m" x "\e[0m" -#define GREEN(x) "\e[0;32m" x "\e[0m" -#define MAGENTA_BOLD(x) "\e[1;35m" x "\e[0m" -#define MAGENTA(x) "\e[0;35m" x "\e[0m" -#define CYAN_BOLD(x) "\e[1;36m" x "\e[0m" -#define CYAN(x) "\e[0;36m" x "\e[0m" -#define WHITE_BOLD(x) "\e[1;37m" x "\e[0m" -#define WHITE(x) "\e[0;37m" x "\e[0m" +#define RED_BOLD(x) "\x1B[1;31m" x "\x1B[0m" +#define RED(x) "\x1B[0;31m" x "\x1B[0m" +#define GREEN_BOLD(x) "\x1B[1;32m" x "\x1B[0m" +#define GREEN(x) "\x1B[0;32m" x "\x1B[0m" +#define MAGENTA_BOLD(x) "\x1B[1;35m" x "\x1B[0m" +#define MAGENTA(x) "\x1B[0;35m" x "\x1B[0m" +#define CYAN_BOLD(x) "\x1B[1;36m" x "\x1B[0m" +#define CYAN(x) "\x1B[0;36m" x "\x1B[0m" +#define WHITE_BOLD(x) "\x1B[1;37m" x "\x1B[0m" +#define WHITE(x) "\x1B[0;37m" x "\x1B[0m" #define LOG_ERR(x, ...) Log::i()->message(Log::ERR, x, ##__VA_ARGS__) diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 497e3060..8991966e 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -301,9 +301,9 @@ void Workers::start(IWorker *worker) const size_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo) / 1048576; if (m_status.colors) { - LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\e[0m memory " CYAN_BOLD("%zu.0 MB") "", + LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu.0 MB") "", m_status.threads, m_status.ways, - (m_status.hugePages == m_status.pages ? "\e[1;32m" : (m_status.hugePages == 0 ? "\e[1;31m" : "\e[1;33m")), + (m_status.hugePages == m_status.pages ? "\x1B[1;32m" : (m_status.hugePages == 0 ? "\x1B[1;31m" : "\x1B[1;33m")), m_status.hugePages, m_status.pages, percent, memory); } else { From 298cf37121e108ca9198be85ed21f8797e22350f Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 4 May 2018 03:19:42 +0700 Subject: [PATCH 108/109] Force variant 1 if no algorithm specified. --- src/common/net/Pool.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/common/net/Pool.cpp b/src/common/net/Pool.cpp index 8c0de46a..06622d28 100644 --- a/src/common/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -221,6 +221,12 @@ void Pool::adjust(xmrig::Algo algorithm) if (!m_algorithm.isValid()) { m_algorithm.setAlgo(algorithm); + + if (m_algorithm.variant() == xmrig::VARIANT_AUTO) { + if (algorithm == xmrig::CRYPTONIGHT) { + m_algorithm.setVariant(xmrig::VARIANT_1); + } + } } if (strstr(m_host.data(), ".nicehash.com")) { From 1f1bdcde51412d44883cafb996dffdd6af8fd5a4 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 4 May 2018 03:31:17 +0700 Subject: [PATCH 109/109] Fix av option in generated config. --- src/config.json | 62 ++++++++++++++++++++++++--------------------- src/core/Config.cpp | 6 ++--- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/config.json b/src/config.json index 3013ba62..b2dad4c9 100644 --- a/src/config.json +++ b/src/config.json @@ -1,34 +1,38 @@ { - "algo": "cryptonight", // cryptonight (default) or cryptonight-lite - "av": 0, // algorithm variation, 0 auto select - "background": false, // true to run the miner in the background - "colors": true, // false to disable colored output - "cpu-affinity": null, // set process affinity to CPU core(s), mask "0x3" for cores 0 and 1 - "cpu-priority": null, // set process priority (0 idle, 2 normal to 5 highest) - "donate-level": 5, // donate level, mininum 1% - "log-file": null, // log all output to a file, example: "c:/some/path/xmrig.log" - "max-cpu-usage": 75, // maximum CPU usage for automatic mode, usually limiting factor is CPU cache not this option. - "print-time": 60, // print hashrate report every N seconds - "retries": 5, // number of times to retry before switch to backup server - "retry-pause": 5, // time to pause between retries - "safe": false, // true to safe adjust threads and av settings for current CPU - "syslog": false, // use system log for output messages - "threads": null, // number of miner threads - "pools": [ - { - "url": "failover.xmrig.com:443", // URL of mining server - "user": "YOUR_WALLET", // username for mining server - "pass": "x", // password for mining server - "keepalive": true, // send keepalived for prevent timeout (need pool support) - "nicehash": false, // enable nicehash/xmrig-proxy support - "variant": -1 // algorithm PoW variant - } - ], + "algo": "cryptonight", "api": { - "port": 0, // port for the miner API https://github.com/xmrig/xmrig/wiki/API - "access-token": null, // access token for API - "worker-id": null, // custom worker-id for API + "port": 0, + "access-token": null, + "worker-id": null, "ipv6": false, "restricted": true - } + }, + "av": 0, + "background": false, + "colors": true, + "cpu-affinity": null, + "cpu-priority": null, + "donate-level": 5, + "huge-pages": true, + "hw-aes": null, + "log-file": null, + "max-cpu-usage": 75, + "pools": [ + { + "url": "proxy.fee.xmrig.com:9999", + "user": "YOUR_WALLET", + "pass": "x", + "rig-id": null, + "nicehash": false, + "keepalive": false, + "variant": 1 + } + ], + "print-time": 60, + "retries": 5, + "retry-pause": 5, + "safe": false, + "threads": null, + "user-agent": null, + "watch": false } \ No newline at end of file diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 0c4ce779..4c283164 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -162,10 +162,10 @@ bool xmrig::Config::finalize() return true; } - m_algoVariant = getAlgoVariant(); + const AlgoVariant av = getAlgoVariant(); m_threads.mode = m_threads.count ? Simple : Automatic; - const size_t size = CpuThread::multiway(m_algoVariant) * cn_select_memory(m_algorithm.algo()) / 1024; + const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024; if (!m_threads.count) { m_threads.count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); @@ -178,7 +178,7 @@ bool xmrig::Config::finalize() } for (size_t i = 0; i < m_threads.count; ++i) { - m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), m_algoVariant, m_threads.mask, m_priority)); + m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), av, m_threads.mask, m_priority)); } return true;