diff --git a/src/Server.cc b/src/Server.cc index ad7b8f6..751cde2 100644 --- a/src/Server.cc +++ b/src/Server.cc @@ -189,7 +189,8 @@ void SessionIDManager::freeSessionId(const uint16_t sessionId) { ///////////////////////////////// StratumMessage ////////////////////////////// StratumMessage::StratumMessage(const string &content): -content_(content), isStringId_(false), r_(0), diff_(0) { +content_(content), isStringId_(false), r_(0), diff_(0), +versionMask_(0), hasVersionMask_(false) { parse(); } StratumMessage::~StratumMessage() { @@ -240,7 +241,7 @@ void StratumMessage::_parseMiningSubmit() { // [Worker Name, Job ID, ExtraNonce2(hex), nTime(hex), nonce(hex)] // if (jsoneq(&t_[i], "params") == 0 && t_[i+1].type == JSMN_ARRAY && t_[i+1].size >= 5) { - bool hasVersionMask = t_[i+1].size >= 6; + hasVersionMask_ = t_[i+1].size >= 6; i++; // ptr move to params i++; // ptr move to params[0] @@ -254,7 +255,7 @@ void StratumMessage::_parseMiningSubmit() { // nonce(hex) share_.nonce_ = (uint32_t)strtoul(getJsonStr(&t_[i+4]).c_str(), NULL, 16); - if (hasVersionMask) { + if (hasVersionMask_) { // versionMask(hex) share_.versionMask_ = (uint32_t)strtoul(getJsonStr(&t_[i+5]).c_str(), NULL, 16); } @@ -905,7 +906,8 @@ StratumSession::StratumSession(const int8_t upSessionIdx, struct bufferevent *bev, StratumServer *server, struct in_addr saddr) : state_(DOWN_CONNECTED), minerAgent_(NULL), upSessionIdx_(upSessionIdx), -sessionId_(sessionId), bev_(bev), server_(server), saddr_(saddr) +sessionId_(sessionId), bev_(bev), server_(server), saddr_(saddr), +versionRollingShareCounter_(0) { inBuf_ = evbuffer_new(); assert(inBuf_ != NULL); @@ -1061,13 +1063,13 @@ void StratumSession::handleRequest_Authorize(const string &idStr, // eg. {"params": ["slush.miner1", "password"], "id": 2, "method": "mining.authorize"} // - string workerName, fullWorkerName; - if (!smsg.parseMiningAuthorize(fullWorkerName)) { + string workerName; + if (!smsg.parseMiningAuthorize(fullWorkerName_)) { responseError(idStr, StratumError::INVALID_USERNAME); return; } - workerName = getWorkerName(fullWorkerName); // split by '.' + workerName = getWorkerName(fullWorkerName_); // split by '.' if (workerName.empty()) workerName = DEFAULT_WORKER_NAME; @@ -1147,6 +1149,27 @@ void StratumSession::handleRequest_Submit(const string &idStr, server_->submitShare(share, this); responseTrue(idStr); // we assume shares are valid + + if (smsg.hasVersionMask()) { + versionRollingShareCounter_++; + } + else if (versionRollingShareCounter_ > 100) { + // Version rolling disabled mid-way, it may be a firmware issue. + // Reconnect to avoid loss of hashrate. + const string s = "{\"id\":null,\"method\":\"client.reconnect\",\"params\":[]}\n"; + sendData(s); + + // get source IP address + char saddrBuffer[INET_ADDRSTRLEN]; + evutil_inet_ntop(AF_INET, &saddr_, saddrBuffer, INET_ADDRSTRLEN); + + LOG(INFO) << "version rolling disabled mid-way, send client.reconnect. " + << "worker: " << fullWorkerName_ + << ", ip: " << saddrBuffer + << ", version rolling shares: " << versionRollingShareCounter_ + << std::endl; + } + } diff --git a/src/Server.h b/src/Server.h index b19fc40..679b47b 100644 --- a/src/Server.h +++ b/src/Server.h @@ -173,6 +173,7 @@ class StratumMessage { string password_; uint32_t diff_; // mining.set_difficulty uint32_t versionMask_; // mining.set_version_mask + bool hasVersionMask_; set serverCapabilities_; // agent.get_capabilities @@ -201,6 +202,7 @@ class StratumMessage { bool getResultBoolean() const; string getId() const; bool isStringId() const; + bool hasVersionMask() const { return hasVersionMask_; } bool parseMiningSubmit(Share &share) const; bool parseMiningSubscribe(string &minerAgent) const; @@ -401,6 +403,8 @@ class StratumSession { struct bufferevent *bev_; StratumServer *server_; struct in_addr saddr_; + size_t versionRollingShareCounter_; // Used to detect and prevent potential problems with version rolling + string fullWorkerName_; public: