Merge branch 'evo' into beta

This commit is contained in:
XMRig 2019-09-28 23:09:20 +07:00
commit 5d73402651
39 changed files with 412 additions and 105 deletions

View file

@ -1,3 +1,8 @@
# v4.2.0-beta
- [#1202](https://github.com/xmrig/xmrig/issues/1202) Fixed algorithm verification in donate strategy.
- Added per pool option `coin` with single possible value `monero` for pools without algorithm negotiation, for upcoming Monero fork.
- Added config option `cpu/max-threads-hint` and command line option `--cpu-max-threads-hint`.
# v4.1.0-beta # v4.1.0-beta
- **OpenCL backend disabled by default.**. - **OpenCL backend disabled by default.**.
- [#1183](https://github.com/xmrig/xmrig/issues/1183) Fixed compatibility with systemd. - [#1183](https://github.com/xmrig/xmrig/issues/1183) Fixed compatibility with systemd.

View file

@ -71,6 +71,7 @@ set(HEADERS_CRYPTO
src/crypto/cn/skein_port.h src/crypto/cn/skein_port.h
src/crypto/cn/soft_aes.h src/crypto/cn/soft_aes.h
src/crypto/common/Algorithm.h src/crypto/common/Algorithm.h
src/crypto/common/Coin.h
src/crypto/common/keccak.h src/crypto/common/keccak.h
src/crypto/common/Nonce.h src/crypto/common/Nonce.h
src/crypto/common/portable/mm_malloc.h src/crypto/common/portable/mm_malloc.h
@ -108,6 +109,7 @@ set(SOURCES_CRYPTO
src/crypto/cn/CnCtx.cpp src/crypto/cn/CnCtx.cpp
src/crypto/cn/CnHash.cpp src/crypto/cn/CnHash.cpp
src/crypto/common/Algorithm.cpp src/crypto/common/Algorithm.cpp
src/crypto/common/Coin.cpp
src/crypto/common/keccak.cpp src/crypto/common/keccak.cpp
src/crypto/common/Nonce.cpp src/crypto/common/Nonce.cpp
src/crypto/common/VirtualMemory.cpp src/crypto/common/VirtualMemory.cpp

View file

@ -94,3 +94,6 @@ Enable/configure or disable ASM optimizations. Possible values: `true`, `false`,
#### `argon2-impl` (since v3.1.0) #### `argon2-impl` (since v3.1.0)
Allow override automatically detected Argon2 implementation, this option added mostly for debug purposes, default value `null` means autodetect. Other possible values: `"x86_64"`, `"SSE2"`, `"SSSE3"`, `"XOP"`, `"AVX2"`, `"AVX-512F"`. Manual selection has no safe guards, if you CPU not support required instuctions, miner will crash. Allow override automatically detected Argon2 implementation, this option added mostly for debug purposes, default value `null` means autodetect. Other possible values: `"x86_64"`, `"SSE2"`, `"SSSE3"`, `"XOP"`, `"AVX2"`, `"AVX-512F"`. Manual selection has no safe guards, if you CPU not support required instuctions, miner will crash.
#### `max-threads-hint` (since v4.2.0)
Maximum CPU threads count (in percentage) hint for autoconfig. [CPU_MAX_USAGE.md](CPU_MAX_USAGE.md)

26
doc/CPU_MAX_USAGE.md Normal file
View file

@ -0,0 +1,26 @@
# Maximum CPU usage
Please read this document carefully, `max-threads-hint` (was known as `max-cpu-usage`) option is most confusing option in the miner with many myth and legends.
This option is just hint for automatic configuration and can't precise define CPU usage.
### Option definition
#### Config file:
```json
{
...
"cpu": {
"max-threads-hint": 100,
...
},
...
}
```
#### Command line
`--cpu-max-threads-hint 100`
### Known issues and usage
* This option has no effect if miner already generated CPU configuration, to prevent config generation use `"autosave":false,`.
* Only threads count can be changed, for 1 core CPU this option has no effect, for 2 core CPU only 2 values possible 50% and 100%, for 4 cores: 25%, 50%, 75%, 100%. etc.
* You CPU may limited by other factors, eg cache.

View file

@ -44,6 +44,7 @@ class Threads
public: public:
inline bool has(const char *profile) const { return m_profiles.count(profile) > 0; } inline bool has(const char *profile) const { return m_profiles.count(profile) > 0; }
inline bool isDisabled(const Algorithm &algo) const { return m_disabled.count(algo) > 0; } inline bool isDisabled(const Algorithm &algo) const { return m_disabled.count(algo) > 0; }
inline bool isEmpty() const { return m_profiles.empty(); }
inline bool isExist(const Algorithm &algo) const { return isDisabled(algo) || m_aliases.count(algo) > 0 || has(algo.shortName()); } inline bool isExist(const Algorithm &algo) const { return isDisabled(algo) || m_aliases.count(algo) > 0 || has(algo.shortName()); }
inline const T &get(const Algorithm &algo, bool strict = false) const { return get(profileName(algo, strict)); } inline const T &get(const Algorithm &algo, bool strict = false) const { return get(profileName(algo, strict)); }
inline void disable(const Algorithm &algo) { m_disabled.insert(algo); } inline void disable(const Algorithm &algo) { m_disabled.insert(algo); }

View file

@ -35,6 +35,7 @@ static const char *kCn = "cn";
static const char *kEnabled = "enabled"; static const char *kEnabled = "enabled";
static const char *kHugePages = "huge-pages"; static const char *kHugePages = "huge-pages";
static const char *kHwAes = "hw-aes"; static const char *kHwAes = "hw-aes";
static const char *kMaxThreadsHint = "max-threads-hint";
static const char *kPriority = "priority"; static const char *kPriority = "priority";
#ifdef XMRIG_FEATURE_ASM #ifdef XMRIG_FEATURE_ASM
@ -72,11 +73,6 @@ extern template class Threads<CpuThreads>;
} }
xmrig::CpuConfig::CpuConfig()
{
}
bool xmrig::CpuConfig::isHwAES() const bool xmrig::CpuConfig::isHwAES() const
{ {
return (m_aes == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aes) == AES_HW; return (m_aes == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aes) == AES_HW;
@ -95,6 +91,10 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator); obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator);
obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator); obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
if (m_threads.isEmpty()) {
obj.AddMember(StringRef(kMaxThreadsHint), m_limit, allocator);
}
# ifdef XMRIG_FEATURE_ASM # ifdef XMRIG_FEATURE_ASM
obj.AddMember(StringRef(kAsm), m_assembly.toJSON(), allocator); obj.AddMember(StringRef(kAsm), m_assembly.toJSON(), allocator);
# endif # endif
@ -133,6 +133,7 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value, uint32_t version)
if (value.IsObject()) { if (value.IsObject()) {
m_enabled = Json::getBool(value, kEnabled, m_enabled); m_enabled = Json::getBool(value, kEnabled, m_enabled);
m_hugePages = Json::getBool(value, kHugePages, m_hugePages); m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
m_limit = Json::getUint(value, kMaxThreadsHint, m_limit);
setAesMode(Json::getValue(value, kHwAes)); setAesMode(Json::getValue(value, kHwAes));
setPriority(Json::getInt(value, kPriority, -1)); setPriority(Json::getInt(value, kPriority, -1));
@ -168,28 +169,28 @@ void xmrig::CpuConfig::generate()
ICpuInfo *cpu = Cpu::info(); ICpuInfo *cpu = Cpu::info();
m_threads.disable(Algorithm::CN_0); m_threads.disable(Algorithm::CN_0);
m_threads.move(kCn, cpu->threads(Algorithm::CN_0)); m_threads.move(kCn, cpu->threads(Algorithm::CN_0, m_limit));
# ifdef XMRIG_ALGO_CN_GPU # ifdef XMRIG_ALGO_CN_GPU
m_threads.move(kCnGPU, cpu->threads(Algorithm::CN_GPU)); m_threads.move(kCnGPU, cpu->threads(Algorithm::CN_GPU, m_limit));
# endif # endif
# ifdef XMRIG_ALGO_CN_LITE # ifdef XMRIG_ALGO_CN_LITE
m_threads.disable(Algorithm::CN_LITE_0); m_threads.disable(Algorithm::CN_LITE_0);
m_threads.move(kCnLite, cpu->threads(Algorithm::CN_LITE_1)); m_threads.move(kCnLite, cpu->threads(Algorithm::CN_LITE_1, m_limit));
# endif # endif
# ifdef XMRIG_ALGO_CN_HEAVY # ifdef XMRIG_ALGO_CN_HEAVY
m_threads.move(kCnHeavy, cpu->threads(Algorithm::CN_HEAVY_0)); m_threads.move(kCnHeavy, cpu->threads(Algorithm::CN_HEAVY_0, m_limit));
# endif # endif
# ifdef XMRIG_ALGO_CN_PICO # ifdef XMRIG_ALGO_CN_PICO
m_threads.move(kCnPico, cpu->threads(Algorithm::CN_PICO_0)); m_threads.move(kCnPico, cpu->threads(Algorithm::CN_PICO_0, m_limit));
# endif # endif
# ifdef XMRIG_ALGO_RANDOMX # ifdef XMRIG_ALGO_RANDOMX
m_threads.move(kRx, cpu->threads(Algorithm::RX_0)); m_threads.move(kRx, cpu->threads(Algorithm::RX_0, m_limit));
m_threads.move(kRxWOW, cpu->threads(Algorithm::RX_WOW)); m_threads.move(kRxWOW, cpu->threads(Algorithm::RX_WOW, m_limit));
# endif # endif
generateArgon2(); generateArgon2();
@ -199,7 +200,7 @@ void xmrig::CpuConfig::generate()
void xmrig::CpuConfig::generateArgon2() void xmrig::CpuConfig::generateArgon2()
{ {
# ifdef XMRIG_ALGO_ARGON2 # ifdef XMRIG_ALGO_ARGON2
m_threads.move(kArgon2, Cpu::info()->threads(Algorithm::AR2_CHUKWA)); m_threads.move(kArgon2, Cpu::info()->threads(Algorithm::AR2_CHUKWA, m_limit));
# endif # endif
} }

View file

@ -44,7 +44,7 @@ public:
AES_SOFT AES_SOFT
}; };
CpuConfig(); CpuConfig() = default;
bool isHwAES() const; bool isHwAES() const;
rapidjson::Value toJSON(rapidjson::Document &doc) const; rapidjson::Value toJSON(rapidjson::Document &doc) const;
@ -74,6 +74,7 @@ private:
int m_priority = -1; int m_priority = -1;
String m_argon2Impl; String m_argon2Impl;
Threads<CpuThreads> m_threads; Threads<CpuThreads> m_threads;
uint32_t m_limit = 100;
}; };

