Merge branch 'beta' of https://github.com/xmrig/xmrig
This commit is contained in:
commit
0ada4ca4ac
150 changed files with 12300 additions and 8764 deletions
|
@ -3,6 +3,7 @@ set(HEADERS_BASE
|
|||
src/base/crypto/Algorithm.h
|
||||
src/base/crypto/Coin.h
|
||||
src/base/crypto/keccak.h
|
||||
src/base/crypto/sha3.h
|
||||
src/base/io/Console.h
|
||||
src/base/io/Env.h
|
||||
src/base/io/json/Json.h
|
||||
|
@ -12,11 +13,13 @@ set(HEADERS_BASE
|
|||
src/base/io/log/backends/FileLog.h
|
||||
src/base/io/log/FileLogWriter.h
|
||||
src/base/io/log/Log.h
|
||||
src/base/io/log/Tags.h
|
||||
src/base/io/Signals.h
|
||||
src/base/io/Watcher.h
|
||||
src/base/kernel/Base.h
|
||||
src/base/kernel/config/BaseConfig.h
|
||||
src/base/kernel/config/BaseTransform.h
|
||||
src/base/kernel/config/Title.h
|
||||
src/base/kernel/Entry.h
|
||||
src/base/kernel/interfaces/IBaseListener.h
|
||||
src/base/kernel/interfaces/IClient.h
|
||||
|
@ -69,6 +72,7 @@ set(SOURCES_BASE
|
|||
src/base/crypto/Algorithm.cpp
|
||||
src/base/crypto/Coin.cpp
|
||||
src/base/crypto/keccak.cpp
|
||||
src/base/crypto/sha3.cpp
|
||||
src/base/io/Console.cpp
|
||||
src/base/io/Env.cpp
|
||||
src/base/io/json/Json.cpp
|
||||
|
@ -78,11 +82,13 @@ set(SOURCES_BASE
|
|||
src/base/io/log/backends/FileLog.cpp
|
||||
src/base/io/log/FileLogWriter.cpp
|
||||
src/base/io/log/Log.cpp
|
||||
src/base/io/log/Tags.cpp
|
||||
src/base/io/Signals.cpp
|
||||
src/base/io/Watcher.cpp
|
||||
src/base/kernel/Base.cpp
|
||||
src/base/kernel/config/BaseConfig.cpp
|
||||
src/base/kernel/config/BaseTransform.cpp
|
||||
src/base/kernel/config/Title.cpp
|
||||
src/base/kernel/Entry.cpp
|
||||
src/base/kernel/Platform.cpp
|
||||
src/base/kernel/Process.cpp
|
||||
|
@ -203,3 +209,16 @@ if (WITH_ENV_VARS)
|
|||
else()
|
||||
remove_definitions(/DXMRIG_FEATURE_ENV)
|
||||
endif()
|
||||
|
||||
|
||||
if (WITH_KAWPOW)
|
||||
list(APPEND HEADERS_BASE
|
||||
src/base/net/stratum/AutoClient.h
|
||||
src/base/net/stratum/EthStratumClient.h
|
||||
)
|
||||
|
||||
list(APPEND SOURCES_BASE
|
||||
src/base/net/stratum/AutoClient.cpp
|
||||
src/base/net/stratum/EthStratumClient.cpp
|
||||
)
|
||||
endif()
|
||||
|
|
|
@ -70,10 +70,6 @@ static AlgoName const algorithm_names[] = {
|
|||
{ "cryptonight/rwz", "cn/rwz", Algorithm::CN_RWZ },
|
||||
{ "cryptonight/zls", "cn/zls", Algorithm::CN_ZLS },
|
||||
{ "cryptonight/double", "cn/double", Algorithm::CN_DOUBLE },
|
||||
# ifdef XMRIG_ALGO_CN_GPU
|
||||
{ "cryptonight/gpu", "cn/gpu", Algorithm::CN_GPU },
|
||||
{ "cryptonight_gpu", nullptr, Algorithm::CN_GPU },
|
||||
# endif
|
||||
# ifdef XMRIG_ALGO_CN_LITE
|
||||
{ "cryptonight-lite/0", "cn-lite/0", Algorithm::CN_LITE_0 },
|
||||
{ "cryptonight-lite/1", "cn-lite/1", Algorithm::CN_LITE_1 },
|
||||
|
@ -128,6 +124,12 @@ static AlgoName const algorithm_names[] = {
|
|||
{ "astrobwt", nullptr, Algorithm::ASTROBWT_DERO },
|
||||
{ "astrobwt/dero", nullptr, Algorithm::ASTROBWT_DERO },
|
||||
# endif
|
||||
# ifdef XMRIG_ALGO_KAWPOW
|
||||
{ "kawpow", nullptr, Algorithm::KAWPOW_RVN },
|
||||
{ "kawpow/rvn", nullptr, Algorithm::KAWPOW_RVN },
|
||||
# endif
|
||||
{ "cryptonight/ccx", "cn/ccx", Algorithm::CN_CCX },
|
||||
{ "cryptonight/conceal", "cn/conceal", Algorithm::CN_CCX },
|
||||
};
|
||||
|
||||
|
||||
|
@ -245,6 +247,18 @@ size_t xmrig::Algorithm::l3() const
|
|||
}
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_KAWPOW
|
||||
if (f == KAWPOW) {
|
||||
switch (m_id) {
|
||||
case KAWPOW_RVN:
|
||||
return 32768;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -269,12 +283,6 @@ uint32_t xmrig::Algorithm::maxIntensity() const
|
|||
}
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_GPU
|
||||
if (m_id == CN_GPU) {
|
||||
return 1;
|
||||
}
|
||||
# endif
|
||||
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
@ -293,9 +301,7 @@ xmrig::Algorithm::Family xmrig::Algorithm::family(Id id)
|
|||
case CN_RWZ:
|
||||
case CN_ZLS:
|
||||
case CN_DOUBLE:
|
||||
# ifdef XMRIG_ALGO_CN_GPU
|
||||
case CN_GPU:
|
||||
# endif
|
||||
case CN_CCX:
|
||||
return CN;
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_LITE
|
||||
|
@ -339,6 +345,11 @@ xmrig::Algorithm::Family xmrig::Algorithm::family(Id id)
|
|||
return ASTROBWT;
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_KAWPOW
|
||||
case KAWPOW_RVN:
|
||||
return KAWPOW;
|
||||
# endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -56,7 +56,6 @@ public:
|
|||
CN_RWZ, // "cn/rwz" CryptoNight variant 2 with 3/4 iterations and reversed shuffle operation (Graft).
|
||||
CN_ZLS, // "cn/zls" CryptoNight variant 2 with 3/4 iterations (Zelerius).
|
||||
CN_DOUBLE, // "cn/double" CryptoNight variant 2 with double iterations (X-CASH).
|
||||
CN_GPU, // "cn/gpu" CryptoNight-GPU (Ryo).
|
||||
CN_LITE_0, // "cn-lite/0" CryptoNight-Lite variant 0.
|
||||
CN_LITE_1, // "cn-lite/1" CryptoNight-Lite variant 1.
|
||||
CN_HEAVY_0, // "cn-heavy/0" CryptoNight-Heavy (4 MB).
|
||||
|
@ -64,6 +63,7 @@ public:
|
|||
CN_HEAVY_XHV, // "cn-heavy/xhv" CryptoNight-Heavy (modified, Haven Protocol only).
|
||||
CN_PICO_0, // "cn-pico" CryptoNight-Pico
|
||||
CN_PICO_TLO, // "cn-pico/tlo" CryptoNight-Pico (TLO)
|
||||
CN_CCX, // "cn/ccx" Conceal (CCX)
|
||||
RX_0, // "rx/0" RandomX (reference configuration).
|
||||
RX_WOW, // "rx/wow" RandomWOW (Wownero).
|
||||
RX_LOKI, // "rx/loki" RandomXL (Loki).
|
||||
|
@ -74,6 +74,7 @@ public:
|
|||
AR2_CHUKWA, // "argon2/chukwa" Argon2id (Chukwa).
|
||||
AR2_WRKZ, // "argon2/wrkz" Argon2id (WRKZ)
|
||||
ASTROBWT_DERO, // "astrobwt" AstroBWT (Dero)
|
||||
KAWPOW_RVN, // "kawpow/rvn" KawPow (RVN)
|
||||
MAX
|
||||
};
|
||||
|
||||
|
@ -85,7 +86,8 @@ public:
|
|||
CN_PICO,
|
||||
RANDOM_X,
|
||||
ARGON2,
|
||||
ASTROBWT
|
||||
ASTROBWT,
|
||||
KAWPOW
|
||||
};
|
||||
|
||||
inline Algorithm() = default;
|
||||
|
|
|
@ -47,12 +47,16 @@ struct CoinName
|
|||
|
||||
|
||||
static CoinName const coin_names[] = {
|
||||
{ "monero", Coin::MONERO },
|
||||
{ "xmr", Coin::MONERO },
|
||||
{ "arqma", Coin::ARQMA },
|
||||
{ "arq", Coin::ARQMA },
|
||||
{ "dero", Coin::DERO },
|
||||
{ "keva", Coin::KEVA }
|
||||
{ "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 }
|
||||
};
|
||||
|
||||
|
||||
|
@ -75,6 +79,12 @@ xmrig::Algorithm::Id xmrig::Coin::algorithm(uint8_t blobVersion) const
|
|||
case KEVA:
|
||||
return (blobVersion >= 11) ? Algorithm::RX_KEVA : Algorithm::CN_R;
|
||||
|
||||
case RAVEN:
|
||||
return Algorithm::KAWPOW_RVN;
|
||||
|
||||
case CONCEAL:
|
||||
return Algorithm::CN_CCX;
|
||||
|
||||
case INVALID:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,9 @@ public:
|
|||
MONERO,
|
||||
ARQMA,
|
||||
DERO,
|
||||
KEVA
|
||||
KEVA,
|
||||
RAVEN,
|
||||
CONCEAL
|
||||
};
|
||||
|
||||
|
||||
|
@ -55,7 +57,7 @@ public:
|
|||
inline bool isValid() const { return m_id != INVALID; }
|
||||
inline Id id() const { return m_id; }
|
||||
|
||||
Algorithm::Id algorithm(uint8_t blobVersion) const;
|
||||
Algorithm::Id algorithm(uint8_t blobVersion = 255) const;
|
||||
const char *name() const;
|
||||
rapidjson::Value toJSON() const;
|
||||
|
||||
|
|
258
src/base/crypto/sha3.cpp
Normal file
258
src/base/crypto/sha3.cpp
Normal file
|
@ -0,0 +1,258 @@
|
|||
/* -------------------------------------------------------------------------
|
||||
* Works when compiled for either 32-bit or 64-bit targets, optimized for
|
||||
* 64 bit.
|
||||
*
|
||||
* Canonical implementation of Init/Update/Finalize for SHA-3 byte input.
|
||||
*
|
||||
* SHA3-256, SHA3-384, SHA-512 are implemented. SHA-224 can easily be added.
|
||||
*
|
||||
* Based on code from http://keccak.noekeon.org/ .
|
||||
*
|
||||
* I place the code that I wrote into public domain, free to use.
|
||||
*
|
||||
* I would appreciate if you give credits to this work if you used it to
|
||||
* write or test * your code.
|
||||
*
|
||||
* Aug 2015. Andrey Jivsov. crypto@brainhub.org
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "sha3.h"
|
||||
#include "base/crypto/keccak.h"
|
||||
|
||||
#define SHA3_ASSERT( x )
|
||||
#if defined(_MSC_VER)
|
||||
#define SHA3_TRACE( format, ...)
|
||||
#define SHA3_TRACE_BUF( format, buf, l, ...)
|
||||
#else
|
||||
#define SHA3_TRACE(format, args...)
|
||||
#define SHA3_TRACE_BUF(format, buf, l, args...)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This flag is used to configure "pure" Keccak, as opposed to NIST SHA3.
|
||||
*/
|
||||
#define SHA3_USE_KECCAK_FLAG 0x80000000
|
||||
#define SHA3_CW(x) ((x) & (~SHA3_USE_KECCAK_FLAG))
|
||||
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define SHA3_CONST(x) x
|
||||
#else
|
||||
#define SHA3_CONST(x) x##L
|
||||
#endif
|
||||
|
||||
#define KECCAK_ROUNDS 24
|
||||
|
||||
|
||||
/* *************************** Public Inteface ************************ */
|
||||
|
||||
/* For Init or Reset call these: */
|
||||
sha3_return_t
|
||||
sha3_Init(void *priv, unsigned bitSize) {
|
||||
sha3_context *ctx = (sha3_context *) priv;
|
||||
if( bitSize != 256 && bitSize != 384 && bitSize != 512 )
|
||||
return SHA3_RETURN_BAD_PARAMS;
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
ctx->capacityWords = 2 * bitSize / (8 * sizeof(uint64_t));
|
||||
return SHA3_RETURN_OK;
|
||||
}
|
||||
|
||||
void
|
||||
sha3_Init256(void *priv)
|
||||
{
|
||||
sha3_Init(priv, 256);
|
||||
}
|
||||
|
||||
void
|
||||
sha3_Init384(void *priv)
|
||||
{
|
||||
sha3_Init(priv, 384);
|
||||
}
|
||||
|
||||
void
|
||||
sha3_Init512(void *priv)
|
||||
{
|
||||
sha3_Init(priv, 512);
|
||||
}
|
||||
|
||||
SHA3_FLAGS
|
||||
sha3_SetFlags(void *priv, SHA3_FLAGS flags)
|
||||
{
|
||||
sha3_context *ctx = (sha3_context *) priv;
|
||||
flags = static_cast<SHA3_FLAGS>(static_cast<int>(flags) & SHA3_FLAGS_KECCAK);
|
||||
ctx->capacityWords |= (flags == SHA3_FLAGS_KECCAK ? SHA3_USE_KECCAK_FLAG : 0);
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sha3_Update(void *priv, void const *bufIn, size_t len)
|
||||
{
|
||||
sha3_context *ctx = (sha3_context *) priv;
|
||||
|
||||
/* 0...7 -- how much is needed to have a word */
|
||||
unsigned old_tail = (8 - ctx->byteIndex) & 7;
|
||||
|
||||
size_t words;
|
||||
unsigned tail;
|
||||
size_t i;
|
||||
|
||||
const uint8_t *buf = reinterpret_cast<const uint8_t*>(bufIn);
|
||||
|
||||
SHA3_TRACE_BUF("called to update with:", buf, len);
|
||||
|
||||
SHA3_ASSERT(ctx->byteIndex < 8);
|
||||
SHA3_ASSERT(ctx->wordIndex < sizeof(ctx->s) / sizeof(ctx->s[0]));
|
||||
|
||||
if(len < old_tail) { /* have no complete word or haven't started
|
||||
* the word yet */
|
||||
SHA3_TRACE("because %d<%d, store it and return", (unsigned)len,
|
||||
(unsigned)old_tail);
|
||||
/* endian-independent code follows: */
|
||||
while (len--)
|
||||
ctx->saved |= (uint64_t) (*(buf++)) << ((ctx->byteIndex++) * 8);
|
||||
SHA3_ASSERT(ctx->byteIndex < 8);
|
||||
return;
|
||||
}
|
||||
|
||||
if(old_tail) { /* will have one word to process */
|
||||
SHA3_TRACE("completing one word with %d bytes", (unsigned)old_tail);
|
||||
/* endian-independent code follows: */
|
||||
len -= old_tail;
|
||||
while (old_tail--)
|
||||
ctx->saved |= (uint64_t) (*(buf++)) << ((ctx->byteIndex++) * 8);
|
||||
|
||||
/* now ready to add saved to the sponge */
|
||||
ctx->s[ctx->wordIndex] ^= ctx->saved;
|
||||
SHA3_ASSERT(ctx->byteIndex == 8);
|
||||
ctx->byteIndex = 0;
|
||||
ctx->saved = 0;
|
||||
if(++ctx->wordIndex ==
|
||||
(SHA3_KECCAK_SPONGE_WORDS - SHA3_CW(ctx->capacityWords))) {
|
||||
xmrig::keccakf(ctx->s, KECCAK_ROUNDS);
|
||||
ctx->wordIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* now work in full words directly from input */
|
||||
|
||||
SHA3_ASSERT(ctx->byteIndex == 0);
|
||||
|
||||
words = len / sizeof(uint64_t);
|
||||
tail = len - words * sizeof(uint64_t);
|
||||
|
||||
SHA3_TRACE("have %d full words to process", (unsigned)words);
|
||||
|
||||
for(i = 0; i < words; i++, buf += sizeof(uint64_t)) {
|
||||
const uint64_t t = (uint64_t) (buf[0]) |
|
||||
((uint64_t) (buf[1]) << 8 * 1) |
|
||||
((uint64_t) (buf[2]) << 8 * 2) |
|
||||
((uint64_t) (buf[3]) << 8 * 3) |
|
||||
((uint64_t) (buf[4]) << 8 * 4) |
|
||||
((uint64_t) (buf[5]) << 8 * 5) |
|
||||
((uint64_t) (buf[6]) << 8 * 6) |
|
||||
((uint64_t) (buf[7]) << 8 * 7);
|
||||
#if defined(__x86_64__ ) || defined(__i386__)
|
||||
SHA3_ASSERT(memcmp(&t, buf, 8) == 0);
|
||||
#endif
|
||||
ctx->s[ctx->wordIndex] ^= t;
|
||||
if(++ctx->wordIndex ==
|
||||
(SHA3_KECCAK_SPONGE_WORDS - SHA3_CW(ctx->capacityWords))) {
|
||||
xmrig::keccakf(ctx->s, KECCAK_ROUNDS);
|
||||
ctx->wordIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SHA3_TRACE("have %d bytes left to process, save them", (unsigned)tail);
|
||||
|
||||
/* finally, save the partial word */
|
||||
SHA3_ASSERT(ctx->byteIndex == 0 && tail < 8);
|
||||
while (tail--) {
|
||||
SHA3_TRACE("Store byte %02x '%c'", *buf, *buf);
|
||||
ctx->saved |= (uint64_t) (*(buf++)) << ((ctx->byteIndex++) * 8);
|
||||
}
|
||||
SHA3_ASSERT(ctx->byteIndex < 8);
|
||||
SHA3_TRACE("Have saved=0x%016" PRIx64 " at the end", ctx->saved);
|
||||
}
|
||||
|
||||
/* This is simply the 'update' with the padding block.
|
||||
* The padding block is 0x01 || 0x00* || 0x80. First 0x01 and last 0x80
|
||||
* bytes are always present, but they can be the same byte.
|
||||
*/
|
||||
void const *
|
||||
sha3_Finalize(void *priv)
|
||||
{
|
||||
sha3_context *ctx = (sha3_context *) priv;
|
||||
|
||||
SHA3_TRACE("called with %d bytes in the buffer", ctx->byteIndex);
|
||||
|
||||
/* Append 2-bit suffix 01, per SHA-3 spec. Instead of 1 for padding we
|
||||
* use 1<<2 below. The 0x02 below corresponds to the suffix 01.
|
||||
* Overall, we feed 0, then 1, and finally 1 to start padding. Without
|
||||
* M || 01, we would simply use 1 to start padding. */
|
||||
|
||||
uint64_t t;
|
||||
|
||||
if( ctx->capacityWords & SHA3_USE_KECCAK_FLAG ) {
|
||||
/* Keccak version */
|
||||
t = (uint64_t)(((uint64_t) 1) << (ctx->byteIndex * 8));
|
||||
}
|
||||
else {
|
||||
/* SHA3 version */
|
||||
t = (uint64_t)(((uint64_t)(0x02 | (1 << 2))) << ((ctx->byteIndex) * 8));
|
||||
}
|
||||
|
||||
ctx->s[ctx->wordIndex] ^= ctx->saved ^ t;
|
||||
|
||||
ctx->s[SHA3_KECCAK_SPONGE_WORDS - SHA3_CW(ctx->capacityWords) - 1] ^=
|
||||
SHA3_CONST(0x8000000000000000UL);
|
||||
xmrig::keccakf(ctx->s, KECCAK_ROUNDS);
|
||||
|
||||
/* Return first bytes of the ctx->s. This conversion is not needed for
|
||||
* little-endian platforms e.g. wrap with #if !defined(__BYTE_ORDER__)
|
||||
* || !defined(__ORDER_LITTLE_ENDIAN__) || __BYTE_ORDER__!=__ORDER_LITTLE_ENDIAN__
|
||||
* ... the conversion below ...
|
||||
* #endif */
|
||||
{
|
||||
unsigned i;
|
||||
for(i = 0; i < SHA3_KECCAK_SPONGE_WORDS; i++) {
|
||||
const unsigned t1 = (uint32_t) ctx->s[i];
|
||||
const unsigned t2 = (uint32_t) ((ctx->s[i] >> 16) >> 16);
|
||||
ctx->sb[i * 8 + 0] = (uint8_t) (t1);
|
||||
ctx->sb[i * 8 + 1] = (uint8_t) (t1 >> 8);
|
||||
ctx->sb[i * 8 + 2] = (uint8_t) (t1 >> 16);
|
||||
ctx->sb[i * 8 + 3] = (uint8_t) (t1 >> 24);
|
||||
ctx->sb[i * 8 + 4] = (uint8_t) (t2);
|
||||
ctx->sb[i * 8 + 5] = (uint8_t) (t2 >> 8);
|
||||
ctx->sb[i * 8 + 6] = (uint8_t) (t2 >> 16);
|
||||
ctx->sb[i * 8 + 7] = (uint8_t) (t2 >> 24);
|
||||
}
|
||||
}
|
||||
|
||||
SHA3_TRACE_BUF("Hash: (first 32 bytes)", ctx->sb, 256 / 8);
|
||||
|
||||
return (ctx->sb);
|
||||
}
|
||||
|
||||
extern "C" sha3_return_t sha3_HashBuffer( unsigned bitSize, enum SHA3_FLAGS flags, const void *in, unsigned inBytes, void *out, unsigned outBytes ) {
|
||||
sha3_return_t err;
|
||||
sha3_context c;
|
||||
|
||||
err = sha3_Init(&c, bitSize);
|
||||
if( err != SHA3_RETURN_OK )
|
||||
return err;
|
||||
if( sha3_SetFlags(&c, flags) != flags ) {
|
||||
return SHA3_RETURN_BAD_PARAMS;
|
||||
}
|
||||
sha3_Update(&c, in, inBytes);
|
||||
const void *h = sha3_Finalize(&c);
|
||||
|
||||
if(outBytes > bitSize/8)
|
||||
outBytes = bitSize/8;
|
||||
memcpy(out, h, outBytes);
|
||||
return SHA3_RETURN_OK;
|
||||
}
|
73
src/base/crypto/sha3.h
Normal file
73
src/base/crypto/sha3.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
#ifndef SHA3_H
|
||||
#define SHA3_H
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Works when compiled for either 32-bit or 64-bit targets, optimized for
|
||||
* 64 bit.
|
||||
*
|
||||
* Canonical implementation of Init/Update/Finalize for SHA-3 byte input.
|
||||
*
|
||||
* SHA3-256, SHA3-384, SHA-512 are implemented. SHA-224 can easily be added.
|
||||
*
|
||||
* Based on code from http://keccak.noekeon.org/ .
|
||||
*
|
||||
* I place the code that I wrote into public domain, free to use.
|
||||
*
|
||||
* I would appreciate if you give credits to this work if you used it to
|
||||
* write or test * your code.
|
||||
*
|
||||
* Aug 2015. Andrey Jivsov. crypto@brainhub.org
|
||||
* ---------------------------------------------------------------------- */
|
||||
|
||||
/* 'Words' here refers to uint64_t */
|
||||
#define SHA3_KECCAK_SPONGE_WORDS \
|
||||
(((1600)/8/*bits to byte*/)/sizeof(uint64_t))
|
||||
typedef struct sha3_context_ {
|
||||
uint64_t saved; /* the portion of the input message that we
|
||||
* didn't consume yet */
|
||||
union { /* Keccak's state */
|
||||
uint64_t s[SHA3_KECCAK_SPONGE_WORDS];
|
||||
uint8_t sb[SHA3_KECCAK_SPONGE_WORDS * 8];
|
||||
};
|
||||
unsigned byteIndex; /* 0..7--the next byte after the set one
|
||||
* (starts from 0; 0--none are buffered) */
|
||||
unsigned wordIndex; /* 0..24--the next word to integrate input
|
||||
* (starts from 0) */
|
||||
unsigned capacityWords; /* the double size of the hash output in
|
||||
* words (e.g. 16 for Keccak 512) */
|
||||
} sha3_context;
|
||||
|
||||
enum SHA3_FLAGS {
|
||||
SHA3_FLAGS_NONE=0,
|
||||
SHA3_FLAGS_KECCAK=1
|
||||
};
|
||||
|
||||
enum SHA3_RETURN {
|
||||
SHA3_RETURN_OK=0,
|
||||
SHA3_RETURN_BAD_PARAMS=1
|
||||
};
|
||||
typedef enum SHA3_RETURN sha3_return_t;
|
||||
|
||||
/* For Init or Reset call these: */
|
||||
sha3_return_t sha3_Init(void *priv, unsigned bitSize);
|
||||
|
||||
void sha3_Init256(void *priv);
|
||||
void sha3_Init384(void *priv);
|
||||
void sha3_Init512(void *priv);
|
||||
|
||||
enum SHA3_FLAGS sha3_SetFlags(void *priv, enum SHA3_FLAGS);
|
||||
|
||||
void sha3_Update(void *priv, void const *bufIn, size_t len);
|
||||
|
||||
void const *sha3_Finalize(void *priv);
|
||||
|
||||
/* Single-call hashing */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
sha3_return_t sha3_HashBuffer(
|
||||
unsigned bitSize, /* 256, 384, 512 */
|
||||
enum SHA3_FLAGS flags, /* SHA3_FLAGS_NONE or SHA3_FLAGS_KECCAK */
|
||||
const void *in, unsigned inBytes,
|
||||
void *out, unsigned outBytes ); /* up to bitSize/8; truncation OK */
|
||||
#endif
|
|
@ -142,8 +142,11 @@ private:
|
|||
#define LOG_NOTICE(x, ...) xmrig::Log::print(xmrig::Log::NOTICE, x, ##__VA_ARGS__)
|
||||
#define LOG_INFO(x, ...) xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__)
|
||||
#define LOG_VERBOSE(x, ...) if (xmrig::Log::verbose() > 0) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); }
|
||||
#define LOG_V(x, ...) if (xmrig::Log::verbose() > 0) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); }
|
||||
#define LOG_VV(x, ...) if (xmrig::Log::verbose() > 1) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); }
|
||||
#define LOG_V1(x, ...) if (xmrig::Log::verbose() > 0) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); }
|
||||
#define LOG_V2(x, ...) if (xmrig::Log::verbose() > 1) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); }
|
||||
#define LOG_V3(x, ...) if (xmrig::Log::verbose() > 2) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); }
|
||||
#define LOG_V4(x, ...) if (xmrig::Log::verbose() > 3) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); }
|
||||
#define LOG_V5(x, ...) if (xmrig::Log::verbose() > 4) { xmrig::Log::print(xmrig::Log::INFO, x, ##__VA_ARGS__); }
|
||||
|
||||
#ifdef APP_DEBUG
|
||||
# define LOG_DEBUG(x, ...) xmrig::Log::print(xmrig::Log::DEBUG, x, ##__VA_ARGS__)
|
||||
|
|
93
src/base/io/log/Tags.cpp
Normal file
93
src/base/io/log/Tags.cpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
/* XMRig
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/io/log/Tags.h"
|
||||
#include "base/io/log/Log.h"
|
||||
|
||||
|
||||
const char *xmrig::Tags::config()
|
||||
{
|
||||
static const char *tag = CYAN_BG_BOLD(WHITE_BOLD_S " config ");
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Tags::network()
|
||||
{
|
||||
static const char *tag = BLUE_BG_BOLD(WHITE_BOLD_S " net ");
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Tags::signal()
|
||||
{
|
||||
static const char *tag = YELLOW_BG_BOLD(WHITE_BOLD_S " signal ");
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_MINER_PROJECT
|
||||
const char *xmrig::Tags::cpu()
|
||||
{
|
||||
static const char *tag = CYAN_BG_BOLD(WHITE_BOLD_S " cpu ");
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::Tags::miner()
|
||||
{
|
||||
static const char *tag = MAGENTA_BG_BOLD(WHITE_BOLD_S " miner ");
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_ALGO_RANDOMX
|
||||
const char *xmrig::Tags::randomx()
|
||||
{
|
||||
static const char *tag = BLUE_BG(WHITE_BOLD_S " randomx ") " ";
|
||||
|
||||
return tag;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_CUDA
|
||||
const char *xmrig::Tags::nvidia()
|
||||
{
|
||||
static const char *tag = GREEN_BG_BOLD(WHITE_BOLD_S " nvidia ");
|
||||
|
||||
return tag;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_OPENCL
|
||||
const char *xmrig::Tags::opencl()
|
||||
{
|
||||
static const char *tag = MAGENTA_BG_BOLD(WHITE_BOLD_S " opencl ");
|
||||
|
||||
return tag;
|
||||
}
|
||||
#endif
|
58
src/base/io/log/Tags.h
Normal file
58
src/base/io/log/Tags.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* XMRig
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_TAGS_H
|
||||
#define XMRIG_TAGS_H
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Tags
|
||||
{
|
||||
public:
|
||||
static const char *config();
|
||||
static const char *network();
|
||||
static const char *signal();
|
||||
|
||||
# ifdef XMRIG_MINER_PROJECT
|
||||
static const char *cpu();
|
||||
static const char *miner();
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
static const char *randomx();
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_CUDA
|
||||
static const char *nvidia();
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_FEATURE_OPENCL
|
||||
static const char *opencl();
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_TAGS_H */
|
|
@ -6,8 +6,8 @@
|
|||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 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,12 +28,13 @@
|
|||
|
||||
|
||||
#include "base/io/log/backends/ConsoleLog.h"
|
||||
#include "base/tools/Handle.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/config/Title.h"
|
||||
#include "base/tools/Handle.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
xmrig::ConsoleLog::ConsoleLog()
|
||||
xmrig::ConsoleLog::ConsoleLog(const Title &title)
|
||||
{
|
||||
if (!isSupported()) {
|
||||
Log::setColors(false);
|
||||
|
@ -61,7 +62,9 @@ xmrig::ConsoleLog::ConsoleLog()
|
|||
}
|
||||
}
|
||||
|
||||
SetConsoleTitleA(APP_NAME " " APP_VERSION);
|
||||
if (title.isEnabled()) {
|
||||
SetConsoleTitleA(title.value());
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2019 Spudz76 <https://github.com/Spudz76>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 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
|
||||
|
@ -38,12 +38,15 @@ using uv_tty_t = struct uv_tty_s;
|
|||
namespace xmrig {
|
||||
|
||||
|
||||
class Title;
|
||||
|
||||
|
||||
class ConsoleLog : public ILogBackend
|
||||
{
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE(ConsoleLog)
|
||||
|
||||
ConsoleLog();
|
||||
ConsoleLog(const Title &title);
|
||||
~ConsoleLog() override;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "base/io/log/backends/ConsoleLog.h"
|
||||
#include "base/io/log/backends/FileLog.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/io/log/Tags.h"
|
||||
#include "base/io/Watcher.h"
|
||||
#include "base/kernel/interfaces/IBaseListener.h"
|
||||
#include "base/kernel/Platform.h"
|
||||
|
@ -183,7 +184,7 @@ int xmrig::Base::init()
|
|||
Log::setBackground(true);
|
||||
}
|
||||
else {
|
||||
Log::add(new ConsoleLog());
|
||||
Log::add(new ConsoleLog(config()->title()));
|
||||
}
|
||||
|
||||
if (config()->logFile()) {
|
||||
|
@ -285,7 +286,7 @@ void xmrig::Base::addListener(IBaseListener *listener)
|
|||
|
||||
void xmrig::Base::onFileChanged(const String &fileName)
|
||||
{
|
||||
LOG_WARN("\"%s\" was changed, reloading configuration", fileName.data());
|
||||
LOG_WARN("%s " YELLOW("\"%s\" was changed, reloading configuration"), Tags::config(), fileName.data());
|
||||
|
||||
JsonChain chain;
|
||||
chain.addFile(fileName);
|
||||
|
@ -293,7 +294,7 @@ void xmrig::Base::onFileChanged(const String &fileName)
|
|||
auto config = new Config();
|
||||
|
||||
if (!config->read(chain, chain.fileName())) {
|
||||
LOG_ERR("reloading failed");
|
||||
LOG_ERR("%s " RED("reloading failed"), Tags::config());
|
||||
|
||||
delete config;
|
||||
return;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#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/IJsonReader.h"
|
||||
#include "version.h"
|
||||
|
||||
|
@ -62,6 +63,7 @@ const char *BaseConfig::kHttp = "http";
|
|||
const char *BaseConfig::kLogFile = "log-file";
|
||||
const char *BaseConfig::kPrintTime = "print-time";
|
||||
const char *BaseConfig::kSyslog = "syslog";
|
||||
const char *BaseConfig::kTitle = "title";
|
||||
const char *BaseConfig::kUserAgent = "user-agent";
|
||||
const char *BaseConfig::kVerbose = "verbose";
|
||||
const char *BaseConfig::kWatch = "watch";
|
||||
|
@ -91,6 +93,7 @@ bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName)
|
|||
m_logFile = reader.getString(kLogFile);
|
||||
m_userAgent = reader.getString(kUserAgent);
|
||||
m_printTime = std::min(reader.getUint(kPrintTime, m_printTime), 3600U);
|
||||
m_title = reader.getValue(kTitle);
|
||||
|
||||
m_rebenchAlgo = reader.getBool("rebench-algo", m_rebenchAlgo);
|
||||
m_benchAlgoTime = reader.getInt("bench-algo-time", m_benchAlgoTime);
|
||||
|
@ -125,7 +128,7 @@ bool xmrig::BaseConfig::save()
|
|||
getJSON(doc);
|
||||
|
||||
if (Json::save(m_fileName, doc)) {
|
||||
LOG_NOTICE("configuration saved to: \"%s\"", m_fileName.data());
|
||||
LOG_NOTICE("%s " WHITE_BOLD("configuration saved to: \"%s\""), Tags::config(), m_fileName.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#define XMRIG_BASECONFIG_H
|
||||
|
||||
|
||||
#include "base/kernel/config/Title.h"
|
||||
#include "base/kernel/interfaces/IConfig.h"
|
||||
#include "base/net/http/Http.h"
|
||||
#include "base/net/stratum/Pools.h"
|
||||
|
@ -56,6 +57,7 @@ public:
|
|||
static const char *kLogFile;
|
||||
static const char *kPrintTime;
|
||||
static const char *kSyslog;
|
||||
static const char *kTitle;
|
||||
static const char *kUserAgent;
|
||||
static const char *kVerbose;
|
||||
static const char *kWatch;
|
||||
|
@ -76,6 +78,7 @@ public:
|
|||
inline const Pools &pools() const { return m_pools; }
|
||||
inline const String &apiId() const { return m_apiId; }
|
||||
inline const String &apiWorkerId() const { return m_apiWorkerId; }
|
||||
inline const Title &title() const { return m_title; }
|
||||
inline uint32_t printTime() const { return m_printTime; }
|
||||
|
||||
inline bool isRebenchAlgo() const { return m_rebenchAlgo; }
|
||||
|
@ -108,6 +111,7 @@ protected:
|
|||
String m_fileName;
|
||||
String m_logFile;
|
||||
String m_userAgent;
|
||||
Title m_title;
|
||||
uint32_t m_printTime = 60;
|
||||
|
||||
bool m_rebenchAlgo = false;
|
||||
|
|
|
@ -204,6 +204,9 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
|
|||
case IConfig::UserAgentKey: /* --user-agent */
|
||||
return set(doc, BaseConfig::kUserAgent, arg);
|
||||
|
||||
case IConfig::TitleKey: /* --title */
|
||||
return set(doc, BaseConfig::kTitle, arg);
|
||||
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
case IConfig::TlsCertKey: /* --tls-cert */
|
||||
return set(doc, BaseConfig::kTls, TlsConfig::kCert, arg);
|
||||
|
@ -250,6 +253,7 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch
|
|||
|
||||
case IConfig::ColorKey: /* --no-color */
|
||||
case IConfig::HttpRestrictedKey: /* --http-no-restricted */
|
||||
case IConfig::NoTitleKey: /* --no-title */
|
||||
return transformBoolean(doc, key, false);
|
||||
|
||||
default:
|
||||
|
@ -303,6 +307,9 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b
|
|||
case IConfig::VerboseKey: /* --verbose */
|
||||
return set(doc, BaseConfig::kVerbose, enable);
|
||||
|
||||
case IConfig::NoTitleKey: /* --no-title */
|
||||
return set(doc, BaseConfig::kTitle, enable);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
58
src/base/kernel/config/Title.cpp
Normal file
58
src/base/kernel/config/Title.cpp
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* XMRig
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/kernel/config/Title.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "base/io/Env.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
xmrig::Title::Title(const rapidjson::Value &value)
|
||||
{
|
||||
if (value.IsBool()) {
|
||||
m_enabled = value.GetBool();
|
||||
}
|
||||
else if (value.IsString()) {
|
||||
m_value = value.GetString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rapidjson::Value xmrig::Title::toJSON() const
|
||||
{
|
||||
if (isEnabled() && !m_value.isNull()) {
|
||||
return m_value.toJSON();
|
||||
}
|
||||
|
||||
return rapidjson::Value(m_enabled);
|
||||
}
|
||||
|
||||
|
||||
xmrig::String xmrig::Title::value() const
|
||||
{
|
||||
if (!isEnabled()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (m_value.isNull()) {
|
||||
return APP_NAME " " APP_VERSION;
|
||||
}
|
||||
|
||||
return Env::expand(m_value);
|
||||
}
|
50
src/base/kernel/config/Title.h
Normal file
50
src/base/kernel/config/Title.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* XMRig
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_TITLE_H
|
||||
#define XMRIG_TITLE_H
|
||||
|
||||
|
||||
#include "3rdparty/rapidjson/fwd.h"
|
||||
#include "base/tools/String.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Title
|
||||
{
|
||||
public:
|
||||
Title() = default;
|
||||
Title(const rapidjson::Value &value);
|
||||
|
||||
inline bool isEnabled() const { return m_enabled; }
|
||||
|
||||
rapidjson::Value toJSON() const;
|
||||
String value() const;
|
||||
|
||||
private:
|
||||
bool m_enabled = true;
|
||||
String m_value;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_TITLE_H */
|
|
@ -64,6 +64,7 @@ public:
|
|||
virtual bool isEnabled() const = 0;
|
||||
virtual bool isTLS() const = 0;
|
||||
virtual const char *mode() const = 0;
|
||||
virtual const char *tag() const = 0;
|
||||
virtual const char *tlsFingerprint() const = 0;
|
||||
virtual const char *tlsVersion() const = 0;
|
||||
virtual const Job &job() const = 0;
|
||||
|
|
|
@ -74,6 +74,8 @@ public:
|
|||
DaemonPollKey = 1019,
|
||||
SelfSelectKey = 1028,
|
||||
DataDirKey = 1035,
|
||||
TitleKey = 1037,
|
||||
NoTitleKey = 1038,
|
||||
|
||||
// xmrig common
|
||||
CPUPriorityKey = 1021,
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
|
||||
#include "3rdparty/rapidjson/fwd.h"
|
||||
#include "base/tools/Object.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
@ -42,10 +43,13 @@ class SubmitResult;
|
|||
class IStrategyListener
|
||||
{
|
||||
public:
|
||||
virtual ~IStrategyListener() = default;
|
||||
XMRIG_DISABLE_COPY_MOVE(IStrategyListener);
|
||||
|
||||
IStrategyListener() = default;
|
||||
virtual ~IStrategyListener() = default;
|
||||
|
||||
virtual void onActive(IStrategy *strategy, IClient *client) = 0;
|
||||
virtual void onJob(IStrategy *strategy, IClient *client, const Job &job) = 0;
|
||||
virtual void onJob(IStrategy *strategy, IClient *client, const Job &job, const rapidjson::Value ¶ms) = 0;
|
||||
virtual void onLogin(IStrategy *strategy, IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) = 0;
|
||||
virtual void onPause(IStrategy *strategy) = 0;
|
||||
virtual void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) = 0;
|
||||
|
|
90
src/base/net/stratum/AutoClient.cpp
Normal file
90
src/base/net/stratum/AutoClient.cpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* XMRig
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/net/stratum/AutoClient.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "base/io/json/Json.h"
|
||||
|
||||
|
||||
xmrig::AutoClient::AutoClient(int id, const char *agent, IClientListener *listener) :
|
||||
EthStratumClient(id, agent, listener)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::AutoClient::handleResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error)
|
||||
{
|
||||
if (m_mode == DEFAULT_MODE) {
|
||||
return Client::handleResponse(id, result, error);
|
||||
}
|
||||
|
||||
return EthStratumClient::handleResponse(id, result, error);
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::AutoClient::parseLogin(const rapidjson::Value &result, int *code)
|
||||
{
|
||||
if (result.HasMember("job")) {
|
||||
return Client::parseLogin(result, code);
|
||||
}
|
||||
|
||||
setRpcId(Json::getString(result, "id"));
|
||||
if (rpcId().isNull()) {
|
||||
*code = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
const Algorithm algo(Json::getString(result, "algo"));
|
||||
if (algo.family() != Algorithm::KAWPOW) {
|
||||
*code = 6;
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
setExtraNonce(Json::getValue(result, "extra_nonce"));
|
||||
} catch (const std::exception &ex) {
|
||||
*code = 6;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_mode = ETH_MODE;
|
||||
setAlgo(algo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int64_t xmrig::AutoClient::submit(const JobResult &result)
|
||||
{
|
||||
if (m_mode == DEFAULT_MODE) {
|
||||
return Client::submit(result);
|
||||
}
|
||||
|
||||
return EthStratumClient::submit(result);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::AutoClient::parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error)
|
||||
{
|
||||
if (m_mode == DEFAULT_MODE) {
|
||||
return Client::parseNotification(method, params, error);
|
||||
}
|
||||
|
||||
return EthStratumClient::parseNotification(method, params, error);
|
||||
}
|
61
src/base/net/stratum/AutoClient.h
Normal file
61
src/base/net/stratum/AutoClient.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* XMRig
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_AUTOCLIENT_H
|
||||
#define XMRIG_AUTOCLIENT_H
|
||||
|
||||
|
||||
#include "base/net/stratum/EthStratumClient.h"
|
||||
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class AutoClient : public EthStratumClient
|
||||
{
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE_DEFAULT(AutoClient)
|
||||
|
||||
AutoClient(int id, const char *agent, IClientListener *listener);
|
||||
~AutoClient() override = default;
|
||||
|
||||
protected:
|
||||
inline void login() override { Client::login(); }
|
||||
|
||||
bool handleResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error) override;
|
||||
bool parseLogin(const rapidjson::Value &result, int *code) override;
|
||||
int64_t submit(const JobResult &result) override;
|
||||
void parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error) override;
|
||||
|
||||
private:
|
||||
enum Mode {
|
||||
DEFAULT_MODE,
|
||||
ETH_MODE
|
||||
};
|
||||
|
||||
Mode m_mode = DEFAULT_MODE;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_AUTOCLIENT_H */
|
|
@ -26,6 +26,8 @@
|
|||
#include "base/net/stratum/BaseClient.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "base/io/Env.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/io/log/Tags.h"
|
||||
#include "base/kernel/interfaces/IClientListener.h"
|
||||
#include "base/net/stratum/SubmitResult.h"
|
||||
|
||||
|
@ -56,6 +58,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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
|
||||
protected:
|
||||
inline bool isEnabled() const override { return m_enabled; }
|
||||
inline const char *tag() const override { return m_tag.c_str(); }
|
||||
inline const Job &job() const override { return m_job; }
|
||||
inline const Pool &pool() const override { return m_pool; }
|
||||
inline const String &ip() const override { return m_ip; }
|
||||
|
@ -83,7 +84,7 @@ protected:
|
|||
|
||||
inline bool isQuiet() const { return m_quiet || m_failures >= m_retries; }
|
||||
|
||||
bool handleResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
|
||||
virtual bool handleResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
|
||||
bool handleSubmitResponse(int64_t id, const char *error = nullptr);
|
||||
|
||||
bool m_quiet = false;
|
||||
|
@ -96,6 +97,7 @@ protected:
|
|||
SocketState m_state = UnconnectedState;
|
||||
std::map<int64_t, SendResult> m_callbacks;
|
||||
std::map<int64_t, SubmitResult> m_results;
|
||||
std::string m_tag;
|
||||
String m_ip;
|
||||
String m_password;
|
||||
String m_rigId;
|
||||
|
|
|
@ -161,7 +161,7 @@ int64_t xmrig::Client::send(const rapidjson::Value &obj)
|
|||
|
||||
const size_t size = buffer.GetSize();
|
||||
if (size > kMaxSendBufferSize) {
|
||||
LOG_ERR("[%s] send failed: \"max send buffer size exceeded: %zu\"", url(), size);
|
||||
LOG_ERR("%s " RED("send failed: ") RED_BOLD("\"max send buffer size exceeded: %zu\""), tag(), size);
|
||||
close();
|
||||
|
||||
return -1;
|
||||
|
@ -307,7 +307,7 @@ void xmrig::Client::onResolved(const Dns &dns, int status)
|
|||
|
||||
if (status < 0 && dns.isEmpty()) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] DNS error: \"%s\"", url(), uv_strerror(status));
|
||||
LOG_ERR("%s " RED("DNS error: ") RED_BOLD("\"%s\""), tag(), uv_strerror(status));
|
||||
}
|
||||
|
||||
return reconnect();
|
||||
|
@ -420,10 +420,6 @@ bool xmrig::Client::parseJob(const rapidjson::Value ¶ms, int *code)
|
|||
}
|
||||
|
||||
if (m_pool.mode() != Pool::MODE_SELF_SELECT && job.algorithm().family() == Algorithm::RANDOM_X && !job.setSeedHash(Json::getString(params, "seed_hash"))) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] failed to parse field \"seed_hash\" required by RandomX", url(), algo);
|
||||
}
|
||||
|
||||
*code = 7;
|
||||
return false;
|
||||
}
|
||||
|
@ -441,7 +437,7 @@ bool xmrig::Client::parseJob(const rapidjson::Value ¶ms, int *code)
|
|||
}
|
||||
|
||||
if (!isQuiet()) {
|
||||
LOG_WARN("[%s] duplicate job received, reconnect", url());
|
||||
LOG_WARN("%s " YELLOW("duplicate job received, reconnect"), tag());
|
||||
}
|
||||
|
||||
close();
|
||||
|
@ -449,23 +445,6 @@ bool xmrig::Client::parseJob(const rapidjson::Value ¶ms, int *code)
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::Client::parseLogin(const rapidjson::Value &result, int *code)
|
||||
{
|
||||
m_rpcId = result["id"].GetString();
|
||||
if (m_rpcId.isNull()) {
|
||||
*code = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
parseExtensions(result);
|
||||
|
||||
const bool rc = parseJob(result["job"], code);
|
||||
m_jobs = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Client::send(BIO *bio)
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
|
@ -500,10 +479,10 @@ bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm, const char *algo
|
|||
if (!algorithm.isValid()) {
|
||||
if (!isQuiet()) {
|
||||
if (algo == nullptr) {
|
||||
LOG_ERR("[%s] unknown algorithm, make sure you set \"algo\" or \"coin\" option", url(), algo);
|
||||
LOG_ERR("%s " RED("unknown algorithm, make sure you set \"algo\" or \"coin\" option"), tag(), algo);
|
||||
}
|
||||
else {
|
||||
LOG_ERR("[%s] unsupported algorithm \"%s\" detected, reconnect", url(), algo);
|
||||
LOG_ERR("%s " RED("unsupported algorithm ") RED_BOLD("\"%s\" ") RED("detected, reconnect"), tag(), algo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,7 +493,7 @@ bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm, const char *algo
|
|||
m_listener->onVerifyAlgorithm(this, algorithm, &ok);
|
||||
|
||||
if (!ok && !isQuiet()) {
|
||||
LOG_ERR("[%s] incompatible/disabled algorithm \"%s\" detected, reconnect", url(), algorithm.shortName());
|
||||
LOG_ERR("%s " RED("incompatible/disabled algorithm ") RED_BOLD("\"%s\" ") RED("detected, reconnect"), tag(), algorithm.shortName());
|
||||
}
|
||||
|
||||
return ok;
|
||||
|
@ -529,7 +508,7 @@ bool xmrig::Client::write(const uv_buf_t &buf)
|
|||
}
|
||||
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] write error: \"%s\"", url(), uv_strerror(rc));
|
||||
LOG_ERR("%s " RED("write error: ") RED_BOLD("\"%s\""), tag(), uv_strerror(rc));
|
||||
}
|
||||
|
||||
close();
|
||||
|
@ -550,7 +529,7 @@ int xmrig::Client::resolve(const String &host)
|
|||
|
||||
if (!m_dns->resolve(host)) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s:%u] getaddrinfo error: \"%s\"", host.data(), m_pool.port(), uv_strerror(m_dns->status()));
|
||||
LOG_ERR("%s " RED("getaddrinfo error: ") RED_BOLD("\"%s\""), tag(), uv_strerror(m_dns->status()));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -633,6 +612,23 @@ void xmrig::Client::handshake()
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::Client::parseLogin(const rapidjson::Value &result, int *code)
|
||||
{
|
||||
setRpcId(Json::getString(result, "id"));
|
||||
if (rpcId().isNull()) {
|
||||
*code = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
parseExtensions(result);
|
||||
|
||||
const bool rc = parseJob(result["job"], code);
|
||||
m_jobs = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Client::login()
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
@ -644,7 +640,7 @@ void xmrig::Client::login()
|
|||
Value params(kObjectType);
|
||||
params.AddMember("login", m_user.toJSON(), allocator);
|
||||
params.AddMember("pass", m_password.toJSON(), allocator);
|
||||
params.AddMember("agent", StringRef(m_agent), allocator);
|
||||
params.AddMember("agent", StringRef(m_agent), allocator);
|
||||
|
||||
if (!m_rigId.isNull()) {
|
||||
params.AddMember("rigid", m_rigId.toJSON(), allocator);
|
||||
|
@ -684,7 +680,7 @@ void xmrig::Client::parse(char *line, size_t len)
|
|||
|
||||
if (len < 32 || line[0] != '{') {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] JSON decode failed", url());
|
||||
LOG_ERR("%s " RED("JSON decode failed"), tag());
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -693,7 +689,7 @@ void xmrig::Client::parse(char *line, size_t len)
|
|||
rapidjson::Document doc;
|
||||
if (doc.ParseInsitu(line).HasParseError()) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] JSON decode failed: \"%s\"", url(), rapidjson::GetParseError_En(doc.GetParseError()));
|
||||
LOG_ERR("%s " RED("JSON decode failed: ") RED_BOLD("\"%s\""), tag(), rapidjson::GetParseError_En(doc.GetParseError()));
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -703,13 +699,28 @@ void xmrig::Client::parse(char *line, size_t len)
|
|||
return;
|
||||
}
|
||||
|
||||
const rapidjson::Value &id = doc["id"];
|
||||
const auto &id = Json::getValue(doc, "id");
|
||||
const auto &error = Json::getValue(doc, "error");
|
||||
|
||||
if (id.IsInt64()) {
|
||||
parseResponse(id.GetInt64(), doc["result"], doc["error"]);
|
||||
return parseResponse(id.GetInt64(), Json::getValue(doc, "result"), error);
|
||||
}
|
||||
else {
|
||||
parseNotification(doc["method"].GetString(), doc["params"], doc["error"]);
|
||||
|
||||
const char *method = Json::getString(doc, "method");
|
||||
if (!method) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (error.IsObject()) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("%s " RED("error: ") RED_BOLD("\"%s\"") RED(", code: ") RED_BOLD("%d"),
|
||||
tag(), Json::getString(error, "message"), Json::getInt(error, "code"));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
parseNotification(method, Json::getValue(doc, "params"), error);
|
||||
}
|
||||
|
||||
|
||||
|
@ -755,19 +766,8 @@ void xmrig::Client::parseExtensions(const rapidjson::Value &result)
|
|||
}
|
||||
|
||||
|
||||
void xmrig::Client::parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error)
|
||||
void xmrig::Client::parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &)
|
||||
{
|
||||
if (error.IsObject()) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] error: \"%s\", code: %d", url(), error["message"].GetString(), error["code"].GetInt());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!method) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(method, "job") == 0) {
|
||||
int code = -1;
|
||||
if (parseJob(params, &code)) {
|
||||
|
@ -779,8 +779,6 @@ void xmrig::Client::parseNotification(const char *method, const rapidjson::Value
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_WARN("[%s] unsupported method: \"%s\"", url(), method);
|
||||
}
|
||||
|
||||
|
||||
|
@ -794,7 +792,7 @@ void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, co
|
|||
const char *message = error["message"].GetString();
|
||||
|
||||
if (!handleSubmitResponse(id, message) && !isQuiet()) {
|
||||
LOG_ERR("[%s] error: " RED_BOLD("\"%s\"") RED_S ", code: %d", url(), message, error["code"].GetInt());
|
||||
LOG_ERR("%s " RED("error: ") RED_BOLD("\"%s\"") RED(", code: ") RED_BOLD("%d"), tag(), message, Json::getInt(error, "code"));
|
||||
}
|
||||
|
||||
if (m_id == 1 || isCriticalError(message)) {
|
||||
|
@ -812,7 +810,7 @@ void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, co
|
|||
int code = -1;
|
||||
if (!parseLogin(result, &code)) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] login error code: %d", url(), code);
|
||||
LOG_ERR("%s " RED("login error code: ") RED_BOLD("%d"), tag(), code);
|
||||
}
|
||||
|
||||
close();
|
||||
|
@ -821,7 +819,11 @@ void xmrig::Client::parseResponse(int64_t id, const rapidjson::Value &result, co
|
|||
|
||||
m_failures = 0;
|
||||
m_listener->onLoginSuccess(this);
|
||||
m_listener->onJobReceived(this, m_job, result["job"]);
|
||||
|
||||
if (m_job.isValid()) {
|
||||
m_listener->onJobReceived(this, m_job, result["job"]);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -840,10 +842,9 @@ void xmrig::Client::ping()
|
|||
void xmrig::Client::read(ssize_t nread, const uv_buf_t *buf)
|
||||
{
|
||||
const auto size = static_cast<size_t>(nread);
|
||||
|
||||
if (nread < 0) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] read error: \"%s\"", url(), uv_strerror(static_cast<int>(nread)));
|
||||
LOG_ERR("%s " RED("read error: ") RED_BOLD("\"%s\""), tag(), uv_strerror(static_cast<int>(nread)));
|
||||
}
|
||||
|
||||
close();
|
||||
|
@ -972,7 +973,7 @@ void xmrig::Client::onConnect(uv_connect_t *req, int status)
|
|||
|
||||
if (status < 0) {
|
||||
if (!client->isQuiet()) {
|
||||
LOG_ERR("[%s] connect error: \"%s\"", client->url(), uv_strerror(status));
|
||||
LOG_ERR("%s " RED("connect error: ") RED_BOLD("\"%s\""), client->tag(), uv_strerror(status));
|
||||
}
|
||||
|
||||
if (client->state() == ReconnectingState || client->state() == ClosingState) {
|
||||
|
@ -980,10 +981,6 @@ void xmrig::Client::onConnect(uv_connect_t *req, int status)
|
|||
}
|
||||
|
||||
if (client->state() != ConnectingState) {
|
||||
if (!client->isQuiet()) {
|
||||
LOG_ERR("[%s] connect error: \"invalid state: %d\"", client->url(), client->state());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -992,8 +989,6 @@ void xmrig::Client::onConnect(uv_connect_t *req, int status)
|
|||
}
|
||||
|
||||
if (client->state() == ConnectedState) {
|
||||
LOG_ERR("[%s] already connected", client->url());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,18 +81,28 @@ protected:
|
|||
|
||||
void onResolved(const Dns &dns, int status) override;
|
||||
|
||||
inline bool hasExtension(Extension extension) const noexcept override { return m_extensions.test(extension); }
|
||||
inline const char *mode() const override { return "pool"; }
|
||||
inline void onLine(char *line, size_t size) override { parse(line, size); }
|
||||
inline bool hasExtension(Extension extension) const noexcept override { return m_extensions.test(extension); }
|
||||
inline const char *mode() const override { return "pool"; }
|
||||
inline void onLine(char *line, size_t size) override { parse(line, size); }
|
||||
|
||||
inline const char *agent() const { return m_agent; }
|
||||
inline const char *url() const { return m_pool.url(); }
|
||||
inline const String &rpcId() const { return m_rpcId; }
|
||||
inline void setRpcId(const char *id) { m_rpcId = id; }
|
||||
|
||||
virtual bool parseLogin(const rapidjson::Value &result, int *code);
|
||||
virtual void login();
|
||||
virtual void parseNotification(const char* method, const rapidjson::Value& params, const rapidjson::Value& error);
|
||||
|
||||
bool close();
|
||||
virtual void onClose();
|
||||
|
||||
private:
|
||||
class Socks5;
|
||||
class Tls;
|
||||
|
||||
bool close();
|
||||
bool isCriticalError(const char *message);
|
||||
bool parseJob(const rapidjson::Value ¶ms, int *code);
|
||||
bool parseLogin(const rapidjson::Value &result, int *code);
|
||||
bool send(BIO *bio);
|
||||
bool verifyAlgorithm(const Algorithm &algorithm, const char *algo) const;
|
||||
bool write(const uv_buf_t &buf);
|
||||
|
@ -100,11 +110,8 @@ private:
|
|||
int64_t send(size_t size);
|
||||
void connect(sockaddr *addr);
|
||||
void handshake();
|
||||
void login();
|
||||
void onClose();
|
||||
void parse(char *line, size_t len);
|
||||
void parseExtensions(const rapidjson::Value &result);
|
||||
void parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error);
|
||||
void parseResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error);
|
||||
void ping();
|
||||
void read(ssize_t nread, const uv_buf_t *buf);
|
||||
|
@ -112,7 +119,6 @@ private:
|
|||
void setState(SocketState state);
|
||||
void startTimeout();
|
||||
|
||||
inline const char *url() const { return m_pool.url(); }
|
||||
inline SocketState state() const { return m_state; }
|
||||
inline uv_stream_t *stream() const { return reinterpret_cast<uv_stream_t *>(m_socket); }
|
||||
inline void setExtension(Extension ext, bool enable) noexcept { m_extensions.set(ext, enable); }
|
||||
|
|
369
src/base/net/stratum/EthStratumClient.cpp
Normal file
369
src/base/net/stratum/EthStratumClient.cpp
Normal file
|
@ -0,0 +1,369 @@
|
|||
/* XMRig
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cinttypes>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
#include "base/net/stratum/EthStratumClient.h"
|
||||
#include "3rdparty/libethash/endian.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "3rdparty/rapidjson/error/en.h"
|
||||
#include "3rdparty/rapidjson/stringbuffer.h"
|
||||
#include "3rdparty/rapidjson/writer.h"
|
||||
#include "base/io/json/Json.h"
|
||||
#include "base/io/json/JsonRequest.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/kernel/interfaces/IClientListener.h"
|
||||
#include "net/JobResult.h"
|
||||
|
||||
|
||||
|
||||
xmrig::EthStratumClient::EthStratumClient(int id, const char *agent, IClientListener *listener) :
|
||||
Client(id, agent, listener)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int64_t xmrig::EthStratumClient::submit(const JobResult& result)
|
||||
{
|
||||
# ifndef XMRIG_PROXY_PROJECT
|
||||
if ((m_state != ConnectedState) || !m_authorized) {
|
||||
return -1;
|
||||
}
|
||||
# endif
|
||||
|
||||
if (result.diff == 0) {
|
||||
LOG_ERR("%s " RED("result.diff is 0"), tag());
|
||||
close();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
using namespace rapidjson;
|
||||
|
||||
Document doc(kObjectType);
|
||||
auto& allocator = doc.GetAllocator();
|
||||
|
||||
Value params(kArrayType);
|
||||
params.PushBack(m_pool.user().toJSON(), allocator);
|
||||
params.PushBack(result.jobId.toJSON(), allocator);
|
||||
|
||||
std::stringstream s;
|
||||
s << "0x" << std::hex << std::setw(16) << std::setfill('0') << result.nonce;
|
||||
params.PushBack(Value(s.str().c_str(), allocator), allocator);
|
||||
|
||||
s.str(std::string());
|
||||
s << "0x";
|
||||
for (size_t i = 0; i < 32; ++i) {
|
||||
const uint32_t k = result.headerHash()[i];
|
||||
s << std::hex << std::setw(2) << std::setfill('0') << k;
|
||||
}
|
||||
params.PushBack(Value(s.str().c_str(), allocator), allocator);
|
||||
|
||||
s.str(std::string());
|
||||
s << "0x";
|
||||
for (size_t i = 0; i < 32; ++i) {
|
||||
const uint32_t k = result.mixHash()[i];
|
||||
s << std::hex << std::setw(2) << std::setfill('0') << k;
|
||||
}
|
||||
params.PushBack(Value(s.str().c_str(), allocator), allocator);
|
||||
|
||||
JsonRequest::create(doc, m_sequence, "mining.submit", params);
|
||||
|
||||
uint64_t actual_diff = ethash_swap_u64(*((uint64_t*)result.result()));
|
||||
actual_diff = actual_diff ? (uint64_t(-1) / actual_diff) : 0;
|
||||
|
||||
# ifdef XMRIG_PROXY_PROJECT
|
||||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, actual_diff, result.id, 0);
|
||||
# else
|
||||
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, actual_diff, 0, result.backend);
|
||||
# endif
|
||||
|
||||
return send(doc);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::EthStratumClient::login()
|
||||
{
|
||||
m_results.clear();
|
||||
|
||||
subscribe();
|
||||
authorize();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::EthStratumClient::onClose()
|
||||
{
|
||||
m_authorized = false;
|
||||
Client::onClose();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::EthStratumClient::handleResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error)
|
||||
{
|
||||
auto it = m_callbacks.find(id);
|
||||
if (it != m_callbacks.end()) {
|
||||
const uint64_t elapsed = Chrono::steadyMSecs() - it->second.ts;
|
||||
|
||||
if (error.IsArray() || error.IsObject() || error.IsString()) {
|
||||
it->second.callback(error, false, elapsed);
|
||||
}
|
||||
else {
|
||||
it->second.callback(result, true, elapsed);
|
||||
}
|
||||
|
||||
m_callbacks.erase(it);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return handleSubmitResponse(id, errorMessage(error));
|
||||
}
|
||||
|
||||
|
||||
void xmrig::EthStratumClient::parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &)
|
||||
{
|
||||
if (strcmp(method, "mining.set_target") == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(method, "mining.notify") == 0) {
|
||||
if (!params.IsArray()) {
|
||||
LOG_ERR("%s " RED("invalid mining.notify notification: params is not an array"), tag());
|
||||
return;
|
||||
}
|
||||
|
||||
auto arr = params.GetArray();
|
||||
|
||||
if (arr.Size() < 6) {
|
||||
LOG_ERR("%s " RED("invalid mining.notify notification: params array has wrong size"), tag());
|
||||
return;
|
||||
}
|
||||
|
||||
Job job;
|
||||
job.setId(arr[0].GetString());
|
||||
|
||||
auto algo = m_pool.algorithm();
|
||||
if (!algo.isValid()) {
|
||||
algo = m_pool.coin().algorithm();
|
||||
}
|
||||
|
||||
job.setAlgorithm(algo);
|
||||
job.setExtraNonce(m_extraNonce.second);
|
||||
|
||||
std::stringstream s;
|
||||
|
||||
// header hash (32 bytes)
|
||||
s << arr[1].GetString();
|
||||
|
||||
// nonce template (8 bytes)
|
||||
for (uint64_t i = 0, k = m_extraNonce.first; i < sizeof(m_extraNonce.first); ++i, k >>= 8) {
|
||||
s << std::hex << std::setw(2) << std::setfill('0') << (k & 0xFF);
|
||||
}
|
||||
|
||||
std::string blob = s.str();
|
||||
|
||||
// zeros up to 76 bytes
|
||||
blob.resize(76 * 2, '0');
|
||||
job.setBlob(blob.c_str());
|
||||
|
||||
std::string target_str = arr[3].GetString();
|
||||
target_str.resize(16, '0');
|
||||
const uint64_t target = strtoull(target_str.c_str(), nullptr, 16);
|
||||
job.setDiff(Job::toDiff(target));
|
||||
|
||||
job.setHeight(arr[5].GetUint64());
|
||||
|
||||
bool ok = true;
|
||||
m_listener->onVerifyAlgorithm(this, algo, &ok);
|
||||
|
||||
if (!ok) {
|
||||
if (!isQuiet()) {
|
||||
LOG_ERR("[%s] incompatible/disabled algorithm \"%s\" detected, reconnect", url(), algo.shortName());
|
||||
}
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_job != job) {
|
||||
m_job = std::move(job);
|
||||
|
||||
// Workaround for nanopool.org, mining.notify received before mining.authorize response.
|
||||
if (!m_authorized) {
|
||||
m_authorized = true;
|
||||
m_listener->onLoginSuccess(this);
|
||||
}
|
||||
|
||||
m_listener->onJobReceived(this, m_job, params);
|
||||
}
|
||||
else {
|
||||
if (!isQuiet()) {
|
||||
LOG_WARN("%s " YELLOW("duplicate job received, reconnect"), tag());
|
||||
}
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::EthStratumClient::setExtraNonce(const rapidjson::Value &nonce)
|
||||
{
|
||||
if (!nonce.IsString()) {
|
||||
throw std::runtime_error("invalid mining.subscribe response: extra nonce is not a string");
|
||||
}
|
||||
|
||||
const char *s = nonce.GetString();
|
||||
size_t len = nonce.GetStringLength();
|
||||
|
||||
// Skip "0x"
|
||||
if ((len >= 2) && (s[0] == '0') && (s[1] == 'x')) {
|
||||
s += 2;
|
||||
len -= 2;
|
||||
}
|
||||
|
||||
if (len & 1) {
|
||||
throw std::runtime_error("invalid mining.subscribe response: extra nonce has an odd number of hex chars");
|
||||
}
|
||||
|
||||
if (len > 8) {
|
||||
throw std::runtime_error("Invalid mining.subscribe response: extra nonce is too long");
|
||||
}
|
||||
|
||||
std::string extra_nonce_str(s);
|
||||
extra_nonce_str.resize(16, '0');
|
||||
|
||||
LOG_DEBUG("[%s] extra nonce set to %s", url(), s);
|
||||
|
||||
m_extraNonce = { std::stoull(extra_nonce_str, nullptr, 16), s };
|
||||
}
|
||||
|
||||
|
||||
const char *xmrig::EthStratumClient::errorMessage(const rapidjson::Value &error) const
|
||||
{
|
||||
if (error.IsArray() && error.GetArray().Size() > 1) {
|
||||
auto &value = error.GetArray()[1];
|
||||
if (value.IsString()) {
|
||||
return value.GetString();
|
||||
}
|
||||
}
|
||||
|
||||
if (error.IsString()) {
|
||||
return error.GetString();
|
||||
}
|
||||
|
||||
if (error.IsObject()) {
|
||||
return Json::getString(error, "message");
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::EthStratumClient::authorize()
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
Document doc(kObjectType);
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
Value params(kArrayType);
|
||||
params.PushBack(m_pool.user().toJSON(), allocator);
|
||||
params.PushBack(m_pool.password().toJSON(), allocator);
|
||||
|
||||
JsonRequest::create(doc, m_sequence, "mining.authorize", params);
|
||||
|
||||
send(doc, [this](const rapidjson::Value& result, bool success, uint64_t elapsed) { onAuthorizeResponse(result, success, elapsed); });
|
||||
}
|
||||
|
||||
|
||||
void xmrig::EthStratumClient::onAuthorizeResponse(const rapidjson::Value &result, bool success, uint64_t)
|
||||
{
|
||||
try {
|
||||
if (!success) {
|
||||
const auto message = errorMessage(result);
|
||||
if (message) {
|
||||
throw std::runtime_error(message);
|
||||
}
|
||||
|
||||
throw std::runtime_error("mining.authorize call failed");
|
||||
}
|
||||
|
||||
if (!result.IsBool()) {
|
||||
throw std::runtime_error("invalid mining.authorize response: result is not a boolean");
|
||||
}
|
||||
|
||||
if (!result.GetBool()) {
|
||||
throw std::runtime_error("login failed");
|
||||
}
|
||||
} catch (const std::exception &ex) {
|
||||
LOG_ERR("%s " RED_BOLD("%s"), tag(), ex.what());
|
||||
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_DEBUG("[%s] login succeeded", url());
|
||||
|
||||
if (!m_authorized) {
|
||||
m_authorized = true;
|
||||
m_listener->onLoginSuccess(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::EthStratumClient::onSubscribeResponse(const rapidjson::Value &result, bool success, uint64_t)
|
||||
{
|
||||
if (!success) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!result.IsArray()) {
|
||||
throw std::runtime_error("invalid mining.subscribe response: result is not an array");
|
||||
}
|
||||
|
||||
if (result.GetArray().Size() <= 1) {
|
||||
throw std::runtime_error("invalid mining.subscribe response: result array is too short");
|
||||
}
|
||||
|
||||
setExtraNonce(result.GetArray()[1]);
|
||||
} catch (const std::exception &ex) {
|
||||
LOG_ERR("%s " RED("%s"), tag(), ex.what());
|
||||
|
||||
m_extraNonce = { 0, {} };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::EthStratumClient::subscribe()
|
||||
{
|
||||
using namespace rapidjson;
|
||||
|
||||
Document doc(kObjectType);
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
Value params(kArrayType);
|
||||
params.PushBack(StringRef(agent()), allocator);
|
||||
|
||||
JsonRequest::create(doc, m_sequence, "mining.subscribe", params);
|
||||
|
||||
send(doc, [this](const rapidjson::Value& result, bool success, uint64_t elapsed) { onSubscribeResponse(result, success, elapsed); });
|
||||
}
|
65
src/base/net/stratum/EthStratumClient.h
Normal file
65
src/base/net/stratum/EthStratumClient.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/* XMRig
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_ETHSTRATUMCLIENT_H
|
||||
#define XMRIG_ETHSTRATUMCLIENT_H
|
||||
|
||||
|
||||
#include "base/net/stratum/Client.h"
|
||||
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class EthStratumClient : public Client
|
||||
{
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE_DEFAULT(EthStratumClient)
|
||||
|
||||
EthStratumClient(int id, const char *agent, IClientListener *listener);
|
||||
~EthStratumClient() override = default;
|
||||
|
||||
protected:
|
||||
int64_t submit(const JobResult &result) override;
|
||||
void login() override;
|
||||
void onClose() override;
|
||||
|
||||
bool handleResponse(int64_t id, const rapidjson::Value &result, const rapidjson::Value &error) override;
|
||||
void parseNotification(const char *method, const rapidjson::Value ¶ms, const rapidjson::Value &error) override;
|
||||
|
||||
void setExtraNonce(const rapidjson::Value &nonce);
|
||||
|
||||
private:
|
||||
const char *errorMessage(const rapidjson::Value &error) const;
|
||||
void authorize();
|
||||
void onAuthorizeResponse(const rapidjson::Value &result, bool success, uint64_t elapsed);
|
||||
void onSubscribeResponse(const rapidjson::Value &result, bool success, uint64_t elapsed);
|
||||
void subscribe();
|
||||
|
||||
bool m_authorized = false;
|
||||
std::pair<uint64_t, String> m_extraNonce{};
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
#endif /* XMRIG_ETHSTRATUMCLIENT_H */
|
|
@ -71,14 +71,17 @@ public:
|
|||
inline const String &extraNonce() const { return m_extraNonce; }
|
||||
inline const String &id() const { return m_id; }
|
||||
inline const String &poolWallet() const { return m_poolWallet; }
|
||||
inline const uint32_t *nonce() const { return reinterpret_cast<const uint32_t*>(m_blob + 39); }
|
||||
inline const uint32_t *nonce() const { return reinterpret_cast<const uint32_t*>(m_blob + nonceOffset()); }
|
||||
inline const uint8_t *blob() const { return m_blob; }
|
||||
inline int32_t nonceOffset() const { return (algorithm().family() == Algorithm::KAWPOW) ? 32 : 39; }
|
||||
inline size_t nonceSize() const { return (algorithm().family() == Algorithm::KAWPOW) ? 8 : 4; }
|
||||
inline size_t size() const { return m_size; }
|
||||
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + 39); }
|
||||
inline uint32_t *nonce() { return reinterpret_cast<uint32_t*>(m_blob + nonceOffset()); }
|
||||
inline uint32_t backend() const { return m_backend; }
|
||||
inline uint64_t diff() const { return m_diff; }
|
||||
inline uint64_t height() const { return m_height; }
|
||||
inline uint64_t target() const { return m_target; }
|
||||
inline uint8_t *blob() { return m_blob; }
|
||||
inline uint8_t fixedByte() const { return *(m_blob + 42); }
|
||||
inline uint8_t index() const { return m_index; }
|
||||
inline void reset() { m_size = 0; m_diff = 0; }
|
||||
|
@ -98,7 +101,6 @@ public:
|
|||
inline const String &rawSeedHash() const { return m_rawSeedHash; }
|
||||
# endif
|
||||
|
||||
static inline uint32_t *nonce(uint8_t *blob) { return reinterpret_cast<uint32_t*>(blob + 39); }
|
||||
static inline uint64_t toDiff(uint64_t target) { return target ? (0xFFFFFFFFFFFFFFFFULL / target) : 0; }
|
||||
|
||||
inline bool operator!=(const Job &other) const { return !isEqual(other); }
|
||||
|
|
|
@ -118,12 +118,12 @@ void xmrig::NetworkState::onActive(IStrategy *strategy, IClient *client)
|
|||
}
|
||||
|
||||
|
||||
void xmrig::NetworkState::onJob(IStrategy *strategy, IClient *client, const Job &job)
|
||||
void xmrig::NetworkState::onJob(IStrategy *strategy, IClient *client, const Job &job, const rapidjson::Value ¶ms)
|
||||
{
|
||||
m_algorithm = job.algorithm();
|
||||
m_diff = job.diff();
|
||||
|
||||
StrategyProxy::onJob(strategy, client, job);
|
||||
StrategyProxy::onJob(strategy, client, job, params);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
|
||||
protected:
|
||||
void onActive(IStrategy *strategy, IClient *client) override;
|
||||
void onJob(IStrategy *strategy, IClient *client, const Job &job) override;
|
||||
void onJob(IStrategy *strategy, IClient *client, const Job &job, const rapidjson::Value ¶ms) override;
|
||||
void onPause(IStrategy *strategy) override;
|
||||
void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) override;
|
||||
|
||||
|
|
|
@ -38,6 +38,11 @@
|
|||
#include "base/kernel/Platform.h"
|
||||
#include "base/net/stratum/Client.h"
|
||||
|
||||
#ifdef XMRIG_ALGO_KAWPOW
|
||||
# include "base/net/stratum/AutoClient.h"
|
||||
# include "base/net/stratum/EthStratumClient.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_HTTP
|
||||
# include "base/net/stratum/DaemonClient.h"
|
||||
|
@ -80,6 +85,20 @@ xmrig::Pool::Pool(const char *url) :
|
|||
}
|
||||
|
||||
|
||||
xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, bool tls, Mode mode) :
|
||||
m_keepAlive(keepAlive),
|
||||
m_mode(mode),
|
||||
m_flags(1 << FLAG_ENABLED),
|
||||
m_password(password),
|
||||
m_user(user),
|
||||
m_pollInterval(kDefaultPollInterval),
|
||||
m_url(host, port, tls)
|
||||
{
|
||||
m_flags.set(FLAG_NICEHASH, nicehash);
|
||||
m_flags.set(FLAG_TLS, tls);
|
||||
}
|
||||
|
||||
|
||||
xmrig::Pool::Pool(const rapidjson::Value &object) :
|
||||
m_flags(1 << FLAG_ENABLED),
|
||||
m_pollInterval(kDefaultPollInterval),
|
||||
|
@ -120,19 +139,6 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
|
|||
}
|
||||
|
||||
|
||||
xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, bool tls) :
|
||||
m_keepAlive(keepAlive),
|
||||
m_flags(1 << FLAG_ENABLED),
|
||||
m_password(password),
|
||||
m_user(user),
|
||||
m_pollInterval(kDefaultPollInterval),
|
||||
m_url(host, port, tls)
|
||||
{
|
||||
m_flags.set(FLAG_NICEHASH, nicehash);
|
||||
m_flags.set(FLAG_TLS, tls);
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Pool::isEnabled() const
|
||||
{
|
||||
# ifndef XMRIG_FEATURE_TLS
|
||||
|
@ -185,7 +191,15 @@ xmrig::IClient *xmrig::Pool::createClient(int id, IClientListener *listener) con
|
|||
IClient *client = nullptr;
|
||||
|
||||
if (m_mode == MODE_POOL) {
|
||||
client = new Client(id, Platform::userAgent(), listener);
|
||||
# ifdef XMRIG_ALGO_KAWPOW
|
||||
if ((m_algorithm.family() == Algorithm::KAWPOW) || (m_coin == Coin::RAVEN)) {
|
||||
client = new EthStratumClient(id, Platform::userAgent(), listener);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
client = new Client(id, Platform::userAgent(), listener);
|
||||
}
|
||||
}
|
||||
# ifdef XMRIG_FEATURE_HTTP
|
||||
else if (m_mode == MODE_DAEMON) {
|
||||
|
@ -195,6 +209,11 @@ xmrig::IClient *xmrig::Pool::createClient(int id, IClientListener *listener) con
|
|||
client = new SelfSelectClient(id, Platform::userAgent(), listener);
|
||||
}
|
||||
# endif
|
||||
# ifdef XMRIG_ALGO_KAWPOW
|
||||
else if (m_mode == MODE_AUTO_ETH) {
|
||||
client = new AutoClient(id, Platform::userAgent(), listener);
|
||||
}
|
||||
# endif
|
||||
|
||||
assert(client != nullptr);
|
||||
|
||||
|
|
|
@ -49,7 +49,8 @@ public:
|
|||
enum Mode {
|
||||
MODE_POOL,
|
||||
MODE_DAEMON,
|
||||
MODE_SELF_SELECT
|
||||
MODE_SELF_SELECT,
|
||||
MODE_AUTO_ETH
|
||||
};
|
||||
|
||||
static const String kDefaultPassword;
|
||||
|
@ -76,16 +77,9 @@ public:
|
|||
constexpr static uint64_t kDefaultPollInterval = 1000;
|
||||
|
||||
Pool() = default;
|
||||
Pool(const char *host, uint16_t port, const char *user, const char *password, int keepAlive, bool nicehash, bool tls, Mode mode);
|
||||
Pool(const char *url);
|
||||
Pool(const rapidjson::Value &object);
|
||||
Pool(const char *host,
|
||||
uint16_t port,
|
||||
const char *user = nullptr,
|
||||
const char *password = nullptr,
|
||||
int keepAlive = 0,
|
||||
bool nicehash = false,
|
||||
bool tls = false
|
||||
);
|
||||
|
||||
inline bool isNicehash() const { return m_flags.test(FLAG_NICEHASH); }
|
||||
inline bool isTLS() const { return m_flags.test(FLAG_TLS) || m_url.isTLS(); }
|
||||
|
|
|
@ -55,6 +55,7 @@ protected:
|
|||
inline bool isEnabled() const override { return m_client->isEnabled(); }
|
||||
inline bool isTLS() const override { return m_client->isTLS(); }
|
||||
inline const char *mode() const override { return m_client->mode(); }
|
||||
inline const char *tag() const override { return m_client->tag(); }
|
||||
inline const char *tlsFingerprint() const override { return m_client->tlsFingerprint(); }
|
||||
inline const char *tlsVersion() const override { return m_client->tlsVersion(); }
|
||||
inline const Job &job() const override { return m_job; }
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
|
||||
#include "base/net/stratum/strategies/FailoverStrategy.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "base/kernel/interfaces/IClient.h"
|
||||
#include "base/kernel/interfaces/IStrategyListener.h"
|
||||
#include "base/kernel/Platform.h"
|
||||
|
@ -96,7 +97,7 @@ void xmrig::FailoverStrategy::resume()
|
|||
return;
|
||||
}
|
||||
|
||||
m_listener->onJob(this, active(), active()->job());
|
||||
m_listener->onJob(this, active(), active()->job(), rapidjson::Value(rapidjson::kNullType));
|
||||
}
|
||||
|
||||
|
||||
|
@ -164,10 +165,10 @@ void xmrig::FailoverStrategy::onLogin(IClient *client, rapidjson::Document &doc,
|
|||
}
|
||||
|
||||
|
||||
void xmrig::FailoverStrategy::onJobReceived(IClient *client, const Job &job, const rapidjson::Value &)
|
||||
void xmrig::FailoverStrategy::onJobReceived(IClient *client, const Job &job, const rapidjson::Value ¶ms)
|
||||
{
|
||||
if (m_active == client->id()) {
|
||||
m_listener->onJob(this, client, job);
|
||||
m_listener->onJob(this, client, job, params);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
|
||||
#include "base/net/stratum/strategies/SinglePoolStrategy.h"
|
||||
#include "3rdparty/rapidjson/document.h"
|
||||
#include "base/kernel/interfaces/IClient.h"
|
||||
#include "base/kernel/interfaces/IStrategyListener.h"
|
||||
#include "base/kernel/Platform.h"
|
||||
|
@ -65,7 +66,7 @@ void xmrig::SinglePoolStrategy::resume()
|
|||
return;
|
||||
}
|
||||
|
||||
m_listener->onJob(this, m_client, m_client->job());
|
||||
m_listener->onJob(this, m_client, m_client->job(), rapidjson::Value(rapidjson::kNullType));
|
||||
}
|
||||
|
||||
|
||||
|
@ -104,9 +105,9 @@ void xmrig::SinglePoolStrategy::onClose(IClient *, int)
|
|||
}
|
||||
|
||||
|
||||
void xmrig::SinglePoolStrategy::onJobReceived(IClient *client, const Job &job, const rapidjson::Value &)
|
||||
void xmrig::SinglePoolStrategy::onJobReceived(IClient *client, const Job &job, const rapidjson::Value ¶ms)
|
||||
{
|
||||
m_listener->onJob(this, client, job);
|
||||
m_listener->onJob(this, client, job, params);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -43,9 +43,9 @@ protected:
|
|||
m_listener->onActive(strategy, client);
|
||||
}
|
||||
|
||||
inline void onJob(IStrategy *strategy, IClient *client, const Job &job) override
|
||||
inline void onJob(IStrategy *strategy, IClient *client, const Job &job, const rapidjson::Value ¶ms) override
|
||||
{
|
||||
m_listener->onJob(strategy, client, job);
|
||||
m_listener->onJob(strategy, client, job, params);
|
||||
}
|
||||
|
||||
inline void onLogin(IStrategy *strategy, IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) override
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue