summaryrefslogtreecommitdiffstats
path: root/xmrstak/net
diff options
context:
space:
mode:
Diffstat (limited to 'xmrstak/net')
-rw-r--r--xmrstak/net/jpsock.cpp120
-rw-r--r--xmrstak/net/jpsock.hpp15
-rw-r--r--xmrstak/net/msgstruct.hpp8
-rw-r--r--xmrstak/net/socket.cpp2
4 files changed, 95 insertions, 50 deletions
diff --git a/xmrstak/net/jpsock.cpp b/xmrstak/net/jpsock.cpp
index 74d1c26..6c41f2b 100644
--- a/xmrstak/net/jpsock.cpp
+++ b/xmrstak/net/jpsock.cpp
@@ -43,8 +43,9 @@ struct jpsock::call_rsp
uint64_t iCallId;
Value* pCallData;
std::string sCallErr;
+ uint64_t iMessageId;
- call_rsp(Value* val) : pCallData(val)
+ call_rsp(Value* val) : pCallData(val), iMessageId(0)
{
bHaveResponse = false;
iCallId = 0;
@@ -215,6 +216,7 @@ void jpsock::jpsock_thread()
prv->oCallRsp.bHaveResponse = true;
prv->oCallRsp.iCallId = 0;
prv->oCallRsp.pCallData = nullptr;
+ prv->oCallRsp.iMessageId = 0;
bCallWaiting = true;
}
mlock.unlock();
@@ -286,6 +288,7 @@ bool jpsock::process_line(char* line, size_t len)
prv->jsonDoc.SetNull();
prv->parseAllocator.Clear();
prv->callAllocator.Clear();
+ ++iMessageCnt;
/*NULL terminate the line instead of '\n', parsing will add some more NULLs*/
line[len-1] = '\0';
@@ -320,7 +323,7 @@ bool jpsock::process_line(char* line, size_t len)
return set_socket_error("PARSE error: Protocol error 2");
opq_json_val v(mt);
- return process_pool_job(&v);
+ return process_pool_job(&v, iMessageCnt);
}
else
{
@@ -334,7 +337,7 @@ bool jpsock::process_line(char* line, size_t len)
mt = GetObjectMember(prv->jsonDoc, "error");
const char* sError = nullptr;
- size_t iErrorLn = 0;
+ size_t iErrorLen = 0;
if (mt == nullptr || mt->IsNull())
{
/* If there was no error we need a result */
@@ -351,7 +354,7 @@ bool jpsock::process_line(char* line, size_t len)
if(msg == nullptr || !msg->IsString())
return set_socket_error("PARSE error: Protocol error 6");
- iErrorLn = msg->GetStringLength();
+ iErrorLen = msg->GetStringLength();
sError = msg->GetString();
}
@@ -365,11 +368,12 @@ bool jpsock::process_line(char* line, size_t len)
prv->oCallRsp.bHaveResponse = true;
prv->oCallRsp.iCallId = iCallId;
+ prv->oCallRsp.iMessageId = iMessageCnt;
if(sError != nullptr)
{
prv->oCallRsp.pCallData = nullptr;
- prv->oCallRsp.sCallErr.assign(sError, iErrorLn);
+ prv->oCallRsp.sCallErr.assign(sError, iErrorLen);
call_error = true;
}
else
@@ -382,8 +386,20 @@ bool jpsock::process_line(char* line, size_t len)
}
}
-bool jpsock::process_pool_job(const opq_json_val* params)
+bool jpsock::process_pool_job(const opq_json_val* params, const uint64_t messageId)
{
+ std::unique_lock<std::mutex> mlock(job_mutex);
+ if(messageId < iLastMessageId)
+ {
+ /* In the case where the processed job message id is lesser than the last
+ * processed job message id we skip the processing to avoid mining old jobs
+ */
+ return true;
+ }
+ iLastMessageId = messageId;
+
+ mlock.unlock();
+
if (!params->val->IsObject())
return set_socket_error("PARSE error: Job error 1");
@@ -399,18 +415,45 @@ bool jpsock::process_pool_job(const opq_json_val* params)
return set_socket_error("PARSE error: Job error 2");
}
+ if(motd != nullptr && motd->IsString() && (motd->GetStringLength() & 0x01) == 0)
+ {
+ std::unique_lock<std::mutex> lck(motd_mutex);
+ if(motd->GetStringLength() > 0)
+ {
+ pool_motd.resize(motd->GetStringLength()/2 + 1);
+ if(!hex2bin(motd->GetString(), motd->GetStringLength(), (unsigned char*)&pool_motd.front()))
+ pool_motd.clear();
+ }
+ else
+ pool_motd.clear();
+ }
+
if (jobid->GetStringLength() >= sizeof(pool_job::sJobID)) // Note >=
return set_socket_error("PARSE error: Job error 3");
- uint32_t iWorkLn = blob->GetStringLength() / 2;
- if (iWorkLn > sizeof(pool_job::bWorkBlob))
- return set_socket_error("PARSE error: Invalid job legth. Are you sure you are mining the correct coin?");
-
pool_job oPoolJob;
- if (!hex2bin(blob->GetString(), iWorkLn * 2, oPoolJob.bWorkBlob))
+
+ const uint32_t iWorkLen = blob->GetStringLength() / 2;
+ oPoolJob.iWorkLen = iWorkLen;
+
+ if (iWorkLen > sizeof(pool_job::bWorkBlob))
+ return set_socket_error("PARSE error: Invalid job length. Are you sure you are mining the correct coin?");
+
+ if (!hex2bin(blob->GetString(), iWorkLen * 2, oPoolJob.bWorkBlob))
return set_socket_error("PARSE error: Job error 4");
- oPoolJob.iWorkLen = iWorkLn;
+ // lock reading of oCurrentJob
+ std::unique_lock<std::mutex> jobIdLock(job_mutex);
+ // compare possible non equal length job id's
+ if(iWorkLen == oCurrentJob.iWorkLen &&
+ memcmp(oPoolJob.bWorkBlob, oCurrentJob.bWorkBlob, iWorkLen) == 0 &&
+ strcmp(jobid->GetString(), oCurrentJob.sJobID) == 0
+ )
+ {
+ return set_socket_error("Duplicate equal job detected! Please contact your pool admin.");
+ }
+ jobIdLock.unlock();
+
memset(oPoolJob.sJobID, 0, sizeof(pool_job::sJobID));
memcpy(oPoolJob.sJobID, jobid->GetString(), jobid->GetStringLength()); //Bounds checking at proto error 3
@@ -423,7 +466,7 @@ bool jpsock::process_pool_job(const opq_json_val* params)
if(!hex2bin(sTempStr, 8, (unsigned char*)&iTempInt) || iTempInt == 0)
return set_socket_error("PARSE error: Invalid target");
-
+
oPoolJob.iTarget = t32_to_t64(iTempInt);
}
else if(target_slen <= 16)
@@ -437,25 +480,14 @@ bool jpsock::process_pool_job(const opq_json_val* params)
else
return set_socket_error("PARSE error: Job error 5");
- if(motd != nullptr && motd->IsString() && (motd->GetStringLength() & 0x01) == 0)
- {
- std::unique_lock<std::mutex> lck(motd_mutex);
- if(motd->GetStringLength() > 0)
- {
- pool_motd.resize(motd->GetStringLength()/2 + 1);
- if(!hex2bin(motd->GetString(), motd->GetStringLength(), (unsigned char*)&pool_motd.front()))
- pool_motd.clear();
- }
- else
- pool_motd.clear();
- }
-
iJobDiff = t64_to_diff(oPoolJob.iTarget);
- executor::inst()->push_event(ex_event(oPoolJob, pool_id));
-
std::unique_lock<std::mutex> lck(job_mutex);
oCurrentJob = oPoolJob;
+ lck.unlock();
+ // send event after current job data are updated
+ executor::inst()->push_event(ex_event(oPoolJob, pool_id));
+
return true;
}
@@ -498,7 +530,7 @@ void jpsock::disconnect(bool quiet)
quiet_close = false;
}
-bool jpsock::cmd_ret_wait(const char* sPacket, opq_json_val& poResult)
+bool jpsock::cmd_ret_wait(const char* sPacket, opq_json_val& poResult, uint64_t& messageId)
{
//printf("SEND: %s\n", sPacket);
@@ -538,8 +570,10 @@ bool jpsock::cmd_ret_wait(const char* sPacket, opq_json_val& poResult)
}
if(bSuccess)
+ {
poResult.val = &prv->oCallValue;
-
+ messageId = prv->oCallRsp.iMessageId;
+ }
return bSuccess;
}
@@ -551,9 +585,10 @@ bool jpsock::cmd_login()
usr_login.c_str(), usr_pass.c_str(), usr_rigid.c_str(), get_version_str().c_str());
opq_json_val oResult(nullptr);
+ uint64_t messageId = 0;
/*Normal error conditions (failed login etc..) will end here*/
- if (!cmd_ret_wait(cmd_buffer, oResult))
+ if (!cmd_ret_wait(cmd_buffer, oResult, messageId))
return false;
if (!oResult.val->IsObject())
@@ -589,7 +624,7 @@ bool jpsock::cmd_login()
for(size_t i=0; i < ext->Size(); i++)
{
const Value& jextname = ext->GetArray()[i];
-
+
if(!jextname.IsString())
continue;
@@ -608,7 +643,7 @@ bool jpsock::cmd_login()
}
opq_json_val v(job);
- if(!process_pool_job(&v))
+ if(!process_pool_job(&v, messageId))
{
disconnect();
return false;
@@ -645,16 +680,22 @@ bool jpsock::cmd_submit(const char* sJobId, uint32_t iNonce, const uint8_t* bRes
algo_name = "cryptonight";
break;
case cryptonight_lite:
- algo_name = "cryptonight-lite";
+ algo_name = "cryptonight_lite";
break;
case cryptonight_monero:
- algo_name = "cryptonight-monerov7";
+ algo_name = "cryptonight_v7";
break;
case cryptonight_aeon:
- algo_name = "cryptonight-aeonv7";
+ algo_name = "cryptonight_lite_v7";
+ break;
+ case cryptonight_stellite:
+ algo_name = "cryptonight_v7_stellite";
+ break;
+ case cryptonight_ipbc:
+ algo_name = "cryptonight_lite_v7_xor";
break;
case cryptonight_heavy:
- algo_name = "cryptonight-heavy";
+ algo_name = "cryptonight_heavy";
break;
default:
algo_name = "unknown";
@@ -673,8 +714,9 @@ bool jpsock::cmd_submit(const char* sJobId, uint32_t iNonce, const uint8_t* bRes
snprintf(cmd_buffer, sizeof(cmd_buffer), "{\"method\":\"submit\",\"params\":{\"id\":\"%s\",\"job_id\":\"%s\",\"nonce\":\"%s\",\"result\":\"%s\"%s%s%s},\"id\":1}\n",
sMinerId, sJobId, sNonce, sResult, sBackend, sHashcount, sAlgo);
+ uint64_t messageId = 0;
opq_json_val oResult(nullptr);
- return cmd_ret_wait(cmd_buffer, oResult);
+ return cmd_ret_wait(cmd_buffer, oResult, messageId);
}
void jpsock::save_nonce(uint32_t nonce)
@@ -696,7 +738,7 @@ bool jpsock::get_current_job(pool_job& job)
bool jpsock::get_pool_motd(std::string& strin)
{
- if(!ext_motd)
+ if(!ext_motd)
return false;
std::unique_lock<std::mutex> lck(motd_mutex);
diff --git a/xmrstak/net/jpsock.hpp b/xmrstak/net/jpsock.hpp
index 2ddeeee..ad34f6c 100644
--- a/xmrstak/net/jpsock.hpp
+++ b/xmrstak/net/jpsock.hpp
@@ -15,7 +15,7 @@
- Parsing or connection error
Those are fatal errors (we drop the connection if we encounter them).
After they are constructed from const char* strings from various places.
- (can be from read-only mem), we passs them in an exectutor message
+ (can be from read-only mem), we pass them in an executor message
once the recv thread expires.
- Call error
This error happens when the "server says no". Usually because the job was
@@ -40,9 +40,9 @@ public:
static bool hex2bin(const char* in, unsigned int len, unsigned char* out);
static void bin2hex(const unsigned char* in, unsigned int len, char* out);
- inline double get_pool_weight(bool gross_weight)
- {
- double ret = pool_weight;
+ inline double get_pool_weight(bool gross_weight)
+ {
+ double ret = pool_weight;
if(gross_weight && bRunning)
ret += 10.0;
if(gross_weight && bLoggedIn)
@@ -124,8 +124,8 @@ private:
void jpsock_thread();
bool jpsock_thd_main();
bool process_line(char* line, size_t len);
- bool process_pool_job(const opq_json_val* params);
- bool cmd_ret_wait(const char* sPacket, opq_json_val& poResult);
+ bool process_pool_job(const opq_json_val* params, const uint64_t messageId);
+ bool cmd_ret_wait(const char* sPacket, opq_json_val& poResult, uint64_t& messageId);
char sMinerId[64];
std::atomic<uint64_t> iJobDiff;
@@ -142,5 +142,8 @@ private:
opaque_private* prv;
base_socket* sck;
+
+ uint64_t iMessageCnt = 0;
+ uint64_t iLastMessageId = 0;
};
diff --git a/xmrstak/net/msgstruct.hpp b/xmrstak/net/msgstruct.hpp
index e401f59..20092fe 100644
--- a/xmrstak/net/msgstruct.hpp
+++ b/xmrstak/net/msgstruct.hpp
@@ -5,7 +5,7 @@
#include <assert.h>
// Structures that we use to pass info between threads constructors are here just to make
-// the stack allocation take up less space, heap is a shared resouce that needs locks too of course
+// the stack allocation take up less space, heap is a shared resource that needs locks too of course
struct pool_job
{
@@ -72,15 +72,15 @@ struct gpu_res_err
};
enum ex_event_name { EV_INVALID_VAL, EV_SOCK_READY, EV_SOCK_ERROR, EV_GPU_RES_ERROR,
- EV_POOL_HAVE_JOB, EV_MINER_HAVE_RESULT, EV_PERF_TICK, EV_EVAL_POOL_CHOICE,
- EV_USR_HASHRATE, EV_USR_RESULTS, EV_USR_CONNSTAT, EV_HASHRATE_LOOP,
+ EV_POOL_HAVE_JOB, EV_MINER_HAVE_RESULT, EV_PERF_TICK, EV_EVAL_POOL_CHOICE,
+ EV_USR_HASHRATE, EV_USR_RESULTS, EV_USR_CONNSTAT, EV_HASHRATE_LOOP,
EV_HTML_HASHRATE, EV_HTML_RESULTS, EV_HTML_CONNSTAT, EV_HTML_JSON };
/*
This is how I learned to stop worrying and love c++11 =).
Ghosts of endless heap allocations have finally been exorcised. Thanks
to the nifty magic of move semantics, string will only be allocated
- once on the heap. Considering that it makes a jorney across stack,
+ once on the heap. Considering that it makes a journey across stack,
heap alloced queue, to another stack before being finally processed
I think it is kind of nifty, don't you?
Also note that for non-arg events we only copy two qwords
diff --git a/xmrstak/net/socket.cpp b/xmrstak/net/socket.cpp
index 9bc608f..6fcb454 100644
--- a/xmrstak/net/socket.cpp
+++ b/xmrstak/net/socket.cpp
@@ -339,7 +339,7 @@ bool tls_socket::connect()
{
if(!pCallback->is_dev_pool())
{
- printer::inst()->print_msg(L0, "FINGERPRINT FAILED CHECK [%s] %.*s was given, %s was configured",
+ printer::inst()->print_msg(L0, "FINGERPRINT FAILED CHECK [%s] %.*s was given, %s was configured",
pCallback->get_pool_addr(), (int)b64_len, b64_md, conf_md);
}
OpenPOWER on IntegriCloud