View file

@ -50,7 +50,7 @@ public:
virtual bool hasAVX2() const = 0; virtual bool hasAVX2() const = 0;
virtual const char *backend() const = 0; virtual const char *backend() const = 0;
virtual const char *brand() const = 0; virtual const char *brand() const = 0;
virtual CpuThreads threads(const Algorithm &algorithm) const = 0; virtual CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const = 0;
virtual size_t cores() const = 0; virtual size_t cores() const = 0;
virtual size_t L2() const = 0; virtual size_t L2() const = 0;
virtual size_t L3() const = 0; virtual size_t L3() const = 0;

View file

@ -23,10 +23,10 @@
*/ */
#include <algorithm> #include <algorithm>
#include <assert.h> #include <cassert>
#include <math.h> #include <cmath>
#include <stdio.h> #include <cstdio>
#include <string.h> #include <cstring>
#include "3rdparty/libcpuid/libcpuid.h" #include "3rdparty/libcpuid/libcpuid.h"
@ -109,7 +109,7 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
} }
xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm) const xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm, uint32_t limit) const
{ {
if (threads() == 1) { if (threads() == 1) {
return 1; return 1;
@ -153,5 +153,12 @@ xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm) co
} }
# endif # endif
return CpuThreads(std::max<size_t>(std::min<size_t>(count, threads()), 1), intensity); if (limit > 0 && limit < 100) {
count = std::min(count, static_cast<size_t>(round(threads() * (limit / 100.0))));
}
else {
count = std::min(count, threads());
}
return CpuThreads(std::max<size_t>(count, 1), intensity);
} }

