11// (c) 2018-present Pttn (https://riecoin.xyz/rieMiner)
22
3- #include < fcntl.h>
4- #ifdef _WIN32
5- #include < winsock2.h>
6- #else
7- #include < arpa/inet.h>
8- #include < netdb.h>
9- #endif
103#include < nlohmann/json.hpp>
114
125#include " Client.hpp"
@@ -194,8 +187,11 @@ void StratumClient::_processMessage(const std::string &message) {
194187 logger.log (" ExtraNonce1 = " s + v8ToHexStr (_extraNonce1) + " \n " s);
195188 logger.log (" extraNonce2Len = " s + std::to_string (_extraNonce2Len) + " \n " s);
196189 const std::string miningAuthorizeMessage (" {\" jsonrpc\" : \" 2.0\" , \" id\" : " s + std::to_string (_jsonId++) + " , \" method\" : \" mining.authorize\" , \" params\" : [\" " s + _username + " \" , \" " s + _password + " \" ]}\n " s);
197- send (_socket, miningAuthorizeMessage.c_str (), miningAuthorizeMessage.size (), 0 );
198- // logger.logDebug("Sent to pool: "s + miningAuthorizeMessage);
190+ // logger.logDebug("Sending: "s + miningAuthorizeMessage);
191+ size_t bytesSent (0 );
192+ CURLcode cc (curl_easy_send (_curl, miningAuthorizeMessage.c_str (), miningAuthorizeMessage.size (), &bytesSent));
193+ if (cc != CURLE_OK)
194+ logger.log (" Could not send Authorize Message: Curl Error " s + std::to_string (cc) + " - " s + curl_easy_strerror (cc) + " \n " s, MessageType::ERROR);
199195 }
200196 else if (_state == SUBSCRIBED) {
201197 nlohmann::json jsonResult;
@@ -247,75 +243,50 @@ void StratumClient::connect() {
247243 _lastPoolMessageTp = std::chrono::steady_clock::now ();
248244 _state = UNSUBSCRIBED;
249245 _jsonId = 0U ;
250- #ifdef _WIN32
251- WORD wVersionRequested (MAKEWORD (2 , 2 ));
252- WSADATA wsaData;
253- const int err (WSAStartup (wVersionRequested, &wsaData));
254- if (err != 0 ) {
255- logger.log (" WSAStartup failed with error " s + std::to_string (err) + " \n " s, MessageType::ERROR);
246+ if (!_curl) {
247+ logger.log (" Unknown Curl Error\n " s, MessageType::ERROR);
256248 return ;
257249 }
258- #endif
259- hostent* hostInfo = gethostbyname (_host.c_str ());
260- if (hostInfo == nullptr ) {
261- logger.log (" Unable to resolve '" s + _host + " ', check the URL.\n " s, MessageType::ERROR);
250+ curl_easy_setopt (_curl, CURLOPT_URL, (_host + " :" + std::to_string (_port) + " /" ).c_str ());
251+ curl_easy_setopt (_curl, CURLOPT_CONNECT_ONLY, 1L );
252+ CURLcode cc (curl_easy_perform (_curl));
253+ if (cc != CURLE_OK) {
254+ logger.log (" Could not connect to Server: Curl Error " s + std::to_string (cc) + " - " s + curl_easy_strerror (cc) + " \n " s, MessageType::ERROR);
262255 return ;
263256 }
264- void ** ipListPtr ((void **) hostInfo->h_addr_list );
265- uint32_t ip (0xFFFFFFFF );
266- if (ipListPtr[0 ]) ip = *(uint32_t *) ipListPtr[0 ];
267- std::ostringstream oss;
268- oss << ((ip >> 0 ) & 0xFF ) << " ." << ((ip >> 8 ) & 0xFF ) << " ." << ((ip >> 16 ) & 0xFF ) << " ." << ((ip >> 24 ) & 0xFF );
269- logger.log (" Host: '" s + _host + " -> " + oss.str () + " \n " s);
270- _socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
271- if (_socket == -1 ) {
272- #ifdef _WIN32
273- logger.log (" Could not create endpoint, error " s + std::to_string (WSAGetLastError ()) + " \n " s, MessageType::ERROR);
274- #else
275- logger.log (" Could not create endpoint: " s + std::strerror (errno) + " \n " s, MessageType::ERROR);
276- #endif
257+ cc = curl_easy_getinfo (_curl, CURLINFO_ACTIVESOCKET, &_socket);
258+ if (cc != CURLE_OK) {
259+ logger.log (" Could not get Socket File Descriptor: Curl Error " s + std::to_string (cc) + " - " s + curl_easy_strerror (cc) + " \n " s, MessageType::ERROR);
277260 return ;
278261 }
279- struct sockaddr_in addr;
280- memset (&addr, 0 , sizeof (sockaddr_in));
281- addr.sin_family = AF_INET;
282- addr.sin_port = htons (_port);
283- addr.sin_addr .s_addr = inet_addr (oss.str ().c_str ());
284- int result = ::connect (_socket, (sockaddr*) &addr, sizeof (sockaddr_in));
285- if (result != 0 ) {
286- #ifdef _WIN32
287- logger.log (" Could not connect to the pool, error " s + std::to_string (WSAGetLastError ()) + " \n " s +
288- #else
289- logger.log (" Could not connect to the pool: " s + std::strerror (errno) + " \n " s +
290- #endif
291- " Check the port." s, MessageType::ERROR);
262+ char *ip;
263+ curl_easy_getinfo (_curl, CURLINFO_PRIMARY_IP, &ip);
264+ if (cc != CURLE_OK) {
265+ logger.log (" Could not get Server IP: Curl Error " s + std::to_string (cc) + " - " s + curl_easy_strerror (cc) + " \n " s, MessageType::ERROR);
292266 return ;
293267 }
294- #ifdef _WIN32
295- uint32_t nonBlocking (true ), cbRet;
296- if (WSAIoctl (_socket, FIONBIO, &nonBlocking, sizeof (nonBlocking), nullptr , 0 , (LPDWORD) &cbRet, nullptr , nullptr ) != 0 ) {
297- #else
298- if (fcntl (_socket, F_SETFL, fcntl (_socket, F_GETFL, 0 ) | O_NONBLOCK) == -1 ) {
299- #endif
300- logger.log (" Unable to make the socket non-blocking\n " s, MessageType::ERROR);
301- return ;
268+ logger.log (" Host: " s + _host + " -> " + ip + " \n " s);
269+ if (_state == UNSUBSCRIBED) {
270+ const std::string miningSubscribeMessage (" {\" jsonrpc\" : \" 2.0\" , \" id\" : " s + std::to_string (_jsonId++) + " , \" method\" : \" mining.subscribe\" , \" params\" : [\" " s + userAgent + " \" ]}\n " s);
271+ size_t bytesSent (0 );
272+ cc = curl_easy_send (_curl, miningSubscribeMessage.c_str (), miningSubscribeMessage.size (), &bytesSent);
273+ logger.logDebug (" Sending: " s + miningSubscribeMessage);
274+ if (cc != CURLE_OK) {
275+ logger.log (" Could not send Subscribe Message: Curl Error " s + std::to_string (cc) + " - " s + curl_easy_strerror (cc) + " \n " s, MessageType::ERROR);
276+ return ;
277+ }
302278 }
303- }
304- if (_state == UNSUBSCRIBED) {
305- const std::string miningSubscribeMessage (" {\" jsonrpc\" : \" 2.0\" , \" id\" : " s + std::to_string (_jsonId++) + " , \" method\" : \" mining.subscribe\" , \" params\" : [\" " s + userAgent + " \" ]}\n " s);
306- send (_socket, miningSubscribeMessage.c_str (), miningSubscribeMessage.size (), 0 );
307- logger.logDebug (" Sent to pool: " s + miningSubscribeMessage);
308- }
309- const std::chrono::time_point<std::chrono::steady_clock> timeOutTimer (std::chrono::steady_clock::now ());
310- while (!getJob ().has_value () || _state != AUTHORIZED) {
311- process ();
312- if (Stella::timeSince (timeOutTimer) > 1 .) {
313- logger.log (" Could not get a first job from the pool!\n " s, MessageType::ERROR);
314- std::lock_guard<std::mutex> lock (_jobMutex);
315- _currentJobTemplate.clientInfo = {};
316- return ;
279+ const std::chrono::time_point<std::chrono::steady_clock> timeOutTimer (std::chrono::steady_clock::now ());
280+ while (!getJob ().has_value () || _state != AUTHORIZED) {
281+ process ();
282+ if (Stella::timeSince (timeOutTimer) > 1 .) {
283+ logger.log (" Could not get a first job from the pool!\n " s, MessageType::ERROR);
284+ std::lock_guard<std::mutex> lock (_jobMutex);
285+ _currentJobTemplate.clientInfo = {};
286+ return ;
287+ }
288+ std::this_thread::sleep_for (std::chrono::milliseconds (100 ));
317289 }
318- std::this_thread::sleep_for (std::chrono::milliseconds (100 ));
319290 }
320291 _connected = true ;
321292}
@@ -331,6 +302,7 @@ void StratumClient::process() {
331302 std::lock_guard<std::mutex> lock (_jobMutex);
332303 for (const auto &job : _currentJobs) {
333304 if (job.id == share.jobId ) {
305+ _shares++;
334306 logger.logDebug (Stella::formattedClockTimeNow () + " " s + std::to_string (share.primeCount ) + " -share found by worker thread " s + std::to_string (share.threadId ) + " \n " s);
335307 std::ostringstream oss;
336308 oss << " {\" jsonrpc\" : \" 2.0\" , \" id\" : " << std::to_string (_jsonId++) << " , \" method\" : \" mining.submit\" , \" params\" : [\" "
@@ -339,9 +311,13 @@ void StratumClient::process() {
339311 << v8ToHexStr (job.extraNonce2 ) << " \" , \" "
340312 << std::setfill (' 0' ) << std::setw (16 ) << std::hex << job.bh .curtime << " \" , \" "
341313 << v8ToHexStr (reverse (a8ToV8 (encodedOffset (share)))) << " \" ]}\n " ;
342- send (_socket, oss.str ().c_str (), oss.str ().size (), 0 );
343- logger.logDebug (" Sent to pool: " s + oss.str ());
344- _shares++;
314+ logger.logDebug (" Sending: " s + oss.str ());
315+ size_t bytesSent (0 );
316+ CURLcode cc (curl_easy_send (_curl, oss.str ().c_str (), oss.str ().size (), &bytesSent));
317+ if (cc != CURLE_OK) {
318+ logger.log (" Could not send Share: Curl Error " s + std::to_string (cc) + " - " s + curl_easy_strerror (cc) + " \n " s, MessageType::ERROR);
319+ _rejectedShares++;
320+ }
345321 break ;
346322 } // If not found then Job was obsoleted due to a new Block, do not submit.
347323 }
@@ -353,19 +329,15 @@ void StratumClient::process() {
353329 constexpr std::size_t bufferSize (4096 );
354330 char buffer[bufferSize];
355331 memset (&buffer, 0 , bufferSize);
356- const ssize_t messageLength (recv (_socket, buffer, bufferSize - 1U , 0 ));
357- if (messageLength <= 0 ) { // No data received.
358- if (messageLength == 0 )
359- logger.log (" Connection closed by the pool.\n " s, MessageType::WARNING);
360- else if (Stella::timeSince (_lastPoolMessageTp) > stratumTimeOut)
332+ size_t bytesReceived (0 );
333+ CURLcode cc (curl_easy_recv (_curl, buffer, bufferSize - 1U , &bytesReceived));
334+ if (bytesReceived == 0 ) { // No data received.
335+ if (Stella::timeSince (_lastPoolMessageTp) > stratumTimeOut)
361336 logger.log (" Received nothing from the pool since a long time, disconnection assumed.\n " s, MessageType::WARNING);
362- #ifdef _WIN32
363- else if (WSAGetLastError () != WSAEWOULDBLOCK)
364- logger.log (" Error receiving work data from pool, error " s + std::to_string (WSAGetLastError ()) + " \n " s, MessageType::ERROR);
365- #else
366- else if (errno != EWOULDBLOCK)
337+ else if (cc == CURLE_OK)
338+ logger.log (" Connection closed by the pool.\n " s, MessageType::WARNING);
339+ else if (cc != CURLE_AGAIN)
367340 logger.log (" Error receiving work data from pool: " s + std::strerror (errno) + " \n " s, MessageType::ERROR);
368- #endif
369341 else // Nothing went wrong, it is expected to get nothing most of the times due to the non blocking socket.
370342 return ;
371343 _socket = -1 ;
0 commit comments