diff --git a/CMakeLists.txt b/CMakeLists.txt index b3a4b5dc..c75efb41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,7 @@ set(HEADERS_CRYPTO src/crypto/cn/skein_port.h src/crypto/cn/soft_aes.h src/crypto/common/Algorithm.h + src/crypto/common/Coin.h src/crypto/common/keccak.h src/crypto/common/Nonce.h src/crypto/common/portable/mm_malloc.h @@ -105,6 +106,7 @@ set(SOURCES_CRYPTO src/crypto/cn/CnCtx.cpp src/crypto/cn/CnHash.cpp src/crypto/common/Algorithm.cpp + src/crypto/common/Coin.cpp src/crypto/common/keccak.cpp src/crypto/common/Nonce.cpp src/crypto/common/VirtualMemory.cpp diff --git a/src/base/kernel/config/BaseTransform.cpp b/src/base/kernel/config/BaseTransform.cpp index 12e7d848..7090b6b7 100644 --- a/src/base/kernel/config/BaseTransform.cpp +++ b/src/base/kernel/config/BaseTransform.cpp @@ -47,6 +47,7 @@ namespace xmrig static const char *kAlgo = "algo"; static const char *kApi = "api"; +static const char *kCoin = "coin"; static const char *kHttp = "http"; static const char *kPools = "pools"; @@ -107,6 +108,15 @@ void xmrig::BaseTransform::finalize(rapidjson::Document &doc) } } } + + if (m_coin.isValid() && doc.HasMember(kPools)) { + auto &pools = doc[kPools]; + for (Value &pool : pools.GetArray()) { + if (!pool.HasMember(kCoin)) { + pool.AddMember(StringRef(kCoin), m_coin.toJSON(), allocator); + } + } + } } @@ -122,6 +132,15 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch } break; + case IConfig::CoinKey: /* --coin */ + if (!doc.HasMember(kPools)) { + m_coin = arg; + } + else { + return add(doc, kPools, kCoin, arg); + } + break; + case IConfig::UserpassKey: /* --userpass */ { const char *p = strrchr(arg, ':'); diff --git a/src/base/kernel/config/BaseTransform.h b/src/base/kernel/config/BaseTransform.h index 02b28c12..ab83a63f 100644 --- a/src/base/kernel/config/BaseTransform.h +++ b/src/base/kernel/config/BaseTransform.h @@ -27,6 +27,7 @@ #include "base/kernel/interfaces/IConfigTransform.h" +#include "crypto/common/Coin.h" #include "rapidjson/document.h" @@ -99,6 +100,7 @@ protected: protected: Algorithm m_algorithm; + Coin m_coin; private: diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index 86b8067c..52aed25f 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -43,6 +43,7 @@ public: enum Keys { // common AlgorithmKey = 'a', + CoinKey = 1025, ApiWorkerIdKey = 4002, ApiIdKey = 4005, HttpPort = 4100, diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index b87466ab..b9189247 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -334,6 +334,9 @@ bool xmrig::Client::parseJob(const rapidjson::Value ¶ms, int *code) if (algo) { job.setAlgorithm(algo); } + else if (m_pool.coin().isValid()) { + job.setAlgorithm(m_pool.coin().algorithm(job.blob()[0])); + } job.setHeight(Json::getUint64(params, "height")); @@ -426,7 +429,12 @@ bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm, const char *algo { if (!algorithm.isValid()) { if (!isQuiet()) { - LOG_ERR("[%s] Unknown/unsupported algorithm \"%s\" detected, reconnect", url(), algo); + if (algo == nullptr) { + LOG_ERR("[%s] unknown algorithm, make sure you set \"algo\" or \"coin\" option", url(), algo); + } + else { + LOG_ERR("[%s] unsupported algorithm \"%s\" detected, reconnect", url(), algo); + } } return false; @@ -436,7 +444,7 @@ bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm, const char *algo m_listener->onVerifyAlgorithm(this, algorithm, &ok); if (!ok && !isQuiet()) { - LOG_ERR("[%s] Incompatible/disabled algorithm \"%s\" detected, reconnect", url(), algorithm.shortName()); + LOG_ERR("[%s] incompatible/disabled algorithm \"%s\" detected, reconnect", url(), algorithm.shortName()); } return ok; diff --git a/src/base/net/stratum/Job.h b/src/base/net/stratum/Job.h index 2b256a12..a1a3b611 100644 --- a/src/base/net/stratum/Job.h +++ b/src/base/net/stratum/Job.h @@ -73,6 +73,7 @@ public: inline uint8_t fixedByte() const { return *(m_blob + 42); } inline uint8_t index() const { return m_index; } inline void reset() { m_size = 0; m_diff = 0; } + inline void setAlgorithm(const Algorithm::Id id) { m_algorithm = id; } inline void setAlgorithm(const char *algo) { m_algorithm = algo; } inline void setClientId(const String &id) { m_clientId = id; } inline void setHeight(uint64_t height) { m_height = height; } diff --git a/src/base/net/stratum/Pool.cpp b/src/base/net/stratum/Pool.cpp index ba31c35d..1b9adfc4 100644 --- a/src/base/net/stratum/Pool.cpp +++ b/src/base/net/stratum/Pool.cpp @@ -48,6 +48,7 @@ namespace xmrig { static const char *kAlgo = "algo"; +static const char *kCoin = "coin"; static const char *kDaemon = "daemon"; static const char *kDaemonPollInterval = "daemon-poll-interval"; static const char *kEnabled = "enabled"; @@ -120,6 +121,7 @@ xmrig::Pool::Pool(const rapidjson::Value &object) : m_fingerprint = Json::getString(object, kFingerprint); m_pollInterval = Json::getUint64(object, kDaemonPollInterval, kDefaultPollInterval); m_algorithm = Json::getString(object, kAlgo); + m_coin = Json::getString(object, kCoin); m_flags.set(FLAG_ENABLED, Json::getBool(object, kEnabled, true)); m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash)); @@ -186,6 +188,7 @@ bool xmrig::Pool::isEqual(const Pool &other) const && m_keepAlive == other.m_keepAlive && m_port == other.m_port && m_algorithm == other.m_algorithm + && m_coin == other.m_coin && m_fingerprint == other.m_fingerprint && m_host == other.m_host && m_password == other.m_password @@ -268,6 +271,7 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const Value obj(kObjectType); obj.AddMember(StringRef(kAlgo), m_algorithm.toJSON(), allocator); + obj.AddMember(StringRef(kCoin), m_coin.toJSON(), allocator); obj.AddMember(StringRef(kUrl), m_url.toJSON(), allocator); obj.AddMember(StringRef(kUser), m_user.toJSON(), allocator); diff --git a/src/base/net/stratum/Pool.h b/src/base/net/stratum/Pool.h index 36c3ed1b..15d31ccc 100644 --- a/src/base/net/stratum/Pool.h +++ b/src/base/net/stratum/Pool.h @@ -32,7 +32,7 @@ #include "base/tools/String.h" -#include "crypto/common/Algorithm.h" +#include "crypto/common/Coin.h" #include "rapidjson/fwd.h" @@ -74,6 +74,7 @@ public: inline bool isTLS() const { return m_flags.test(FLAG_TLS); } inline bool isValid() const { return !m_host.isNull() && m_port > 0; } inline const Algorithm &algorithm() const { return m_algorithm; } + inline const Coin &coin() const { return m_coin; } inline const String &fingerprint() const { return m_fingerprint; } inline const String &host() const { return m_host; } inline const String &password() const { return !m_password.isNull() ? m_password : kDefaultPassword; } @@ -107,6 +108,7 @@ private: bool parseIPv6(const char *addr); Algorithm m_algorithm; + Coin m_coin; int m_keepAlive; std::bitset m_flags; String m_fingerprint; diff --git a/src/base/net/stratum/Pools.cpp b/src/base/net/stratum/Pools.cpp index 4641ecd4..600c97ed 100644 --- a/src/base/net/stratum/Pools.cpp +++ b/src/base/net/stratum/Pools.cpp @@ -135,11 +135,12 @@ void xmrig::Pools::print() const { size_t i = 1; for (const Pool &pool : m_data) { - Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CSI "1;%dm%s" CLEAR " algo " WHITE_BOLD("%s"), + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CSI "1;%dm%s" CLEAR " %s " WHITE_BOLD("%s"), i, (pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31), pool.url().data(), - pool.algorithm().isValid() ? pool.algorithm().shortName() : "auto" + pool.coin().isValid() ? "coin" : "algo", + pool.coin().isValid() ? pool.coin().name() : (pool.algorithm().isValid() ? pool.algorithm().shortName() : "auto") ); i++; diff --git a/src/config.json b/src/config.json index c9f53f26..3041407d 100644 --- a/src/config.json +++ b/src/config.json @@ -34,6 +34,7 @@ "pools": [ { "algo": null, + "coin": null, "url": "donate.v2.xmrig.com:3333", "user": "YOUR_WALLET_ADDRESS", "pass": "x", diff --git a/src/core/config/Config_default.h b/src/core/config/Config_default.h index c8b2e6e6..b811540a 100644 --- a/src/core/config/Config_default.h +++ b/src/core/config/Config_default.h @@ -68,6 +68,7 @@ R"===( "pools": [ { "algo": null, + "coin": null, "url": "donate.v2.xmrig.com:3333", "user": "YOUR_WALLET_ADDRESS", "pass": "x", diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h index b7415f4d..649e6725 100644 --- a/src/core/config/Config_platform.h +++ b/src/core/config/Config_platform.h @@ -45,6 +45,7 @@ static const char short_options[] = "a:c:kBp:Px:r:R:s:t:T:o:u:O:v:l:S"; static const option options[] = { { "algo", 1, nullptr, IConfig::AlgorithmKey }, + { "coin", 1, nullptr, IConfig::CoinKey }, { "api-worker-id", 1, nullptr, IConfig::ApiWorkerIdKey }, { "api-id", 1, nullptr, IConfig::ApiIdKey }, { "http-enabled", 0, nullptr, IConfig::HttpEnabledKey }, diff --git a/src/core/config/usage.h b/src/core/config/usage.h index b41ec6db..3f172427 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.h @@ -60,6 +60,7 @@ Options:\n\ rx/wow, rx/loki\n" #endif "\ + --coin=COIN specify coin instead of algorithm\ -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/common/Coin.cpp b/src/crypto/common/Coin.cpp new file mode 100644 index 00000000..f5a32851 --- /dev/null +++ b/src/crypto/common/Coin.cpp @@ -0,0 +1,103 @@ +/* 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 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "crypto/common/Coin.h" +#include "rapidjson/document.h" + + +#include + + +#ifdef _MSC_VER +# define strcasecmp _stricmp +#endif + + +namespace xmrig { + + +struct CoinName +{ + const char *name; + const Coin::Id id; +}; + + +static CoinName const coin_names[] = { + { "monero", Coin::MONERO }, + { "xmr", Coin::MONERO }, +}; + + +} /* namespace xmrig */ + + + +xmrig::Algorithm::Id xmrig::Coin::algorithm(uint8_t blobVersion) const +{ + if (id() == MONERO) { + return (blobVersion >= 12) ? Algorithm::RX_0 : Algorithm::CN_R; + } + + return Algorithm::INVALID; +} + + + +const char *xmrig::Coin::name() const +{ + for (const auto &i : coin_names) { + if (i.id == m_id) { + return i.name; + } + } + + return nullptr; +} + + +rapidjson::Value xmrig::Coin::toJSON() const +{ + using namespace rapidjson; + + return isValid() ? Value(StringRef(name())) : Value(kNullType); +} + + +xmrig::Coin::Id xmrig::Coin::parse(const char *name) +{ + if (name == nullptr || strlen(name) < 3) { + return INVALID; + } + + for (const auto &i : coin_names) { + if (strcasecmp(name, i.name) == 0) { + return i.id; + } + } + + return INVALID; +} diff --git a/src/crypto/common/Coin.h b/src/crypto/common/Coin.h new file mode 100644 index 00000000..779d60b8 --- /dev/null +++ b/src/crypto/common/Coin.h @@ -0,0 +1,75 @@ +/* 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 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_COIN_H +#define XMRIG_COIN_H + + +#include "crypto/common/Algorithm.h" +#include "rapidjson/fwd.h" + + +namespace xmrig { + + +class Coin +{ +public: + enum Id : int { + INVALID = -1, + MONERO, + }; + + + Coin() = default; + inline Coin(const char *name) : m_id(parse(name)) {} + inline Coin(Id id) : m_id(id) {} + + + inline bool isEqual(const Coin &other) const { return m_id == other.m_id; } + inline bool isValid() const { return m_id != INVALID; } + inline Id id() const { return m_id; } + + Algorithm::Id algorithm(uint8_t blobVersion) const; + const char *name() const; + rapidjson::Value toJSON() const; + + inline bool operator!=(Coin::Id id) const { return m_id != id; } + inline bool operator!=(const Coin &other) const { return !isEqual(other); } + inline bool operator==(Coin::Id id) const { return m_id == id; } + inline bool operator==(const Coin &other) const { return isEqual(other); } + inline operator Coin::Id() const { return m_id; } + + static Id parse(const char *name); + +private: + Id m_id = INVALID; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_COIN_H */