View file

@ -38,7 +38,7 @@ public:
AdvancedCpuInfo(); AdvancedCpuInfo();
protected: protected:
CpuThreads threads(const Algorithm &algorithm) const override; CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
inline Assembly::Id assembly() const override { return m_assembly; } inline Assembly::Id assembly() const override { return m_assembly; }
inline bool hasAES() const override { return m_aes; } inline bool hasAES() const override { return m_aes; }

View file

@ -179,7 +179,7 @@ const char *xmrig::BasicCpuInfo::backend() const
} }
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm) const xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm, uint32_t limit) const
{ {
const size_t count = std::thread::hardware_concurrency(); const size_t count = std::thread::hardware_concurrency();

View file

@ -39,7 +39,7 @@ public:
protected: protected:
const char *backend() const override; const char *backend() const override;
CpuThreads threads(const Algorithm &algorithm) const override; CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
inline Assembly::Id assembly() const override { return m_assembly; } inline Assembly::Id assembly() const override { return m_assembly; }
inline bool hasAES() const override { return m_aes; } inline bool hasAES() const override { return m_aes; }

View file

@ -29,6 +29,7 @@
#include <algorithm> #include <algorithm>
#include <cmath>
#include <hwloc.h> #include <hwloc.h>
@ -127,9 +128,7 @@ static inline bool isCacheExclusive(hwloc_obj_t obj)
} // namespace xmrig } // namespace xmrig
xmrig::HwlocCpuInfo::HwlocCpuInfo() : BasicCpuInfo(), xmrig::HwlocCpuInfo::HwlocCpuInfo()
m_backend(),
m_cache()
{ {
m_threads = 0; m_threads = 0;
@ -149,7 +148,7 @@ xmrig::HwlocCpuInfo::HwlocCpuInfo() : BasicCpuInfo(),
# endif # endif
const std::vector<hwloc_obj_t> packages = findByType(hwloc_get_root_obj(m_topology), HWLOC_OBJ_PACKAGE); const std::vector<hwloc_obj_t> packages = findByType(hwloc_get_root_obj(m_topology), HWLOC_OBJ_PACKAGE);
if (packages.size()) { if (!packages.empty()) {
const char *value = hwloc_obj_get_info_by_name(packages[0], "CPUModel"); const char *value = hwloc_obj_get_info_by_name(packages[0], "CPUModel");
if (value) { if (value) {
strncpy(m_brand, value, 64); strncpy(m_brand, value, 64);
@ -202,10 +201,10 @@ xmrig::HwlocCpuInfo::~HwlocCpuInfo()
} }
xmrig::CpuThreads xmrig::HwlocCpuInfo::threads(const Algorithm &algorithm) const xmrig::CpuThreads xmrig::HwlocCpuInfo::threads(const Algorithm &algorithm, uint32_t limit) const
{ {
if (L2() == 0 && L3() == 0) { if (L2() == 0 && L3() == 0) {
return BasicCpuInfo::threads(algorithm); return BasicCpuInfo::threads(algorithm, limit);
} }
const unsigned depth = L3() > 0 ? 3 : 2; const unsigned depth = L3() > 0 ? 3 : 2;
@ -218,21 +217,37 @@ xmrig::CpuThreads xmrig::HwlocCpuInfo::threads(const Algorithm &algorithm) const
findCache(hwloc_get_root_obj(m_topology), depth, depth, [&caches](hwloc_obj_t found) { caches.emplace_back(found); }); findCache(hwloc_get_root_obj(m_topology), depth, depth, [&caches](hwloc_obj_t found) { caches.emplace_back(found); });
if (limit > 0 && limit < 100 && !caches.empty()) {
const double maxTotalThreads = round(m_threads * (limit / 100.0));
const auto maxPerCache = std::max(static_cast<int>(round(maxTotalThreads / caches.size())), 1);
int remaining = std::max(static_cast<int>(maxTotalThreads), 1);
for (hwloc_obj_t cache : caches) { for (hwloc_obj_t cache : caches) {
processTopLevelCache(cache, algorithm, threads); processTopLevelCache(cache, algorithm, threads, std::min(maxPerCache, remaining));
remaining -= maxPerCache;
if (remaining <= 0) {
break;
}
}
}
else {
for (hwloc_obj_t cache : caches) {
processTopLevelCache(cache, algorithm, threads, 0);
}
} }
if (threads.isEmpty()) { if (threads.isEmpty()) {
LOG_WARN("hwloc auto configuration for algorithm \"%s\" failed.", algorithm.shortName()); LOG_WARN("hwloc auto configuration for algorithm \"%s\" failed.", algorithm.shortName());
return BasicCpuInfo::threads(algorithm); return BasicCpuInfo::threads(algorithm, limit);
} }
return threads; return threads;
} }
void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorithm &algorithm, CpuThreads &threads) const void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorithm &algorithm, CpuThreads &threads, size_t limit) const
{ {
constexpr size_t oneMiB = 1024u * 1024u; constexpr size_t oneMiB = 1024u * 1024u;
@ -296,6 +311,10 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
} }
# endif # endif
if (limit > 0) {
cacheHashes = std::min(cacheHashes, limit);
}
if (cacheHashes >= PUs) { if (cacheHashes >= PUs) {
for (hwloc_obj_t core : cores) { for (hwloc_obj_t core : cores) {
const std::vector<hwloc_obj_t> units = findByType(core, HWLOC_OBJ_PU); const std::vector<hwloc_obj_t> units = findByType(core, HWLOC_OBJ_PU);

View file

@ -27,10 +27,11 @@
#include "backend/cpu/platform/BasicCpuInfo.h" #include "backend/cpu/platform/BasicCpuInfo.h"
#include "base/tools/Object.h"
typedef struct hwloc_obj *hwloc_obj_t; using hwloc_obj_t = struct hwloc_obj *;
typedef struct hwloc_topology *hwloc_topology_t; using hwloc_topology_t = struct hwloc_topology *;
namespace xmrig { namespace xmrig {
@ -39,6 +40,9 @@ namespace xmrig {
class HwlocCpuInfo : public BasicCpuInfo class HwlocCpuInfo : public BasicCpuInfo
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE(HwlocCpuInfo)
enum Feature : uint32_t { enum Feature : uint32_t {
SET_THISTHREAD_MEMBIND = 1 SET_THISTHREAD_MEMBIND = 1
}; };
@ -51,7 +55,7 @@ public:
static inline const std::vector<uint32_t> &nodeIndexes() { return m_nodeIndexes; } static inline const std::vector<uint32_t> &nodeIndexes() { return m_nodeIndexes; }
protected: protected:
CpuThreads threads(const Algorithm &algorithm) const override; CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
inline const char *backend() const override { return m_backend; } inline const char *backend() const override { return m_backend; }
inline size_t cores() const override { return m_cores; } inline size_t cores() const override { return m_cores; }
@ -61,14 +65,14 @@ protected:
inline size_t packages() const override { return m_packages; } inline size_t packages() const override { return m_packages; }
private: private:
void processTopLevelCache(hwloc_obj_t obj, const Algorithm &algorithm, CpuThreads &threads) const; void processTopLevelCache(hwloc_obj_t obj, const Algorithm &algorithm, CpuThreads &threads, size_t limit) const;
static std::vector<uint32_t> m_nodeIndexes; static std::vector<uint32_t> m_nodeIndexes;
static uint32_t m_features; static uint32_t m_features;
char m_backend[20]; char m_backend[20] = { 0 };
hwloc_topology_t m_topology; hwloc_topology_t m_topology = nullptr;
size_t m_cache[5]; size_t m_cache[5] = { 0 };
size_t m_cores = 0; size_t m_cores = 0;
size_t m_nodes = 0; size_t m_nodes = 0;
size_t m_packages = 0; size_t m_packages = 0;

View file

@ -59,7 +59,7 @@ extern bool ocl_vega_cn_generator(const OclDevice &device, const Algorithm &algo
extern bool ocl_generic_cn_generator(const OclDevice &device, const Algorithm &algorithm, OclThreads &threads); extern bool ocl_generic_cn_generator(const OclDevice &device, const Algorithm &algorithm, OclThreads &threads);
ocl_gen_config_fun generators[] = { static ocl_gen_config_fun generators[] = {
# ifdef XMRIG_ALGO_RANDOMX # ifdef XMRIG_ALGO_RANDOMX
ocl_generic_rx_generator, ocl_generic_rx_generator,
# endif # endif
@ -215,6 +215,6 @@ void xmrig::OclDevice::toJSON(rapidjson::Value &out, rapidjson::Document &doc) c
out.AddMember("name", name().toJSON(doc), allocator); out.AddMember("name", name().toJSON(doc), allocator);
out.AddMember("bus_id", topology().toString().toJSON(doc), allocator); out.AddMember("bus_id", topology().toString().toJSON(doc), allocator);
out.AddMember("cu", computeUnits(), allocator); out.AddMember("cu", computeUnits(), allocator);
out.AddMember("global_mem", globalMemSize(), allocator); out.AddMember("global_mem", static_cast<uint64_t>(globalMemSize()), allocator);
} }
#endif #endif

View file

@ -73,7 +73,7 @@ rapidjson::Value xmrig::OclPlatform::toJSON(rapidjson::Document &doc) const
} }
Value out(kObjectType); Value out(kObjectType);
out.AddMember("index", index(), allocator); out.AddMember("index", static_cast<uint64_t>(index()), allocator);
out.AddMember("profile", profile().toJSON(doc), allocator); out.AddMember("profile", profile().toJSON(doc), allocator);
out.AddMember("version", version().toJSON(doc), allocator); out.AddMember("version", version().toJSON(doc), allocator);
out.AddMember("name", name().toJSON(doc), allocator); out.AddMember("name", name().toJSON(doc), allocator);

View file

@ -47,6 +47,7 @@ namespace xmrig
static const char *kAlgo = "algo"; static const char *kAlgo = "algo";
static const char *kApi = "api"; static const char *kApi = "api";
static const char *kCoin = "coin";
static const char *kHttp = "http"; static const char *kHttp = "http";
static const char *kPools = "pools"; static const char *kPools = "pools";
@ -103,6 +104,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);
}
}
}
if (m_http) { if (m_http) {
set(doc, kHttp, "enabled", true); set(doc, kHttp, "enabled", true);
} }
@ -121,6 +131,15 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
} }
break; break;
case IConfig::CoinKey: /* --coin */
if (!doc.HasMember(kPools)) {
m_coin = arg;
}
else {
return add(doc, kPools, kCoin, arg);
}
break;
case IConfig::UserpassKey: /* --userpass */ case IConfig::UserpassKey: /* --userpass */
{ {
const char *p = strrchr(arg, ':'); const char *p = strrchr(arg, ':');

View file

@ -27,6 +27,7 @@
#include "base/kernel/interfaces/IConfigTransform.h" #include "base/kernel/interfaces/IConfigTransform.h"
#include "crypto/common/Coin.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
@ -97,6 +98,7 @@ protected:
protected: protected:
Algorithm m_algorithm; Algorithm m_algorithm;
Coin m_coin;
private: private:

View file

@ -43,6 +43,7 @@ public:
enum Keys { enum Keys {
// common // common
AlgorithmKey = 'a', AlgorithmKey = 'a',
CoinKey = 1025,
ApiWorkerIdKey = 4002, ApiWorkerIdKey = 4002,
ApiIdKey = 4005, ApiIdKey = 4005,
HttpPort = 4100, HttpPort = 4100,
@ -87,6 +88,7 @@ public:
AssemblyKey = 1015, AssemblyKey = 1015,
RandomXInitKey = 1022, RandomXInitKey = 1022,
RandomXNumaKey = 1023, RandomXNumaKey = 1023,
CPUMaxThreadsKey = 1026,
// xmrig amd // xmrig amd
OclPlatformKey = 1400, OclPlatformKey = 1400,

View file

@ -334,6 +334,9 @@ bool xmrig::Client::parseJob(const rapidjson::Value &params, int *code)
if (algo) { if (algo) {
job.setAlgorithm(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")); job.setHeight(Json::getUint64(params, "height"));
@ -426,7 +429,12 @@ bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm, const char *algo
{ {
if (!algorithm.isValid()) { if (!algorithm.isValid()) {
if (!isQuiet()) { 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; return false;
@ -436,7 +444,7 @@ bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm, const char *algo
m_listener->onVerifyAlgorithm(this, algorithm, &ok); m_listener->onVerifyAlgorithm(this, algorithm, &ok);
if (!ok && !isQuiet()) { 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; return ok;

View file

@ -25,7 +25,7 @@
#include <algorithm> #include <algorithm>
#include <assert.h> #include <cassert>
#include "3rdparty/http-parser/http_parser.h" #include "3rdparty/http-parser/http_parser.h"
@ -225,6 +225,10 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value &params, int *code)
job.setDiff(Json::getUint64(params, "difficulty")); job.setDiff(Json::getUint64(params, "difficulty"));
job.setId(blocktemplate.data() + blocktemplate.size() - 32); job.setId(blocktemplate.data() + blocktemplate.size() - 32);
if (m_pool.coin().isValid()) {
job.setAlgorithm(m_pool.coin().algorithm(job.blob()[0]));
}
m_job = std::move(job); m_job = std::move(job);
m_blocktemplate = std::move(blocktemplate); m_blocktemplate = std::move(blocktemplate);
m_prevHash = Json::getString(params, "prev_hash"); m_prevHash = Json::getString(params, "prev_hash");

View file

@ -75,6 +75,7 @@ public:
inline uint8_t fixedByte() const { return *(m_blob + 42); } inline uint8_t fixedByte() const { return *(m_blob + 42); }
inline uint8_t index() const { return m_index; } inline uint8_t index() const { return m_index; }
inline void reset() { m_size = 0; m_diff = 0; } 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 setAlgorithm(const char *algo) { m_algorithm = algo; }
inline void setClientId(const String &id) { m_clientId = id; } inline void setClientId(const String &id) { m_clientId = id; }
inline void setHeight(uint64_t height) { m_height = height; } inline void setHeight(uint64_t height) { m_height = height; }

View file

@ -48,6 +48,7 @@
namespace xmrig { namespace xmrig {
static const char *kAlgo = "algo"; static const char *kAlgo = "algo";
static const char *kCoin = "coin";
static const char *kDaemon = "daemon"; static const char *kDaemon = "daemon";
static const char *kDaemonPollInterval = "daemon-poll-interval"; static const char *kDaemonPollInterval = "daemon-poll-interval";
static const char *kEnabled = "enabled"; static const char *kEnabled = "enabled";
@ -120,6 +121,7 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
m_fingerprint = Json::getString(object, kFingerprint); m_fingerprint = Json::getString(object, kFingerprint);
m_pollInterval = Json::getUint64(object, kDaemonPollInterval, kDefaultPollInterval); m_pollInterval = Json::getUint64(object, kDaemonPollInterval, kDefaultPollInterval);
m_algorithm = Json::getString(object, kAlgo); 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_ENABLED, Json::getBool(object, kEnabled, true));
m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash)); m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash));
@ -172,7 +174,7 @@ bool xmrig::Pool::isEnabled() const
} }
# endif # endif
if (isDaemon() && !algorithm().isValid()) { if (isDaemon() && (!algorithm().isValid() && !coin().isValid())) {
return false; return false;
} }
@ -186,6 +188,7 @@ bool xmrig::Pool::isEqual(const Pool &other) const
&& m_keepAlive == other.m_keepAlive && m_keepAlive == other.m_keepAlive
&& m_port == other.m_port && m_port == other.m_port
&& m_algorithm == other.m_algorithm && m_algorithm == other.m_algorithm
&& m_coin == other.m_coin
&& m_fingerprint == other.m_fingerprint && m_fingerprint == other.m_fingerprint
&& m_host == other.m_host && m_host == other.m_host
&& m_password == other.m_password && m_password == other.m_password
@ -268,6 +271,7 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
Value obj(kObjectType); Value obj(kObjectType);
obj.AddMember(StringRef(kAlgo), m_algorithm.toJSON(), allocator); 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(kUrl), m_url.toJSON(), allocator);
obj.AddMember(StringRef(kUser), m_user.toJSON(), allocator); obj.AddMember(StringRef(kUser), m_user.toJSON(), allocator);

View file

@ -32,7 +32,7 @@
#include "base/tools/String.h" #include "base/tools/String.h"
#include "crypto/common/Algorithm.h" #include "crypto/common/Coin.h"
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"
@ -74,6 +74,7 @@ public:
inline bool isTLS() const { return m_flags.test(FLAG_TLS); } inline bool isTLS() const { return m_flags.test(FLAG_TLS); }
inline bool isValid() const { return !m_host.isNull() && m_port > 0; } inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
inline const Algorithm &algorithm() const { return m_algorithm; } 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 &fingerprint() const { return m_fingerprint; }
inline const String &host() const { return m_host; } inline const String &host() const { return m_host; }
inline const String &password() const { return !m_password.isNull() ? m_password : kDefaultPassword; } inline const String &password() const { return !m_password.isNull() ? m_password : kDefaultPassword; }
@ -107,6 +108,7 @@ private:
bool parseIPv6(const char *addr); bool parseIPv6(const char *addr);
Algorithm m_algorithm; Algorithm m_algorithm;
Coin m_coin;
int m_keepAlive; int m_keepAlive;
std::bitset<FLAG_MAX> m_flags; std::bitset<FLAG_MAX> m_flags;
String m_fingerprint; String m_fingerprint;

View file

@ -135,11 +135,12 @@ void xmrig::Pools::print() const
{ {
size_t i = 1; size_t i = 1;
for (const Pool &pool : m_data) { 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, i,
(pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31), (pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31),
pool.url().data(), 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++; i++;

View file

@ -23,6 +23,7 @@
"huge-pages": true, "huge-pages": true,
"hw-aes": null, "hw-aes": null,
"priority": null, "priority": null,
"max-threads-hint": 100,
"asm": true, "asm": true,
"argon2-impl": null, "argon2-impl": null,
"cn/0": false, "cn/0": false,
@ -42,6 +43,7 @@
"pools": [ "pools": [
{ {
"algo": null, "algo": null,
"coin": null,
"url": "donate.v2.xmrig.com:3333", "url": "donate.v2.xmrig.com:3333",
"user": "YOUR_WALLET_ADDRESS", "user": "YOUR_WALLET_ADDRESS",
"pass": "x", "pass": "x",

View file

@ -97,7 +97,7 @@ public:
bool isEnabled(const Algorithm &algorithm) const bool isEnabled(const Algorithm &algorithm) const
{ {
for (IBackend *backend : backends) { for (IBackend *backend : backends) {
if (backend->isEnabled(algorithm)) { if (backend->isEnabled() && backend->isEnabled(algorithm)) {
return true; return true;
} }
} }

View file

@ -138,6 +138,9 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
return transformUint64(doc, key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10)); return transformUint64(doc, key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
} }
case IConfig::CPUMaxThreadsKey: /* --cpu-max-threads-hint */
return set(doc, kCpu, "max-threads-hint", static_cast<uint64_t>(strtol(arg, nullptr, 10)));
# ifdef XMRIG_FEATURE_ASM # ifdef XMRIG_FEATURE_ASM
case IConfig::AssemblyKey: /* --asm */ case IConfig::AssemblyKey: /* --asm */
return set(doc, kCpu, "asm", arg); return set(doc, kCpu, "asm", arg);

View file

@ -57,6 +57,7 @@ R"===(
"huge-pages": true, "huge-pages": true,
"hw-aes": null, "hw-aes": null,
"priority": null, "priority": null,
"max-threads-hint": 100,
"asm": true, "asm": true,
"argon2-impl": null, "argon2-impl": null,
"cn/0": false, "cn/0": false,
@ -76,6 +77,7 @@ R"===(
"pools": [ "pools": [
{ {
"algo": null, "algo": null,
"coin": null,
"url": "donate.v2.xmrig.com:3333", "url": "donate.v2.xmrig.com:3333",
"user": "YOUR_WALLET_ADDRESS", "user": "YOUR_WALLET_ADDRESS",
"pass": "x", "pass": "x",

View file

@ -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[] = { static const option options[] = {
{ "algo", 1, nullptr, IConfig::AlgorithmKey }, { "algo", 1, nullptr, IConfig::AlgorithmKey },
{ "coin", 1, nullptr, IConfig::CoinKey },
# ifdef XMRIG_FEATURE_HTTP # ifdef XMRIG_FEATURE_HTTP
{ "api-worker-id", 1, nullptr, IConfig::ApiWorkerIdKey }, { "api-worker-id", 1, nullptr, IConfig::ApiWorkerIdKey },
{ "api-id", 1, nullptr, IConfig::ApiIdKey }, { "api-id", 1, nullptr, IConfig::ApiIdKey },
@ -81,6 +82,8 @@ static const option options[] = {
{ "userpass", 1, nullptr, IConfig::UserpassKey }, { "userpass", 1, nullptr, IConfig::UserpassKey },
{ "rig-id", 1, nullptr, IConfig::RigIdKey }, { "rig-id", 1, nullptr, IConfig::RigIdKey },
{ "no-cpu", 0, nullptr, IConfig::CPUKey }, { "no-cpu", 0, nullptr, IConfig::CPUKey },
{ "max-cpu-usage", 1, nullptr, IConfig::CPUMaxThreadsKey },
{ "cpu-max-threads-hint", 1, nullptr, IConfig::CPUMaxThreadsKey },
# ifdef XMRIG_FEATURE_TLS # ifdef XMRIG_FEATURE_TLS
{ "tls", 0, nullptr, IConfig::TlsKey }, { "tls", 0, nullptr, IConfig::TlsKey },
{ "tls-fingerprint", 1, nullptr, IConfig::FingerprintKey }, { "tls-fingerprint", 1, nullptr, IConfig::FingerprintKey },

View file

@ -76,6 +76,7 @@ static inline const std::string &usage()
u += " -v, --av=N algorithm variation, 0 auto select\n"; u += " -v, --av=N algorithm variation, 0 auto select\n";
u += " --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n"; u += " --cpu-affinity set process affinity to CPU core(s), mask 0x3 for cores 0 and 1\n";
u += " --cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n"; u += " --cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n";
u += " --cpu-max-threads-hint=N maximum CPU threads count (in percentage) hint for autoconfig\n";
u += " --no-huge-pages disable huge pages support\n"; u += " --no-huge-pages disable huge pages support\n";
u += " --asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer\n"; u += " --asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer\n";

View file

@ -103,9 +103,8 @@ static AlgoName const algorithm_names[] = {
{ "cryptonight_turtle", "cn_turtle", Algorithm::CN_PICO_0 }, { "cryptonight_turtle", "cn_turtle", Algorithm::CN_PICO_0 },
# endif # endif
# ifdef XMRIG_ALGO_RANDOMX # ifdef XMRIG_ALGO_RANDOMX
{ "randomx/0", "rx/0", Algorithm::RX_0 },
{ "randomx/test", "rx/test", Algorithm::RX_0 }, { "randomx/test", "rx/test", Algorithm::RX_0 },
{ "randomx/0", "rx/0", Algorithm::RX_0 },
{ "randomx/0", "rx/0", Algorithm::RX_0 },
{ "RandomX", "rx", Algorithm::RX_0 }, { "RandomX", "rx", Algorithm::RX_0 },
{ "randomx/wow", "rx/wow", Algorithm::RX_WOW }, { "randomx/wow", "rx/wow", Algorithm::RX_WOW },
{ "RandomWOW", nullptr, Algorithm::RX_WOW }, { "RandomWOW", nullptr, Algorithm::RX_WOW },

103
src/crypto/common/Coin.cpp Normal file
View file

@ -0,0 +1,103 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "crypto/common/Coin.h"
#include "rapidjson/document.h"
#include <cstring>
#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;
}

75
src/crypto/common/Coin.h Normal file
View file

@ -0,0 +1,75 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_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 */

View file

@ -28,10 +28,10 @@
#endif #endif
#include <algorithm> #include <algorithm>
#include <inttypes.h> #include <cinttypes>
#include <ctime>
#include <iterator> #include <iterator>
#include <memory> #include <memory>
#include <time.h>
#include "base/io/log/Log.h" #include "base/io/log/Log.h"
@ -83,11 +83,7 @@ xmrig::Network::~Network()
JobResults::stop(); JobResults::stop();
delete m_timer; delete m_timer;
if (m_donate) {
delete m_donate; delete m_donate;
}
delete m_strategy; delete m_strategy;
} }
@ -304,8 +300,8 @@ void xmrig::Network::getResults(rapidjson::Value &reply, rapidjson::Document &do
results.AddMember("hashes_total", m_state.total, allocator); results.AddMember("hashes_total", m_state.total, allocator);
Value best(kArrayType); Value best(kArrayType);
for (size_t i = 0; i < m_state.topDiff.size(); ++i) { for (uint64_t i : m_state.topDiff) {
best.PushBack(m_state.topDiff[i], allocator); best.PushBack(i, allocator);
} }
results.AddMember("best", best, allocator); results.AddMember("best", best, allocator);

View file

@ -34,6 +34,7 @@
#include "base/kernel/interfaces/IBaseListener.h" #include "base/kernel/interfaces/IBaseListener.h"
#include "base/kernel/interfaces/IStrategyListener.h" #include "base/kernel/interfaces/IStrategyListener.h"
#include "base/kernel/interfaces/ITimerListener.h" #include "base/kernel/interfaces/ITimerListener.h"
#include "base/tools/Object.h"
#include "interfaces/IJobResultListener.h" #include "interfaces/IJobResultListener.h"
#include "net/NetworkState.h" #include "net/NetworkState.h"
#include "rapidjson/fwd.h" #include "rapidjson/fwd.h"
@ -49,6 +50,8 @@ class IStrategy;
class Network : public IJobResultListener, public IStrategyListener, public IBaseListener, public ITimerListener, public IApiListener class Network : public IJobResultListener, public IStrategyListener, public IBaseListener, public ITimerListener, public IApiListener
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Network)
Network(Controller *controller); Network(Controller *controller);
~Network() override; ~Network() override;

View file

@ -24,7 +24,7 @@
#include <algorithm> #include <algorithm>
#include <assert.h> #include <cassert>
#include <iterator> #include <iterator>
@ -58,17 +58,10 @@ static const char *kDonateHostTls = "donate.ssl.xmrig.com";
xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener *listener) : xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener *listener) :
m_tls(false),
m_userId(),
m_donateTime(static_cast<uint64_t>(controller->config()->pools().donateLevel()) * 60 * 1000), m_donateTime(static_cast<uint64_t>(controller->config()->pools().donateLevel()) * 60 * 1000),
m_idleTime((100 - static_cast<uint64_t>(controller->config()->pools().donateLevel())) * 60 * 1000), m_idleTime((100 - static_cast<uint64_t>(controller->config()->pools().donateLevel())) * 60 * 1000),
m_controller(controller), m_controller(controller),
m_proxy(nullptr), m_listener(listener)
m_strategy(nullptr),
m_listener(listener),
m_state(STATE_NEW),
m_now(0),
m_timestamp(0)
{ {
uint8_t hash[200]; uint8_t hash[200];
@ -77,15 +70,15 @@ xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener
Buffer::toHex(hash, 32, m_userId); Buffer::toHex(hash, 32, m_userId);
# ifdef XMRIG_FEATURE_TLS # ifdef XMRIG_FEATURE_TLS
m_pools.push_back(Pool(kDonateHostTls, 443, m_userId, nullptr, 0, true, true)); m_pools.emplace_back(kDonateHostTls, 443, m_userId, nullptr, 0, true, true);
# endif # endif
m_pools.push_back(Pool(kDonateHost, 3333, m_userId, nullptr, 0, true)); m_pools.emplace_back(kDonateHost, 3333, m_userId, nullptr, 0, true);
if (m_pools.size() > 1) { if (m_pools.size() > 1) {
m_strategy = new FailoverStrategy(m_pools, 1, 2, this, true); m_strategy = new FailoverStrategy(m_pools, 10, 2, this, true);
} }
else { else {
m_strategy = new SinglePoolStrategy(m_pools.front(), 1, 2, this, true); m_strategy = new SinglePoolStrategy(m_pools.front(), 10, 2, this, true);
} }
m_timer = new Timer(this); m_timer = new Timer(this);
@ -223,6 +216,18 @@ void xmrig::DonateStrategy::onLoginSuccess(IClient *client)
} }
void xmrig::DonateStrategy::onVerifyAlgorithm(const IClient *client, const Algorithm &algorithm, bool *ok)
{
m_listener->onVerifyAlgorithm(this, client, algorithm, ok);
}
void xmrig::DonateStrategy::onVerifyAlgorithm(IStrategy *, const IClient *client, const Algorithm &algorithm, bool *ok)
{
m_listener->onVerifyAlgorithm(this, client, algorithm, ok);
}
void xmrig::DonateStrategy::onTimer(const Timer *) void xmrig::DonateStrategy::onTimer(const Timer *)
{ {
setState(isActive() ? STATE_WAIT : STATE_CONNECT); setState(isActive() ? STATE_WAIT : STATE_CONNECT);
@ -246,7 +251,7 @@ xmrig::Client *xmrig::DonateStrategy::createProxy()
Pool pool(client->ip(), client->pool().port(), m_userId, client->pool().password(), 0, true, client->isTLS()); Pool pool(client->ip(), client->pool().port(), m_userId, client->pool().password(), 0, true, client->isTLS());
pool.setAlgo(client->pool().algorithm()); pool.setAlgo(client->pool().algorithm());
Client *proxy = new Client(-1, Platform::userAgent(), this); auto proxy = new Client(-1, Platform::userAgent(), this);
proxy->setPool(pool); proxy->setPool(pool);
proxy->setQuiet(true); proxy->setQuiet(true);

View file

@ -34,6 +34,7 @@
#include "base/kernel/interfaces/IStrategyListener.h" #include "base/kernel/interfaces/IStrategyListener.h"
#include "base/kernel/interfaces/ITimerListener.h" #include "base/kernel/interfaces/ITimerListener.h"
#include "base/net/stratum/Pool.h" #include "base/net/stratum/Pool.h"
#include "base/tools/Object.h"
namespace xmrig { namespace xmrig {
@ -47,6 +48,8 @@ class IStrategyListener;
class DonateStrategy : public IStrategy, public IStrategyListener, public ITimerListener, public IClientListener class DonateStrategy : public IStrategy, public IStrategyListener, public ITimerListener, public IClientListener
{ {
public: public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(DonateStrategy)
DonateStrategy(Controller *controller, IStrategyListener *listener); DonateStrategy(Controller *controller, IStrategyListener *listener);
~DonateStrategy() override; ~DonateStrategy() override;
@ -57,8 +60,6 @@ protected:
inline void onJobReceived(IClient *client, const Job &job, const rapidjson::Value &) override { setJob(client, job); } inline void onJobReceived(IClient *client, const Job &job, const rapidjson::Value &) override { setJob(client, job); }
inline void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) override { setResult(client, result, error); } inline void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) override { setResult(client, result, error); }
inline void onResultAccepted(IStrategy *, IClient *client, const SubmitResult &result, const char *error) override { setResult(client, result, error); } inline void onResultAccepted(IStrategy *, IClient *client, const SubmitResult &result, const char *error) override { setResult(client, result, error); }
inline void onVerifyAlgorithm(const IClient *, const Algorithm &, bool *) override {}
inline void onVerifyAlgorithm(IStrategy *, const IClient *, const Algorithm &, bool *) override {}
inline void resume() override {} inline void resume() override {}
int64_t submit(const JobResult &result) override; int64_t submit(const JobResult &result) override;
@ -74,6 +75,8 @@ protected:
void onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value &params) override; void onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value &params) override;
void onLogin(IStrategy *strategy, IClient *client, rapidjson::Document &doc, rapidjson::Value &params) override; void onLogin(IStrategy *strategy, IClient *client, rapidjson::Document &doc, rapidjson::Value &params) override;
void onLoginSuccess(IClient *client) override; void onLoginSuccess(IClient *client) override;
void onVerifyAlgorithm(const IClient *client, const Algorithm &algorithm, bool *ok) override;
void onVerifyAlgorithm(IStrategy *strategy, const IClient *client, const Algorithm &algorithm, bool *ok) override;
void onTimer(const Timer *timer) override; void onTimer(const Timer *timer) override;
@ -96,19 +99,19 @@ private:
void setState(State state); void setState(State state);
Algorithm m_algorithm; Algorithm m_algorithm;
bool m_tls; bool m_tls = false;
char m_userId[65]; char m_userId[65] = { 0 };
const uint64_t m_donateTime; const uint64_t m_donateTime;
const uint64_t m_idleTime; const uint64_t m_idleTime;
Controller *m_controller; Controller *m_controller;
IClient *m_proxy; IClient *m_proxy = nullptr;
IStrategy *m_strategy; IStrategy *m_strategy = nullptr;
IStrategyListener *m_listener; IStrategyListener *m_listener;
State m_state; State m_state = STATE_NEW;
std::vector<Pool> m_pools; std::vector<Pool> m_pools;
Timer *m_timer; Timer *m_timer = nullptr;
uint64_t m_now; uint64_t m_now = 0;
uint64_t m_timestamp; uint64_t m_timestamp = 0;
}; };

View file

@ -28,14 +28,14 @@
#define APP_ID "xmrig" #define APP_ID "xmrig"
#define APP_NAME "XMRig" #define APP_NAME "XMRig"
#define APP_DESC "XMRig miner" #define APP_DESC "XMRig miner"
#define APP_VERSION "4.1.0-beta" #define APP_VERSION "4.2.0-evo"
#define APP_DOMAIN "xmrig.com" #define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com" #define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2019 xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2019 xmrig.com"
#define APP_KIND "miner" #define APP_KIND "miner"
#define APP_VER_MAJOR 4 #define APP_VER_MAJOR 4
#define APP_VER_MINOR 1 #define APP_VER_MINOR 2
#define APP_VER_PATCH 0 #define APP_VER_PATCH 0
#ifdef _MSC_VER #ifdef _MSC_VER