mirror of
https://github.com/xmrig/xmrig.git
synced 2025-01-10 21:04:37 +00:00
Merge pull request #2548 from xmrig/feature-auto-coin
Added automatic coin detection for daemon mining
This commit is contained in:
commit
a28f411339
13 changed files with 476 additions and 279 deletions
|
@ -1,13 +1,6 @@
|
|||
/* 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 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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
|
||||
|
@ -23,9 +16,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/crypto/Coin.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "base/io/log/Log.h"
|
||||
|
||||
|
||||
#include <cstring>
|
||||
|
@ -39,74 +33,66 @@
|
|||
namespace xmrig {
|
||||
|
||||
|
||||
struct CoinName
|
||||
struct CoinInfo
|
||||
{
|
||||
const Algorithm::Id algorithm;
|
||||
const char *code;
|
||||
const char *name;
|
||||
const Coin::Id id;
|
||||
const uint64_t target;
|
||||
const uint64_t units;
|
||||
const char *tag;
|
||||
};
|
||||
|
||||
|
||||
static CoinName const coin_names[] = {
|
||||
{ "monero", Coin::MONERO },
|
||||
{ "xmr", Coin::MONERO },
|
||||
{ "arqma", Coin::ARQMA },
|
||||
{ "arq", Coin::ARQMA },
|
||||
{ "dero", Coin::DERO },
|
||||
{ "keva", Coin::KEVA },
|
||||
{ "ravencoin", Coin::RAVEN },
|
||||
{ "raven", Coin::RAVEN },
|
||||
{ "rvn", Coin::RAVEN },
|
||||
{ "conceal", Coin::CONCEAL },
|
||||
{ "wownero", Coin::WOWNERO }
|
||||
static const CoinInfo coinInfo[] = {
|
||||
{ Algorithm::INVALID, nullptr, nullptr, 0, 0, nullptr },
|
||||
{ Algorithm::RX_0, "XMR", "Monero", 120, 1000000000000, YELLOW_BG_BOLD( WHITE_BOLD_S " monero ") },
|
||||
{ Algorithm::CN_R, "SUMO", "Sumokoin", 240, 1000000000, BLUE_BG_BOLD( WHITE_BOLD_S " sumo ") },
|
||||
{ Algorithm::RX_ARQ, "ARQ", "ArQmA", 120, 1000000000, BLUE_BG_BOLD( WHITE_BOLD_S " arqma ") },
|
||||
{ Algorithm::ASTROBWT_DERO, "DERO", "DERO", 0, 0, BLUE_BG_BOLD( WHITE_BOLD_S " dero ") },
|
||||
{ Algorithm::RX_KEVA, "KVA", "Kevacoin", 0, 0, MAGENTA_BG_BOLD(WHITE_BOLD_S " keva ") },
|
||||
{ Algorithm::KAWPOW_RVN, "RVN", "Ravencoin", 0, 0, BLUE_BG_BOLD( WHITE_BOLD_S " raven ") },
|
||||
{ Algorithm::RX_WOW, "WOW", "Wownero", 300, 100000000000, MAGENTA_BG_BOLD(WHITE_BOLD_S " wownero ") },
|
||||
};
|
||||
|
||||
|
||||
static_assert(Coin::MAX == sizeof(coinInfo) / sizeof(coinInfo[0]), "size mismatch");
|
||||
|
||||
|
||||
const char *Coin::kDisabled = "DISABLED_COIN";
|
||||
const char *Coin::kField = "coin";
|
||||
const char *Coin::kUnknown = "UNKNOWN_COIN";
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
|
||||
xmrig::Algorithm::Id xmrig::Coin::algorithm(uint8_t blobVersion) const
|
||||
xmrig::Coin::Coin(const rapidjson::Value &value)
|
||||
{
|
||||
switch (id()) {
|
||||
case MONERO:
|
||||
return (blobVersion >= 12) ? Algorithm::RX_0 : Algorithm::CN_R;
|
||||
|
||||
case ARQMA:
|
||||
return (blobVersion >= 15) ? Algorithm::RX_ARQ : Algorithm::CN_PICO_0;
|
||||
|
||||
case DERO:
|
||||
return (blobVersion >= 4) ? Algorithm::ASTROBWT_DERO : Algorithm::CN_0;
|
||||
|
||||
case KEVA:
|
||||
return (blobVersion >= 11) ? Algorithm::RX_KEVA : Algorithm::CN_R;
|
||||
|
||||
case RAVEN:
|
||||
return Algorithm::KAWPOW_RVN;
|
||||
|
||||
case CONCEAL:
|
||||
return Algorithm::CN_CCX;
|
||||
|
||||
case WOWNERO:
|
||||
return Algorithm::RX_WOW;
|
||||
|
||||
case INVALID:
|
||||
break;
|
||||
if (value.IsString()) {
|
||||
m_id = parse(value.GetString());
|
||||
}
|
||||
else if (value.IsObject() && !value.ObjectEmpty()) {
|
||||
m_id = parse(Json::getString(value, kField));
|
||||
}
|
||||
|
||||
return Algorithm::INVALID;
|
||||
}
|
||||
|
||||
|
||||
xmrig::Algorithm xmrig::Coin::algorithm(uint8_t) const
|
||||
{
|
||||
return coinInfo[m_id].algorithm;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Coin::code() const
|
||||
{
|
||||
return coinInfo[m_id].code;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Coin::name() const
|
||||
{
|
||||
for (const auto &i : coin_names) {
|
||||
if (i.id == m_id) {
|
||||
return i.name;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
return coinInfo[m_id].name;
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,7 +100,19 @@ rapidjson::Value xmrig::Coin::toJSON() const
|
|||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
return isValid() ? Value(StringRef(name())) : Value(kNullType);
|
||||
return isValid() ? Value(StringRef(code())) : Value(kNullType);
|
||||
}
|
||||
|
||||
|
||||
uint64_t xmrig::Coin::target(uint8_t) const
|
||||
{
|
||||
return coinInfo[m_id].target;
|
||||
}
|
||||
|
||||
|
||||
uint64_t xmrig::Coin::units() const
|
||||
{
|
||||
return coinInfo[m_id].units;
|
||||
}
|
||||
|
||||
|
||||
|
@ -124,11 +122,17 @@ xmrig::Coin::Id xmrig::Coin::parse(const char *name)
|
|||
return INVALID;
|
||||
}
|
||||
|
||||
for (const auto &i : coin_names) {
|
||||
if (strcasecmp(name, i.name) == 0) {
|
||||
return i.id;
|
||||
for (uint32_t i = 1; i < MAX; ++i) {
|
||||
if (strcasecmp(name, coinInfo[i].code) == 0 || strcasecmp(name, coinInfo[i].name) == 0) {
|
||||
return static_cast<Id>(i);
|
||||
}
|
||||
}
|
||||
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Coin::tag(Id id)
|
||||
{
|
||||
return coinInfo[id].tag;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
/* 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 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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
|
||||
|
@ -37,38 +30,52 @@ namespace xmrig {
|
|||
class Coin
|
||||
{
|
||||
public:
|
||||
enum Id : int {
|
||||
INVALID = -1,
|
||||
enum Id : uint32_t {
|
||||
INVALID,
|
||||
MONERO,
|
||||
SUMO,
|
||||
ARQMA,
|
||||
DERO,
|
||||
KEVA,
|
||||
RAVEN,
|
||||
CONCEAL,
|
||||
WOWNERO
|
||||
WOWNERO,
|
||||
MAX
|
||||
};
|
||||
|
||||
static const char *kDisabled;
|
||||
static const char *kField;
|
||||
static const char *kUnknown;
|
||||
|
||||
Coin() = default;
|
||||
inline Coin(const char *name) : m_id(parse(name)) {}
|
||||
inline Coin(Id id) : m_id(id) {}
|
||||
Coin(const rapidjson::Value &value);
|
||||
inline Coin(const char *name) : m_id(parse(name)) {}
|
||||
inline Coin(Id id) : m_id(id) {}
|
||||
inline Coin(uint32_t id) : m_id(id < MAX ? static_cast<Id>(id) : INVALID) {}
|
||||
|
||||
|
||||
inline bool isEqual(const Coin &other) const { return m_id == other.m_id; }
|
||||
inline bool isValid() const { return m_id != INVALID; }
|
||||
inline Id id() const { return m_id; }
|
||||
inline bool isEqual(const Coin &other) const { return m_id == other.m_id; }
|
||||
inline bool isValid() const { return m_id != INVALID; }
|
||||
inline Id id() const { return m_id; }
|
||||
inline const char *tag() const { return tag(m_id); }
|
||||
inline double decimal(uint64_t amount) const { return static_cast<double>(amount) / units(); }
|
||||
|
||||
Algorithm::Id algorithm(uint8_t blobVersion = 255) const;
|
||||
Algorithm algorithm(uint8_t blobVersion = 255) const;
|
||||
const char *code() const;
|
||||
const char *name() const;
|
||||
rapidjson::Value toJSON() const;
|
||||
uint64_t target(uint8_t blobVersion = 255) const;
|
||||
uint64_t units() const;
|
||||
|
||||
inline bool operator!=(Coin::Id id) const { return m_id != id; }
|
||||
inline bool operator!=(const Coin &other) const { return !isEqual(other); }
|
||||
inline bool operator==(Coin::Id id) const { return m_id == id; }
|
||||
inline bool operator==(const Coin &other) const { return isEqual(other); }
|
||||
inline operator Coin::Id() const { return m_id; }
|
||||
inline bool operator!=(Id id) const { return m_id != id; }
|
||||
inline bool operator!=(const Coin &other) const { return !isEqual(other); }
|
||||
inline bool operator<(Id id) const { return m_id < id; }
|
||||
inline bool operator<(const Coin &other) const { return m_id < other.m_id; }
|
||||
inline bool operator==(Id id) const { return m_id == id; }
|
||||
inline bool operator==(const Coin &other) const { return isEqual(other); }
|
||||
inline operator Id() const { return m_id; }
|
||||
|
||||
static Id parse(const char *name);
|
||||
static const char *tag(Id id);
|
||||
|
||||
private:
|
||||
Id m_id = INVALID;
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
/* 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 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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
|
||||
|
@ -27,6 +21,7 @@
|
|||
|
||||
|
||||
#include "3rdparty/rapidjson/fwd.h"
|
||||
#include "base/tools/Object.h"
|
||||
|
||||
|
||||
#include <functional>
|
||||
|
@ -46,6 +41,8 @@ class String;
|
|||
class IClient
|
||||
{
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE(IClient)
|
||||
|
||||
enum Extension {
|
||||
EXT_ALGO,
|
||||
EXT_NICEHASH,
|
||||
|
@ -57,7 +54,8 @@ public:
|
|||
|
||||
using Callback = std::function<void(const rapidjson::Value &result, bool success, uint64_t elapsed)>;
|
||||
|
||||
virtual ~IClient() = default;
|
||||
IClient() = default;
|
||||
virtual ~IClient() = default;
|
||||
|
||||
virtual bool disconnect() = 0;
|
||||
virtual bool hasExtension(Extension extension) const noexcept = 0;
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
/* 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 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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
|
||||
|
@ -22,8 +16,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/net/stratum/BaseClient.h"
|
||||
#include "3rdparty/fmt/core.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "base/io/Env.h"
|
||||
#include "base/io/log/Log.h"
|
||||
|
@ -58,7 +52,7 @@ void xmrig::BaseClient::setPool(const Pool &pool)
|
|||
m_user = Env::expand(pool.user());
|
||||
m_password = Env::expand(pool.password());
|
||||
m_rigId = Env::expand(pool.rigId());
|
||||
m_tag = std::string(Tags::network()) + " " CYAN_BOLD_S + m_pool.url().data() + CLEAR;
|
||||
m_tag = fmt::format("{} " CYAN_BOLD("{}"), Tags::network(), m_pool.url().data());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
/* 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 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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
|
||||
|
|
|
@ -24,6 +24,9 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "base/net/stratum/DaemonClient.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "3rdparty/rapidjson/error/en.h"
|
||||
|
@ -42,7 +45,6 @@
|
|||
#include "base/tools/Cvt.h"
|
||||
#include "base/tools/Timer.h"
|
||||
#include "base/tools/cryptonote/Signatures.h"
|
||||
#include "base/tools/cryptonote/WalletAddress.h"
|
||||
#include "net/JobResult.h"
|
||||
|
||||
|
||||
|
@ -181,12 +183,28 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result)
|
|||
|
||||
void xmrig::DaemonClient::connect()
|
||||
{
|
||||
if ((m_pool.algorithm() == Algorithm::ASTROBWT_DERO) || (m_pool.coin() == Coin::DERO)) {
|
||||
m_apiVersion = API_DERO;
|
||||
}
|
||||
auto connectError = [this](const char *message) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("%s " RED("connect error: ") RED_BOLD("\"%s\""), tag(), message);
|
||||
}
|
||||
|
||||
retry();
|
||||
};
|
||||
|
||||
setState(ConnectingState);
|
||||
|
||||
if (!m_walletAddress.isValid()) {
|
||||
return connectError("Invalid wallet address.");
|
||||
}
|
||||
|
||||
if (!m_coin.isValid() && !m_pool.algorithm().isValid()) {
|
||||
return connectError("Invalid algorithm.");
|
||||
}
|
||||
|
||||
if ((m_pool.algorithm() == Algorithm::ASTROBWT_DERO) || (m_coin == Coin::DERO)) {
|
||||
m_apiVersion = API_DERO;
|
||||
}
|
||||
|
||||
if (m_pool.zmq_port() >= 0) {
|
||||
m_dns = Dns::resolve(m_pool.host(), this);
|
||||
}
|
||||
|
@ -203,6 +221,20 @@ void xmrig::DaemonClient::connect(const Pool &pool)
|
|||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::setPool(const Pool &pool)
|
||||
{
|
||||
BaseClient::setPool(pool);
|
||||
|
||||
m_walletAddress.decode(m_user);
|
||||
|
||||
m_coin = pool.coin().isValid() ? pool.coin() : m_walletAddress.coin();
|
||||
|
||||
if (!m_coin.isValid() && pool.algorithm() == Algorithm::RX_WOW) {
|
||||
m_coin = Coin::WOWNERO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::onHttpData(const HttpData &data)
|
||||
{
|
||||
if (data.status != 200) {
|
||||
|
@ -219,7 +251,7 @@ void xmrig::DaemonClient::onHttpData(const HttpData &data)
|
|||
rapidjson::Document doc;
|
||||
if (doc.Parse(data.body.c_str()).HasParseError()) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s:%d] JSON decode failed: \"%s\"", m_pool.host().data(), m_pool.port(), rapidjson::GetParseError_En(doc.GetParseError()));
|
||||
LOG_ERR("%s " RED("JSON decode failed: ") RED_BOLD("\"%s\""), tag(), rapidjson::GetParseError_En(doc.GetParseError()));
|
||||
}
|
||||
|
||||
return retry();
|
||||
|
@ -284,7 +316,7 @@ void xmrig::DaemonClient::onTimer(const Timer *)
|
|||
}
|
||||
|
||||
|
||||
void xmrig::DaemonClient::onResolved(const DnsRecords& records, int status, const char* error)
|
||||
void xmrig::DaemonClient::onResolved(const DnsRecords &records, int status, const char* error)
|
||||
{
|
||||
m_dns.reset();
|
||||
|
||||
|
@ -297,14 +329,14 @@ void xmrig::DaemonClient::onResolved(const DnsRecords& records, int status, cons
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_ZMQSocket) {
|
||||
delete m_ZMQSocket;
|
||||
}
|
||||
|
||||
const auto& record = records.get();
|
||||
delete m_ZMQSocket;
|
||||
|
||||
|
||||
const auto &record = records.get();
|
||||
m_ip = record.ip();
|
||||
|
||||
uv_connect_t* req = new uv_connect_t;
|
||||
auto req = new uv_connect_t;
|
||||
req->data = m_storage.ptr(m_key);
|
||||
|
||||
m_ZMQSocket = new uv_tcp_t;
|
||||
|
@ -329,26 +361,26 @@ bool xmrig::DaemonClient::isOutdated(uint64_t height, const char *hash) const
|
|||
|
||||
bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code)
|
||||
{
|
||||
auto jobError = [this, code](const char *message) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("%s " RED("job error: ") RED_BOLD("\"%s\""), tag(), message);
|
||||
}
|
||||
|
||||
*code = 1;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
Job job(false, m_pool.algorithm(), String());
|
||||
|
||||
String blocktemplate = Json::getString(params, kBlocktemplateBlob);
|
||||
|
||||
if (blocktemplate.isNull()) {
|
||||
LOG_ERR("Empty block template received from daemon");
|
||||
*code = 1;
|
||||
return false;
|
||||
return jobError("Empty block template received from daemon.");
|
||||
}
|
||||
|
||||
Coin pool_coin = m_pool.coin();
|
||||
|
||||
if (!pool_coin.isValid() && (m_pool.algorithm() == Algorithm::RX_WOW)) {
|
||||
pool_coin = Coin::WOWNERO;
|
||||
}
|
||||
|
||||
if (!m_blocktemplate.Init(blocktemplate, pool_coin)) {
|
||||
LOG_ERR("Invalid block template received from daemon");
|
||||
*code = 2;
|
||||
return false;
|
||||
if (!m_blocktemplate.Init(blocktemplate, m_coin)) {
|
||||
return jobError("Invalid block template received from daemon.");
|
||||
}
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
|
@ -368,29 +400,21 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code)
|
|||
|
||||
if (m_blocktemplate.has_miner_signature) {
|
||||
if (m_pool.spendSecretKey().isEmpty()) {
|
||||
LOG_ERR("Secret spend key is not set");
|
||||
*code = 4;
|
||||
return false;
|
||||
return jobError("Secret spend key is not set.");
|
||||
}
|
||||
|
||||
if (m_pool.spendSecretKey().size() != 64) {
|
||||
LOG_ERR("Secret spend key has invalid length. It must be 64 hex characters.");
|
||||
*code = 5;
|
||||
return false;
|
||||
return jobError("Secret spend key has invalid length. It must be 64 hex characters.");
|
||||
}
|
||||
|
||||
uint8_t secret_spendkey[32];
|
||||
if (!Cvt::fromHex(secret_spendkey, 32, m_pool.spendSecretKey(), 64)) {
|
||||
LOG_ERR("Secret spend key is not a valid hex data.");
|
||||
*code = 6;
|
||||
return false;
|
||||
return jobError("Secret spend key is not a valid hex data.");
|
||||
}
|
||||
|
||||
uint8_t public_spendkey[32];
|
||||
if (!secret_key_to_public_key(secret_spendkey, public_spendkey)) {
|
||||
LOG_ERR("Secret spend key is invalid.");
|
||||
*code = 7;
|
||||
return false;
|
||||
return jobError("Secret spend key is invalid.");
|
||||
}
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
|
@ -401,35 +425,24 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code)
|
|||
|
||||
uint8_t public_viewkey[32];
|
||||
if (!secret_key_to_public_key(secret_viewkey, public_viewkey)) {
|
||||
LOG_ERR("Secret view key is invalid.");
|
||||
*code = 8;
|
||||
return false;
|
||||
return jobError("Secret view key is invalid.");
|
||||
}
|
||||
|
||||
uint8_t derivation[32];
|
||||
if (!generate_key_derivation(m_blocktemplate.raw_blob.data() + m_blocktemplate.tx_pubkey_index, secret_viewkey, derivation)) {
|
||||
LOG_ERR("Failed to generate key derivation for miner signature.");
|
||||
*code = 9;
|
||||
return false;
|
||||
return jobError("Failed to generate key derivation for miner signature.");
|
||||
}
|
||||
|
||||
WalletAddress user_address;
|
||||
if (!user_address.Decode(m_pool.user())) {
|
||||
LOG_ERR("Invalid wallet address.");
|
||||
*code = 10;
|
||||
return false;
|
||||
if (!m_walletAddress.decode(m_pool.user())) {
|
||||
return jobError("Invalid wallet address.");
|
||||
}
|
||||
|
||||
if (memcmp(user_address.public_spend_key, public_spendkey, sizeof(public_spendkey)) != 0) {
|
||||
LOG_ERR("Wallet address and spend key don't match.");
|
||||
*code = 11;
|
||||
return false;
|
||||
if (memcmp(m_walletAddress.spendKey(), public_spendkey, sizeof(public_spendkey)) != 0) {
|
||||
return jobError("Wallet address and spend key don't match.");
|
||||
}
|
||||
|
||||
if (memcmp(user_address.public_view_key, public_viewkey, sizeof(public_viewkey)) != 0) {
|
||||
LOG_ERR("Wallet address and view key don't match.");
|
||||
*code = 12;
|
||||
return false;
|
||||
if (memcmp(m_walletAddress.viewKey(), public_viewkey, sizeof(public_viewkey)) != 0) {
|
||||
return jobError("Wallet address and view key don't match.");
|
||||
}
|
||||
|
||||
uint8_t eph_secret_key[32];
|
||||
|
@ -444,8 +457,8 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code)
|
|||
Cvt::toHex(m_blockhashingblob.data() + offset * 2, kBlobReserveSize * 2, Cvt::randomBytes(kBlobReserveSize).data(), kBlobReserveSize);
|
||||
}
|
||||
|
||||
if (pool_coin.isValid()) {
|
||||
job.setAlgorithm(pool_coin.algorithm(m_blocktemplate.major_version));
|
||||
if (m_coin.isValid()) {
|
||||
job.setAlgorithm(m_coin.algorithm(m_blocktemplate.major_version));
|
||||
}
|
||||
|
||||
if (!job.setBlob(m_blockhashingblob)) {
|
||||
|
@ -594,7 +607,6 @@ void xmrig::DaemonClient::send(const char *path)
|
|||
|
||||
void xmrig::DaemonClient::setState(SocketState state)
|
||||
{
|
||||
assert(m_state != state);
|
||||
if (m_state == state) {
|
||||
return;
|
||||
}
|
||||
|
@ -735,10 +747,9 @@ void xmrig::DaemonClient::ZMQRead(ssize_t nread, const uv_buf_t* buf)
|
|||
m_ZMQConnectionState = ZMQ_GREETING_2;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
LOG_ERR("%s " RED("ZMQ handshake failed: invalid greeting format"), tag());
|
||||
ZMQClose();
|
||||
}
|
||||
|
||||
LOG_ERR("%s " RED("ZMQ handshake failed: invalid greeting format"), tag());
|
||||
ZMQClose();
|
||||
}
|
||||
return;
|
||||
|
||||
|
@ -751,10 +762,10 @@ void xmrig::DaemonClient::ZMQRead(ssize_t nread, const uv_buf_t* buf)
|
|||
ZMQWrite(kZMQHandshake, sizeof(kZMQHandshake) - 1);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
LOG_ERR("%s " RED("ZMQ handshake failed: invalid greeting format 2"), tag());
|
||||
ZMQClose();
|
||||
}
|
||||
|
||||
LOG_ERR("%s " RED("ZMQ handshake failed: invalid greeting format 2"), tag());
|
||||
ZMQClose();
|
||||
|
||||
}
|
||||
return;
|
||||
|
||||
|
|
|
@ -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 2019 Howard Chu <https://github.com/hyc>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2019 Howard Chu <https://github.com/hyc>
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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
|
||||
|
@ -27,21 +21,25 @@
|
|||
#define XMRIG_DAEMONCLIENT_H
|
||||
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#include "base/kernel/interfaces/IDnsListener.h"
|
||||
#include "base/kernel/interfaces/IHttpListener.h"
|
||||
#include "base/kernel/interfaces/ITimerListener.h"
|
||||
#include "base/net/stratum/BaseClient.h"
|
||||
#include "base/tools/Object.h"
|
||||
#include "base/tools/cryptonote/BlockTemplate.h"
|
||||
#include "base/net/tools/Storage.h"
|
||||
#include "base/tools/cryptonote/BlockTemplate.h"
|
||||
#include "base/tools/cryptonote/WalletAddress.h"
|
||||
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
using uv_buf_t = struct uv_buf_t;
|
||||
using uv_connect_t = struct uv_connect_s;
|
||||
using uv_handle_t = struct uv_handle_s;
|
||||
using uv_stream_t = struct uv_stream_s;
|
||||
using uv_tcp_t = struct uv_tcp_s;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
|
@ -62,10 +60,11 @@ protected:
|
|||
int64_t submit(const JobResult &result) override;
|
||||
void connect() override;
|
||||
void connect(const Pool &pool) override;
|
||||
void setPool(const Pool &pool) override;
|
||||
|
||||
void onHttpData(const HttpData &data) override;
|
||||
void onTimer(const Timer *timer) override;
|
||||
void onResolved(const DnsRecords& records, int status, const char* error) override;
|
||||
void onResolved(const DnsRecords &records, int status, const char* error) override;
|
||||
|
||||
inline bool hasExtension(Extension) const noexcept override { return false; }
|
||||
inline const char *mode() const override { return "daemon"; }
|
||||
|
@ -92,18 +91,19 @@ private:
|
|||
API_DERO,
|
||||
} m_apiVersion = API_MONERO;
|
||||
|
||||
BlockTemplate m_blocktemplate;
|
||||
Coin m_coin;
|
||||
std::shared_ptr<IHttpListener> m_httpListener;
|
||||
String m_currentJobId;
|
||||
String m_blocktemplateStr;
|
||||
String m_blockhashingblob;
|
||||
String m_blocktemplateRequestHash;
|
||||
String m_blocktemplateStr;
|
||||
String m_currentJobId;
|
||||
String m_prevHash;
|
||||
String m_tlsFingerprint;
|
||||
String m_tlsVersion;
|
||||
Timer *m_timer;
|
||||
uint64_t m_blocktemplateRequestHeight = 0;
|
||||
String m_blocktemplateRequestHash;
|
||||
|
||||
BlockTemplate m_blocktemplate;
|
||||
WalletAddress m_walletAddress;
|
||||
|
||||
private:
|
||||
static inline DaemonClient* getClient(void* data) { return m_storage.get(data); }
|
||||
|
|
|
@ -190,10 +190,6 @@ bool xmrig::Pool::isEnabled() const
|
|||
}
|
||||
# endif
|
||||
|
||||
if (m_mode == MODE_DAEMON && (!algorithm().isValid() && !coin().isValid())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_flags.test(FLAG_ENABLED) && isValid();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* XMRig
|
||||
* Copyright 2012-2013 The Cryptonote developers
|
||||
* Copyright 2014-2021 The Monero Project
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2012-2013 The Cryptonote developers
|
||||
* Copyright (c) 2014-2021 The Monero Project
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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
|
||||
|
@ -23,58 +23,71 @@
|
|||
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class CBlobReader
|
||||
class BlobReader
|
||||
{
|
||||
public:
|
||||
inline CBlobReader(const void* data, size_t size)
|
||||
: m_data(reinterpret_cast<const uint8_t*>(data))
|
||||
, m_size(size)
|
||||
, m_index(0)
|
||||
inline BlobReader(const uint8_t *data, size_t size) :
|
||||
m_size(size),
|
||||
m_data(data)
|
||||
{}
|
||||
|
||||
inline bool operator()(uint8_t& data) { return getByte(data); }
|
||||
inline bool operator()(uint64_t& data) { return getVarint(data); }
|
||||
inline bool operator()(uint64_t &data) { return getVarint(data); }
|
||||
inline bool operator()(uint8_t &data) { return getByte(data); }
|
||||
inline size_t index() const { return m_index; }
|
||||
inline size_t remaining() const { return m_size - m_index; }
|
||||
|
||||
inline bool skip(size_t n)
|
||||
{
|
||||
if (m_index + n > m_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_index += n;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
inline bool operator()(uint8_t(&data)[N])
|
||||
{
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
if (!getByte(data[i])) {
|
||||
return false;
|
||||
}
|
||||
if (m_index + N > m_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(data, m_data + m_index, N);
|
||||
m_index += N;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void readItems(T& data, size_t count)
|
||||
inline void readItems(T &data, size_t count)
|
||||
{
|
||||
data.resize(count);
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
operator()(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
inline size_t index() const { return m_index; }
|
||||
|
||||
inline void skip(size_t N) { m_index += N; }
|
||||
|
||||
private:
|
||||
inline bool getByte(uint8_t& data)
|
||||
inline bool getByte(uint8_t &data)
|
||||
{
|
||||
if (m_index >= m_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data = m_data[m_index++];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool getVarint(uint64_t& data)
|
||||
inline bool getVarint(uint64_t &data)
|
||||
{
|
||||
uint64_t result = 0;
|
||||
uint8_t t;
|
||||
|
@ -89,12 +102,13 @@ private:
|
|||
} while (t & 0x80);
|
||||
|
||||
data = result;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint8_t* m_data;
|
||||
size_t m_size;
|
||||
size_t m_index;
|
||||
const size_t m_size;
|
||||
const uint8_t *m_data;
|
||||
size_t m_index = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* XMRig
|
||||
* Copyright 2012-2013 The Cryptonote developers
|
||||
* Copyright 2014-2021 The Monero Project
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2012-2013 The Cryptonote developers
|
||||
* Copyright (c) 2014-2021 The Monero Project
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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
|
||||
|
@ -32,7 +32,7 @@ bool BlockTemplate::Init(const String& blockTemplate, Coin coin)
|
|||
{
|
||||
raw_blob = Cvt::fromHex(blockTemplate);
|
||||
|
||||
CBlobReader ar(raw_blob.data(), raw_blob.size());
|
||||
BlobReader ar(raw_blob.data(), raw_blob.size());
|
||||
|
||||
// Block header
|
||||
ar(major_version);
|
||||
|
@ -90,7 +90,7 @@ bool BlockTemplate::Init(const String& blockTemplate, Coin coin)
|
|||
|
||||
ar.readItems(extra, extra_size);
|
||||
|
||||
CBlobReader ar_extra(extra.data(), extra_size);
|
||||
BlobReader ar_extra(extra.data(), extra_size);
|
||||
|
||||
tx_extra_nonce_size = 0;
|
||||
tx_extra_nonce_index = 0;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* XMRig
|
||||
* Copyright 2012-2013 The Cryptonote developers
|
||||
* Copyright 2014-2021 The Monero Project
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2012-2013 The Cryptonote developers
|
||||
* Copyright (c) 2014-2021 The Monero Project
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* XMRig
|
||||
* Copyright 2012-2013 The Cryptonote developers
|
||||
* Copyright 2014-2021 The Monero Project
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2012-2013 The Cryptonote developers
|
||||
* Copyright (c) 2014-2021 The Monero Project
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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,24 +18,29 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/crypto/keccak.h"
|
||||
#include "base/tools/cryptonote/BlobReader.h"
|
||||
#include "base/tools/cryptonote/WalletAddress.h"
|
||||
#include "base/tools/cryptonote/umul128.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "base/crypto/keccak.h"
|
||||
#include "base/tools/Buffer.h"
|
||||
#include "base/tools/cryptonote/BlobReader.h"
|
||||
#include "base/tools/cryptonote/umul128.h"
|
||||
#include "base/tools/Cvt.h"
|
||||
|
||||
|
||||
#include <array>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
bool WalletAddress::Decode(const String& address)
|
||||
bool xmrig::WalletAddress::decode(const char *address, size_t size)
|
||||
{
|
||||
static constexpr std::array<int, 9> block_sizes{ 0, 2, 3, 5, 6, 7, 9, 10, 11 };
|
||||
static constexpr char alphabet[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
constexpr size_t alphabet_size = sizeof(alphabet) - 1;
|
||||
|
||||
if (size < kMinSize || size > kMaxSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int8_t reverse_alphabet[256];
|
||||
memset(reverse_alphabet, -1, sizeof(reverse_alphabet));
|
||||
|
||||
|
@ -43,7 +48,7 @@ bool WalletAddress::Decode(const String& address)
|
|||
reverse_alphabet[static_cast<int>(alphabet[i])] = i;
|
||||
}
|
||||
|
||||
const int len = static_cast<int>(address.size());
|
||||
const int len = static_cast<int>(size);
|
||||
const int num_full_blocks = len / block_sizes.back();
|
||||
const int last_block_size = len % block_sizes.back();
|
||||
|
||||
|
@ -60,10 +65,15 @@ bool WalletAddress::Decode(const String& address)
|
|||
return false;
|
||||
}
|
||||
|
||||
Buffer data;
|
||||
data.reserve(static_cast<size_t>(num_full_blocks) * sizeof(uint64_t) + last_block_size_index);
|
||||
const size_t data_size = static_cast<size_t>(num_full_blocks) * sizeof(uint64_t) + last_block_size_index;
|
||||
if (data_size < kMinDataSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* address_data = address.data();
|
||||
Buffer data;
|
||||
data.reserve(data_size);
|
||||
|
||||
const char *address_data = address;
|
||||
|
||||
for (int i = 0; i <= num_full_blocks; ++i) {
|
||||
uint64_t num = 0;
|
||||
|
@ -87,28 +97,138 @@ bool WalletAddress::Decode(const String& address)
|
|||
|
||||
address_data += block_sizes.back();
|
||||
|
||||
uint8_t* p = reinterpret_cast<uint8_t*>(&num);
|
||||
for (int j = ((i < num_full_blocks) ? sizeof(num) : last_block_size_index) - 1; j >= 0; --j) {
|
||||
auto p = reinterpret_cast<const uint8_t*>(&num);
|
||||
for (int j = ((i < num_full_blocks) ? static_cast<int>(sizeof(num)) : last_block_size_index) - 1; j >= 0; --j) {
|
||||
data.emplace_back(p[j]);
|
||||
}
|
||||
}
|
||||
|
||||
CBlobReader ar(data.data(), data.size());
|
||||
assert(data.size() == data_size);
|
||||
|
||||
ar(tag);
|
||||
ar(public_spend_key);
|
||||
ar(public_view_key);
|
||||
ar(checksum);
|
||||
BlobReader ar(data.data(), data_size);
|
||||
|
||||
uint8_t md[200];
|
||||
keccak(data.data(), data.size() - sizeof(checksum), md);
|
||||
if (ar(m_tag) && ar(m_publicSpendKey) && ar(m_publicViewKey) && ar.skip(ar.remaining() - sizeof(m_checksum)) && ar(m_checksum)) {
|
||||
uint8_t md[200];
|
||||
keccak(data.data(), data_size - sizeof(m_checksum), md);
|
||||
|
||||
if (memcmp(checksum, md, sizeof(checksum)) != 0) {
|
||||
return false;
|
||||
if (memcmp(m_checksum, md, sizeof(m_checksum)) == 0) {
|
||||
m_data = { address, size };
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
m_tag = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
bool xmrig::WalletAddress::decode(const rapidjson::Value &address)
|
||||
{
|
||||
return address.IsString() && decode(address.GetString(), address.GetStringLength());
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::WalletAddress::netName() const
|
||||
{
|
||||
static const std::array<const char *, 3> names = { "mainnet", "testnet", "stagenet" };
|
||||
|
||||
return names[net()];
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::WalletAddress::typeName() const
|
||||
{
|
||||
static const std::array<const char *, 3> names = { "public", "integrated", "subaddress" };
|
||||
|
||||
return names[type()];
|
||||
}
|
||||
|
||||
|
||||
rapidjson::Value xmrig::WalletAddress::toJSON(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
return isValid() ? m_data.toJSON(doc) : Value(kNullType);
|
||||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_API
|
||||
rapidjson::Value xmrig::WalletAddress::toAPI(rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
if (!isValid()) {
|
||||
return Value(kNullType);
|
||||
}
|
||||
|
||||
auto &allocator = doc.GetAllocator();
|
||||
Value out(kObjectType);
|
||||
out.AddMember(StringRef(Coin::kField), coin().toJSON(), allocator);
|
||||
out.AddMember("address", m_data.toJSON(doc), allocator);
|
||||
out.AddMember("type", StringRef(typeName()), allocator);
|
||||
out.AddMember("net", StringRef(netName()), allocator);
|
||||
out.AddMember("rpc_port", rpcPort(), allocator);
|
||||
out.AddMember("zmq_port", zmqPort(), allocator);
|
||||
out.AddMember("tag", m_tag, allocator);
|
||||
out.AddMember("view_key", Cvt::toHex(m_publicViewKey, kKeySize, doc), allocator);
|
||||
out.AddMember("spend_key", Cvt::toHex(m_publicSpendKey, kKeySize, doc), allocator);
|
||||
out.AddMember("checksum", Cvt::toHex(m_checksum, sizeof(m_checksum), doc), allocator);
|
||||
|
||||
return out;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
const xmrig::WalletAddress::TagInfo &xmrig::WalletAddress::tagInfo(uint64_t tag)
|
||||
{
|
||||
static TagInfo dummy = { Coin::INVALID, MAINNET, PUBLIC, 0 };
|
||||
static const std::map<uint64_t, TagInfo> tags = {
|
||||
{ 18, { Coin::MONERO, MAINNET, PUBLIC, 18081, 18082 } },
|
||||
{ 19, { Coin::MONERO, MAINNET, INTEGRATED, 18081, 18082 } },
|
||||
{ 42, { Coin::MONERO, MAINNET, SUBADDRESS, 18081, 18082 } },
|
||||
|
||||
{ 53, { Coin::MONERO, TESTNET, PUBLIC, 28081, 28082 } },
|
||||
{ 54, { Coin::MONERO, TESTNET, INTEGRATED, 28081, 28082 } },
|
||||
{ 63, { Coin::MONERO, TESTNET, SUBADDRESS, 28081, 28082 } },
|
||||
|
||||
{ 24, { Coin::MONERO, STAGENET, PUBLIC, 38081, 38082 } },
|
||||
{ 25, { Coin::MONERO, STAGENET, INTEGRATED, 38081, 38082 } },
|
||||
{ 36, { Coin::MONERO, STAGENET, SUBADDRESS, 38081, 38082 } },
|
||||
|
||||
{ 0x2bb39a, { Coin::SUMO, MAINNET, PUBLIC, 19734, 19735 } },
|
||||
{ 0x29339a, { Coin::SUMO, MAINNET, INTEGRATED, 19734, 19735 } },
|
||||
{ 0x8319a, { Coin::SUMO, MAINNET, SUBADDRESS, 19734, 19735 } },
|
||||
|
||||
{ 0x37751a, { Coin::SUMO, TESTNET, PUBLIC, 29734, 29735 } },
|
||||
{ 0x34f51a, { Coin::SUMO, TESTNET, INTEGRATED, 29734, 29735 } },
|
||||
{ 0x1d351a, { Coin::SUMO, TESTNET, SUBADDRESS, 29734, 29735 } },
|
||||
|
||||
{ 0x2cca, { Coin::ARQMA, MAINNET, PUBLIC, 19994, 19995 } },
|
||||
{ 0x116bc7, { Coin::ARQMA, MAINNET, INTEGRATED, 19994, 19995 } },
|
||||
{ 0x6847, { Coin::ARQMA, MAINNET, SUBADDRESS, 19994, 19995 } },
|
||||
|
||||
{ 0x53ca, { Coin::ARQMA, TESTNET, PUBLIC, 29994, 29995 } },
|
||||
{ 0x504a, { Coin::ARQMA, TESTNET, INTEGRATED, 29994, 29995 } },
|
||||
{ 0x524a, { Coin::ARQMA, TESTNET, SUBADDRESS, 29994, 29995 } },
|
||||
|
||||
{ 0x39ca, { Coin::ARQMA, STAGENET, PUBLIC, 39994, 39995 } },
|
||||
{ 0x1742ca, { Coin::ARQMA, STAGENET, INTEGRATED, 39994, 39995 } },
|
||||
{ 0x1d84ca, { Coin::ARQMA, STAGENET, SUBADDRESS, 39994, 39995 } },
|
||||
|
||||
{ 0xc8ed8, { Coin::DERO, MAINNET, PUBLIC, 20206, 0 } },
|
||||
{ 0xa0ed8, { Coin::DERO, MAINNET, INTEGRATED, 20206, 0 } },
|
||||
|
||||
{ 0x6cf58, { Coin::DERO, TESTNET, PUBLIC, 30306, 0 } },
|
||||
{ 0x44f58, { Coin::DERO, TESTNET, INTEGRATED, 30306, 0 } },
|
||||
|
||||
{ 4146, { Coin::WOWNERO, MAINNET, PUBLIC, 34568, 34569 } },
|
||||
{ 6810, { Coin::WOWNERO, MAINNET, INTEGRATED, 34568, 34569 } },
|
||||
{ 12208, { Coin::WOWNERO, MAINNET, SUBADDRESS, 34568, 34569 } },
|
||||
};
|
||||
|
||||
const auto it = tags.find(tag);
|
||||
|
||||
return it == tags.end() ? dummy : it->second;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* XMRig
|
||||
* Copyright 2012-2013 The Cryptonote developers
|
||||
* Copyright 2014-2021 The Monero Project
|
||||
* Copyright 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2012-2013 The Cryptonote developers
|
||||
* Copyright (c) 2014-2021 The Monero Project
|
||||
* Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2021 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
|
||||
|
@ -23,19 +23,78 @@
|
|||
|
||||
|
||||
#include "base/tools/String.h"
|
||||
#include "base/crypto/Coin.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
struct WalletAddress
|
||||
class WalletAddress
|
||||
{
|
||||
uint64_t tag;
|
||||
uint8_t public_spend_key[32];
|
||||
uint8_t public_view_key[32];
|
||||
uint8_t checksum[4];
|
||||
public:
|
||||
enum Net : uint32_t {
|
||||
MAINNET,
|
||||
TESTNET,
|
||||
STAGENET
|
||||
};
|
||||
|
||||
bool Decode(const String& address);
|
||||
enum Type : uint32_t {
|
||||
PUBLIC,
|
||||
INTEGRATED,
|
||||
SUBADDRESS
|
||||
};
|
||||
|
||||
constexpr static size_t kKeySize = 32;
|
||||
constexpr static size_t kMaxSize = 256;
|
||||
constexpr static size_t kMinDataSize = 69;
|
||||
constexpr static size_t kMinSize = 95;
|
||||
|
||||
WalletAddress() = default;
|
||||
inline WalletAddress(const char *address, size_t size) { decode(address, size); }
|
||||
inline WalletAddress(const char *address) { decode(address); }
|
||||
inline WalletAddress(const rapidjson::Value &address) { decode(address); }
|
||||
inline WalletAddress(const String &address) { decode(address); }
|
||||
|
||||
inline bool decode(const char *address) { return decode(address, strlen(address)); }
|
||||
inline bool decode(const String &address) { return decode(address, address.size()); }
|
||||
inline bool isValid() const { return m_tag > 0 && m_data.size() >= kMinSize; }
|
||||
inline const char *data() const { return m_data; }
|
||||
inline const Coin &coin() const { return tagInfo(m_tag).coin; }
|
||||
inline const uint8_t *spendKey() const { return m_publicSpendKey; }
|
||||
inline const uint8_t *viewKey() const { return m_publicViewKey; }
|
||||
inline Net net() const { return tagInfo(m_tag).net; }
|
||||
inline Type type() const { return tagInfo(m_tag).type; }
|
||||
inline uint16_t rpcPort() const { return tagInfo(m_tag).rpcPort; }
|
||||
inline uint16_t zmqPort() const { return tagInfo(m_tag).zmqPort; }
|
||||
inline uint64_t tag() const { return m_tag; }
|
||||
|
||||
bool decode(const char *address, size_t size);
|
||||
bool decode(const rapidjson::Value &address);
|
||||
const char *netName() const;
|
||||
const char *typeName() const;
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
rapidjson::Value toAPI(rapidjson::Document &doc) const;
|
||||
# endif
|
||||
|
||||
private:
|
||||
struct TagInfo
|
||||
{
|
||||
const Coin coin;
|
||||
const Net net;
|
||||
const Type type;
|
||||
const uint16_t rpcPort;
|
||||
const uint16_t zmqPort;
|
||||
};
|
||||
|
||||
static const TagInfo &tagInfo(uint64_t tag);
|
||||
|
||||
String m_data;
|
||||
uint64_t m_tag = 0;
|
||||
uint8_t m_checksum[4]{};
|
||||
uint8_t m_publicSpendKey[kKeySize]{};
|
||||
uint8_t m_publicViewKey[kKeySize]{};
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue