From 75f18c9b316a28ee980ad3f6306738bbbe41964c Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 20 Nov 2020 08:15:04 +0700 Subject: [PATCH] Use static RandomX seed for benchmark. --- src/backend/common/benchmark/BenchState.cpp | 2 +- .../common/interfaces/IBenchListener.h | 2 +- src/backend/cpu/CpuWorker.cpp | 4 + .../net/stratum/benchmark/BenchClient.cpp | 216 +++++++++++------- src/base/net/stratum/benchmark/BenchClient.h | 23 +- src/net/Network.cpp | 19 +- 6 files changed, 162 insertions(+), 104 deletions(-) diff --git a/src/backend/common/benchmark/BenchState.cpp b/src/backend/common/benchmark/BenchState.cpp index 38edf688..4fd5df82 100644 --- a/src/backend/common/benchmark/BenchState.cpp +++ b/src/backend/common/benchmark/BenchState.cpp @@ -82,7 +82,7 @@ uint64_t xmrig::BenchState::start(size_t threads, const IBackend *backend) }); const uint64_t ts = Chrono::steadyMSecs(); - m_listener->onBenchStart(ts, remaining, backend); + m_listener->onBenchReady(ts, remaining, backend); return ts; } diff --git a/src/backend/common/interfaces/IBenchListener.h b/src/backend/common/interfaces/IBenchListener.h index 91ec2e38..fe122df8 100644 --- a/src/backend/common/interfaces/IBenchListener.h +++ b/src/backend/common/interfaces/IBenchListener.h @@ -38,7 +38,7 @@ public: virtual ~IBenchListener() = default; virtual void onBenchDone(uint64_t result, uint64_t diff, uint64_t ts) = 0; - virtual void onBenchStart(uint64_t ts, uint32_t threads, const IBackend *backend) = 0; + virtual void onBenchReady(uint64_t ts, uint32_t threads, const IBackend *backend) = 0; }; diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index afc47766..d61e8038 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -397,6 +397,10 @@ void xmrig::CpuWorker::consumeJob() m_job.add(m_miner->job(), m_benchSize ? 1 : kReserveCount, Nonce::CPU); +# ifdef XMRIG_FEATURE_BENCHMARK + m_benchData = 0; +# endif + # ifdef XMRIG_ALGO_RANDOMX if (m_job.currentJob().algorithm().family() == Algorithm::RANDOM_X) { allocateRandomX_VM(); diff --git a/src/base/net/stratum/benchmark/BenchClient.cpp b/src/base/net/stratum/benchmark/BenchClient.cpp index 831ecea6..71d6a183 100644 --- a/src/base/net/stratum/benchmark/BenchClient.cpp +++ b/src/base/net/stratum/benchmark/BenchClient.cpp @@ -46,6 +46,10 @@ xmrig::BenchClient::BenchClient(const std::shared_ptr &benchmark, I m_job.setAlgorithm(m_benchmark->algorithm()); m_job.setDiff(std::numeric_limits::max()); m_job.setHeight(1); + m_job.setId("00000000"); + + blob[Job::kMaxSeedSize * 2] = '\0'; + m_job.setSeedHash(blob.data()); BenchState::setListener(this); BenchState::setSize(m_benchmark->size()); @@ -66,16 +70,11 @@ xmrig::BenchClient::BenchClient(const std::shared_ptr &benchmark, I } # endif - m_job.setId("00000000"); - - if (m_hash && m_job.setSeedHash(m_benchmark->seed())) { + if (m_hash && setSeed(m_benchmark->seed())) { m_mode = STATIC_VERIFY; return; } - - blob[Job::kMaxSeedSize * 2] = '\0'; - m_job.setSeedHash(blob.data()); } @@ -111,26 +110,20 @@ void xmrig::BenchClient::setPool(const Pool &pool) void xmrig::BenchClient::onBenchDone(uint64_t result, uint64_t diff, uint64_t ts) { + m_result = result; + m_diff = diff; + m_doneTime = ts; + # ifdef XMRIG_FEATURE_HTTP if (!m_token.isEmpty()) { - m_doneTime = ts; - - rapidjson::Document doc(rapidjson::kObjectType); - auto &allocator = doc.GetAllocator(); - - doc.AddMember("steady_done_ts", m_doneTime, allocator); - doc.AddMember("hash", rapidjson::Value(fmt::format("{:016X}", result).c_str(), allocator), allocator); - doc.AddMember("diff", diff, allocator); - doc.AddMember("backend", m_backend->toJSON(doc), allocator); - - update(doc); + send(DONE_BENCH); } # endif const uint64_t ref = referenceHash(); const char *color = ref ? ((result == ref) ? GREEN_BOLD_S : RED_BOLD_S) : BLACK_BOLD_S; - LOG_NOTICE("%s " WHITE_BOLD("benchmark finished in ") CYAN_BOLD("%.3f seconds") WHITE_BOLD_S " hash sum = " CLEAR "%s%016" PRIX64 CLEAR, tag(), static_cast(ts - m_startTime) / 1000.0, color, result); + LOG_NOTICE("%s " WHITE_BOLD("benchmark finished in ") CYAN_BOLD("%.3f seconds") WHITE_BOLD_S " hash sum = " CLEAR "%s%016" PRIX64 CLEAR, tag(), static_cast(ts - m_readyTime) / 1000.0, color, result); if (m_token.isEmpty()) { printExit(); @@ -138,21 +131,15 @@ void xmrig::BenchClient::onBenchDone(uint64_t result, uint64_t diff, uint64_t ts } -void xmrig::BenchClient::onBenchStart(uint64_t ts, uint32_t threads, const IBackend *backend) +void xmrig::BenchClient::onBenchReady(uint64_t ts, uint32_t threads, const IBackend *backend) { - m_startTime = ts; + m_readyTime = ts; m_threads = threads; m_backend = backend; # ifdef XMRIG_FEATURE_HTTP if (m_mode == ONLINE_BENCH) { - rapidjson::Document doc(rapidjson::kObjectType); - auto &allocator = doc.GetAllocator(); - - doc.AddMember("threads", threads, allocator); - doc.AddMember("steady_start_ts", m_startTime, allocator); - - update(doc); + send(CREATE_BENCH); } # endif } @@ -173,22 +160,18 @@ void xmrig::BenchClient::onHttpData(const HttpData &data) return setError(data.statusName()); } - if (m_doneTime) { - LOG_NOTICE("%s " WHITE_BOLD("benchmark submitted ") CYAN_BOLD("https://xmrig.com/benchmark/%s"), tag(), m_job.id().data()); - printExit(); + switch (m_request) { + case GET_BENCH: + return onGetReply(doc); - return; - } + case CREATE_BENCH: + return onCreateReply(doc); - if (m_startTime) { - return; - } + case DONE_BENCH: + return onDoneReply(doc); - if (m_mode == ONLINE_BENCH) { - startBench(doc); - } - else { - startVerify(doc); + default: + break; } # endif } @@ -207,15 +190,41 @@ void xmrig::BenchClient::onResolved(const Dns &dns, int status) m_httpListener = std::make_shared(this, tag()); if (m_mode == ONLINE_BENCH) { - createBench(); + start(); } else { - getBench(); + send(GET_BENCH); } # endif } +bool xmrig::BenchClient::setSeed(const char *seed) +{ + if (!seed) { + return false; + } + + size_t size = strlen(seed); + if (size % 2 != 0) { + return false; + } + + size /= 2; + if (size < 4 || size >= m_job.size()) { + return false; + } + + if (!Buffer::fromHex(seed, size * 2, m_job.blob())) { + return false; + } + + LOG_NOTICE("%s " WHITE_BOLD("seed ") BLACK_BOLD("%s"), tag(), seed); + + return true; +} + + uint64_t xmrig::BenchClient::referenceHash() const { if (m_hash || m_mode == ONLINE_BENCH) { @@ -234,6 +243,14 @@ void xmrig::BenchClient::printExit() void xmrig::BenchClient::start() { + const uint32_t size = BenchState::size(); + + LOG_NOTICE("%s " MAGENTA_BOLD("start benchmark ") "hashes " CYAN_BOLD("%u%s") " algo " WHITE_BOLD("%s"), + tag(), + size < 1000000 ? size / 1000 : size / 1000000, + size < 1000000 ? "K" : "M", + m_job.algorithm().shortName()); + m_listener->onLoginSuccess(this); m_listener->onJobReceived(this, m_job, rapidjson::Value()); } @@ -241,27 +258,40 @@ void xmrig::BenchClient::start() #ifdef XMRIG_FEATURE_HTTP -void xmrig::BenchClient::createBench() +void xmrig::BenchClient::onCreateReply(const rapidjson::Value &value) { - using namespace rapidjson; + m_startTime = Chrono::steadyMSecs(); + m_token = Json::getString(value, BenchConfig::kToken); - Document doc(kObjectType); - auto &allocator = doc.GetAllocator(); + m_job.setId(Json::getString(value, BenchConfig::kId)); + setSeed(Json::getString(value, BenchConfig::kSeed)); - doc.AddMember(StringRef(BenchConfig::kSize), m_benchmark->size(), allocator); - doc.AddMember(StringRef(BenchConfig::kAlgo), m_benchmark->algorithm().toJSON(), allocator); - doc.AddMember("version", APP_VERSION, allocator); - doc.AddMember("cpu", Cpu::toJSON(doc), allocator); + m_listener->onJobReceived(this, m_job, rapidjson::Value()); - FetchRequest req(HTTP_POST, m_ip, BenchConfig::kApiPort, "/1/benchmark", doc, BenchConfig::kApiTLS, true); - fetch(std::move(req), m_httpListener); + send(START_BENCH); } -void xmrig::BenchClient::getBench() +void xmrig::BenchClient::onDoneReply(const rapidjson::Value &) { - FetchRequest req(HTTP_GET, m_ip, BenchConfig::kApiPort, fmt::format("/1/benchmark/{}", m_job.id()).c_str(), BenchConfig::kApiTLS, true); - fetch(std::move(req), m_httpListener); + LOG_NOTICE("%s " WHITE_BOLD("benchmark submitted ") CYAN_BOLD("https://xmrig.com/benchmark/%s"), tag(), m_job.id().data()); + printExit(); +} + + +void xmrig::BenchClient::onGetReply(const rapidjson::Value &value) +{ + const char *hash = Json::getString(value, BenchConfig::kHash); + if (hash) { + m_hash = strtoull(hash, nullptr, 16); + } + + m_job.setAlgorithm(Json::getString(value, BenchConfig::kAlgo)); + setSeed(Json::getString(value, BenchConfig::kSeed)); + + BenchState::setSize(Json::getUint(value, BenchConfig::kSize)); + + start(); } @@ -275,6 +305,55 @@ void xmrig::BenchClient::resolve() } +void xmrig::BenchClient::send(Request request) +{ + using namespace rapidjson; + + Document doc(kObjectType); + auto &allocator = doc.GetAllocator(); + m_request = request; + + switch (m_request) { + case GET_BENCH: + { + FetchRequest req(HTTP_GET, m_ip, BenchConfig::kApiPort, fmt::format("/1/benchmark/{}", m_job.id()).c_str(), BenchConfig::kApiTLS, true); + fetch(std::move(req), m_httpListener); + } + break; + + case CREATE_BENCH: + { + doc.AddMember(StringRef(BenchConfig::kSize), m_benchmark->size(), allocator); + doc.AddMember(StringRef(BenchConfig::kAlgo), m_benchmark->algorithm().toJSON(), allocator); + doc.AddMember("version", APP_VERSION, allocator); + doc.AddMember("threads", m_threads, allocator); + doc.AddMember("steady_ready_ts", m_readyTime, allocator); + doc.AddMember("cpu", Cpu::toJSON(doc), allocator); + + FetchRequest req(HTTP_POST, m_ip, BenchConfig::kApiPort, "/1/benchmark", doc, BenchConfig::kApiTLS, true); + fetch(std::move(req), m_httpListener); + } + break; + + case START_BENCH: + doc.AddMember("steady_start_ts", m_startTime, allocator); + update(doc); + break; + + case DONE_BENCH: + doc.AddMember("steady_done_ts", m_doneTime, allocator); + doc.AddMember("hash", Value(fmt::format("{:016X}", m_result).c_str(), allocator), allocator); + doc.AddMember("diff", m_diff, allocator); + doc.AddMember("backend", m_backend->toJSON(doc), allocator); + update(doc); + break; + + case NO_REQUEST: + break; + } +} + + void xmrig::BenchClient::setError(const char *message, const char *label) { LOG_ERR("%s " RED("%s: ") RED_BOLD("\"%s\""), tag(), label ? label : "benchmark failed", message); @@ -284,33 +363,6 @@ void xmrig::BenchClient::setError(const char *message, const char *label) } -void xmrig::BenchClient::startBench(const rapidjson::Value &value) -{ - m_job.setId(Json::getString(value, BenchConfig::kId)); - m_job.setSeedHash(Json::getString(value, BenchConfig::kSeed)); - - m_token = Json::getString(value, BenchConfig::kToken); - - start(); -} - - -void xmrig::BenchClient::startVerify(const rapidjson::Value &value) -{ - const char *hash = Json::getString(value, BenchConfig::kHash); - if (hash) { - m_hash = strtoull(hash, nullptr, 16); - } - - m_job.setAlgorithm(Json::getString(value, BenchConfig::kAlgo)); - m_job.setSeedHash(Json::getString(value, BenchConfig::kSeed)); - - BenchState::setSize(Json::getUint(value, BenchConfig::kSize)); - - start(); -} - - void xmrig::BenchClient::update(const rapidjson::Value &body) { assert(!m_token.isEmpty()); diff --git a/src/base/net/stratum/benchmark/BenchClient.h b/src/base/net/stratum/benchmark/BenchClient.h index 65b9d05f..018bceaa 100644 --- a/src/base/net/stratum/benchmark/BenchClient.h +++ b/src/base/net/stratum/benchmark/BenchClient.h @@ -68,7 +68,7 @@ public: protected: void onBenchDone(uint64_t result, uint64_t diff, uint64_t ts) override; - void onBenchStart(uint64_t ts, uint32_t threads, const IBackend *backend) override; + void onBenchReady(uint64_t ts, uint32_t threads, const IBackend *backend) override; void onHttpData(const HttpData &data) override; void onResolved(const Dns &dns, int status) override; @@ -80,17 +80,26 @@ private: ONLINE_VERIFY }; + enum Request : uint32_t { + NO_REQUEST, + GET_BENCH, + CREATE_BENCH, + START_BENCH, + DONE_BENCH + }; + + bool setSeed(const char *seed); uint64_t referenceHash() const; void printExit(); void start(); # ifdef XMRIG_FEATURE_HTTP - void createBench(); - void getBench(); + void onCreateReply(const rapidjson::Value &value); + void onDoneReply(const rapidjson::Value &value); + void onGetReply(const rapidjson::Value &value); void resolve(); + void send(Request request); void setError(const char *message, const char *label = nullptr); - void startBench(const rapidjson::Value &value); - void startVerify(const rapidjson::Value &value); void update(const rapidjson::Value &body); # endif @@ -99,14 +108,18 @@ private: Job m_job; Mode m_mode = STATIC_BENCH; Pool m_pool; + Request m_request = NO_REQUEST; std::shared_ptr m_benchmark; std::shared_ptr m_dns; std::shared_ptr m_httpListener; String m_ip; String m_token; uint32_t m_threads = 0; + uint64_t m_diff = 0; uint64_t m_doneTime = 0; uint64_t m_hash = 0; + uint64_t m_readyTime = 0; + uint64_t m_result = 0; uint64_t m_startTime = 0; }; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 3715244a..fb8b21b3 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -265,24 +265,13 @@ void xmrig::Network::onRequest(IApiRequest &request) void xmrig::Network::setJob(IClient *client, const Job &job, bool donate) { - uint64_t diff = job.diff();; - const char *scale = NetworkState::scaleDiff(diff); - # ifdef XMRIG_FEATURE_BENCHMARK - const uint32_t size = BenchState::size(); - if (size) { - LOG_NOTICE("%s " MAGENTA_BOLD("start benchmark ") "hashes " CYAN_BOLD("%u%s") " algo " WHITE_BOLD("%s") " print_time " CYAN_BOLD("%us"), - Tags::bench(), - size < 1000000 ? size / 1000 : size / 1000000, - size < 1000000 ? "K" : "M", - job.algorithm().shortName(), - m_controller->config()->printTime()); - - LOG_NOTICE("%s " WHITE_BOLD("seed ") BLACK_BOLD("%s"), Tags::bench(), job.seed().toHex().data()); - } - else + if (!BenchState::size()) # endif { + uint64_t diff = job.diff();; + const char *scale = NetworkState::scaleDiff(diff); + LOG_INFO("%s " MAGENTA_BOLD("new job") " from " WHITE_BOLD("%s:%d") " diff " WHITE_BOLD("%" PRIu64 "%s") " algo " WHITE_BOLD("%s") " height " WHITE_BOLD("%" PRIu64), Tags::network(), client->pool().host().data(), client->pool().port(), diff, scale, job.algorithm().shortName(), job.height()); }