From 52e99b4d77429267a01bb416fd9ad79fc5cac4aa Mon Sep 17 00:00:00 2001 From: Tanguy Pruvot Date: Sat, 20 Feb 2016 14:29:38 +0100 Subject: [PATCH] rpc/curl: retry getwork if no data was received seems to happen with a high number of workers... (overflow) --- stratum/client_submit.cpp | 2 +- stratum/coind.h | 2 +- stratum/coind_template.cpp | 34 ++++++++++++++++++++++++---------- stratum/rpc.h | 1 + stratum/rpc_curl.cpp | 30 ++++++++++++++++-------------- 5 files changed, 43 insertions(+), 26 deletions(-) diff --git a/stratum/client_submit.cpp b/stratum/client_submit.cpp index c44c5d1..d4d3846 100644 --- a/stratum/client_submit.cpp +++ b/stratum/client_submit.cpp @@ -2,7 +2,7 @@ #include "stratum.h" //#define MERKLE_DEBUGLOG -#define HASH_DEBUGLOG_ +//#define HASH_DEBUGLOG_ //#define DONTSUBMIT void build_submit_values(YAAMP_JOB_VALUES *submitvalues, YAAMP_JOB_TEMPLATE *templ, diff --git a/stratum/coind.h b/stratum/coind.h index d05b9c2..e1df7c8 100644 --- a/stratum/coind.h +++ b/stratum/coind.h @@ -96,7 +96,7 @@ void coind_init(YAAMP_COIND *coind); void coind_terminate(YAAMP_COIND *coind); //void coind_getauxblock(YAAMP_COIND *coind); -void coind_create_job(YAAMP_COIND *coind, bool force=false); +bool coind_create_job(YAAMP_COIND *coind, bool force=false); bool coind_validate_user_address(YAAMP_COIND *coind, char* const address); diff --git a/stratum/coind_template.cpp b/stratum/coind_template.cpp index cb64ef1..46b9859 100644 --- a/stratum/coind_template.cpp +++ b/stratum/coind_template.cpp @@ -143,16 +143,25 @@ static int decred_parse_header(YAAMP_JOB_TEMPLATE *templ, const char *header_hex // decred getwork over stratum static YAAMP_JOB_TEMPLATE *decred_create_worktemplate(YAAMP_COIND *coind) { - int retry_max = 3; + char rpc_error[1024] = { 0 }; + #define GETWORK_RETRY_MAX 3 + int retry_cnt = GETWORK_RETRY_MAX; retry: json_value *gw = rpc_call(&coind->rpc, "getwork", "[]"); if(!gw || json_is_null(gw)) { - coind_error(coind, "getwork"); + usleep(500*YAAMP_MS); // too much connections ? no data received + if (--retry_cnt > 0) { + if (coind->rpc.curl) + rpc_curl_get_lasterr(rpc_error, 1023); + debuglog("%s getwork retry %d\n", coind->symbol, GETWORK_RETRY_MAX-retry_cnt); + goto retry; + } + debuglog("%s error getwork %s\n", coind->symbol, rpc_error); return NULL; } json_value *gwr = json_get_object(gw, "result"); if(!gwr) { - coind_error(coind, "getwork json result"); + debuglog("%s no getwork json result!\n", coind->symbol); return NULL; } else if (json_is_null(gwr)) { @@ -161,14 +170,17 @@ retry: const char *err = json_get_string(jr, "message"); if (err && !strcmp(err, "internal error")) { usleep(500*YAAMP_MS); // not enough voters (testnet) - if (--retry_max > 0) goto retry; - debuglog("%s getwork %s\n", coind->symbol, err); + if (--retry_cnt > 0) { + goto retry; + } + debuglog("%s getwork failed after %d tries: %s\n", + coind->symbol, GETWORK_RETRY_MAX, err); } return NULL; } const char *header_hex = json_get_string(gwr, "data"); if (!header_hex || !strlen(header_hex)) { - coind_error(coind, "getwork data"); + debuglog("%s no getwork data!\n", coind->symbol); return NULL; } @@ -358,12 +370,12 @@ YAAMP_JOB_TEMPLATE *coind_create_template(YAAMP_COIND *coind) //////////////////////////////////////////////////////////////////////////////////////////////////////////// -void coind_create_job(YAAMP_COIND *coind, bool force) +bool coind_create_job(YAAMP_COIND *coind, bool force) { // debuglog("create job %s\n", coind->symbol); bool b = rpc_connected(&coind->rpc); - if(!b) return; + if(!b) return false; CommonLock(&coind->mutex); @@ -380,7 +392,7 @@ void coind_create_job(YAAMP_COIND *coind, bool force) { CommonUnlock(&coind->mutex); // debuglog("%s: create job template failed!\n", coind->symbol); - return; + return false; } YAAMP_JOB *job_last = coind->job; @@ -398,7 +410,7 @@ void coind_create_job(YAAMP_COIND *coind, bool force) delete templ; CommonUnlock(&coind->mutex); - return; + return true; } //////////////////////////////////////////////////////////////////////////////////////// @@ -449,6 +461,8 @@ void coind_create_job(YAAMP_COIND *coind, bool force) CommonUnlock(&coind->mutex); // debuglog("coind_create_job %s %d new job %x\n", coind->name, coind->height, coind->job->id); + + return true; } diff --git a/stratum/rpc.h b/stratum/rpc.h index 7f711eb..d8327f9 100644 --- a/stratum/rpc.h +++ b/stratum/rpc.h @@ -36,4 +36,5 @@ int rpc_flush(YAAMP_RPC *rpc); json_value *rpc_call(YAAMP_RPC *rpc, char const *method, char const *params=NULL); json_value *rpc_curl_call(YAAMP_RPC *rpc, char const *method, char const *params); +void rpc_curl_get_lasterr(char* buffer, int buflen); void rpc_curl_close(YAAMP_RPC *rpc); diff --git a/stratum/rpc_curl.cpp b/stratum/rpc_curl.cpp index 5b7b746..378dc42 100644 --- a/stratum/rpc_curl.cpp +++ b/stratum/rpc_curl.cpp @@ -20,6 +20,9 @@ bool opt_protocol = false; bool opt_proxy = false; long opt_proxy_type = 0; //CURLPROXY_SOCKS5; +static __thread char curl_last_err[1024] = { 0 }; +const int last_err_len = 1023; + #define USER_AGENT "stratum/yiimp" #define JSON_INDENT(x) 0 #define json_object_get(j,k) json_get_object(j,k) @@ -281,13 +284,13 @@ static json_value *curl_json_rpc(YAAMP_RPC *rpc, const char *url, const char *rp *curl_err = rc; if (rc) { if (rc != CURLE_OPERATION_TIMEDOUT) { - debuglog("ERR: HTTP request failed: %s", curl_err_str); + snprintf(curl_last_err, last_err_len, "HTTP request failed: %s", curl_err_str); goto err_out; } } if (!all_data.buf || !all_data.len) { - debuglog("ERR: Empty data received in json_rpc_call."); + strcpy(curl_last_err, "rpc warning: no data received"); goto err_out; } @@ -297,16 +300,17 @@ static json_value *curl_json_rpc(YAAMP_RPC *rpc, const char *url, const char *rp long errcode = 0; CURLcode c = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &errcode); if (c == CURLE_OK && errcode == 401) { - debuglog("ERR: You are not authorized, check your login and password."); + debuglog("ERR: You are not authorized, check your login and password.\n"); goto err_out; } } val = json_parse(httpdata, strlen(httpdata)); if (!val) { - debuglog("ERR: JSON decode failed!"); + snprintf(curl_last_err, last_err_len, "JSON decode failed!"); + debuglog("ERR: JSON decode failed!\n"); if (opt_protocol) - debuglog("%s", httpdata); + debuglog("%s\n", httpdata); goto err_out; } @@ -362,10 +366,6 @@ void rpc_curl_close(YAAMP_RPC *rpc) curl_easy_cleanup(rpc->CURL); rpc->CURL = NULL; - - //made by rpc_close - //pthread_mutex_destroy(&rpc->mutex); - //rpc->sock = 0; } bool rpc_curl_connect(YAAMP_RPC *rpc) @@ -377,14 +377,14 @@ bool rpc_curl_connect(YAAMP_RPC *rpc) rpc->CURL = curl_easy_init(); } - //made by rpc_connect - //rpc->id = 0; - //rpc->bufpos = 0; - //yaamp_create_mutex(&rpc->mutex); - return true; } +void rpc_curl_get_lasterr(char* buffer, int buflen) +{ + snprintf(buffer, buflen, "%s", curl_last_err); +} + ///////////////////////////////////////////////////////////////////////////////// static json_value *rpc_curl_do_call(YAAMP_RPC *rpc, char const *data) @@ -394,6 +394,8 @@ static json_value *rpc_curl_do_call(YAAMP_RPC *rpc, char const *data) char url[1024]; int curl_err = 0; sprintf(url, "http%s://%s:%d", rpc->ssl?"s":"", rpc->host, rpc->port); + strcpy(curl_last_err, ""); + json_value *res = curl_json_rpc(rpc, url, data, &curl_err); CommonUnlock(&rpc->mutex);