Dero HE fork support (astrobwt/v2 algorithm)

This commit is contained in:
SChernykh 2022-03-05 00:31:18 +01:00
parent f7543ada60
commit b5da73389f
27 changed files with 879 additions and 39 deletions

View file

@ -3,10 +3,12 @@ if (WITH_ASTROBWT)
list(APPEND HEADERS_CRYPTO
src/crypto/astrobwt/AstroBWT.h
src/crypto/astrobwt/sort_indices2.h
)
list(APPEND SOURCES_CRYPTO
src/crypto/astrobwt/AstroBWT.cpp
src/crypto/astrobwt/sort_indices2.cpp
)
if (XMRIG_ARM)
@ -21,6 +23,10 @@ if (WITH_ASTROBWT)
src/crypto/astrobwt/salsa20_ref/salsa20.c
)
else()
if (CMAKE_C_COMPILER_ID MATCHES MSVC)
set_source_files_properties(src/crypto/astrobwt/sort_indices2.cpp PROPERTIES COMPILE_FLAGS "/std:c++20")
endif()
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
add_definitions(/DASTROBWT_AVX2)
list(APPEND SOURCES_CRYPTO src/crypto/astrobwt/xmm6int/salsa20_xmm6int-avx2.c)

View file

@ -157,7 +157,15 @@ size_t inline generate<Algorithm::ARGON2>(Threads<CpuThreads> &threads, uint32_t
template<>
size_t inline generate<Algorithm::ASTROBWT>(Threads<CpuThreads>& threads, uint32_t limit)
{
return generate(Algorithm::kASTROBWT, threads, Algorithm::ASTROBWT_DERO, limit);
size_t count = 0;
if (!threads.isExist(Algorithm::ASTROBWT_DERO_2)) {
auto v2 = Cpu::info()->threads(Algorithm::ASTROBWT_DERO_2, limit);
count += threads.move(Algorithm::kASTROBWT_DERO_2, std::move(v2));
}
count += generate(Algorithm::kASTROBWT, threads, Algorithm::ASTROBWT_DERO, limit);
return count;
}
#endif

View file

@ -224,9 +224,8 @@ bool xmrig::CpuWorker<N>::selfTest()
# endif
# ifdef XMRIG_ALGO_ASTROBWT
if (m_algorithm.family() == Algorithm::ASTROBWT) {
return verify(Algorithm::ASTROBWT_DERO, astrobwt_dero_test_out);
}
if (m_algorithm.id() == Algorithm::ASTROBWT_DERO) return verify(Algorithm::ASTROBWT_DERO, astrobwt_dero_test_out);
if (m_algorithm.id() == Algorithm::ASTROBWT_DERO_2) return verify(Algorithm::ASTROBWT_DERO_2, astrobwt_dero_2_test_out);
# endif
return false;
@ -320,8 +319,15 @@ void xmrig::CpuWorker<N>::start()
# ifdef XMRIG_ALGO_ASTROBWT
case Algorithm::ASTROBWT:
if (!astrobwt::astrobwt_dero(m_job.blob(), job.size(), m_ctx[0]->memory, m_hash, m_astrobwtMaxSize, m_astrobwtAVX2)) {
valid = false;
if (job.algorithm().id() == Algorithm::ASTROBWT_DERO) {
if (!astrobwt::astrobwt_dero(m_job.blob(), job.size(), m_ctx[0]->memory, m_hash, m_astrobwtMaxSize, m_astrobwtAVX2)) {
valid = false;
}
}
else {
if (!astrobwt::astrobwt_dero_v2(m_job.blob(), job.size(), m_ctx[0]->memory, m_hash)) {
valid = false;
}
}
break;
# endif

View file

@ -94,6 +94,7 @@ const char *Algorithm::kAR2_WRKZ = "argon2/ninja";
#ifdef XMRIG_ALGO_ASTROBWT
const char *Algorithm::kASTROBWT = "astrobwt";
const char *Algorithm::kASTROBWT_DERO = "astrobwt";
const char *Algorithm::kASTROBWT_DERO_2 = "astrobwt/v2";
#endif
#ifdef XMRIG_ALGO_KAWPOW
@ -163,6 +164,7 @@ static const std::map<uint32_t, const char *> kAlgorithmNames = {
# ifdef XMRIG_ALGO_ASTROBWT
ALGO_NAME(ASTROBWT_DERO),
ALGO_NAME(ASTROBWT_DERO_2),
# endif
# ifdef XMRIG_ALGO_KAWPOW
@ -282,6 +284,8 @@ static const std::map<const char *, Algorithm::Id, aliasCompare> kAlgorithmAlias
# ifdef XMRIG_ALGO_ASTROBWT
ALGO_ALIAS_AUTO(ASTROBWT_DERO), ALGO_ALIAS(ASTROBWT_DERO, "astrobwt/dero"),
ALGO_ALIAS_AUTO(ASTROBWT_DERO_2), ALGO_ALIAS(ASTROBWT_DERO_2, "astrobwt/derov2"),
ALGO_ALIAS_AUTO(ASTROBWT_DERO_2), ALGO_ALIAS(ASTROBWT_DERO_2, "astrobwt/v2"),
# endif
# ifdef XMRIG_ALGO_KAWPOW
@ -365,7 +369,7 @@ std::vector<xmrig::Algorithm> xmrig::Algorithm::all(const std::function<bool(con
CN_UPX2,
RX_0, RX_WOW, RX_ARQ, RX_GRAFT, RX_SFX, RX_KEVA,
AR2_CHUKWA, AR2_CHUKWA_V2, AR2_WRKZ,
ASTROBWT_DERO,
ASTROBWT_DERO, ASTROBWT_DERO_2,
KAWPOW_RVN,
GHOSTRIDER_RTM
};

View file

@ -82,6 +82,7 @@ public:
AR2_CHUKWA_V2 = 0x61140000, // "argon2/chukwav2" Argon2id (Chukwa v2).
AR2_WRKZ = 0x61120000, // "argon2/wrkz" Argon2id (WRKZ)
ASTROBWT_DERO = 0x41000000, // "astrobwt" AstroBWT (Dero)
ASTROBWT_DERO_2 = 0x41110000, // "astrobwt/v2" AstroBWT (Dero HE)
KAWPOW_RVN = 0x6b0f0000, // "kawpow/rvn" KawPow (RVN)
};
@ -158,6 +159,7 @@ public:
# ifdef XMRIG_ALGO_ASTROBWT
static const char *kASTROBWT;
static const char *kASTROBWT_DERO;
static const char* kASTROBWT_DERO_2;
# endif
# ifdef XMRIG_ALGO_KAWPOW

View file

@ -45,15 +45,16 @@ struct CoinInfo
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_GRAFT, "GRFT", "Graft", 120, 10000000000, BLUE_BG_BOLD( WHITE_BOLD_S " graft ") },
{ 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 ") },
{ 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::ASTROBWT_DERO_2, "DERO_HE", "DERO_HE", 0, 0, BLUE_BG_BOLD( WHITE_BOLD_S " dero_he ") },
{ Algorithm::RX_GRAFT, "GRFT", "Graft", 120, 10000000000, BLUE_BG_BOLD( WHITE_BOLD_S " graft ") },
{ 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 ") },
};

View file

@ -36,6 +36,7 @@ public:
SUMO,
ARQMA,
DERO,
DERO_HE,
GRAFT,
KEVA,
RAVEN,

View file

@ -61,6 +61,7 @@ public:
virtual bool hasExtension(Extension extension) const noexcept = 0;
virtual bool isEnabled() const = 0;
virtual bool isTLS() const = 0;
virtual bool isWSS() const = 0;
virtual const char *mode() const = 0;
virtual const char *tag() const = 0;
virtual const char *tlsFingerprint() const = 0;

View file

@ -59,6 +59,8 @@ protected:
void setPool(const Pool &pool) override;
protected:
bool isWSS() const override { return false; }
enum SocketState {
UnconnectedState,
HostLookupState,

View file

@ -48,8 +48,14 @@
#include "net/JobResult.h"
#ifdef XMRIG_FEATURE_TLS
#include <openssl/ssl.h>
#endif
#include <algorithm>
#include <cassert>
#include <random>
namespace xmrig {
@ -58,7 +64,9 @@ namespace xmrig {
Storage<DaemonClient> DaemonClient::m_storage;
static const char* kBlocktemplateBlob = "blocktemplate_blob";
static const char* kBlocktemplateBlob = "blocktemplate_blob";
static const char* kBlockhashingBlob = "blockhashing_blob";
static const char* kLastError = "lasterror";
static const char *kGetHeight = "/getheight";
static const char *kGetInfo = "/getinfo";
static const char *kHash = "hash";
@ -73,6 +81,14 @@ static constexpr size_t kZMQGreetingSize1 = 11;
static const char kZMQHandshake[] = "\4\x19\5READY\xbSocket-Type\0\0\0\3SUB";
static const char kZMQSubscribe[] = "\0\x18\1json-minimal-chain_main";
static const char kWSSLogin[] = "\
GET /ws/%s HTTP/1.1\r\n\
Host: %s\r\n\
Upgrade: websocket\r\n\
Connection: Upgrade\r\n\
Sec-WebSocket-Key: %s\r\n\
Sec-WebSocket-Version: 13\r\n\r\n";
} // namespace xmrig
@ -89,11 +105,20 @@ xmrig::DaemonClient::~DaemonClient()
{
delete m_timer;
delete m_ZMQSocket;
# ifdef XMRIG_FEATURE_TLS
delete m_wss.m_socket;
# endif
}
void xmrig::DaemonClient::deleteLater()
{
# ifdef XMRIG_FEATURE_TLS
if (m_pool.isWSS()) {
WSSClose(true);
}
else
# endif
if (m_pool.zmq_port() >= 0) {
ZMQClose(true);
}
@ -123,6 +148,12 @@ bool xmrig::DaemonClient::isTLS() const
}
bool xmrig::DaemonClient::isWSS() const
{
return m_pool.isWSS();
}
int64_t xmrig::DaemonClient::submit(const JobResult &result)
{
if (result.jobId != m_currentJobId) {
@ -151,6 +182,17 @@ int64_t xmrig::DaemonClient::submit(const JobResult &result)
Cvt::toHex(data + m_job.nonceOffset() * 2, 8, reinterpret_cast<const uint8_t*>(&result.nonce), 4);
# ifdef XMRIG_FEATURE_TLS
if (m_pool.isWSS() && (m_apiVersion == API_DERO) && (m_pool.algorithm().id() == Algorithm::ASTROBWT_DERO_2)) {
char buf[256];
const int n = snprintf(buf, sizeof(buf), "{\"jobid\":\"%s\",\"mbl_blob\":\"%s\"}", m_job.id().data(), data);
if (0 <= n && n < static_cast<int>(sizeof(buf))) {
return WSSWrite(buf, n) ? 1 : -1;
}
return -1;
}
# endif
if (m_blocktemplate.hasMinerSignature()) {
Cvt::toHex(data + sig_offset * 2, 128, result.minerSignature(), 64);
}
@ -193,19 +235,20 @@ void xmrig::DaemonClient::connect()
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)) {
const xmrig::Algorithm algo = m_pool.algorithm();
if ((algo == Algorithm::ASTROBWT_DERO) || (algo == Algorithm::ASTROBWT_DERO_2) || (m_coin == Coin::DERO) || (m_coin == Coin::DERO_HE)) {
m_apiVersion = API_DERO;
}
if (m_pool.zmq_port() >= 0) {
if ((m_apiVersion == API_MONERO) && !m_walletAddress.isValid()) {
return connectError("Invalid wallet address.");
}
if ((m_pool.zmq_port() >= 0) || m_pool.isWSS()) {
m_dns = Dns::resolve(m_pool.host(), this);
}
else {
@ -306,6 +349,9 @@ void xmrig::DaemonClient::onTimer(const Timer *)
connect();
}
else if (m_state == ConnectedState) {
if (m_pool.isWSS()) {
return;
}
if (m_apiVersion == API_DERO) {
rpcSend(JsonRequest::create(m_sequence, "get_info"));
}
@ -330,26 +376,35 @@ void xmrig::DaemonClient::onResolved(const DnsRecords &records, int status, cons
}
delete m_ZMQSocket;
const auto &record = records.get();
m_ip = record.ip();
auto req = new uv_connect_t;
req->data = m_storage.ptr(m_key);
m_ZMQSocket = new uv_tcp_t;
m_ZMQSocket->data = m_storage.ptr(m_key);
uv_tcp_t* s = new uv_tcp_t;
s->data = m_storage.ptr(m_key);
uv_tcp_init(uv_default_loop(), m_ZMQSocket);
uv_tcp_nodelay(m_ZMQSocket, 1);
uv_tcp_init(uv_default_loop(), s);
uv_tcp_nodelay(s, 1);
# ifndef WIN32
uv_tcp_keepalive(m_ZMQSocket, 1, 60);
uv_tcp_keepalive(s, 1, 60);
# endif
uv_tcp_connect(req, m_ZMQSocket, record.addr(m_pool.zmq_port()), onZMQConnect);
# ifdef XMRIG_FEATURE_TLS
if (m_pool.isWSS()) {
delete m_wss.m_socket;
m_wss.m_socket = s;
uv_tcp_connect(req, s, record.addr(m_pool.port()), onWSSConnect);
}
else
# endif
if (m_pool.zmq_port() > 0) {
delete m_ZMQSocket;
m_ZMQSocket = s;
uv_tcp_connect(req, s, record.addr(m_pool.zmq_port()), onZMQConnect);
}
}
@ -396,7 +451,7 @@ bool xmrig::DaemonClient::parseJob(const rapidjson::Value &params, int *code)
);
# endif
m_blockhashingblob = Json::getString(params, "blockhashing_blob");
m_blockhashingblob = Json::getString(params, kBlockhashingBlob);
if (m_blocktemplate.hasMinerSignature()) {
if (m_pool.spendSecretKey().isEmpty()) {
@ -589,6 +644,12 @@ void xmrig::DaemonClient::retry()
setState(ConnectingState);
}
# ifdef XMRIG_FEATURE_TLS
if (m_wss.m_socket) {
uv_close(reinterpret_cast<uv_handle_t*>(m_wss.m_socket), onWSSClose);
}
else
# endif
if ((m_ZMQConnectionState != ZMQ_NOT_CONNECTED) && (m_ZMQConnectionState != ZMQ_DISCONNECTING)) {
uv_close(reinterpret_cast<uv_handle_t*>(m_ZMQSocket), onZMQClose);
}
@ -913,3 +974,373 @@ bool xmrig::DaemonClient::ZMQClose(bool shutdown)
return false;
}
#ifdef XMRIG_FEATURE_TLS
void xmrig::DaemonClient::onWSSConnect(uv_connect_t* req, int status)
{
DaemonClient* client = getClient(req->data);
delete req;
if (!client) {
return;
}
if (status < 0) {
LOG_ERR("%s " RED("WSS connect error: ") RED_BOLD("\"%s\""), client->tag(), uv_strerror(status));
client->retry();
return;
}
client->WSSConnected();
}
void xmrig::DaemonClient::onWSSRead(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
{
DaemonClient* client = getClient(stream->data);
if (client) {
client->WSSRead(nread, buf);
}
NetBuffer::release(buf);
}
void xmrig::DaemonClient::onWSSClose(uv_handle_t* handle)
{
DaemonClient* client = getClient(handle->data);
if (client) {
# ifdef APP_DEBUG
LOG_DEBUG(CYAN("%s") BLACK_BOLD(" disconnected"), client->m_pool.url().data());
# endif
client->m_wss.cleanup();
client->retry();
}
}
void xmrig::DaemonClient::onWSSShutdown(uv_handle_t* handle)
{
DaemonClient* client = getClient(handle->data);
if (client) {
# ifdef APP_DEBUG
LOG_DEBUG(CYAN("%s") BLACK_BOLD(" shutdown"), client->m_pool.url().data());
# endif
client->m_wss.cleanup();
m_storage.remove(client->m_key);
}
}
void xmrig::DaemonClient::WSSConnected()
{
m_wss.m_ctx = SSL_CTX_new(SSLv23_method());
m_wss.m_write = BIO_new(BIO_s_mem());
m_wss.m_read = BIO_new(BIO_s_mem());
SSL_CTX_set_options(m_wss.m_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
m_wss.m_ssl = SSL_new(m_wss.m_ctx);
SSL_set_connect_state(m_wss.m_ssl);
SSL_set_bio(m_wss.m_ssl, m_wss.m_read, m_wss.m_write);
SSL_do_handshake(m_wss.m_ssl);
if (WSSWrite(nullptr, 0)) {
uv_read_start(reinterpret_cast<uv_stream_t*>(m_wss.m_socket), NetBuffer::onAlloc, onWSSRead);
}
}
bool xmrig::DaemonClient::WSSWrite(const char* data, size_t size)
{
if (!m_wss.m_socket) {
return false;
}
if (data && size) {
# ifdef APP_DEBUG
LOG_DEBUG(CYAN("%s") BLACK_BOLD(" write ") CYAN_BOLD("%zu") BLACK_BOLD(" bytes") " %s", m_pool.url().data(), size, data);
# endif
if (!m_wss.m_handshake) {
WSS::Header h{};
h.fin = 1;
h.mask = 1;
h.opcode = 1;
uint8_t size_buf[8];
if (size < 126) {
h.payload_len = static_cast<uint8_t>(size);
}
else if (size < 65536) {
h.payload_len = 126;
size_buf[0] = static_cast<uint8_t>(size >> 8);
size_buf[1] = static_cast<uint8_t>(size & 0xFF);
}
else {
h.payload_len = 127;
uint64_t k = size;
for (int i = 7; i >= 0; --i, k >>= 8) {
size_buf[i] = static_cast<uint8_t>(k & 0xFF);
}
}
// Header
SSL_write(m_wss.m_ssl, &h, sizeof(h));
// Optional extended payload length
if (h.payload_len == 126) SSL_write(m_wss.m_ssl, size_buf, 2);
if (h.payload_len == 127) SSL_write(m_wss.m_ssl, size_buf, 8);
// Masking-key
SSL_write(m_wss.m_ssl, "\0\0\0\0", 4);
}
SSL_write(m_wss.m_ssl, data, static_cast<int>(size));
}
uv_buf_t buf;
buf.len = BIO_get_mem_data(m_wss.m_write, &buf.base);
if (buf.len == 0) {
return true;
}
const int rc = uv_try_write(reinterpret_cast<uv_stream_t*>(m_wss.m_socket), &buf, 1);
BIO_reset(m_wss.m_write);
if (static_cast<size_t>(rc) == buf.len) {
return true;
}
LOG_ERR("%s " RED("WSS write failed, rc = %d"), tag(), rc);
WSSClose();
return false;
}
void xmrig::DaemonClient::WSSRead(ssize_t nread, const uv_buf_t* read_buf)
{
if (nread <= 0) {
LOG_ERR("%s " RED("WSS read failed, nread = %" PRId64), tag(), nread);
WSSClose();
return;
}
BIO_write(m_wss.m_read, read_buf->base, static_cast<int>(nread));
if (!SSL_is_init_finished(m_wss.m_ssl)) {
const int rc = SSL_connect(m_wss.m_ssl);
if ((rc < 0) && (SSL_get_error(m_wss.m_ssl, rc) == SSL_ERROR_WANT_READ)) {
WSSWrite(nullptr, 0);
}
else if (rc == 1) {
// login
static constexpr char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char key[25];
std::random_device r;
for (int i = 0; i < 21; ++i) {
key[i] = Base64[r() % 64];
}
key[21] = Base64[0];
key[22] = '=';
key[23] = '=';
key[24] = '\0';
const int n = snprintf(m_wss.m_buf, sizeof(m_wss.m_buf), kWSSLogin, m_pool.user().data(), m_pool.host().data(), key);
if (0 <= n && n < static_cast<int>(sizeof(m_wss.m_buf))) {
WSSWrite(m_wss.m_buf, n);
}
else {
WSSClose();
}
}
return;
}
int n = 0;
while ((n = SSL_read(m_wss.m_ssl, m_wss.m_buf, sizeof(m_wss.m_buf))) > 0) {
m_wss.m_data.insert(m_wss.m_data.end(), m_wss.m_buf, m_wss.m_buf + n);
// Skip the first message (HTTP upgrade response)
if (m_wss.m_handshake) {
const size_t len = m_wss.m_data.size();
if (len >= 4) {
for (size_t k = 0; k <= len - 4; ++k) {
if (memcmp(m_wss.m_data.data() + k, "\r\n\r\n", 4) == 0) {
m_wss.m_handshake = false;
m_wss.m_data.erase(m_wss.m_data.begin(), m_wss.m_data.begin() + k + 4);
break;
}
}
}
continue;
}
const uint8_t* p0 = reinterpret_cast<uint8_t*>(m_wss.m_data.data());
const uint8_t* p = p0;
const uint8_t* e = p0 + m_wss.m_data.size();
if (e - p < static_cast<int>(sizeof(WSS::Header)))
continue;
const WSS::Header* h = reinterpret_cast<const WSS::Header*>(p);
p += sizeof(WSS::Header);
uint64_t len = h->payload_len;
if (len == 126) {
if (e - p < static_cast<int>(sizeof(uint16_t))) {
continue;
}
len = 0;
for (size_t i = 0; i < sizeof(uint16_t); ++i, ++p) {
len = (len << 8) | *p;
}
}
else if (len == 127) {
if (e - p < static_cast<int>(sizeof(uint64_t))) {
continue;
}
len = 0;
for (size_t i = 0; i < sizeof(uint64_t); ++i, ++p) {
len = (len << 8) | *p;
}
}
uint8_t mask_key[4] = {};
if (h->mask) {
if (e - p < 4)
continue;
memcpy(mask_key, p, 4);
p += 4;
}
if (static_cast<uint64_t>(e - p) < len)
continue;
for (uint64_t i = 0; i < len; ++i) {
m_wss.m_message.push_back(p[i] ^ mask_key[i % 4]);
}
p += len;
m_wss.m_data.erase(m_wss.m_data.begin(), m_wss.m_data.begin() + (p - p0));
if (h->fin) {
if (m_wss.m_message.back() == '\n') {
m_wss.m_message.back() = '\0';
}
else {
m_wss.m_message.push_back('\0');
}
WSSParse();
m_wss.m_message.clear();
}
}
}
void xmrig::DaemonClient::WSSParse()
{
# ifdef APP_DEBUG
LOG_DEBUG(CYAN("%s") BLACK_BOLD(" read ") CYAN_BOLD("%zu") BLACK_BOLD(" bytes") " %s", m_pool.url().data(), m_wss.m_message.size(), m_wss.m_message.data());
# endif
using namespace rapidjson;
Document doc;
if (doc.ParseInsitu(m_wss.m_message.data()).HasParseError() || !doc.IsObject()) {
if (!isQuiet()) {
LOG_ERR("%s " RED("JSON decode failed: ") RED_BOLD("\"%s\""), tag(), GetParseError_En(doc.GetParseError()));
}
return retry();
}
if (doc.HasMember(kLastError)) {
String err = Json::getString(doc, kLastError, "");
if (!err.isEmpty()) {
LOG_ERR("%s " RED_BOLD("\"%s\""), tag(), err.data());
return;
}
}
if (doc.HasMember(kBlockhashingBlob)) {
Job job(false, m_pool.algorithm(), String());
m_blockhashingblob = Json::getString(doc, kBlockhashingBlob, "");
if (m_blockhashingblob.isEmpty()) {
LOG_ERR("%s " RED_BOLD("blockhashing_blob is empty"), tag());
return;
}
job.setBlob(m_blockhashingblob);
memset(job.blob() + job.nonceOffset(), 0, job.nonceSize());
job.setHeight(Json::getUint64(doc, kHeight));
job.setDiff(Json::getUint64(doc, "difficultyuint64"));
//job.setDiff(100000);
m_currentJobId = Json::getString(doc, "jobid");
job.setId(m_currentJobId);
m_job = std::move(job);
if (m_state == ConnectingState) {
setState(ConnectedState);
}
const uint64_t blocks = Json::getUint64(doc, "blocks");
const uint64_t miniblocks = Json::getUint64(doc, "miniblocks");
if ((blocks != m_wss.m_blocks) || (miniblocks != m_wss.m_miniblocks)) {
LOG_INFO("%s " GREEN_BOLD("%" PRIu64 " blocks, %" PRIu64 " mini blocks"), tag(), blocks, miniblocks);
m_wss.m_blocks = blocks;
m_wss.m_miniblocks = miniblocks;
}
m_listener->onJobReceived(this, m_job, doc);
return;
}
}
bool xmrig::DaemonClient::WSSClose(bool shutdown)
{
if (m_wss.m_socket && (uv_is_closing(reinterpret_cast<uv_handle_t*>(m_wss.m_socket)) == 0)) {
uv_close(reinterpret_cast<uv_handle_t*>(m_wss.m_socket), shutdown ? onWSSShutdown : onWSSClose);
return true;
}
return false;
}
void xmrig::DaemonClient::WSS::cleanup()
{
delete m_socket;
m_socket = nullptr;
if (m_ctx) {
SSL_CTX_free(m_ctx);
m_ctx = nullptr;
}
if (m_ssl) {
SSL_free(m_ssl);
m_ssl = nullptr;
}
m_read = nullptr;
m_write = nullptr;
m_handshake = true;
m_blocks = 0;
m_miniblocks = 0;
m_data.clear();
m_message.clear();
}
#endif

View file

@ -39,6 +39,12 @@ using uv_handle_t = struct uv_handle_s;
using uv_stream_t = struct uv_stream_s;
using uv_tcp_t = struct uv_tcp_s;
#ifdef XMRIG_FEATURE_TLS
using BIO = struct bio_st;
using SSL = struct ssl_st;
using SSL_CTX = struct ssl_ctx_st;
#endif
namespace xmrig {
@ -57,6 +63,7 @@ public:
protected:
bool disconnect() override;
bool isTLS() const override;
bool isWSS() const override;
int64_t submit(const JobResult &result) override;
void connect() override;
void connect(const Pool &pool) override;
@ -136,6 +143,44 @@ private:
std::vector<char> m_ZMQSendBuf;
std::vector<char> m_ZMQRecvBuf;
# ifdef XMRIG_FEATURE_TLS
static void onWSSConnect(uv_connect_t* req, int status);
static void onWSSRead(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
static void onWSSClose(uv_handle_t* handle);
static void onWSSShutdown(uv_handle_t* handle);
void WSSConnected();
bool WSSWrite(const char* data, size_t size);
void WSSRead(ssize_t nread, const uv_buf_t* buf);
void WSSParse();
bool WSSClose(bool shutdown = false);
struct WSS {
struct Header
{
uint8_t opcode : 4;
uint8_t reserved : 3;
uint8_t fin : 1;
uint8_t payload_len : 7;
uint8_t mask : 1;
};
uv_tcp_t* m_socket = nullptr;
SSL_CTX* m_ctx = nullptr;
BIO* m_read = nullptr;
BIO* m_write = nullptr;
SSL* m_ssl = nullptr;
char m_buf[512] = {};
bool m_handshake = true;
uint64_t m_blocks = 0;
uint64_t m_miniblocks = 0;
std::vector<char> m_data;
std::vector<char> m_message;
void cleanup();
} m_wss;
# endif
};

View file

@ -164,6 +164,18 @@ void xmrig::Job::setSigKey(const char *sig_key)
}
int32_t xmrig::Job::nonceOffset() const
{
auto f = algorithm().family();
if (f == Algorithm::KAWPOW) return 32;
if (f == Algorithm::GHOSTRIDER) return 76;
auto id = algorithm().id();
if (id == Algorithm::ASTROBWT_DERO_2) return 44;
return 39;
}
uint32_t xmrig::Job::getNumTransactions() const
{
if (!(m_algorithm.isCN() || m_algorithm.family() == Algorithm::RANDOM_X)) {

View file

@ -76,7 +76,7 @@ public:
inline const String &poolWallet() const { return m_poolWallet; }
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 { auto f = algorithm().family(); return (f == Algorithm::KAWPOW) ? 32 : ((f == Algorithm::GHOSTRIDER) ? 76 : 39); }
int32_t nonceOffset() const;
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 + nonceOffset()); }

View file

@ -76,6 +76,7 @@ const char *Pool::kSelfSelect = "self-select";
const char *Pool::kSOCKS5 = "socks5";
const char *Pool::kSubmitToOrigin = "submit-to-origin";
const char *Pool::kTls = "tls";
const char *Pool::kWSS = "wss";
const char *Pool::kUrl = "url";
const char *Pool::kUser = "user";
const char *Pool::kSpendSecretKey = "spend-secret-key";
@ -93,7 +94,7 @@ xmrig::Pool::Pool(const char *url) :
}
xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, const char* spendSecretKey, int keepAlive, bool nicehash, bool tls, Mode mode) :
xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char *password, const char* spendSecretKey, int keepAlive, bool nicehash, bool tls, bool wss, Mode mode) :
m_keepAlive(keepAlive),
m_mode(mode),
m_flags(1 << FLAG_ENABLED),
@ -105,6 +106,7 @@ xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char
{
m_flags.set(FLAG_NICEHASH, nicehash || strstr(host, kNicehashHost));
m_flags.set(FLAG_TLS, tls);
m_flags.set(FLAG_WSS, wss);
}
@ -132,6 +134,7 @@ xmrig::Pool::Pool(const rapidjson::Value &object) :
m_flags.set(FLAG_ENABLED, Json::getBool(object, kEnabled, true));
m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash) || m_url.host().contains(kNicehashHost));
m_flags.set(FLAG_TLS, Json::getBool(object, kTls) || m_url.isTLS());
m_flags.set(FLAG_WSS, Json::getBool(object, kWSS) || m_url.isWSS());
setKeepAlive(Json::getValue(object, kKeepalive));
@ -293,6 +296,7 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const
obj.AddMember(StringRef(kEnabled), m_flags.test(FLAG_ENABLED), allocator);
obj.AddMember(StringRef(kTls), isTLS(), allocator);
obj.AddMember(StringRef(kWSS), isWSS(), allocator);
obj.AddMember(StringRef(kFingerprint), m_fingerprint.toJSON(), allocator);
obj.AddMember(StringRef(kDaemon), m_mode == MODE_DAEMON, allocator);
obj.AddMember(StringRef(kSOCKS5), m_proxy.toJSON(doc), allocator);

View file

@ -69,10 +69,12 @@ public:
static const char *kSOCKS5;
static const char *kSubmitToOrigin;
static const char *kTls;
static const char* kWSS;
static const char *kUrl;
static const char *kUser;
static const char* kSpendSecretKey;
static const char* kDaemonZMQPort;
static const char* kDaemonWSSPort;
static const char *kNicehashHost;
constexpr static int kKeepAliveTimeout = 60;
@ -80,7 +82,7 @@ public:
constexpr static uint64_t kDefaultPollInterval = 1000;
Pool() = default;
Pool(const char *host, uint16_t port, const char *user, const char *password, const char* spendSecretKey, int keepAlive, bool nicehash, bool tls, Mode mode);
Pool(const char *host, uint16_t port, const char *user, const char *password, const char* spendSecretKey, int keepAlive, bool nicehash, bool tls, bool wss, Mode mode);
Pool(const char *url);
Pool(const rapidjson::Value &object);
@ -93,6 +95,7 @@ public:
inline bool isNicehash() const { return m_flags.test(FLAG_NICEHASH); }
inline bool isTLS() const { return m_flags.test(FLAG_TLS) || m_url.isTLS(); }
inline bool isWSS() const { return m_flags.test(FLAG_WSS) || m_url.isWSS(); }
inline bool isValid() const { return m_url.isValid(); }
inline const Algorithm &algorithm() const { return m_algorithm; }
inline const Coin &coin() const { return m_coin; }
@ -135,6 +138,7 @@ private:
FLAG_ENABLED,
FLAG_NICEHASH,
FLAG_TLS,
FLAG_WSS,
FLAG_MAX
};

View file

@ -49,6 +49,7 @@ protected:
inline bool hasExtension(Extension extension) const noexcept override { return m_client->hasExtension(extension); }
inline bool isEnabled() const override { return m_client->isEnabled(); }
inline bool isTLS() const override { return m_client->isTLS(); }
inline bool isWSS() const override { return m_client->isWSS(); }
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(); }

View file

@ -39,6 +39,7 @@ static const char kSOCKS5[] = "socks5://";
#ifdef XMRIG_FEATURE_HTTP
static const char kDaemonHttp[] = "daemon+http://";
static const char kDaemonHttps[] = "daemon+https://";
static const char kDaemonWss[] = "daemon+wss://";
#endif
} // namespace xmrig
@ -103,6 +104,11 @@ bool xmrig::Url::parse(const char *url)
m_scheme = DAEMON;
m_tls = false;
}
else if (strncasecmp(url, kDaemonWss, sizeof(kDaemonWss) - 1) == 0) {
m_scheme = DAEMON;
m_tls = true;
m_wss = true;
}
# endif
else {
return false;

View file

@ -41,6 +41,7 @@ public:
Url(const char *host, uint16_t port, bool tls = false, Scheme scheme = UNSPECIFIED);
inline bool isTLS() const { return m_tls; }
inline bool isWSS() const { return m_wss; }
inline bool isValid() const { return !m_host.isNull() && m_port > 0; }
inline const String &host() const { return m_host; }
inline const String &url() const { return m_url; }
@ -57,6 +58,7 @@ protected:
bool parseIPv6(const char *addr);
bool m_tls = false;
bool m_wss = false;
Scheme m_scheme = UNSPECIFIED;
String m_host;
String m_url;

View file

@ -41,6 +41,7 @@ public:
inline bool hasExtension(Extension) const noexcept override { return false; }
inline bool isEnabled() const override { return true; }
inline bool isTLS() const override { return false; }
inline bool isWSS() const override { return false; }
inline const char *mode() const override { return "benchmark"; }
inline const char *tlsFingerprint() const override { return nullptr; }
inline const char *tlsVersion() const override { return nullptr; }

View file

@ -23,10 +23,12 @@
#include <stdlib.h>
#define bswap_64(x) _byteswap_uint64(x)
#define bswap_32(x) _byteswap_ulong(x)
#elif defined __GNUC__
#define bswap_64(x) __builtin_bswap64(x)
#define bswap_32(x) __builtin_bswap32(x)
#else

View file

@ -25,6 +25,7 @@
#include "base/crypto/sha3.h"
#include "base/tools/bswap_64.h"
#include "crypto/cn/CryptoNight.h"
#include "crypto/astrobwt/sort_indices2.h"
#include <limits>
@ -433,6 +434,45 @@ bool xmrig::astrobwt::astrobwt_dero(const void* input_data, uint32_t input_size,
}
bool xmrig::astrobwt::astrobwt_dero_v2(const void* input_data, uint32_t input_size, void* scratchpad, uint8_t* output_hash)
{
constexpr size_t N = 9973;
constexpr size_t STRIDE = 10240;
alignas(8) uint8_t key[32];
uint8_t* scratchpad_ptr = (uint8_t*)(scratchpad) + 64;
uint8_t* v = scratchpad_ptr;
uint32_t* indices = (uint32_t*)(scratchpad_ptr + STRIDE);
uint32_t* tmp_indices = (uint32_t*)(scratchpad_ptr + STRIDE * 5);
#ifdef ASTROBWT_AVX2
if (hasAVX2) {
SHA3_256_AVX2_ASM(input_data, input_size, key);
Salsa20_XORKeyStream_AVX256(key, v, N);
}
else
#endif
{
sha3_HashBuffer(256, SHA3_FLAGS_NONE, input_data, input_size, key, sizeof(key));
Salsa20_XORKeyStream(key, v, N);
}
sort_indices_astrobwt_v2(N, v, indices, tmp_indices);
#ifdef ASTROBWT_AVX2
if (hasAVX2) {
SHA3_256_AVX2_ASM(indices, N * 2, output_hash);
}
else
#endif
{
sha3_HashBuffer(256, SHA3_FLAGS_NONE, indices, N * 2, output_hash, 32);
}
return true;
}
void xmrig::astrobwt::init()
{
if (!astrobwtInitialized) {
@ -450,3 +490,10 @@ void xmrig::astrobwt::single_hash<xmrig::Algorithm::ASTROBWT_DERO>(const uint8_t
{
astrobwt_dero(input, static_cast<uint32_t>(size), ctx[0]->memory, output, std::numeric_limits<int>::max(), true);
}
template<>
void xmrig::astrobwt::single_hash<xmrig::Algorithm::ASTROBWT_DERO_2>(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx** ctx, uint64_t)
{
astrobwt_dero_v2(input, static_cast<uint32_t>(size), ctx[0]->memory, output);
}

View file

@ -32,6 +32,7 @@ namespace xmrig {
namespace astrobwt {
bool astrobwt_dero(const void* input_data, uint32_t input_size, void* scratchpad, uint8_t* output_hash, int stage2_max_size, bool avx2);
bool astrobwt_dero_v2(const void* input_data, uint32_t input_size, void* scratchpad, uint8_t* output_hash);
void init();
template<Algorithm::Id ALGO>
@ -40,5 +41,7 @@ void single_hash(const uint8_t* input, size_t size, uint8_t* output, cryptonight
template<>
void single_hash<Algorithm::ASTROBWT_DERO>(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx** ctx, uint64_t);
template<>
void single_hash<Algorithm::ASTROBWT_DERO_2>(const uint8_t* input, size_t size, uint8_t* output, cryptonight_ctx** ctx, uint64_t);
}} // namespace xmrig::astrobwt

View file

@ -0,0 +1,208 @@
/* XMRig
* Copyright (c) 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
* Copyright (c) 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
* Copyright (c) 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
* 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
* 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 "crypto/astrobwt/sort_indices2.h"
#include "base/tools/bswap_64.h"
#include <cstring>
#ifdef __GNUC__
#define NOINLINE __attribute__((noinline))
#define RESTRICT __restrict__
#elif _MSC_VER
#define NOINLINE __declspec(noinline)
#define RESTRICT __restrict
#else
#define NOINLINE
#define RESTRICT
#endif
#if __has_cpp_attribute(unlikely)
#define UNLIKELY(X) (X) [[unlikely]]
#elif defined __GNUC__
#define UNLIKELY(X) (__builtin_expect((X), 0))
#else
#define UNLIKELY(X) (X)
#endif
static NOINLINE void fix(const uint8_t* RESTRICT v, uint32_t* RESTRICT indices, int32_t i)
{
uint32_t prev_t = indices[i - 1];
uint32_t t = indices[i];
const uint32_t data_a = bswap_32(*(const uint32_t*)(v + (t & 0xFFFF) + 2));
if (data_a < bswap_32(*(const uint32_t*)(v + (prev_t & 0xFFFF) + 2)))
{
const uint32_t t2 = prev_t;
int32_t j = i - 1;
do
{
indices[j + 1] = prev_t;
--j;
if (j < 0) {
break;
}
prev_t = indices[j];
} while (((t ^ prev_t) <= 0xFFFF) && (data_a < bswap_32(*(const uint32_t*)(v + (prev_t & 0xFFFF) + 2))));
indices[j + 1] = t;
t = t2;
}
}
static NOINLINE void sort_indices(uint32_t N, const uint8_t* RESTRICT v, uint32_t* RESTRICT indices, uint32_t* RESTRICT tmp_indices)
{
uint8_t byte_counters[2][256] = {};
uint32_t counters[2][256];
{
#define ITER(X) ++byte_counters[1][v[i + X]];
enum { unroll = 12 };
uint32_t i = 0;
const uint32_t n = N - (unroll - 1);
for (; i < n; i += unroll) {
ITER(0); ITER(1); ITER(2); ITER(3); ITER(4); ITER(5); ITER(6); ITER(7); ITER(8); ITER(9); ITER(10); ITER(11);
}
for (; i < N; ++i) {
ITER(0);
}
memcpy(&byte_counters[0], &byte_counters[1], 256);
--byte_counters[0][v[0]];
#undef ITER
}
{
uint32_t c0 = byte_counters[0][0];
uint32_t c1 = byte_counters[1][0] - 1;
counters[0][0] = c0;
counters[1][0] = c1;
uint8_t* src = &byte_counters[0][0] + 1;
uint32_t* dst = &counters[0][0] + 1;
const uint8_t* const e = &byte_counters[0][0] + 256;
do {
c0 += src[0];
c1 += src[256];
dst[0] = c0;
dst[256] = c1;
++src;
++dst;
} while (src < e);
}
{
#define ITER(X) \
do { \
const uint32_t byte0 = v[i - X + 0]; \
const uint32_t byte1 = v[i - X + 1]; \
tmp_indices[counters[0][byte1]--] = (byte0 << 24) | (byte1 << 16) | (i - X); \
} while (0)
enum { unroll = 8 };
uint32_t i = N;
for (; i >= unroll; i -= unroll) {
ITER(1); ITER(2); ITER(3); ITER(4); ITER(5); ITER(6); ITER(7); ITER(8);
}
for (; i > 0; --i) {
ITER(1);
}
#undef ITER
}
{
#define ITER(X) \
do { \
const uint32_t data = tmp_indices[i - X]; \
indices[counters[1][data >> 24]--] = data; \
} while (0)
enum { unroll = 8 };
uint32_t i = N;
for (; i >= unroll; i -= unroll) {
ITER(1); ITER(2); ITER(3); ITER(4); ITER(5); ITER(6); ITER(7); ITER(8);
}
for (; i > 0; --i) {
ITER(1);
}
#undef ITER
}
{
#define ITER(X) do { if UNLIKELY(a[X * 2] == a[(X + 1) * 2]) fix(v, indices, i + X); } while (0)
enum { unroll = 16 };
uint32_t i = 1;
const uint32_t n = N - (unroll - 1);
const uint16_t* a = ((const uint16_t*)indices) + 1;
for (; i < n; i += unroll, a += unroll * 2) {
ITER(0); ITER(1); ITER(2); ITER(3); ITER(4); ITER(5); ITER(6); ITER(7);
ITER(8); ITER(9); ITER(10); ITER(11); ITER(12); ITER(13); ITER(14); ITER(15);
}
for (; i < N; ++i, a += 2) {
ITER(0);
}
#undef ITER
}
{
#define ITER(X) a[X] = b[X * 2];
enum { unroll = 32 };
uint16_t* a = (uint16_t*)indices;
uint16_t* b = (uint16_t*)indices;
uint16_t* e = (uint16_t*)(indices + (N - (unroll - 1)));
for (; a < e; a += unroll, b += unroll * 2) {
ITER(0); ITER(1); ITER(2); ITER(3); ITER(4); ITER(5); ITER(6); ITER(7);
ITER(8); ITER(9); ITER(10); ITER(11); ITER(12); ITER(13); ITER(14); ITER(15);
ITER(16); ITER(17); ITER(18); ITER(19); ITER(20); ITER(21); ITER(22); ITER(23);
ITER(24); ITER(25); ITER(26); ITER(27); ITER(28); ITER(29); ITER(30); ITER(31);
}
e = (uint16_t*)(indices + N);
for (; a < e; ++a, b += 2) {
ITER(0);
}
#undef ITER
}
}
void sort_indices_astrobwt_v2(uint32_t N, const uint8_t* v, uint32_t* indices, uint32_t* tmp_indices)
{
sort_indices(N, v, indices, tmp_indices);
}

View file

@ -0,0 +1,26 @@
/* XMRig
* Copyright (c) 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
* Copyright (c) 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
* Copyright (c) 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
* 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
* 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 <stdint.h>
void sort_indices_astrobwt_v2(uint32_t N, const uint8_t* v, uint32_t* indices, uint32_t* tmp_indices);

View file

@ -379,6 +379,10 @@ xmrig::CnHash::CnHash()
m_map[Algorithm::ASTROBWT_DERO] = new cn_hash_fun_array{};
m_map[Algorithm::ASTROBWT_DERO]->data[AV_SINGLE][Assembly::NONE] = astrobwt::single_hash<Algorithm::ASTROBWT_DERO>;
m_map[Algorithm::ASTROBWT_DERO]->data[AV_SINGLE_SOFT][Assembly::NONE] = astrobwt::single_hash<Algorithm::ASTROBWT_DERO>;
m_map[Algorithm::ASTROBWT_DERO_2] = new cn_hash_fun_array{};
m_map[Algorithm::ASTROBWT_DERO_2]->data[AV_SINGLE][Assembly::NONE] = astrobwt::single_hash<Algorithm::ASTROBWT_DERO_2>;
m_map[Algorithm::ASTROBWT_DERO_2]->data[AV_SINGLE_SOFT][Assembly::NONE] = astrobwt::single_hash<Algorithm::ASTROBWT_DERO_2>;
# endif
# ifdef XMRIG_ALGO_GHOSTRIDER

View file

@ -447,6 +447,19 @@ const static uint8_t astrobwt_dero_test_out[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// "astrobwt/v2"
const static uint8_t astrobwt_dero_2_test_out[256] = {
0x48, 0x9E, 0xD2, 0x66, 0x14, 0x27, 0x98, 0x65, 0x03, 0xFB, 0x87, 0x25, 0xE1, 0xD3, 0x98, 0xDA,
0x27, 0xEE, 0x25, 0x3D, 0xB4, 0x37, 0x87, 0x98, 0xBF, 0x5A, 0x5C, 0x94, 0xEE, 0x0C, 0xE2, 0x2A,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#endif

View file

@ -70,9 +70,9 @@ xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener
# endif
# ifdef XMRIG_FEATURE_TLS
m_pools.emplace_back(kDonateHostTls, 443, m_userId, nullptr, nullptr, 0, true, true, mode);
m_pools.emplace_back(kDonateHostTls, 443, m_userId, nullptr, nullptr, 0, true, true, false, mode);
# endif
m_pools.emplace_back(kDonateHost, 3333, m_userId, nullptr, nullptr, 0, true, false, mode);
m_pools.emplace_back(kDonateHost, 3333, m_userId, nullptr, nullptr, 0, true, false, false, mode);
if (m_pools.size() > 1) {
m_strategy = new FailoverStrategy(m_pools, 10, 2, this, true);
@ -252,7 +252,7 @@ xmrig::IClient *xmrig::DonateStrategy::createProxy()
const IClient *client = strategy->client();
m_tls = client->hasExtension(IClient::EXT_TLS);
Pool pool(client->pool().proxy().isValid() ? client->pool().host() : client->ip(), client->pool().port(), m_userId, client->pool().password(), client->pool().spendSecretKey(), 0, true, client->isTLS(), Pool::MODE_POOL);
Pool pool(client->pool().proxy().isValid() ? client->pool().host() : client->ip(), client->pool().port(), m_userId, client->pool().password(), client->pool().spendSecretKey(), 0, true, client->isTLS(), client->isWSS(), Pool::MODE_POOL);
pool.setAlgo(client->pool().algorithm());
pool.setProxy(client->pool().proxy());