From 6551818610aa48bc99aa1047443a8dd9842a811a Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 6 Jun 2017 03:31:44 +0300 Subject: [PATCH 1/7] Update libjansson to 2.10. --- compat/jansson/CMakeLists.txt | 2 + compat/jansson/dump.c | 64 ++++++++++++++++++++++++++++---- compat/jansson/hashtable_seed.c | 4 +- compat/jansson/jansson.h | 8 +++- compat/jansson/jansson_private.h | 1 + compat/jansson/load.c | 49 ++++++++++++++++++++++-- version.h | 2 +- 7 files changed, 115 insertions(+), 15 deletions(-) diff --git a/compat/jansson/CMakeLists.txt b/compat/jansson/CMakeLists.txt index 9a73da225..7bd74c671 100644 --- a/compat/jansson/CMakeLists.txt +++ b/compat/jansson/CMakeLists.txt @@ -6,6 +6,8 @@ add_definitions(-DHAVE_CONFIG_H) # Add the lib sources. file(GLOB JANSSON_SRC *.c) +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os") + set(JANSSON_HDR_PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/hashtable.h ${CMAKE_CURRENT_SOURCE_DIR}/jansson_private.h diff --git a/compat/jansson/dump.c b/compat/jansson/dump.c index 6b1aabd45..a23fabb7c 100644 --- a/compat/jansson/dump.c +++ b/compat/jansson/dump.c @@ -9,13 +9,17 @@ #define _GNU_SOURCE #endif +#include "jansson_private.h" + #include #include #include #include +#ifdef HAVE_UNISTD_H +#include +#endif #include "jansson.h" -#include "jansson_private.h" #include "strbuffer.h" #include "utf.h" @@ -25,11 +29,28 @@ #define FLAGS_TO_INDENT(f) ((f) & 0x1F) #define FLAGS_TO_PRECISION(f) (((f) >> 11) & 0x1F) +struct buffer { + const size_t size; + size_t used; + char *data; +}; + static int dump_to_strbuffer(const char *buffer, size_t size, void *data) { return strbuffer_append_bytes((strbuffer_t *)data, buffer, size); } +static int dump_to_buffer(const char *buffer, size_t size, void *data) +{ + struct buffer *buf = (struct buffer *)data; + + if(buf->used + size <= buf->size) + memcpy(&buf->data[buf->used], buffer, size); + + buf->used += size; + return 0; +} + static int dump_to_file(const char *buffer, size_t size, void *data) { FILE *dest = (FILE *)data; @@ -38,6 +59,16 @@ static int dump_to_file(const char *buffer, size_t size, void *data) return 0; } +static int dump_to_fd(const char *buffer, size_t size, void *data) +{ + int *dest = (int *)data; +#ifdef HAVE_UNISTD_H + if(write(*dest, buffer, size) == (ssize_t)size) + return 0; +#endif + return -1; +} + /* 32 spaces (the maximum indentation size) */ static const char whitespace[] = " "; @@ -168,6 +199,10 @@ static int compare_keys(const void *key1, const void *key2) static int do_dump(const json_t *json, size_t flags, int depth, json_dump_callback_t dump, void *data) { + int embed = flags & JSON_EMBED; + + flags &= ~JSON_EMBED; + if(!json) return -1; @@ -227,11 +262,11 @@ static int do_dump(const json_t *json, size_t flags, int depth, n = json_array_size(json); - if(dump("[", 1, data)) + if(!embed && dump("[", 1, data)) goto array_error; if(n == 0) { array->visited = 0; - return dump("]", 1, data); + return embed ? 0 : dump("]", 1, data); } if(dump_indent(flags, depth + 1, 0, dump, data)) goto array_error; @@ -255,7 +290,7 @@ static int do_dump(const json_t *json, size_t flags, int depth, } array->visited = 0; - return dump("]", 1, data); + return embed ? 0 : dump("]", 1, data); array_error: array->visited = 0; @@ -286,11 +321,11 @@ static int do_dump(const json_t *json, size_t flags, int depth, iter = json_object_iter((json_t *)json); - if(dump("{", 1, data)) + if(!embed && dump("{", 1, data)) goto object_error; if(!iter) { object->visited = 0; - return dump("}", 1, data); + return embed ? 0 : dump("}", 1, data); } if(dump_indent(flags, depth + 1, 0, dump, data)) goto object_error; @@ -386,7 +421,7 @@ static int do_dump(const json_t *json, size_t flags, int depth, } object->visited = 0; - return dump("}", 1, data); + return embed ? 0 : dump("}", 1, data); object_error: object->visited = 0; @@ -416,11 +451,26 @@ char *json_dumps(const json_t *json, size_t flags) return result; } +size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags) +{ + struct buffer buf = { size, 0, buffer }; + + if(json_dump_callback(json, dump_to_buffer, (void *)&buf, flags)) + return 0; + + return buf.used; +} + int json_dumpf(const json_t *json, FILE *output, size_t flags) { return json_dump_callback(json, dump_to_file, (void *)output, flags); } +int json_dumpfd(const json_t *json, int output, size_t flags) +{ + return json_dump_callback(json, dump_to_fd, (void *)&output, flags); +} + int json_dump_file(const json_t *json, const char *path, size_t flags) { int result; diff --git a/compat/jansson/hashtable_seed.c b/compat/jansson/hashtable_seed.c index 751e0e326..8aed54068 100644 --- a/compat/jansson/hashtable_seed.c +++ b/compat/jansson/hashtable_seed.c @@ -168,12 +168,12 @@ static uint32_t generate_seed() { int done = 0; #if !defined(_WIN32) && defined(USE_URANDOM) - if (!done && seed_from_urandom(&seed) == 0) + if (seed_from_urandom(&seed) == 0) done = 1; #endif #if defined(_WIN32) && defined(USE_WINDOWS_CRYPTOAPI) - if (!done && seed_from_windows_cryptoapi(&seed) == 0) + if (seed_from_windows_cryptoapi(&seed) == 0) done = 1; #endif diff --git a/compat/jansson/jansson.h b/compat/jansson/jansson.h index 591f2a944..a5927bd63 100644 --- a/compat/jansson/jansson.h +++ b/compat/jansson/jansson.h @@ -21,11 +21,11 @@ extern "C" { /* version */ #define JANSSON_MAJOR_VERSION 2 -#define JANSSON_MINOR_VERSION 9 +#define JANSSON_MINOR_VERSION 10 #define JANSSON_MICRO_VERSION 0 /* Micro version is omitted if it's 0 */ -#define JANSSON_VERSION "2.9" +#define JANSSON_VERSION "2.10" /* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */ @@ -273,6 +273,7 @@ typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data); json_t *json_loads(const char *input, size_t flags, json_error_t *error); json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error); json_t *json_loadf(FILE *input, size_t flags, json_error_t *error); +json_t *json_loadfd(int input, size_t flags, json_error_t *error); json_t *json_load_file(const char *path, size_t flags, json_error_t *error); json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error); @@ -288,11 +289,14 @@ json_t *json_load_callback(json_load_callback_t callback, void *data, size_t fla #define JSON_ENCODE_ANY 0x200 #define JSON_ESCAPE_SLASH 0x400 #define JSON_REAL_PRECISION(n) (((n) & 0x1F) << 11) +#define JSON_EMBED 0x10000 typedef int (*json_dump_callback_t)(const char *buffer, size_t size, void *data); char *json_dumps(const json_t *json, size_t flags); +size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags); int json_dumpf(const json_t *json, FILE *output, size_t flags); +int json_dumpfd(const json_t *json, int output, size_t flags); int json_dump_file(const json_t *json, const char *path, size_t flags); int json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags); diff --git a/compat/jansson/jansson_private.h b/compat/jansson/jansson_private.h index 4a4927bb2..5ed961582 100644 --- a/compat/jansson/jansson_private.h +++ b/compat/jansson/jansson_private.h @@ -8,6 +8,7 @@ #ifndef JANSSON_PRIVATE_H #define JANSSON_PRIVATE_H +#include "jansson_private_config.h" #include #include "jansson.h" #include "hashtable.h" diff --git a/compat/jansson/load.c b/compat/jansson/load.c index 7a8f96ecb..c212489a1 100644 --- a/compat/jansson/load.c +++ b/compat/jansson/load.c @@ -9,15 +9,19 @@ #define _GNU_SOURCE #endif +#include "jansson_private.h" + #include #include #include #include #include #include +#ifdef HAVE_UNISTD_H +#include +#endif #include "jansson.h" -#include "jansson_private.h" #include "strbuffer.h" #include "utf.h" @@ -340,7 +344,7 @@ static void lex_scan_string(lex_t *lex, json_error_t *error) /* control character */ lex_unget_unsave(lex, c); if(c == '\n') - error_set(error, lex, "unexpected newline", c); + error_set(error, lex, "unexpected newline"); else error_set(error, lex, "control character 0x%x", c); goto out; @@ -914,7 +918,7 @@ static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error) typedef struct { const char *data; - int pos; + size_t pos; } string_data_t; static int string_get(void *data) @@ -1028,6 +1032,45 @@ json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) return result; } +static int fd_get_func(int *fd) +{ + uint8_t c; +#ifdef HAVE_UNISTD_H + if (read(*fd, &c, 1) == 1) + return c; +#endif + return EOF; +} + +json_t *json_loadfd(int input, size_t flags, json_error_t *error) +{ + lex_t lex; + const char *source; + json_t *result; + +#ifdef HAVE_UNISTD_H + if(input == STDIN_FILENO) + source = ""; + else +#endif + source = ""; + + jsonp_error_init(error, source); + + if (input < 0) { + error_set(error, NULL, "wrong arguments"); + return NULL; + } + + if(lex_init(&lex, (get_func)fd_get_func, flags, &input)) + return NULL; + + result = parse_json(&lex, flags, error); + + lex_close(&lex); + return result; +} + json_t *json_load_file(const char *path, size_t flags, json_error_t *error) { json_t *result; diff --git a/version.h b/version.h index 330d96975..a17b3301f 100644 --- a/version.h +++ b/version.h @@ -27,7 +27,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "Monero (XMR) CPU miner" -#define APP_VERSION "0.8.3" +#define APP_VERSION "0.8.3-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com" From 9dc02fc7f30ffb3815cd78a866e3cda18d7e7499 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 6 Jun 2017 03:34:49 +0300 Subject: [PATCH 2/7] Fix for `-a cryptonight-light`. --- options.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/options.c b/options.c index eb88bcb0f..5dabefbdf 100644 --- a/options.c +++ b/options.c @@ -175,14 +175,10 @@ static void parse_arg(int key, char *arg) { } # ifndef XMRIG_NO_AEON - if (i == ARRAY_SIZE(algo_names) && !strcmp(arg, "cryptonight-light")) { + if (i == ARRAY_SIZE(algo_names) - 1 && !strcmp(arg, "cryptonight-light")) { opt_algo = i = ALGO_CRYPTONIGHT_LITE; } # endif - - if (i == ARRAY_SIZE(algo_names)) { - show_usage_and_exit(1); - } } break; From 72569a7fc7820c4e354d7fd4c799889ba3ffabc5 Mon Sep 17 00:00:00 2001 From: xmrig Date: Sun, 2 Jul 2017 22:21:29 +0300 Subject: [PATCH 3/7] Update README.md --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8910c977b..83f3292ad 100644 --- a/README.md +++ b/README.md @@ -38,11 +38,16 @@ Based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of xmrig.exe -o xmr-eu.dwarfpool.com:8005 -u YOUR_WALLET -p x -k ``` +### Failover +``` +xmrig.exe -o pool.supportxmr.com:5555 -u YOUR_WALLET1 -k -o xmr-eu.dwarfpool.com:8005 -u YOUR_WALLET2 -p x -k +``` +For failover you can add multiple pools, maximum count not limited. + ### Options ``` -a, --algo=ALGO cryptonight (default) or cryptonight-lite -o, --url=URL URL of mining server - -b, --backup-url=URL URL of backup mining server -O, --userpass=U:P username:password pair for mining server -u, --user=USERNAME username for mining server -p, --pass=PASSWORD password for mining server From c16388ade30b26d383bcb9dd3d402e7e74221979 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 2 Jul 2017 23:35:06 +0300 Subject: [PATCH 4/7] Fix possibility crash --- src/net/Url.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/net/Url.cpp b/src/net/Url.cpp index 06e44aaae..82b788d9d 100644 --- a/src/net/Url.cpp +++ b/src/net/Url.cpp @@ -146,6 +146,10 @@ bool Url::setUserpass(const char *userpass) void Url::setPassword(const char *password) { + if (!password) { + return; + } + free(m_password); m_password = strdup(password); } @@ -153,6 +157,10 @@ void Url::setPassword(const char *password) void Url::setUser(const char *user) { + if (!user) { + return; + } + free(m_user); m_user = strdup(user); } From 32e7041def694245e41e6e651159861b7469e4f7 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 3 Jul 2017 03:34:23 +0300 Subject: [PATCH 5/7] Fix possibility duplicate share for short donation intervals. --- src/net/JobResult.h | 13 ++++++ src/workers/DoubleWorker.cpp | 86 ++++++++++++++++++++++++++++-------- src/workers/DoubleWorker.h | 11 +++-- src/workers/SingleWorker.cpp | 33 ++++++++++++-- src/workers/SingleWorker.h | 3 ++ 5 files changed, 119 insertions(+), 27 deletions(-) diff --git a/src/net/JobResult.h b/src/net/JobResult.h index 0279b8be4..9ced3cac8 100644 --- a/src/net/JobResult.h +++ b/src/net/JobResult.h @@ -29,6 +29,9 @@ #include +#include "Job.h" + + class JobResult { public: @@ -39,6 +42,16 @@ public: memcpy(this->result, result, sizeof(this->result)); } + + inline JobResult &operator=(const Job &job) { + memcpy(jobId, job.id(), sizeof(jobId)); + poolId = job.poolId(); + diff = job.diff(); + + return *this; + } + + char jobId[64]; int poolId; uint32_t diff; diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index 86dbd13db..1ce29760d 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -30,11 +30,33 @@ #include "workers/Workers.h" -DoubleWorker::DoubleWorker(Handle *handle) - : Worker(handle), - m_nonce1(0), - m_nonce2(0) +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; } @@ -56,17 +78,17 @@ void DoubleWorker::start() } m_count += 2; - *Job::nonce(m_blob) = ++m_nonce1; - *Job::nonce(m_blob + m_job.size()) = ++m_nonce2; + *Job::nonce(m_state->blob) = ++m_state->nonce1; + *Job::nonce(m_state->blob + m_state->job.size()) = ++m_state->nonce2; - CryptoNight::hash(m_blob, m_job.size(), m_hash, m_ctx); + CryptoNight::hash(m_state->blob, m_state->job.size(), m_hash, m_ctx); - if (*reinterpret_cast(m_hash + 24) < m_job.target()) { - Workers::submit(JobResult(m_job.poolId(), m_job.id(), m_nonce1, m_hash, m_job.diff())); + 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_job.target()) { - Workers::submit(JobResult(m_job.poolId(), m_job.id(), m_nonce2, m_hash + 32, m_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(); @@ -77,20 +99,46 @@ void DoubleWorker::start() } +bool DoubleWorker::resume(const Job &job) +{ + if (m_state->job.poolId() == -1 && job.poolId() >= 0 && memcmp(job.id(), m_pausedState->job.id(), 64) == 0) { + *m_state = *m_pausedState; + return true; + } + + return false; +} + + void DoubleWorker::consumeJob() { - m_job = Workers::job(); + Job job = Workers::job(); m_sequence = Workers::sequence(); - memcpy(m_blob, m_job.blob(), m_job.size()); - memcpy(m_blob + m_job.size(), m_job.blob(), m_job.size()); + save(job); - if (m_job.isNicehash()) { - m_nonce1 = (*Job::nonce(m_blob) & 0xff000000U) + (0xffffffU / (m_threads * 2) * m_id); - m_nonce2 = (*Job::nonce(m_blob + m_job.size()) & 0xff000000U) + (0xffffffU / (m_threads * 2) * (m_id + m_threads)); + 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_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)); } else { - m_nonce1 = 0xffffffffU / (m_threads * 2) * m_id; - m_nonce2 = 0xffffffffU / (m_threads * 2) * (m_id + m_threads); + m_state->nonce1 = 0xffffffffU / (m_threads * 2) * m_id; + m_state->nonce2 = 0xffffffffU / (m_threads * 2) * (m_id + m_threads); + } +} + + +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 index d062dac0c..711f4bd1c 100644 --- a/src/workers/DoubleWorker.h +++ b/src/workers/DoubleWorker.h @@ -38,17 +38,20 @@ class DoubleWorker : public Worker { public: DoubleWorker(Handle *handle); + ~DoubleWorker(); void start() override; private: + bool resume(const Job &job); void consumeJob(); + void save(const Job &job); + + class State; - Job m_job; - uint32_t m_nonce1; - uint32_t m_nonce2; uint8_t m_hash[64]; - uint8_t m_blob[84 * 2]; + State *m_state; + State *m_pausedState; }; diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index 68ff21b70..10931fb90 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -68,15 +68,32 @@ void SingleWorker::start() } +bool SingleWorker::resume(const Job &job) +{ + if (m_job.poolId() == -1 && job.poolId() >= 0 && memcmp(job.id(), m_paused.id(), 64) == 0) { + m_job = m_paused; + m_result = m_job; + m_result.nonce = *m_job.nonce(); + return true; + } + + return false; +} + void SingleWorker::consumeJob() { - m_job = Workers::job(); + Job job = Workers::job(); m_sequence = Workers::sequence(); - memcpy(m_result.jobId, m_job.id(), sizeof(m_result.jobId)); - m_result.poolId = m_job.poolId(); - m_result.diff = m_job.diff(); + save(job); + + if (resume(job)) { + return; + } + + m_job = std::move(job); + m_result = m_job; if (m_job.isNicehash()) { m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_threads * m_id); @@ -85,3 +102,11 @@ void SingleWorker::consumeJob() m_result.nonce = 0xffffffffU / m_threads * m_id; } } + + +void SingleWorker::save(const Job &job) +{ + if (job.poolId() == -1 && m_job.poolId() >= 0) { + m_paused = m_job; + } +} diff --git a/src/workers/SingleWorker.h b/src/workers/SingleWorker.h index 6ba59468a..08ab1857e 100644 --- a/src/workers/SingleWorker.h +++ b/src/workers/SingleWorker.h @@ -41,9 +41,12 @@ public: void start() override; private: + bool resume(const Job &job); void consumeJob(); + void save(const Job &job); Job m_job; + Job m_paused; JobResult m_result; }; From a96782218f588ab6fe4518b2fbe1453b934f9531 Mon Sep 17 00:00:00 2001 From: xmrig Date: Mon, 3 Jul 2017 07:24:56 +0300 Subject: [PATCH 6/7] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83f3292ad..d5d082835 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ XMRig is high performance Monero (XMR) CPU miner, with the official full Windows support. Based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of legacy code. - + #### Table of contents * [Features](#features) From 6ed2d61586e0a778096df7f951fbd73539128f6c Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 3 Jul 2017 11:02:32 +0300 Subject: [PATCH 7/7] Probably fix OS X support. --- src/Cpu_mac.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cpu_mac.cpp b/src/Cpu_mac.cpp index 3b6c44001..357e15efe 100644 --- a/src/Cpu_mac.cpp +++ b/src/Cpu_mac.cpp @@ -40,6 +40,6 @@ void Cpu::init() } -void Cpu::setAffinity(int id, unsigned long mask) +void Cpu::setAffinity(int id, uint64_t mask) { }