Verify & send algorithm name.

This commit is contained in:
XMRig 2018-04-26 23:27:53 +07:00
parent 2ddac1ce68
commit 85f9bd97f1
6 changed files with 109 additions and 44 deletions

View file

@ -54,6 +54,7 @@ Client::Client(int id, const char *agent, IClientListener *listener) :
m_quiet(false),
m_agent(agent),
m_listener(listener),
m_extensions(0),
m_id(id),
m_retries(5),
m_retryPause(5000),
@ -161,12 +162,14 @@ bool Client::disconnect()
int64_t Client::submit(const JobResult &result)
{
using namespace rapidjson;
# ifdef XMRIG_PROXY_PROJECT
const char *nonce = result.nonce;
const char *data = result.result;
# else
char nonce[9];
char data[65];
char *nonce = m_sendBuf;
char *data = m_sendBuf + 16;
Job::toHex(reinterpret_cast<const unsigned char*>(&result.nonce), 4, nonce);
nonce[8] = '\0';
@ -175,8 +178,24 @@ int64_t Client::submit(const JobResult &result)
data[64] = '\0';
# endif
const size_t size = snprintf(m_sendBuf, sizeof(m_sendBuf), "{\"id\":%" PRIu64 ",\"jsonrpc\":\"2.0\",\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"}}\n",
m_sequence, m_rpcId.data(), result.jobId.data(), nonce, data);
Document doc(kObjectType);
auto &allocator = doc.GetAllocator();
doc.AddMember("id", m_sequence, allocator);
doc.AddMember("jsonrpc", "2.0", allocator);
doc.AddMember("method", "submit", allocator);
Value params(kObjectType);
params.AddMember("id", StringRef(m_rpcId.data()), allocator);
params.AddMember("job_id", StringRef(result.jobId.data()), allocator);
params.AddMember("nonce", StringRef(nonce), allocator);
params.AddMember("result", StringRef(data), allocator);
if (m_extensions & AlgoExt) {
params.AddMember("algo", StringRef(result.algorithm.shortName()), allocator);
}
doc.AddMember("params", params, allocator);
# ifdef XMRIG_PROXY_PROJECT
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff(), result.id);
@ -184,7 +203,7 @@ int64_t Client::submit(const JobResult &result)
m_results[m_sequence] = SubmitResult(m_sequence, result.diff, result.actualDiff());
# endif
return send(size);
return send(doc);
}
@ -258,6 +277,13 @@ bool Client::parseJob(const rapidjson::Value &params, int *code)
job.algorithm().parseVariant(params["variant"].GetInt());
}
if (!verifyAlgorithm(job.algorithm())) {
*code = 6;
close();
return false;
}
if (m_job != job) {
m_jobs++;
m_job = std::move(job);
@ -284,9 +310,7 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code)
return false;
}
# ifndef XMRIG_PROXY_PROJECT
m_nicehash = m_pool.isNicehash();
# endif
if (result.HasMember("extensions")) {
parseExtensions(result["extensions"]);
@ -299,6 +323,27 @@ bool Client::parseLogin(const rapidjson::Value &result, int *code)
}
bool Client::verifyAlgorithm(const xmrig::Algorithm &algorithm) const
{
if (m_pool.isCompatible(algorithm)) {
return true;
}
if (isQuiet()) {
return false;
}
if (algorithm.isValid()) {
LOG_ERR("Incompatible algorithm \"%s\" detected, reconnect", algorithm.name());
}
else {
LOG_ERR("Unknown/unsupported algorithm detected, reconnect");
}
return false;
}
int Client::resolve(const char *host)
{
setState(HostLookupState);
@ -322,6 +367,27 @@ int Client::resolve(const char *host)
}
int64_t Client::send(const rapidjson::Document &doc)
{
using namespace rapidjson;
StringBuffer buffer(0, 512);
Writer<StringBuffer> writer(buffer);
doc.Accept(writer);
const size_t size = buffer.GetSize();
if (size > (sizeof(m_buf) - 2)) {
return -1;
}
memcpy(m_sendBuf, buffer.GetString(), size);
m_sendBuf[size] = '\n';
m_sendBuf[size + 1] = '\0';
return send(size + 1);
}
int64_t Client::send(size_t size)
{
LOG_DEBUG("[%s] send (%d bytes): \"%s\"", m_pool.url(), size, m_sendBuf);
@ -389,9 +455,7 @@ void Client::login()
using namespace rapidjson;
m_results.clear();
Document doc;
doc.SetObject();
Document doc(kObjectType);
auto &allocator = doc.GetAllocator();
doc.AddMember("id", 1, allocator);
@ -416,20 +480,7 @@ void Client::login()
params.AddMember("algo", algo, allocator);
doc.AddMember("params", params, allocator);
StringBuffer buffer(0, 512);
Writer<StringBuffer> writer(buffer);
doc.Accept(writer);
const size_t size = buffer.GetSize();
if (size > (sizeof(m_buf) - 2)) {
return;
}
memcpy(m_sendBuf, buffer.GetString(), size);
m_sendBuf[size] = '\n';
m_sendBuf[size + 1] = '\0';
send(size + 1);
send(doc);
}
@ -486,6 +537,8 @@ void Client::parse(char *line, size_t len)
void Client::parseExtensions(const rapidjson::Value &value)
{
m_extensions = 0;
if (!value.IsArray()) {
return;
}
@ -495,8 +548,15 @@ void Client::parseExtensions(const rapidjson::Value &value)
continue;
}
if (strcmp(ext.GetString(), "algo") == 0) {
m_extensions |= AlgoExt;
continue;
}
if (strcmp(ext.GetString(), "nicehash") == 0) {
m_extensions |= NicehashExt;
m_nicehash = true;
continue;
}
}
}

