Implemented BenchClient.

This commit is contained in:
XMRig 2020-10-24 19:43:23 +07:00
parent 36c1cb23e0
commit 79c96418c7
No known key found for this signature in database
GPG key ID: 446A53638BE94409
9 changed files with 200 additions and 18 deletions

View file

@ -44,6 +44,7 @@ xmrig::Benchmark::Benchmark(const Job &job, size_t workers, const IBackend *back
m_algo(job.algorithm()),
m_backend(backend),
m_workers(workers),
m_id(job.id()),
m_token(job.benchToken()),
m_end(job.benchSize()),
m_hash(job.benchHash())
@ -116,6 +117,10 @@ uint64_t xmrig::Benchmark::referenceHash() const
return m_hash;
}
if (!m_token.isEmpty()) {
return 0;
}
const uint32_t N = (m_end / 1000000) - 1;
if (((m_algo == Algorithm::RX_0) || (m_algo == Algorithm::RX_WOW)) && ((m_end % 1000000) == 0) && (N < 10)) {
return hashCheck[(m_algo == Algorithm::RX_0) ? 0 : 1][N];

View file

@ -53,6 +53,7 @@ private:
const Algorithm m_algo;
const IBackend *m_backend;
const size_t m_workers;
const String m_id;
const String m_token;
const uint64_t m_end;
const uint64_t m_hash;

View file

@ -346,7 +346,13 @@ void xmrig::CpuBackend::setJob(const Job &job)
const auto &cpu = d_ptr->controller->config()->cpu();
std::vector<CpuLaunchData> threads = cpu.get(d_ptr->controller->miner(), job.algorithm(), d_ptr->controller->config()->pools().benchSize());
# ifdef XMRIG_FEATURE_BENCHMARK
uint32_t benchSize = job.benchSize();
# else
constexpr uint32_t benchSize = 0;
# endif
auto threads = cpu.get(d_ptr->controller->miner(), job.algorithm(), benchSize);
if (!d_ptr->threads.empty() && d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) {
return;
}
@ -363,7 +369,7 @@ void xmrig::CpuBackend::setJob(const Job &job)
stop();
# ifdef XMRIG_FEATURE_BENCHMARK
if (job.benchSize()) {
if (benchSize) {
d_ptr->benchmark = std::make_shared<Benchmark>(job, threads.size(), this);
}
# endif

View file

@ -1,6 +1,7 @@
/* XMRig
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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
@ -18,6 +19,14 @@
#include "base/net/http/HttpData.h"
#include "3rdparty/http-parser/http_parser.h"
#include "3rdparty/rapidjson/document.h"
#include "3rdparty/rapidjson/error/en.h"
#include "base/io/json/Json.h"
#include <uv.h>
#include <stdexcept>
namespace xmrig {
@ -42,3 +51,46 @@ bool xmrig::HttpData::isJSON() const
return type == kApplicationJson || type == kTextPlain;
}
const char *xmrig::HttpData::methodName() const
{
return http_method_str(static_cast<http_method>(method));
}
const char *xmrig::HttpData::statusName() const
{
if (status < 0) {
return uv_strerror(status);
}
return http_status_str(static_cast<http_status>(status));
}
rapidjson::Document xmrig::HttpData::json() const
{
if (status < 0) {
throw std::runtime_error(statusName());
}
if (!isJSON()) {
throw std::runtime_error("the response is not a valid JSON response");
}
using namespace rapidjson;
Document doc;
if (doc.Parse(body.c_str()).HasParseError()) {
throw std::runtime_error(GetParseError_En(doc.GetParseError()));
}
if (doc.IsObject() && !doc.ObjectEmpty()) {
const char *error = Json::getString(doc, "error");
if (error) {
throw std::runtime_error(error);
}
}
return doc;
}

View file

@ -1,13 +1,7 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright (c) 2014-2019 heapwolf <https://github.com/heapwolf>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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
@ -28,6 +22,7 @@
#define XMRIG_HTTPDATA_H
#include "3rdparty/rapidjson/document.h"
#include "base/tools/Object.h"
@ -63,6 +58,9 @@ public:
virtual void write(std::string &&data, bool close) = 0;
bool isJSON() const;
const char *methodName() const;
const char *statusName() const;
rapidjson::Document json() const;
int method = 0;
int status = 0;
@ -70,6 +68,7 @@ public:
std::map<const std::string, const std::string> headers;
std::string body;
std::string url;
uint64_t rpcId = 0;
private:
const uint64_t m_id;

View file

@ -18,16 +18,22 @@
#include "base/net/stratum/benchmark/BenchClient.h"
#include "3rdparty/rapidjson/document.h"
#include "base/io/json/Json.h"
#include "base/io/log/Log.h"
#include "base/io/log/Tags.h"
#include "base/kernel/interfaces/IClientListener.h"
#include "base/net/http/Fetch.h"
#include "base/net/http/HttpData.h"
#include "base/net/http/HttpListener.h"
#include "base/net/stratum/benchmark/BenchConfig.h"
#include "version.h"
xmrig::BenchClient::BenchClient(const std::shared_ptr<BenchConfig> &benchmark, IClientListener* listener) :
m_listener(listener),
m_benchmark(benchmark)
{
m_httpListener = std::make_shared<HttpListener>(this);
m_httpListener = std::make_shared<HttpListener>(this, Tags::bench());
std::vector<char> blob(112 * 2 + 1, '0');
blob.back() = '\0';
@ -66,10 +72,17 @@ xmrig::BenchClient::BenchClient(const std::shared_ptr<BenchConfig> &benchmark, I
void xmrig::BenchClient::connect()
{
if (m_mode == STATIC_BENCH || m_mode == STATIC_VERIFY) {
m_listener->onLoginSuccess(this);
m_listener->onJobReceived(this, m_job, rapidjson::Value());
{
switch (m_mode) {
case STATIC_BENCH:
case STATIC_VERIFY:
return start();
case ONLINE_BENCH:
return createBench();
case ONLINE_VERIFY:
return getBench();
}
}
@ -82,4 +95,85 @@ void xmrig::BenchClient::setPool(const Pool &pool)
void xmrig::BenchClient::onHttpData(const HttpData &data)
{
rapidjson::Document doc;
try {
doc = data.json();
} catch (const std::exception &ex) {
return setError(ex.what());
}
if (data.status != 200) {
return setError(data.statusName());
}
if (m_mode == ONLINE_BENCH) {
startBench(doc);
}
else {
startVerify(doc);
}
}
void xmrig::BenchClient::createBench()
{
using namespace rapidjson;
Document doc(kObjectType);
auto &allocator = doc.GetAllocator();
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);
FetchRequest req(HTTP_POST, BenchConfig::kApiHost, BenchConfig::kApiPort, "/1/benchmark", doc, BenchConfig::kApiTLS, true);
fetch(std::move(req), m_httpListener);
}
void xmrig::BenchClient::getBench()
{
const auto path = std::string("/1/benchmark/") + m_job.id().data();
FetchRequest req(HTTP_GET, BenchConfig::kApiHost, BenchConfig::kApiPort, path.c_str(), BenchConfig::kApiTLS, true);
fetch(std::move(req), m_httpListener);
}
void xmrig::BenchClient::setError(const char *message)
{
LOG_ERR("%s " RED("benchmark failed ") RED_BOLD("\"%s\""), Tags::bench(), message);
}
void xmrig::BenchClient::start()
{
m_listener->onLoginSuccess(this);
m_listener->onJobReceived(this, m_job, rapidjson::Value());
}
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_job.setBenchToken(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_job.setBenchHash(strtoull(hash, nullptr, 16));
}
m_job.setAlgorithm(Json::getString(value, BenchConfig::kAlgo));
m_job.setSeedHash(Json::getString(value, BenchConfig::kSeed));
m_job.setBenchSize(Json::getUint(value, BenchConfig::kSize));
start();
}

View file

@ -75,6 +75,13 @@ private:
ONLINE_VERIFY
};
void createBench();
void getBench();
void setError(const char *message);
void start();
void startBench(const rapidjson::Value &value);
void startVerify(const rapidjson::Value &value);
IClientListener* m_listener;
Job m_job;
Pool m_pool;

View file

@ -30,11 +30,18 @@ namespace xmrig {
const char *BenchConfig::kAlgo = "algo";
const char *BenchConfig::kBenchmark = "benchmark";
const char *BenchConfig::kHash = "hash";
const char *BenchConfig::kId = "id";
const char *BenchConfig::kSeed = "seed";
const char *BenchConfig::kSize = "size";
const char *BenchConfig::kSubmit = "submit";
const char *BenchConfig::kToken = "token";
const char *BenchConfig::kVerify = "verify";
#ifndef XMRIG_DEBUG_BENCHMARK_API
const char *BenchConfig::kApiHost = "api.xmrig.com";
#else
const char *BenchConfig::kApiHost = "127.0.0.1";
#endif
} // namespace xmrig

View file

@ -31,13 +31,24 @@ class BenchConfig
{
public:
static const char *kAlgo;
static const char *kApiHost;
static const char *kBenchmark;
static const char *kHash;
static const char *kId;
static const char *kSeed;
static const char *kSize;
static const char *kSubmit;
static const char *kToken;
static const char *kVerify;
# ifndef XMRIG_DEBUG_BENCHMARK_API
static constexpr bool kApiTLS = true;
static constexpr const uint16_t kApiPort = 443;
# else
static constexpr bool kApiTLS = false;
static constexpr const uint16_t kApiPort = 18805;
# endif
BenchConfig(uint32_t size, const String &id, const rapidjson::Value &object);
static BenchConfig *create(const rapidjson::Value &object);