diff --git a/CMakeLists.txt b/CMakeLists.txt index 342951f33..47a4d7419 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ set(HEADERS src/workers/SingleWorker.h src/workers/Worker.h src/workers/Workers.h + src/xmrig.h ) set(HEADERS_CRYPTO diff --git a/src/Mem.cpp b/src/Mem.cpp index 1943b22ac..73576d204 100644 --- a/src/Mem.cpp +++ b/src/Mem.cpp @@ -29,6 +29,7 @@ #include "crypto/CryptoNight.h" #include "Mem.h" #include "Options.h" +#include "xmrig.h" bool Mem::m_doubleHash = false; @@ -42,7 +43,7 @@ uint8_t *Mem::m_memory = nullptr; cryptonight_ctx *Mem::create(int threadId) { # ifndef XMRIG_NO_AEON - if (m_algo == Options::ALGO_CRYPTONIGHT_LITE) { + if (m_algo == xmrig::ALGO_CRYPTONIGHT_LITE) { return createLite(threadId); } # endif diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index ec4017da9..93cdbec04 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -38,6 +38,7 @@ #include "log/Log.h" #include "Mem.h" #include "Options.h" +#include "xmrig.h" bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled) @@ -46,7 +47,7 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled) m_threads = threads; m_doubleHash = doubleHash; - const int ratio = (doubleHash && algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1; + const int ratio = (doubleHash && algo != xmrig::ALGO_CRYPTONIGHT_LITE) ? 2 : 1; const size_t size = MONERO_MEMORY * (threads * ratio + 1); if (!enabled) { diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index 79c6d12ee..28eaff496 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -38,6 +38,7 @@ #include "crypto/CryptoNight.h" #include "Mem.h" #include "Options.h" +#include "xmrig.h" /***************************************************************** @@ -151,7 +152,7 @@ bool Mem::allocate(int algo, int threads, bool doubleHash, bool enabled) m_threads = threads; m_doubleHash = doubleHash; - const int ratio = (doubleHash && algo != Options::ALGO_CRYPTONIGHT_LITE) ? 2 : 1; + const int ratio = (doubleHash && algo != xmrig::ALGO_CRYPTONIGHT_LITE) ? 2 : 1; const size_t size = MONERO_MEMORY * (threads * ratio + 1); if (!enabled) { diff --git a/src/Options.cpp b/src/Options.cpp index f60b12858..939075f8a 100644 --- a/src/Options.cpp +++ b/src/Options.cpp @@ -47,6 +47,7 @@ #include "rapidjson/error/en.h" #include "rapidjson/filereadstream.h" #include "version.h" +#include "xmrig.h" #ifndef ARRAY_SIZE @@ -74,7 +75,7 @@ Options:\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\ - --no-monero disable Monero v7 PoW\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\ @@ -119,7 +120,7 @@ static struct option const options[] = { { "nicehash", 0, nullptr, 1006 }, { "no-color", 0, nullptr, 1002 }, { "no-huge-pages", 0, nullptr, 1009 }, - { "no-monero", 0, nullptr, 1010 }, + { "variant", 1, nullptr, 1010 }, { "pass", 1, nullptr, 'p' }, { "print-time", 1, nullptr, 1007 }, { "retries", 1, nullptr, 'r' }, @@ -160,12 +161,12 @@ static struct option const config_options[] = { static struct option const pool_options[] = { - { "pass", 1, nullptr, 'p' }, { "url", 1, nullptr, 'o' }, + { "pass", 1, nullptr, 'p' }, { "user", 1, nullptr, 'u' }, { "userpass", 1, nullptr, 'O' }, { "keepalive", 0, nullptr ,'k' }, - { "monero", 0, nullptr, 1010 }, + { "variant", 1, nullptr, 1010 }, { "nicehash", 0, nullptr, 1006 }, { 0, 0, 0, 0 } }; @@ -275,9 +276,7 @@ Options::Options(int argc, char **argv) : } } - for (Url *url : m_pools) { - url->applyExceptions(); - } + adjust(); m_ready = true; } @@ -383,6 +382,7 @@ bool Options::parseArg(int key, const char *arg) 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 */ @@ -395,7 +395,6 @@ bool Options::parseArg(int key, const char *arg) case 1002: /* --no-color */ case 1009: /* --no-huge-pages */ - case 1010: /* --no-monero */ return parseBoolean(key, false); case 't': /* --threads */ @@ -502,6 +501,10 @@ bool Options::parseArg(int key, uint64_t arg) m_printTime = (int) arg; break; + case 1010: /* --variant */ + m_pools.back()->setVariant((int) arg); + break; + case 1020: /* --cpu-affinity */ if (arg) { m_affinity = arg; @@ -561,10 +564,6 @@ bool Options::parseBoolean(int key, bool enable) m_hugePages = enable; break; - case 1010: /* monero */ - m_pools.back()->setMonero(enable); - break; - case 2000: /* colors */ m_colors = enable; break; @@ -593,6 +592,14 @@ Url *Options::parseUrl(const char *arg) const } +void Options::adjust() +{ + for (Url *url : m_pools) { + url->adjust(m_algo); + } +} + + void Options::parseConfig(const char *fileName) { rapidjson::Document doc; @@ -637,7 +644,7 @@ void Options::parseJSON(const struct option *option, const rapidjson::Value &obj if (option->has_arg && value.IsString()) { parseArg(option->val, value.GetString()); } - else if (option->has_arg && value.IsUint64()) { + else if (option->has_arg && value.IsInt64()) { parseArg(option->val, value.GetUint64()); } else if (!option->has_arg && value.IsBool()) { @@ -703,7 +710,7 @@ bool Options::setAlgo(const char *algo) # ifndef XMRIG_NO_AEON if (i == ARRAY_SIZE(algo_names) - 1 && !strcmp(algo, "cryptonight-light")) { - m_algo = ALGO_CRYPTONIGHT_LITE; + m_algo = xmrig::ALGO_CRYPTONIGHT_LITE; break; } # endif @@ -721,7 +728,7 @@ bool Options::setAlgo(const char *algo) int Options::getAlgoVariant() const { # ifndef XMRIG_NO_AEON - if (m_algo == ALGO_CRYPTONIGHT_LITE) { + if (m_algo == xmrig::ALGO_CRYPTONIGHT_LITE) { return getAlgoVariantLite(); } # endif diff --git a/src/Options.h b/src/Options.h index 625ac78d8..e29059ecc 100644 --- a/src/Options.h +++ b/src/Options.h @@ -39,11 +39,6 @@ struct option; class Options { public: - enum Algo { - ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */ - ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ - }; - enum AlgoVariant { AV0_AUTO, AV1_AESNI, @@ -96,6 +91,7 @@ private: 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; diff --git a/src/crypto/CryptoNight.cpp b/src/crypto/CryptoNight.cpp index 8a818fda8..1d71d1cd2 100644 --- a/src/crypto/CryptoNight.cpp +++ b/src/crypto/CryptoNight.cpp @@ -36,81 +36,74 @@ #include "net/Job.h" #include "net/JobResult.h" #include "Options.h" +#include "xmrig.h" - -void (*cryptonight_hash_ctx)(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) = nullptr; +void (*cryptonight_hash_ctx)(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) = nullptr; -static void cryptonight_av1_aesni(const void *input, size_t size, void *output, struct cryptonight_ctx *ctx, uint8_t version) { +#define CRYPTONIGHT_HASH(NAME, ITERATIONS, MEM, MASK, 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 void *input, size_t size, void *output, struct cryptonight_ctx *ctx, int variant) { # if !defined(XMRIG_ARMv7) - if (version > 6) { - cryptonight_hash(input, size, output, ctx, version); - } - else { - cryptonight_hash(input, size, output, ctx, version); - } + CRYPTONIGHT_HASH(single, MONERO_ITER, MONERO_MEMORY, MONERO_MASK, false) # endif } -static void cryptonight_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { +static void cryptonight_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) { # if !defined(XMRIG_ARMv7) - if (version > 6) { - cryptonight_double_hash(input, size, output, ctx, version); - } - else { - cryptonight_double_hash(input, size, output, ctx, version); - } + CRYPTONIGHT_HASH(double, MONERO_ITER, MONERO_MEMORY, MONERO_MASK, false) # endif } -static void cryptonight_av3_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { - if (version > 6) { - cryptonight_hash(input, size, output, ctx, version); - } - else { - cryptonight_hash(input, size, output, ctx, version); - } +static void cryptonight_av3_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) { + CRYPTONIGHT_HASH(single, MONERO_ITER, MONERO_MEMORY, MONERO_MASK, true) } -static void cryptonight_av4_softaes_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { - if (version > 6) { - cryptonight_double_hash(input, size, output, ctx, version); - } - else { - cryptonight_double_hash(input, size, output, ctx, version); - } +static void cryptonight_av4_softaes_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) { + CRYPTONIGHT_HASH(double, MONERO_ITER, MONERO_MEMORY, MONERO_MASK, true) } #ifndef XMRIG_NO_AEON -static void cryptonight_lite_av1_aesni(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { +static void cryptonight_lite_av1_aesni(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) { # if !defined(XMRIG_ARMv7) - cryptonight_hash(input, size, output, ctx, version); + CRYPTONIGHT_HASH(single, AEON_ITER, AEON_MEMORY, AEON_MASK, false) # endif } -static void cryptonight_lite_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { +static void cryptonight_lite_av2_aesni_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) { # if !defined(XMRIG_ARMv7) - cryptonight_double_hash(input, size, output, ctx, version); + CRYPTONIGHT_HASH(double, AEON_ITER, AEON_MEMORY, AEON_MASK, false) # endif } -static void cryptonight_lite_av3_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { - cryptonight_hash(input, size, output, ctx, version); +static void cryptonight_lite_av3_softaes(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) { + CRYPTONIGHT_HASH(single, AEON_ITER, AEON_MEMORY, AEON_MASK, true) } -static void cryptonight_lite_av4_softaes_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t version) { - cryptonight_double_hash(input, size, output, ctx, version); +static void cryptonight_lite_av4_softaes_double(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) { + CRYPTONIGHT_HASH(double, AEON_ITER, AEON_MEMORY, AEON_MASK, true) } -void (*cryptonight_variations[8])(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t) = { +void (*cryptonight_variations[8])(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) = { cryptonight_av1_aesni, cryptonight_av2_aesni_double, cryptonight_av3_softaes, @@ -121,7 +114,7 @@ void (*cryptonight_variations[8])(const void *input, size_t size, void *output, cryptonight_lite_av4_softaes_double }; #else -void (*cryptonight_variations[4])(const void *input, size_t size, void *output, cryptonight_ctx *ctx, uint8_t) = { +void (*cryptonight_variations[4])(const void *input, size_t size, void *output, cryptonight_ctx *ctx, int variant) = { cryptonight_av1_aesni, cryptonight_av2_aesni_double, cryptonight_av3_softaes, @@ -132,7 +125,7 @@ void (*cryptonight_variations[4])(const void *input, size_t size, void *output, bool CryptoNight::hash(const Job &job, JobResult &result, cryptonight_ctx *ctx) { - cryptonight_hash_ctx(job.blob(), job.size(), result.result, ctx, job.version()); + cryptonight_hash_ctx(job.blob(), job.size(), result.result, ctx, job.variant()); return *reinterpret_cast(result.result + 24) < job.target(); } @@ -145,7 +138,7 @@ bool CryptoNight::init(int algo, int variant) } # ifndef XMRIG_NO_AEON - const int index = algo == Options::ALGO_CRYPTONIGHT_LITE ? (variant + 3) : (variant - 1); + const int index = algo == xmrig::ALGO_CRYPTONIGHT_LITE ? (variant + 3) : (variant - 1); # else const int index = variant - 1; # endif @@ -156,9 +149,9 @@ bool CryptoNight::init(int algo, int variant) } -void CryptoNight::hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, uint8_t version) +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, version); + cryptonight_hash_ctx(input, size, output, ctx, variant); } @@ -175,13 +168,13 @@ bool CryptoNight::selfTest(int algo) { cryptonight_hash_ctx(test_input, 76, output, ctx, 0); # ifndef XMRIG_NO_AEON - bool rc = memcmp(output, algo == Options::ALGO_CRYPTONIGHT_LITE ? test_output1 : test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0; + bool rc = memcmp(output, algo == xmrig::ALGO_CRYPTONIGHT_LITE ? test_output1 : test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0; # else bool rc = memcmp(output, test_output0, (Options::i()->doubleHash() ? 64 : 32)) == 0; # endif - if (rc && algo == Options::ALGO_CRYPTONIGHT) { - cryptonight_hash_ctx(test_input, 76, output, ctx, 7); + if (rc && algo == xmrig::ALGO_CRYPTONIGHT) { + cryptonight_hash_ctx(test_input, 76, output, ctx, 1); rc = memcmp(output, test_output2, (Options::i()->doubleHash() ? 64 : 32)) == 0; } diff --git a/src/crypto/CryptoNight.h b/src/crypto/CryptoNight.h index 06bb98880..9526309dd 100644 --- a/src/crypto/CryptoNight.h +++ b/src/crypto/CryptoNight.h @@ -57,7 +57,7 @@ class CryptoNight public: static bool hash(const Job &job, JobResult &result, cryptonight_ctx *ctx); static bool init(int algo, int variant); - static void hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, uint8_t version); + static void hash(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx *ctx, int variant); private: static bool selfTest(int algo); diff --git a/src/crypto/CryptoNight_arm.h b/src/crypto/CryptoNight_arm.h index 6d8c454ea..6b214d66e 100644 --- a/src/crypto/CryptoNight_arm.h +++ b/src/crypto/CryptoNight_arm.h @@ -332,8 +332,8 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) } -template -inline void cryptonight_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, cryptonight_ctx *__restrict__ ctx, uint8_t version) +template +inline void cryptonight_single_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, cryptonight_ctx *__restrict__ ctx) { keccak(static_cast(input), (int) size, ctx->state0, 200); @@ -393,8 +393,8 @@ inline void cryptonight_hash(const void *__restrict__ input, size_t size, void * } -template -inline void cryptonight_double_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx, uint8_t version) +template +inline void cryptonight_double_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) { keccak((const uint8_t *) input, (int) size, ctx->state0, 200); keccak((const uint8_t *) input + size, (int) size, ctx->state1, 200); diff --git a/src/crypto/CryptoNight_monero.h b/src/crypto/CryptoNight_monero.h index 9bf3db846..3c6146aca 100644 --- a/src/crypto/CryptoNight_monero.h +++ b/src/crypto/CryptoNight_monero.h @@ -29,28 +29,22 @@ // VARIANT ALTERATIONS #define VARIANT1_INIT(part) \ uint64_t tweak1_2_##part = 0; \ - if (MONERO) { \ - if (version > 6) { \ - tweak1_2_##part = (*reinterpret_cast(reinterpret_cast(input) + 35 + part * size) ^ \ - *(reinterpret_cast(ctx->state##part) + 24)); \ - } \ + if (VARIANT > 0) { \ + tweak1_2_##part = (*reinterpret_cast(reinterpret_cast(input) + 35 + part * size) ^ \ + *(reinterpret_cast(ctx->state##part) + 24)); \ } #define VARIANT1_1(p) \ - if (MONERO) { \ - if (version > 6) { \ - const uint8_t tmp = reinterpret_cast(p)[11]; \ - static const uint32_t table = 0x75310; \ - const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \ - ((uint8_t*)(p))[11] = tmp ^ ((table >> index) & 0x30); \ - } \ + if (VARIANT > 0) { \ + const uint8_t tmp = reinterpret_cast(p)[11]; \ + static const uint32_t table = 0x75310; \ + const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \ + ((uint8_t*)(p))[11] = tmp ^ ((table >> index) & 0x30); \ } #define VARIANT1_2(p, part) \ - if (MONERO) { \ - if (version > 6) { \ - (p) ^= tweak1_2_##part; \ - } \ + if (VARIANT > 0) { \ + (p) ^= tweak1_2_##part; \ } diff --git a/src/crypto/CryptoNight_x86.h b/src/crypto/CryptoNight_x86.h index 7393bbfa6..1e5190d8f 100644 --- a/src/crypto/CryptoNight_x86.h +++ b/src/crypto/CryptoNight_x86.h @@ -309,8 +309,8 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) } -template -inline void cryptonight_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, cryptonight_ctx *__restrict__ ctx, uint8_t version) +template +inline void cryptonight_single_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, cryptonight_ctx *__restrict__ ctx) { keccak(static_cast(input), (int) size, ctx->state0, 200); @@ -367,8 +367,8 @@ inline void cryptonight_hash(const void *__restrict__ input, size_t size, void * } -template -inline void cryptonight_double_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx, uint8_t version) +template +inline void cryptonight_double_hash(const void *__restrict__ input, size_t size, void *__restrict__ output, struct cryptonight_ctx *__restrict__ ctx) { keccak((const uint8_t *) input, (int) size, ctx->state0, 200); keccak((const uint8_t *) input + size, (int) size, ctx->state1, 200); diff --git a/src/net/Client.cpp b/src/net/Client.cpp index b01483366..f6543b4e7 100644 --- a/src/net/Client.cpp +++ b/src/net/Client.cpp @@ -221,7 +221,7 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } - Job job(m_id, m_nicehash, m_url.isMonero()); + Job job(m_id, m_nicehash, m_url.algo(), m_url.variant()); if (!job.setId(params["job_id"].GetString())) { *code = 3; return false; @@ -241,6 +241,10 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) job.setCoin(params["coin"].GetString()); } + if (params.HasMember("variant")) { + job.setVariant(params["variant"].GetInt()); + } + if (m_job == job) { if (!m_quiet) { LOG_WARN("[%s:%u] duplicate job received, reconnect", m_url.host(), m_url.port()); diff --git a/src/net/Job.cpp b/src/net/Job.cpp index 3faed6a18..c8331fb9b 100644 --- a/src/net/Job.cpp +++ b/src/net/Job.cpp @@ -27,6 +27,7 @@ #include "net/Job.h" +#include "xmrig.h" static inline unsigned char hf_hex2bin(char c, bool &err) @@ -56,11 +57,26 @@ static inline char hf_bin2hex(unsigned char c) } -Job::Job(int poolId, bool nicehash, bool monero) : - m_monero(monero), +Job::Job() : + m_nicehash(false), + m_algo(xmrig::ALGO_CRYPTONIGHT), + m_poolId(-2), + m_threadId(-1), + m_variant(xmrig::VARIANT_AUTO), + m_size(0), + m_diff(0), + m_target(0) +{ + memset(m_coin, 0, sizeof(m_coin)); +} + + +Job::Job(int poolId, bool nicehash, int algo, int variant) : m_nicehash(nicehash), + m_algo(algo), m_poolId(poolId), m_threadId(-1), + m_variant(variant), m_size(0), m_diff(0), m_target(0) @@ -149,6 +165,22 @@ bool Job::setTarget(const char *target) } +int Job::variant() const +{ + if (m_variant != xmrig::VARIANT_AUTO) { + return m_variant; + } + + const uint8_t version = m_blob[0]; + + if (m_algo == xmrig::ALGO_CRYPTONIGHT) { + return version > 6 ? 1 : 0; + } + + return version > 1 ? 1 : 0; +} + + void Job::setCoin(const char *coin) { if (!coin || strlen(coin) > 4) { @@ -157,7 +189,22 @@ void Job::setCoin(const char *coin) } strncpy(m_coin, coin, sizeof(m_coin)); - m_monero = strcmp(m_coin, "XMR") == 0; + m_algo = strcmp(m_coin, "AEON") == 0 ? xmrig::ALGO_CRYPTONIGHT_LITE : xmrig::ALGO_CRYPTONIGHT; +} + + +void Job::setVariant(int variant) +{ + switch (variant) { + case xmrig::VARIANT_AUTO: + case xmrig::VARIANT_NONE: + case xmrig::VARIANT_V1: + m_variant = variant; + break; + + default: + break; + } } diff --git a/src/net/Job.h b/src/net/Job.h index 755de9ec4..28d5e111b 100644 --- a/src/net/Job.h +++ b/src/net/Job.h @@ -37,14 +37,16 @@ class Job { public: - Job(int poolId = -2, bool nicehash = false, bool monero = true); + Job(); + Job(int poolId, bool nicehash, int algo, int variant); ~Job(); bool setBlob(const char *blob); bool setTarget(const char *target); + int variant() const; void setCoin(const char *coin); + void setVariant(int variant); - inline bool isMonero() const { return m_monero; } 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); } @@ -58,7 +60,6 @@ public: 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 uint8_t version() const { return isMonero() ? m_blob[0] : 0; } inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } inline void setThreadId(int threadId) { m_threadId = threadId; } @@ -77,11 +78,12 @@ public: private: VAR_ALIGN(16, uint8_t m_blob[84]); // Max blob size is 84 (75 fixed + 9 variable), aligned to 96. https://github.com/xmrig/xmrig/issues/1 Thanks fireice-uk. - bool m_monero; bool m_nicehash; char m_coin[5]; + int m_algo; int m_poolId; int m_threadId; + int m_variant; size_t m_size; uint64_t m_diff; uint64_t m_target; diff --git a/src/net/Url.cpp b/src/net/Url.cpp index cd020b322..c17ef690a 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -28,6 +28,7 @@ #include "net/Url.h" +#include "xmrig.h" #ifdef _MSC_VER @@ -37,11 +38,12 @@ Url::Url() : m_keepAlive(false), - m_monero(true), m_nicehash(false), m_host(nullptr), m_password(nullptr), m_user(nullptr), + m_algo(xmrig::ALGO_CRYPTONIGHT), + m_variant(xmrig::VARIANT_AUTO), m_url(nullptr), m_port(kDefaultPort) { @@ -61,11 +63,12 @@ Url::Url() : */ Url::Url(const char *url) : m_keepAlive(false), - m_monero(true), m_nicehash(false), m_host(nullptr), m_password(nullptr), m_user(nullptr), + m_algo(xmrig::ALGO_CRYPTONIGHT), + m_variant(xmrig::VARIANT_AUTO), m_url(nullptr), m_port(kDefaultPort) { @@ -73,12 +76,13 @@ Url::Url(const char *url) : } -Url::Url(const char *host, uint16_t port, const char *user, const char *password, bool keepAlive, bool nicehash, bool monero) : +Url::Url(const char *host, uint16_t port, const char *user, const char *password, bool keepAlive, bool nicehash, int variant) : m_keepAlive(keepAlive), - m_monero(monero), m_nicehash(nicehash), m_password(password ? strdup(password) : nullptr), m_user(user ? strdup(user) : nullptr), + m_algo(xmrig::ALGO_CRYPTONIGHT), + m_variant(variant), m_url(nullptr), m_port(port) { @@ -165,12 +169,14 @@ const char *Url::url() const } -void Url::applyExceptions() +void Url::adjust(int algo) { if (!isValid()) { return; } + m_algo = algo; + if (strstr(m_host, ".nicehash.com")) { m_keepAlive = false; m_nicehash = true; @@ -204,6 +210,21 @@ void Url::setUser(const char *user) } +void Url::setVariant(int variant) +{ + switch (variant) { + case xmrig::VARIANT_AUTO: + case xmrig::VARIANT_NONE: + case xmrig::VARIANT_V1: + m_variant = variant; + break; + + default: + break; + } +} + + bool Url::operator==(const Url &other) const { if (m_port != other.m_port || m_keepAlive != other.m_keepAlive || m_nicehash != other.m_nicehash) { @@ -221,7 +242,8 @@ bool Url::operator==(const Url &other) const Url &Url::operator=(const Url *other) { m_keepAlive = other->m_keepAlive; - m_monero = other->m_monero; + m_algo = other->m_algo; + m_variant = other->m_variant; m_nicehash = other->m_nicehash; m_port = other->m_port; diff --git a/src/net/Url.h b/src/net/Url.h index 32eea5bfd..f861fec54 100644 --- a/src/net/Url.h +++ b/src/net/Url.h @@ -37,27 +37,29 @@ public: 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, bool monero = true); + 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(); inline bool isKeepAlive() const { return m_keepAlive; } - inline bool isMonero() const { return m_monero; } 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 variant() const { return m_variant; } inline uint16_t port() const { return m_port; } inline void setKeepAlive(bool keepAlive) { m_keepAlive = keepAlive; } - inline void setMonero(bool monero) { m_monero = monero; } inline void setNicehash(bool nicehash) { m_nicehash = nicehash; } + inline void setVariant(bool monero) { m_variant = monero; } bool parse(const char *url); bool setUserpass(const char *userpass); const char *url() const; - void applyExceptions(); + void adjust(int algo); void setPassword(const char *password); void setUser(const char *user); + void setVariant(int variant); bool operator==(const Url &other) const; Url &operator=(const Url *other); @@ -66,11 +68,12 @@ private: bool parseIPv6(const char *addr); bool m_keepAlive; - bool m_monero; bool m_nicehash; char *m_host; char *m_password; char *m_user; + int m_algo; + int m_variant; mutable char *m_url; uint16_t m_port; }; diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 288e6e486..22cffd28a 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -27,6 +27,7 @@ #include "net/Job.h" #include "net/strategies/DonateStrategy.h" #include "Options.h" +#include "xmrig.h" extern "C" @@ -48,7 +49,7 @@ DonateStrategy::DonateStrategy(const char *agent, IStrategyListener *listener) : keccak(reinterpret_cast(user), static_cast(strlen(user)), hash, sizeof(hash)); Job::toHex(hash, 32, userId); - Url *url = new Url("thanks.xmrig.com", Options::i()->algo() == Options::ALGO_CRYPTONIGHT_LITE ? 3333 : 80, userId, nullptr, false, true); + Url *url = new Url("thanks.xmrig.com", Options::i()->algo() == xmrig::ALGO_CRYPTONIGHT_LITE ? 3333 : 80, userId, nullptr, false, true); m_client = new Client(-1, agent, this); m_client->setUrl(url); diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index d29603207..46c8ed2ea 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -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.version()); + CryptoNight::hash(m_state->blob, m_state->job.size(), m_hash, m_ctx, m_state->job.variant()); 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())); diff --git a/src/xmrig.h b/src/xmrig.h new file mode 100644 index 000000000..103e8a68e --- /dev/null +++ b/src/xmrig.h @@ -0,0 +1,47 @@ +/* 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 __XMRIG_H__ +#define __XMRIG_H__ + + +namespace xmrig +{ + + +enum Algo { + ALGO_CRYPTONIGHT, /* CryptoNight (Monero) */ + ALGO_CRYPTONIGHT_LITE, /* CryptoNight-Lite (AEON) */ +}; + + +enum Variant { + VARIANT_AUTO = -1, + VARIANT_NONE = 0, + VARIANT_V1 = 1 +}; + +} /* xmrig */ + + +#endif /* __XMRIG_H__ */