View file

@ -78,11 +78,18 @@ public:
inline void setRetryPause(int ms) { m_retryPause = ms; }
private:
enum Extensions {
NicehashExt = 1,
AlgoExt = 2
};
bool close();
bool isCriticalError(const char *message);
bool parseJob(const rapidjson::Value &params, int *code);
bool parseLogin(const rapidjson::Value &result, int *code);
bool verifyAlgorithm(const xmrig::Algorithm &algorithm) const;
int resolve(const char *host);
int64_t send(const rapidjson::Document &doc);
int64_t send(size_t size);
void connect(const std::vector<addrinfo*> &ipv4, const std::vector<addrinfo*> &ipv6);
void connect(sockaddr *addr);
@ -116,6 +123,7 @@ private:
char m_sendBuf[768];
const char *m_agent;
IClientListener *m_listener;
int m_extensions;
int m_id;
int m_retries;
int m_retryPause;

View file

@ -92,6 +92,18 @@ Pool::Pool(const char *host, uint16_t port, const char *user, const char *passwo
}
bool Pool::isCompatible(const xmrig::Algorithm &algorithm) const
{
for (const auto &a : m_algorithms) {
if (algorithm == a) {
return true;
}
}
return false;
}
bool Pool::isEqual(const Pool &other) const
{
return (m_nicehash == other.m_nicehash

View file

@ -72,6 +72,7 @@ public:
inline bool operator!=(const Pool &other) const { return !isEqual(other); }
inline bool operator==(const Pool &other) const { return isEqual(other); }
bool isCompatible(const xmrig::Algorithm &algorithm) const;
bool isEqual(const Pool &other) const;
bool parse(const char *url);
bool setUserpass(const char *userpass);

View file

@ -36,34 +36,17 @@ class JobResult
{
public:
inline JobResult() : poolId(0), diff(0), nonce(0) {}
inline JobResult(int poolId, const xmrig::Id &jobId, uint32_t nonce, const uint8_t *result, uint32_t diff) :
inline JobResult(int poolId, const xmrig::Id &jobId, uint32_t nonce, const uint8_t *result, uint32_t diff, const xmrig::Algorithm &algorithm) :
poolId(poolId),
diff(diff),
nonce(nonce),
algorithm(algorithm),
jobId(jobId)
{
memcpy(this->result, result, sizeof(this->result));
}
inline JobResult(const Job &job) : poolId(0), diff(0), nonce(0)
{
jobId = job.id();
poolId = job.poolId();
diff = job.diff();
nonce = *job.nonce();
}
inline JobResult &operator=(const Job &job) {
jobId = job.id();
poolId = job.poolId();
diff = job.diff();
return *this;
}
inline uint64_t actualDiff() const
{
return Job::toDiff(reinterpret_cast<const uint64_t*>(result)[3]);
@ -74,6 +57,7 @@ public:
uint32_t diff;
uint32_t nonce;
uint8_t result[32];
xmrig::Algorithm algorithm;
xmrig::Id jobId;
};

View file

@ -108,7 +108,7 @@ void MultiWorker<N>::start()
for (size_t i = 0; i < N; ++i) {
if (*reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24) < m_state.job.target()) {
Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash + (i * 32), m_state.job.diff()));
Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), *nonce(i), m_hash + (i * 32), m_state.job.diff(), m_state.job.algorithm()));
}
*nonce(i) += 1;