From a3b303e885acbf79240c200e92659674a30720ec Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 14 Apr 2019 03:21:23 +0700 Subject: [PATCH] Added checking for top_block_hash/hash. --- src/base/net/stratum/DaemonClient.cpp | 49 ++++++++++++++++++++++----- src/base/net/stratum/DaemonClient.h | 3 ++ 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index b4492e7e3..769e2116f 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -50,8 +50,21 @@ #endif +namespace xmrig { + +static const char *kBlocktemplateBlob = "blocktemplate_blob"; +static const char *kGetHeight = "/getheight"; +static const char *kGetInfo = "/getinfo"; +static const char *kHash = "hash"; +static const char *kHeight = "height"; +static const char *kJsonRPC = "/json_rpc"; + +} + + xmrig::DaemonClient::DaemonClient(int id, IClientListener *listener) : - BaseClient(id, listener) + BaseClient(id, listener), + m_monero(true) { m_timer = new Timer(this); } @@ -109,7 +122,7 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result) m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff()); # endif - send(HTTP_POST, "/json_rpc", doc); + send(HTTP_POST, kJsonRPC, doc); return m_sequence++; } @@ -155,8 +168,19 @@ void xmrig::DaemonClient::onHttpData(const HttpData &data) return retry(); } - if (data.method == HTTP_GET && data.url == "/getheight") { - if (m_job.height() != Json::getUint64(doc, "height")) { + if (data.method == HTTP_GET) { + if (data.url == kGetHeight) { + if (!doc.HasMember(kHash)) { + m_monero = false; + + return send(HTTP_GET, kGetInfo); + } + + if (isOutdated(Json::getUint64(doc, kHeight), Json::getString(doc, kHash))) { + getBlockTemplate(); + } + } + else if (data.url == kGetInfo && isOutdated(Json::getUint64(doc, kHeight), Json::getString(doc, "top_block_hash"))) { getBlockTemplate(); } @@ -175,27 +199,34 @@ void xmrig::DaemonClient::onTimer(const Timer *) getBlockTemplate(); } else if (m_state == ConnectedState) { - send(HTTP_GET, "/getheight"); + send(HTTP_GET, m_monero ? kGetHeight : kGetInfo); } } +bool xmrig::DaemonClient::isOutdated(uint64_t height, const char *hash) const +{ + return m_job.height() != height || m_prevHash != hash; +} + + bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code) { Job job(m_id, false, m_pool.algorithm(), String()); - String blocktemplate = Json::getString(params, "blocktemplate_blob"); + String blocktemplate = Json::getString(params, kBlocktemplateBlob); if (blocktemplate.isNull() || !job.setBlob(Json::getString(params, "blockhashing_blob"))) { *code = 4; return false; } - job.setHeight(Json::getUint64(params, "height")); + job.setHeight(Json::getUint64(params, kHeight)); job.setDiff(Json::getUint64(params, "difficulty")); job.setId(blocktemplate.data() + blocktemplate.size() - 32); m_job = std::move(job); m_blocktemplate = std::move(blocktemplate); + m_prevHash = Json::getString(params, "prev_hash"); if (m_state == ConnectingState) { setState(ConnectedState); @@ -227,7 +258,7 @@ bool xmrig::DaemonClient::parseResponse(int64_t id, const rapidjson::Value &resu } int code = -1; - if (result.HasMember("blocktemplate_blob") && parseJob(result, &code)) { + if (result.HasMember(kBlocktemplateBlob) && parseJob(result, &code)) { return true; } @@ -253,7 +284,7 @@ int64_t xmrig::DaemonClient::getBlockTemplate() JsonRequest::create(doc, m_sequence, "getblocktemplate", params); - send(HTTP_POST, "/json_rpc", doc); + send(HTTP_POST, kJsonRPC, doc); return m_sequence++; } diff --git a/src/base/net/stratum/DaemonClient.h b/src/base/net/stratum/DaemonClient.h index f9438f676..00b62e39a 100644 --- a/src/base/net/stratum/DaemonClient.h +++ b/src/base/net/stratum/DaemonClient.h @@ -59,6 +59,7 @@ protected: inline void tick(uint64_t) override {} private: + bool isOutdated(uint64_t height, const char *hash) const; bool parseJob(const rapidjson::Value ¶ms, int *code); bool parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error); int64_t getBlockTemplate(); @@ -67,7 +68,9 @@ private: void send(int method, const char *url, const rapidjson::Document &doc); void setState(SocketState state); + bool m_monero; String m_blocktemplate; + String m_prevHash; String m_tlsFingerprint; String m_tlsVersion; Timer *m_timer;