From 85f9bd97f14eaba2432d5012772949500eb30621 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 26 Apr 2018 23:27:53 +0700 Subject: [PATCH] Verify & send algorithm name. --- src/common/net/Client.cpp | 108 ++++++++++++++++++++++++++++-------- src/common/net/Client.h | 8 +++ src/common/net/Pool.cpp | 12 ++++ src/common/net/Pool.h | 1 + src/net/JobResult.h | 22 +------- src/workers/MultiWorker.cpp | 2 +- 6 files changed, 109 insertions(+), 44 deletions(-) diff --git a/src/common/net/Client.cpp b/src/common/net/Client.cpp index f141af66b..c53397a34 100644 --- a/src/common/net/Client.cpp +++ b/src/common/net/Client.cpp @@ -54,6 +54,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) : m_quiet(false), m_agent(agent), m_listener(listener), + m_extensions(0), m_id(id), m_retries(5), m_retryPause(5000), @@ -161,12 +162,14 @@ bool Client::disconnect() int64_t Client::submit(const JobResult &result) { + using namespace rapidjson; + # ifdef XMRIG_PROXY_PROJECT const char *nonce = result.nonce; const char *data = result.result; # else - char nonce[9]; - char data[65]; + char *nonce = m_sendBuf; + char *data = m_sendBuf + 16; Job::toHex(reinterpret_cast(&result.nonce), 4, nonce); nonce[8] = '\0'; @@ -175,8 +178,24 @@ int64_t Client::submit(const JobResult &result) data[64] = '\0'; # endif - const size_t size = snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRIu64 ",\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n", - m_sequence, m_rpcId.data(), result.jobId.data(), nonce, data); + Document doc(kObjectType); + auto &allocator = doc.GetAllocator(); + + doc.AddMember("id", m_sequence, allocator); + doc.AddMember("jsonrpc", "2.0", allocator); + doc.AddMember("method", "submit", allocator); + + Value params(kObjectType); + params.AddMember("id", StringRef(m_rpcId.data()), allocator); + params.AddMember("job_id", StringRef(result.jobId.data()), allocator); + params.AddMember("nonce", StringRef(nonce), allocator); + params.AddMember("result", StringRef(data), allocator); + + if (m_extensions & AlgoExt) { + params.AddMember("algo", StringRef(result.algorithm.shortName()), allocator); + } + + doc.AddMember("params", params, allocator); # ifdef XMRIG_PROXY_PROJECT m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id); @@ -184,7 +203,7 @@ int64_t Client::submit(const JobResult &result) m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff()); # endif - return send(size); + return send(doc); } @@ -258,6 +277,13 @@ bool Client::parseJob(const rapidjson::Value ¶ms, int *code) job.algorithm().parseVariant(params["variant"].GetInt()); } + if (!verifyAlgorithm(job.algorithm())) { + *code = 6; + + close(); + return false; + } + if (m_job != job) { m_jobs++; m_job = std::move(job); @@ -284,9 +310,7 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code) return false; } -# ifndef XMRIG_PROXY_PROJECT m_nicehash = m_pool.isNicehash(); -# endif if (result.HasMember("extensions")) { parseExtensions(result["extensions"]); @@ -299,6 +323,27 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code) } +bool Client::verifyAlgorithm(const xmrig::Algorithm &algorithm) const +{ + if (m_pool.isCompatible(algorithm)) { + return true; + } + + if (isQuiet()) { + return false; + } + + if (algorithm.isValid()) { + LOG_ERR("Incompatible algorithm \"%s\" detected, reconnect", algorithm.name()); + } + else { + LOG_ERR("Unknown/unsupported algorithm detected, reconnect"); + } + + return false; +} + + int Client::resolve(const char *host) { setState(HostLookupState); @@ -322,6 +367,27 @@ int Client::resolve(const char *host) } +int64_t Client::send(const rapidjson::Document &doc) +{ + using namespace rapidjson; + + StringBuffer buffer(0, 512); + Writer writer(buffer); + doc.Accept(writer); + + const size_t size = buffer.GetSize(); + if (size > (sizeof(m_buf) - 2)) { + return -1; + } + + memcpy(m_sendBuf, buffer.GetString(), size); + m_sendBuf[size] = '\n'; + m_sendBuf[size + 1] = '\0'; + + return send(size + 1); +} + + int64_t Client::send(size_t size) { LOG_DEBUG("[%s] send (%d bytes): \"%s\"", m_pool.url(), size, m_sendBuf); @@ -389,9 +455,7 @@ void Client::login() using namespace rapidjson; m_results.clear(); - Document doc; - doc.SetObject(); - + Document doc(kObjectType); auto &allocator = doc.GetAllocator(); doc.AddMember("id", 1, allocator); @@ -416,20 +480,7 @@ void Client::login() params.AddMember("algo", algo, allocator); doc.AddMember("params", params, allocator); - StringBuffer buffer(0, 512); - Writer writer(buffer); - doc.Accept(writer); - - const size_t size = buffer.GetSize(); - if (size > (sizeof(m_buf) - 2)) { - return; - } - - memcpy(m_sendBuf, buffer.GetString(), size); - m_sendBuf[size] = '\n'; - m_sendBuf[size + 1] = '\0'; - - send(size + 1); + send(doc); } @@ -486,6 +537,8 @@ void Client::parse(char *line, size_t len) void Client::parseExtensions(const rapidjson::Value &value) { + m_extensions = 0; + if (!value.IsArray()) { return; } @@ -495,8 +548,15 @@ void Client::parseExtensions(const rapidjson::Value &value) continue; } + if (strcmp(ext.GetString(), "algo") == 0) { + m_extensions |= AlgoExt; + continue; + } + if (strcmp(ext.GetString(), "nicehash") == 0) { + m_extensions |= NicehashExt; m_nicehash = true; + continue; } } } diff --git a/src/common/net/Client.h b/src/common/net/Client.h index 97bf16a53..27273092c 100644 --- a/src/common/net/Client.h +++ b/src/common/net/Client.h @@ -78,11 +78,18 @@ public: inline void setRetryPause(int ms) { m_retryPause = ms; } private: + enum Extensions { + NicehashExt = 1, + AlgoExt = 2 + }; + bool close(); bool isCriticalError(const char *message); bool parseJob(const rapidjson::Value ¶ms, int *code); bool parseLogin(const rapidjson::Value &result, int *code); + bool verifyAlgorithm(const xmrig::Algorithm &algorithm) const; int resolve(const char *host); + int64_t send(const rapidjson::Document &doc); int64_t send(size_t size); void connect(const std::vector &ipv4, const std::vector &ipv6); void connect(sockaddr *addr); @@ -116,6 +123,7 @@ private: char m_sendBuf[768]; const char *m_agent; IClientListener *m_listener; + int m_extensions; int m_id; int m_retries; int m_retryPause; diff --git a/src/common/net/Pool.cpp b/src/common/net/Pool.cpp index aa1fa651d..ab3bdea75 100644 --- a/src/common/net/Pool.cpp +++ b/src/common/net/Pool.cpp @@ -92,6 +92,18 @@ Pool::Pool(const char *host, uint16_t port, const char *user, const char *passwo } +bool Pool::isCompatible(const xmrig::Algorithm &algorithm) const +{ + for (const auto &a : m_algorithms) { + if (algorithm == a) { + return true; + } + } + + return false; +} + + bool Pool::isEqual(const Pool &other) const { return (m_nicehash == other.m_nicehash diff --git a/src/common/net/Pool.h b/src/common/net/Pool.h index eb926b3b2..5475e10d3 100644 --- a/src/common/net/Pool.h +++ b/src/common/net/Pool.h @@ -72,6 +72,7 @@ public: inline bool operator!=(const Pool &other) const { return !isEqual(other); } inline bool operator==(const Pool &other) const { return isEqual(other); } + bool isCompatible(const xmrig::Algorithm &algorithm) const; bool isEqual(const Pool &other) const; bool parse(const char *url); bool setUserpass(const char *userpass); diff --git a/src/net/JobResult.h b/src/net/JobResult.h index 68afc8621..4a920ca08 100644 --- a/src/net/JobResult.h +++ b/src/net/JobResult.h @@ -36,34 +36,17 @@ class JobResult { public: inline JobResult() : poolId(0), diff(0), nonce(0) {} - inline JobResult(int poolId, const xmrig::Id &jobId, uint32_t nonce, const uint8_t *result, uint32_t diff) : + inline JobResult(int poolId, const xmrig::Id &jobId, uint32_t nonce, const uint8_t *result, uint32_t diff, const xmrig::Algorithm &algorithm) : poolId(poolId), diff(diff), nonce(nonce), + algorithm(algorithm), jobId(jobId) { memcpy(this->result, result, sizeof(this->result)); } - inline JobResult(const Job &job) : poolId(0), diff(0), nonce(0) - { - jobId = job.id(); - poolId = job.poolId(); - diff = job.diff(); - nonce = *job.nonce(); - } - - - inline JobResult &operator=(const Job &job) { - jobId = job.id(); - poolId = job.poolId(); - diff = job.diff(); - - return *this; - } - - inline uint64_t actualDiff() const { return Job::toDiff(reinterpret_cast(result)[3]); @@ -74,6 +57,7 @@ public: uint32_t diff; uint32_t nonce; uint8_t result[32]; + xmrig::Algorithm algorithm; xmrig::Id jobId; }; diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index b3b384f69..d4d5992cf 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -108,7 +108,7 @@ void MultiWorker::start() for (size_t i = 0; i < N; ++i) { if (*reinterpret_cast(m_hash + (i * 32) + 24) < m_state.job.target()) { - Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash + (i * 32), m_state.job.diff())); + Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash + (i * 32), m_state.job.diff(), m_state.job.algorithm())); } *nonce(i) += 1;