From 14b95e8be36ce6055a1fa2201a0428fca39a0675 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 31 Jul 2017 19:09:41 +0300 Subject: [PATCH] Add class NonceStorage. --- CMakeLists.txt | 2 + src/proxy/Miner.cpp | 5 +- src/proxy/Miner.h | 5 +- src/proxy/splitters/NonceMapper.cpp | 118 ++++--------------- src/proxy/splitters/NonceMapper.h | 11 +- src/proxy/splitters/NonceSplitter.cpp | 2 +- src/proxy/splitters/NonceStorage.cpp | 161 ++++++++++++++++++++++++++ src/proxy/splitters/NonceStorage.h | 71 ++++++++++++ src/version.h | 4 +- 9 files changed, 272 insertions(+), 107 deletions(-) create mode 100644 src/proxy/splitters/NonceStorage.cpp create mode 100644 src/proxy/splitters/NonceStorage.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 204123a..761260e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,7 @@ set(HEADERS src/proxy/Server.h src/proxy/splitters/NonceMapper.h src/proxy/splitters/NonceSplitter.h + src/proxy/splitters/NonceStorage.h src/proxy/Uuid.h src/Summary.h src/version.h @@ -64,6 +65,7 @@ set(SOURCES src/proxy/Server.cpp src/proxy/splitters/NonceMapper.cpp src/proxy/splitters/NonceSplitter.cpp + src/proxy/splitters/NonceStorage.cpp src/Summary.cpp src/xmrig.cpp ) diff --git a/src/proxy/Miner.cpp b/src/proxy/Miner.cpp index 184dd1d..40d5c5d 100644 --- a/src/proxy/Miner.cpp +++ b/src/proxy/Miner.cpp @@ -45,6 +45,7 @@ Miner::Miner() : m_recvBufPos(0), m_mapperId(-1), m_state(WaitLoginState), + m_realmId(0), m_expire(uv_now(uv_default_loop()) + kLoginTimeout), m_rx(0), m_timestamp(uv_now(uv_default_loop())), @@ -57,7 +58,7 @@ Miner::Miner() : m_socket.data = this; uv_tcp_init(uv_default_loop(), &m_socket); - m_recvBuf.base = static_cast(malloc(kRecvBufSize)); + m_recvBuf.base = new char[kRecvBufSize]; m_recvBuf.len = kRecvBufSize; memset(m_recvBuf.base, 0, kRecvBufSize); @@ -71,7 +72,7 @@ Miner::~Miner() Counters::remove(Counters::Connection); m_socket.data = nullptr; - free(m_recvBuf.base); + delete [] m_recvBuf.base; } diff --git a/src/proxy/Miner.h b/src/proxy/Miner.h index bf38485..b40f45d 100644 --- a/src/proxy/Miner.h +++ b/src/proxy/Miner.h @@ -55,6 +55,7 @@ public: inline int64_t id() const { return m_id; } inline ssize_t mapperId() const { return m_mapperId; } inline State state() const { return m_state; } + inline uint32_t realmId() const { return m_realmId; } inline uint64_t expire() const { return m_expire; } inline uint64_t rx() const { return m_rx; } inline uint64_t timestamp() const { return m_timestamp; } @@ -64,10 +65,11 @@ public: inline void setFixedByte(uint8_t fixedByte) { m_fixedByte = fixedByte; } inline void setListener(IMinerListener *listener) { m_listener = listener; } inline void setMapperId(ssize_t mapperId) { m_mapperId = mapperId; } + inline void setRealmId(uint32_t realmId) { m_realmId = realmId; } private: constexpr static size_t kLoginTimeout = 10 * 1000; - constexpr static size_t kRecvBufSize = 4096; + constexpr static size_t kRecvBufSize = 2048; constexpr static size_t kSocketTimeout = 60 * 10 * 1000; bool parseRequest(int64_t id, const char *method, const json_t *params); @@ -90,6 +92,7 @@ private: size_t m_recvBufPos; ssize_t m_mapperId; State m_state; + uint32_t m_realmId; uint64_t m_expire; uint64_t m_rx; uint64_t m_timestamp; diff --git a/src/proxy/splitters/NonceMapper.cpp b/src/proxy/splitters/NonceMapper.cpp index a2b7b74..0630a8b 100644 --- a/src/proxy/splitters/NonceMapper.cpp +++ b/src/proxy/splitters/NonceMapper.cpp @@ -35,20 +35,18 @@ #include "Options.h" #include "proxy/Counters.h" #include "proxy/JobResult.h" -#include "proxy/LoginRequest.h" #include "proxy/Miner.h" #include "proxy/splitters/NonceMapper.h" +#include "proxy/splitters/NonceStorage.h" NonceMapper::NonceMapper(size_t id, const Options *options, const char *agent) : - m_active(false), m_suspended(false), m_agent(agent), m_options(options), - m_id(id), - m_used(256, 0), - m_index(std::rand() % 256) + m_id(id) { + m_storage = new NonceStorage(); const std::vector &pools = options->pools(); if (pools.size() > 1) { @@ -63,13 +61,13 @@ NonceMapper::NonceMapper(size_t id, const Options *options, const char *agent) : NonceMapper::~NonceMapper() { delete m_strategy; + delete m_storage; } bool NonceMapper::add(Miner *miner, const LoginRequest &request) { - const int index = nextIndex(request.clientType() == LoginRequest::XMRig20Client ? 1 : 0); - if (index == -1) { + if (!m_storage->add(miner, request)) { return false; } @@ -77,20 +75,16 @@ bool NonceMapper::add(Miner *miner, const LoginRequest &request) connect(); } - miner->setFixedByte(index); - - m_index = index; - m_used[index] = miner->id(); - m_miners[miner->id()] = miner; - - if (m_active) { - miner->setJob(m_job); - } - return true; } +bool NonceMapper::isActive() const +{ + return m_storage->isActive(); +} + + void NonceMapper::connect() { m_suspended = false; @@ -102,43 +96,32 @@ void NonceMapper::connect() void NonceMapper::gc() { - if (m_suspended || m_id == 0) { + if (m_suspended || m_id == 0 || m_storage->isUsed()) { return; } - for (const int64_t v : m_used) { - if (v > 0) { - return; - } - } - suspend(); } void NonceMapper::remove(const Miner *miner) { - m_used[miner->fixedByte()] = -miner->id(); - - auto it = m_miners.find(miner->id()); - if (it != m_miners.end()) { - m_miners.erase(it); - } + m_storage->remove(miner); } void NonceMapper::submit(Miner *miner, const JobResult &request) { - if (!m_active) { + if (!m_storage->isActive()) { return miner->reject(request.id, "Bad gateway"); } - if (strncmp(m_job.id(), request.jobId, 64) != 0) { + if (strncmp(m_storage->job().id(), request.jobId, 64) != 0) { return miner->reject(request.id, "Invalid job id"); } JobResult req = request; - req.diff = m_job.diff(); + req.diff = m_storage->job().diff(); m_results[m_strategy->submit(req)] = SubmitCtx(request.id, miner->id()); } @@ -151,29 +134,14 @@ void NonceMapper::printState() return; } - int available = 0; - int dead = 0; - - for (const int64_t v : m_used) { - if (v == 0) { - available++; - } - else if (v < 0) { - dead++; - } - } - - int miners = 256 - available - dead; - - LOG_INFO("#%03u - \x1B[32m%03d \x1B[33m%03d \x1B[35m%03d\x1B[0m - 0x%02hhX, % 5.1f%%", - m_id, available, dead, miners, m_index, (double) miners / 256 * 100.0); + m_storage->printState(m_id); } #endif void NonceMapper::onActive(Client *client) { - m_active = true; + m_storage->setActive(true); LOG_INFO("#%03u \x1B[01;37muse pool \x1B[01;36m%s:%d \x1B[01;30m%s", m_id, client->host(), client->port(), client->ip()); } @@ -185,28 +153,13 @@ void NonceMapper::onJob(Client *client, const Job &job) LOG_INFO("#%03u \x1B[01;35mnew job\x1B[0m from \x1B[01;37m%s:%d\x1B[0m diff \x1B[01;37m%d", m_id, client->host(), client->port(), job.diff()); } - for (size_t i = 0; i < m_used.size(); ++i) { - if (m_used[i] < 0) { - m_used[i] = 0; - } - } - - m_job = job; - - for (size_t i = 0; i < m_used.size(); ++i) { - const size_t index = m_used[i]; - Miner *miner = index > 0 ? m_miners[index] : nullptr; - - if (miner) { - miner->setJob(m_job); - } - } + m_storage->setJob(job); } void NonceMapper::onPause(IStrategy *strategy) { - m_active = false; + m_storage->setActive(false); if (!m_suspended) { LOG_ERR("#%03u no active pools, stop", m_id); @@ -228,7 +181,7 @@ void NonceMapper::onResultAccepted(Client *client, int64_t seq, uint32_t diff, u const SubmitCtx &ctx = m_results[seq]; - Miner *miner = m_miners[ctx.minerId]; + Miner *miner = m_storage->miner(ctx.minerId); if (miner) { if (error) { miner->reject(ctx.id, error, false); @@ -245,33 +198,12 @@ void NonceMapper::onResultAccepted(Client *client, int64_t seq, uint32_t diff, u } -int NonceMapper::nextIndex(int start) const -{ - for (size_t i = m_index; i < m_used.size(); ++i) { - if (m_used[i] == 0) { - return i; - } - } - - for (size_t i = start; i < m_index; ++i) { - if (m_used[i] == 0) { - return i; - } - } - - return -1; -} - - void NonceMapper::suspend() { m_suspended = true; - m_active = false; - Counters::remove(Counters::Upstream); - - for (size_t i = 0; i < m_used.size(); ++i) { - m_used[i] = 0; - } - + m_storage->setActive(false); + m_storage->reset(); m_strategy->stop(); + + Counters::remove(Counters::Upstream); } diff --git a/src/proxy/splitters/NonceMapper.h b/src/proxy/splitters/NonceMapper.h index 0a6e3ba..8b024c4 100644 --- a/src/proxy/splitters/NonceMapper.h +++ b/src/proxy/splitters/NonceMapper.h @@ -38,6 +38,7 @@ class IStrategy; class JobResult; class LoginRequest; class Miner; +class NonceStorage; class Options; class Url; @@ -60,15 +61,14 @@ public: ~NonceMapper(); bool add(Miner *miner, const LoginRequest &request); + bool isActive() const; void connect(); void gc(); void remove(const Miner *miner); void submit(Miner *miner, const JobResult &request); - inline bool isActive() const { return m_active; } inline bool isSuspended() const { return m_suspended; } - # ifdef APP_DEVEL void printState(); # endif @@ -80,20 +80,15 @@ protected: void onResultAccepted(Client *client, int64_t seq, uint32_t diff, uint64_t ms, const char *error) override; private: - int nextIndex(int start) const; void suspend(); - bool m_active; bool m_suspended; const char *m_agent; const Options *m_options; IStrategy *m_strategy; - Job m_job; + NonceStorage *m_storage; size_t m_id; - std::map m_miners; std::map m_results; - std::vector m_used; - uint8_t m_index; }; diff --git a/src/proxy/splitters/NonceSplitter.cpp b/src/proxy/splitters/NonceSplitter.cpp index e909b24..d8a9a30 100644 --- a/src/proxy/splitters/NonceSplitter.cpp +++ b/src/proxy/splitters/NonceSplitter.cpp @@ -32,7 +32,7 @@ #include "proxy/splitters/NonceSplitter.h" -#define LABEL(x) " \x1B[01;30m" x ":\x1B[0m " +#define LABEL(x) " \x1B[01;30m" x ":\x1B[0m " NonceSplitter::NonceSplitter(const Options *options, const char *agent) : diff --git a/src/proxy/splitters/NonceStorage.cpp b/src/proxy/splitters/NonceStorage.cpp new file mode 100644 index 0000000..0428996 --- /dev/null +++ b/src/proxy/splitters/NonceStorage.cpp @@ -0,0 +1,161 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 . + */ + +#include + + +#include "log/Log.h" +#include "proxy/LoginRequest.h" +#include "proxy/Miner.h" +#include "proxy/splitters/NonceStorage.h" + + +NonceStorage::NonceStorage() : + m_active(false), + m_used(256, 0), + m_index(std::rand() % 256) +{ +} + + +NonceStorage::~NonceStorage() +{ +} + + +bool NonceStorage::add(Miner *miner, const LoginRequest &request) +{ + const int index = nextIndex(request.clientType() == LoginRequest::XMRig20Client ? 1 : 0); + if (index == -1) { + return false; + } + + miner->setFixedByte(index); + + m_index = index; + m_used[index] = miner->id(); + m_miners[miner->id()] = miner; + + if (isActive()) { + miner->setJob(m_job); + } + + return true; +} + + +bool NonceStorage::isUsed() const +{ + for (size_t i = 0; i < 256; ++i) { + if (m_used[i] > 0) { + return true; + } + } + + return false; +} + + +Miner *NonceStorage::miner(int64_t id) +{ + return m_miners[id]; +} + + +void NonceStorage::remove(const Miner *miner) +{ + m_used[miner->fixedByte()] = -miner->id(); + + auto it = m_miners.find(miner->id()); + if (it != m_miners.end()) { + m_miners.erase(it); + } +} + + +void NonceStorage::reset() +{ + std::fill(m_used.begin(), m_used.end(), 0); +} + + +void NonceStorage::setJob(const Job &job) +{ + for (size_t i = 0; i < 256; ++i) { + if (m_used[i] < 0) { + m_used[i] = 0; + } + } + + m_job = job; + + for (size_t i = 0; i < 256; ++i) { + const size_t index = m_used[i]; + Miner *miner = index > 0 ? m_miners[index] : nullptr; + + if (miner) { + miner->setJob(m_job); + } + } +} + + +#ifdef APP_DEVEL +void NonceStorage::printState(size_t id) +{ int available = 0; + int dead = 0; + + for (const int64_t v : m_used) { + if (v == 0) { + available++; + } + else if (v < 0) { + dead++; + } + } + + int miners = 256 - available - dead; + + LOG_INFO("#%03u - \x1B[32m%03d \x1B[33m%03d \x1B[35m%03d\x1B[0m - 0x%02hhX, % 5.1f%%", + id, available, dead, miners, m_index, (double) miners / 256 * 100.0); + +} +#endif + + +int NonceStorage::nextIndex(int start) const +{ + for (size_t i = m_index; i < m_used.size(); ++i) { + if (m_used[i] == 0) { + return i; + } + } + + for (size_t i = start; i < m_index; ++i) { + if (m_used[i] == 0) { + return i; + } + } + + return -1; +} diff --git a/src/proxy/splitters/NonceStorage.h b/src/proxy/splitters/NonceStorage.h new file mode 100644 index 0000000..f9063d9 --- /dev/null +++ b/src/proxy/splitters/NonceStorage.h @@ -0,0 +1,71 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 XMRig + * + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 . + */ + +#ifndef __NONCESTORAGE_H__ +#define __NONCESTORAGE_H__ + + +#include +#include + + +#include "net/Job.h" + + +class LoginRequest; +class Miner; + + +class NonceStorage +{ +public: + NonceStorage(); + ~NonceStorage(); + + bool add(Miner *miner, const LoginRequest &request); + bool isUsed() const; + Miner *miner(int64_t id); + void remove(const Miner *miner); + void reset(); + void setJob(const Job &job); + + inline bool isActive() const { return m_active; } + inline const Job &job() const { return m_job; } + inline void setActive(bool active) { m_active = active; } + +# ifdef APP_DEVEL + void printState(size_t id); +# endif + +private: + int nextIndex(int start) const; + + bool m_active; + Job m_job; + std::map m_miners; + std::vector m_used; + uint8_t m_index; +}; + + +#endif /* __NONCESTORAGE_H__ */ diff --git a/src/version.h b/src/version.h index 0f90df8..918e37d 100644 --- a/src/version.h +++ b/src/version.h @@ -27,13 +27,13 @@ #define APP_ID "xmrig-proxy" #define APP_NAME "xmrig-proxy" #define APP_DESC "Monero (XMR) Stratum proxy" -#define APP_VERSION "2.2.0" +#define APP_VERSION "2.3.0-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2017 xmrig.com" #define APP_VER_MAJOR 2 -#define APP_VER_MINOR 2 +#define APP_VER_MINOR 3 #define APP_VER_BUILD 0 #define APP_VER_REV 0