diff --git a/src/base/io/log/Tags.cpp b/src/base/io/log/Tags.cpp index 3960a14df..23ef63d79 100644 --- a/src/base/io/log/Tags.cpp +++ b/src/base/io/log/Tags.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 XMRig , * * 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 @@ -37,6 +37,14 @@ const char *xmrig::Tags::network() } +const char* xmrig::Tags::origin() +{ + static const char* tag = YELLOW_BG_BOLD(WHITE_BOLD_S " origin "); + + return tag; +} + + const char *xmrig::Tags::signal() { static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " signal "); diff --git a/src/base/io/log/Tags.h b/src/base/io/log/Tags.h index 9f690ef2a..07312d4e7 100644 --- a/src/base/io/log/Tags.h +++ b/src/base/io/log/Tags.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 XMRig , * * 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 @@ -32,6 +32,7 @@ class Tags public: static const char *config(); static const char *network(); + static const char *origin(); static const char *signal(); # ifdef XMRIG_MINER_PROJECT diff --git a/src/base/kernel/config/BaseTransform.cpp b/src/base/kernel/config/BaseTransform.cpp index 7df0a7952..e6dc4e2e7 100644 --- a/src/base/kernel/config/BaseTransform.cpp +++ b/src/base/kernel/config/BaseTransform.cpp @@ -260,6 +260,7 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch case IConfig::DryRunKey: /* --dry-run */ case IConfig::HttpEnabledKey: /* --http-enabled */ case IConfig::DaemonKey: /* --daemon */ + case IConfig::SubmitToOriginKey: /* --submit-to-origin */ case IConfig::VerboseKey: /* --verbose */ case IConfig::PauseOnBatteryKey: /* --pause-on-battery */ case IConfig::PauseOnActiveKey: /* --pause-on-active */ @@ -291,6 +292,8 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b case IConfig::TlsKey: /* --tls */ return add(doc, Pools::kPools, Pool::kTls, enable); + case IConfig::SubmitToOriginKey: /* --submit-to-origin */ + return add(doc, Pools::kPools, Pool::kSubmitToOrigin, enable); # ifdef XMRIG_FEATURE_HTTP case IConfig::DaemonKey: /* --daemon */ return add(doc, Pools::kPools, Pool::kDaemon, enable); diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index d5fdb5c92..7a7f657ec 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -1,12 +1,6 @@ /* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2021 SChernykh - * Copyright 2016-2021 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 XMRig , * * 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 @@ -87,6 +81,7 @@ public: DmiKey = 1049, HugePageSizeKey = 1050, PauseOnActiveKey = 1051, + SubmitToOriginKey = 1052, // xmrig common CPUPriorityKey = 1021, diff --git a/src/base/net/stratum/Pool.cpp b/src/base/net/stratum/Pool.cpp index f80f1f626..e39df3b58 100644 --- a/src/base/net/stratum/Pool.cpp +++ b/src/base/net/stratum/Pool.cpp @@ -1,13 +1,7 @@ /* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2019 XMR-Stak , - * Copyright 2019 Howard Chu - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright (c) 2019 Howard Chu + * Copyright (c) 2018-2020 SChernykh + * Copyright (c) 2016-2020 XMRig , * * 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 @@ -80,6 +74,7 @@ const char *Pool::kPass = "pass"; const char *Pool::kRigId = "rig-id"; const char *Pool::kSelfSelect = "self-select"; const char *Pool::kSOCKS5 = "socks5"; +const char *Pool::kSubmitToOrigin = "submit-to-origin"; const char *Pool::kTls = "tls"; const char *Pool::kUrl = "url"; const char *Pool::kUser = "user"; @@ -137,7 +132,8 @@ xmrig::Pool::Pool(const rapidjson::Value &object) : setKeepAlive(Json::getValue(object, kKeepalive)); if (m_daemon.isValid()) { - m_mode = MODE_SELF_SELECT; + m_mode = MODE_SELF_SELECT; + m_submitToOrigin = Json::getBool(object, kSubmitToOrigin, m_submitToOrigin); } else if (Json::getBool(object, kDaemon)) { m_mode = MODE_DAEMON; @@ -237,7 +233,7 @@ xmrig::IClient *xmrig::Pool::createClient(int id, IClientListener *listener) con client = new DaemonClient(id, listener); } else if (m_mode == MODE_SELF_SELECT) { - client = new SelfSelectClient(id, Platform::userAgent(), listener); + client = new SelfSelectClient(id, Platform::userAgent(), listener, m_submitToOrigin); } # endif # ifdef XMRIG_ALGO_KAWPOW @@ -300,7 +296,8 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const obj.AddMember(StringRef(kDaemonPollInterval), m_pollInterval, allocator); } else { - obj.AddMember(StringRef(kSelfSelect), m_daemon.url().toJSON(), allocator); + obj.AddMember(StringRef(kSelfSelect), m_daemon.url().toJSON(), allocator); + obj.AddMember(StringRef(kSubmitToOrigin), m_submitToOrigin, allocator); } return obj; @@ -319,7 +316,7 @@ std::string xmrig::Pool::printableName() const } if (m_mode == MODE_SELF_SELECT) { - out += std::string(" self-select ") + CSI "1;" + std::to_string(m_daemon.isTLS() ? 32 : 36) + "m" + m_daemon.url().data() + CLEAR; + out += std::string(" self-select ") + CSI "1;" + std::to_string(m_daemon.isTLS() ? 32 : 36) + "m" + m_daemon.url().data() + WHITE_BOLD_S + (m_submitToOrigin ? " submit-to-origin" : "") + CLEAR; } return out; diff --git a/src/base/net/stratum/Pool.h b/src/base/net/stratum/Pool.h index dc0fec87a..3f9baecf5 100644 --- a/src/base/net/stratum/Pool.h +++ b/src/base/net/stratum/Pool.h @@ -1,13 +1,7 @@ /* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2019 Howard Chu - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright (c) 2019 Howard Chu + * Copyright (c) 2018-2020 SChernykh + * Copyright (c) 2016-2020 XMRig , * * 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 @@ -73,6 +67,7 @@ public: static const char *kRigId; static const char *kSelfSelect; static const char *kSOCKS5; + static const char *kSubmitToOrigin; static const char *kTls; static const char *kUrl; static const char *kUser; @@ -144,6 +139,7 @@ private: void setKeepAlive(const rapidjson::Value &value); Algorithm m_algorithm; + bool m_submitToOrigin = false; Coin m_coin; int m_keepAlive = 0; Mode m_mode = MODE_POOL; diff --git a/src/base/net/stratum/SelfSelectClient.cpp b/src/base/net/stratum/SelfSelectClient.cpp index fc4cea6e0..2dca057ad 100644 --- a/src/base/net/stratum/SelfSelectClient.cpp +++ b/src/base/net/stratum/SelfSelectClient.cpp @@ -1,13 +1,8 @@ /* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2019 jtgrassie - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright (c) 2019 jtgrassie + * Copyright (c) 2021 Hansie Odendaal + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 XMRig , * * 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 @@ -31,9 +26,12 @@ #include "base/io/json/Json.h" #include "base/io/json/JsonRequest.h" #include "base/io/log/Log.h" +#include "base/io/log/Tags.h" #include "base/net/http/Fetch.h" #include "base/net/http/HttpData.h" #include "base/net/stratum/Client.h" +#include "net/JobResult.h" +#include "base/tools/Cvt.h" namespace xmrig { @@ -54,7 +52,8 @@ static const char * const required_fields[] = { kBlocktemplateBlob, kBlockhashin } /* namespace xmrig */ -xmrig::SelfSelectClient::SelfSelectClient(int id, const char *agent, IClientListener *listener) : +xmrig::SelfSelectClient::SelfSelectClient(int id, const char *agent, IClientListener *listener, bool submitToOrigin) : + m_submitToOrigin(submitToOrigin), m_listener(listener) { m_httpListener = std::make_shared(this); @@ -68,6 +67,16 @@ xmrig::SelfSelectClient::~SelfSelectClient() } +int64_t xmrig::SelfSelectClient::submit(const JobResult &result) +{ + if (m_submitToOrigin) { + submitOriginDaemon(result); + } + + return m_client->submit(result); +} + + void xmrig::SelfSelectClient::tick(uint64_t now) { m_client->tick(now); @@ -201,6 +210,9 @@ void xmrig::SelfSelectClient::submitBlockTemplate(rapidjson::Value &result) Document doc(kObjectType); auto &allocator = doc.GetAllocator(); + m_blocktemplate = Json::getString(result,kBlocktemplateBlob); + m_blockDiff = Json::getUint64(result, kDifficulty); + Value params(kObjectType); params.AddMember(StringRef(kId), m_job.clientId().toJSON(), allocator); params.AddMember(StringRef(kJobId), m_job.id().toJSON(), allocator); @@ -236,6 +248,44 @@ void xmrig::SelfSelectClient::submitBlockTemplate(rapidjson::Value &result) } +void xmrig::SelfSelectClient::submitOriginDaemon(const JobResult& result) +{ + if (result.diff == 0 || m_blockDiff == 0) { + return; + } + + if (result.actualDiff() < m_blockDiff) { + m_originNotSubmitted++; + LOG_DEBUG("%s " RED_BOLD("not submitted to origin daemon, difficulty too low") " (%" PRId64 "/%" PRId64 ") " + BLACK_BOLD(" diff ") BLACK_BOLD("%" PRIu64) BLACK_BOLD(" vs. ") BLACK_BOLD("%" PRIu64), + Tags::origin(), m_originSubmitted, m_originNotSubmitted, m_blockDiff, result.actualDiff()); + return; + } + + char *data = m_blocktemplate.data(); + Cvt::toHex(data + 78, 8, reinterpret_cast(&result.nonce), 4); + + using namespace rapidjson; + Document doc(kObjectType); + + Value params(kArrayType); + params.PushBack(m_blocktemplate.toJSON(), doc.GetAllocator()); + + JsonRequest::create(doc, m_sequence, "submitblock", params); + m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), 0, result.backend); + + FetchRequest req(HTTP_POST, pool().daemon().host(), pool().daemon().port(), "/json_rpc", doc, pool().daemon().isTLS(), isQuiet()); + fetch(tag(), std::move(req), m_httpListener); + + m_originSubmitted++; + LOG_INFO("%s " GREEN_BOLD("submitted to origin daemon") " (%" PRId64 "/%" PRId64 ") " + " diff " WHITE("%" PRIu64) " vs. " WHITE("%" PRIu64), + Tags::origin(), m_originSubmitted, m_originNotSubmitted, m_blockDiff, result.actualDiff(), result.diff); + + // Ensure that the latest block template is available after block submission + getBlockTemplate(); +} + void xmrig::SelfSelectClient::onHttpData(const HttpData &data) { if (data.status != HTTP_STATUS_OK) { diff --git a/src/base/net/stratum/SelfSelectClient.h b/src/base/net/stratum/SelfSelectClient.h index b02e5212e..c73198a5a 100644 --- a/src/base/net/stratum/SelfSelectClient.h +++ b/src/base/net/stratum/SelfSelectClient.h @@ -1,13 +1,8 @@ /* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2019 jtgrassie - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright (c) 2019 jtgrassie + * Copyright (c) 2021 Hansie Odendaal + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 XMRig , * * 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 @@ -31,9 +26,9 @@ #include "base/kernel/interfaces/IClientListener.h" #include "base/net/http/HttpListener.h" #include "base/net/stratum/Job.h" -#include "base/tools/Object.h" +#include #include @@ -45,7 +40,7 @@ class SelfSelectClient : public IClient, public IClientListener, public IHttpLis public: XMRIG_DISABLE_COPY_MOVE_DEFAULT(SelfSelectClient) - SelfSelectClient(int id, const char *agent, IClientListener *listener); + SelfSelectClient(int id, const char *agent, IClientListener *listener, bool submitToOrigin); ~SelfSelectClient() override; protected: @@ -65,7 +60,6 @@ protected: inline int64_t send(const rapidjson::Value &obj, Callback callback) override { return m_client->send(obj, callback); } inline int64_t send(const rapidjson::Value &obj) override { return m_client->send(obj); } inline int64_t sequence() const override { return m_client->sequence(); } - inline int64_t submit(const JobResult &result) override { return m_client->submit(result); } inline void connect() override { m_client->connect(); } inline void connect(const Pool &pool) override { m_client->connect(pool); } inline void deleteLater() override { m_client->deleteLater(); } @@ -77,6 +71,7 @@ protected: inline void setRetries(int retries) override { m_client->setRetries(retries); m_retries = retries; } inline void setRetryPause(uint64_t ms) override { m_client->setRetryPause(ms); m_retryPause = ms; } + int64_t submit(const JobResult &result) override; void tick(uint64_t now) override; // IClientListener @@ -105,19 +100,26 @@ private: void retry(); void setState(State state); void submitBlockTemplate(rapidjson::Value &result); + void submitOriginDaemon(const JobResult &result); - bool m_active = false; - bool m_quiet = false; + bool m_active = false; + bool m_quiet = false; + const bool m_submitToOrigin; IClient *m_client; IClientListener *m_listener; - int m_retries = 5; - int64_t m_failures = 0; - int64_t m_sequence = 1; + int m_retries = 5; + int64_t m_failures = 0; + int64_t m_sequence = 1; Job m_job; - State m_state = IdleState; + State m_state = IdleState; + std::map m_results; std::shared_ptr m_httpListener; - uint64_t m_retryPause = 5000; - uint64_t m_timestamp = 0; + String m_blocktemplate; + uint64_t m_blockDiff = 0; + uint64_t m_originNotSubmitted = 0; + uint64_t m_originSubmitted = 0; + uint64_t m_retryPause = 5000; + uint64_t m_timestamp = 0; }; diff --git a/src/config.json b/src/config.json index 7722d19b3..e25c57673 100644 --- a/src/config.json +++ b/src/config.json @@ -75,7 +75,8 @@ "tls-fingerprint": null, "daemon": false, "socks5": null, - "self-select": null + "self-select": null, + "submit-to-origin": false } ], "print-time": 60, diff --git a/src/core/config/Config_default.h b/src/core/config/Config_default.h index c16d421ee..6c46fa956 100644 --- a/src/core/config/Config_default.h +++ b/src/core/config/Config_default.h @@ -105,7 +105,8 @@ R"===( "tls-fingerprint": null, "daemon": false, "socks5": null, - "self-select": null + "self-select": null, + "submit-to-origin": false } ], "print-time": 60, diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h index d1b17345f..dbe2a4d81 100644 --- a/src/core/config/Config_platform.h +++ b/src/core/config/Config_platform.h @@ -1,12 +1,6 @@ /* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 XMRig , * * 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 @@ -57,6 +51,7 @@ static const option options[] = { { "daemon", 0, nullptr, IConfig::DaemonKey }, { "daemon-poll-interval", 1, nullptr, IConfig::DaemonPollKey }, { "self-select", 1, nullptr, IConfig::SelfSelectKey }, + { "submit-to-origin", 0, nullptr, IConfig::SubmitToOriginKey }, # endif { "av", 1, nullptr, IConfig::AVKey }, { "background", 0, nullptr, IConfig::BackgroundKey }, diff --git a/src/core/config/usage.h b/src/core/config/usage.h index bf9088481..8b8ec533a 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.h @@ -1,12 +1,11 @@ /* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright (c) 2010 Jeff Garzik + * Copyright (c) 2012-2014 pooler + * Copyright (c) 2014 Lucas Jones + * Copyright (c) 2014-2016 Wolf9466 + * Copyright (c) 2016 Jay D Dee + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 XMRig , * * 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 @@ -64,6 +63,7 @@ static inline const std::string &usage() u += " --daemon use daemon RPC instead of pool for solo mining\n"; u += " --daemon-poll-interval=N daemon poll interval in milliseconds (default: 1000)\n"; u += " --self-select=URL self-select block templates from URL\n"; + u += " --submit-to-origin also submit solution back to self-select URL\n"; # endif u += " -r, --retries=N number of times to retry before switch to backup server (default: 5)\n";