Browse Source

solo: get bloc height and trap more errors

and disable multiple nonce on wallets,
a bloc cant be resolved twice ;)

Signed-off-by: Tanguy Pruvot <tanguy.pruvot@gmail.com>
master
Tanguy Pruvot 10 years ago
parent
commit
70743eb48d
  1. 87
      ccminer.cpp
  2. 33
      util.cpp

87
ccminer.cpp

@ -192,6 +192,7 @@ bool want_longpoll = true;
bool have_longpoll = false; bool have_longpoll = false;
bool want_stratum = true; bool want_stratum = true;
bool have_stratum = false; bool have_stratum = false;
bool allow_gbt = true;
static bool submit_old = false; static bool submit_old = false;
bool use_syslog = false; bool use_syslog = false;
bool use_colors = true; bool use_colors = true;
@ -661,6 +662,55 @@ static bool submit_upstream_work(CURL *curl, struct work *work)
return true; return true;
} }
/* simplified method to only get some extra infos in solo mode */
static bool gbt_work_decode(const json_t *val, struct work *work)
{
json_t *err = json_object_get(val, "error");
if (err && !json_is_null(err)) {
allow_gbt = false;
applog(LOG_INFO, "GBT not supported, bloc height unavailable");
return false;
}
if (!work->height) {
// complete missing data from getwork
json_t *key = json_object_get(val, "height");
if (key && json_is_integer(key)) {
work->height = (uint32_t) json_integer_value(key);
if (!opt_quiet && work->height != g_work.height) {
applog(LOG_BLUE, "%s %s block %d", short_url,
algo_names[opt_algo], work->height);
}
}
}
return true;
}
#define GBT_CAPABILITIES "[\"coinbasetxn\", \"coinbasevalue\", \"longpoll\", \"workid\"]"
static const char *gbt_req =
"{\"method\": \"getblocktemplate\", \"params\": ["
// "{\"capabilities\": " GBT_CAPABILITIES "}"
"], \"id\":0}\r\n";
static bool get_blocktemplate(CURL *curl, struct work *work)
{
if (!allow_gbt)
return false;
json_t *val = json_rpc_call(curl, rpc_url, rpc_userpass, gbt_req,
want_longpoll, false, NULL);
if (!val)
return false;
bool rc = gbt_work_decode(json_object_get(val, "result"), work);
json_decref(val);
return rc;
}
static const char *rpc_req = static const char *rpc_req =
"{\"method\": \"getwork\", \"params\": [], \"id\":0}\r\n"; "{\"method\": \"getwork\", \"params\": [], \"id\":0}\r\n";
@ -695,6 +745,8 @@ static bool get_upstream_work(CURL *curl, struct work *work)
json_decref(val); json_decref(val);
get_blocktemplate(curl, work);
return rc; return rc;
} }
@ -985,6 +1037,15 @@ static void stratum_gen_work(struct stratum_ctx *sctx, struct work *work)
} }
} }
static void restart_threads(void)
{
if (opt_debug && !opt_quiet)
applog(LOG_DEBUG,"%s", __FUNCTION__);
for (int i = 0; i < opt_n_threads; i++)
work_restart[i].restart = 1;
}
static void *miner_thread(void *userdata) static void *miner_thread(void *userdata)
{ {
struct thr_info *mythr = (struct thr_info *)userdata; struct thr_info *mythr = (struct thr_info *)userdata;
@ -1063,7 +1124,8 @@ static void *miner_thread(void *userdata)
} }
} }
if (!opt_benchmark && memcmp(work.target, g_work.target, sizeof(work.target))) { if (!opt_benchmark && (g_work.height != work.height || memcmp(work.target, g_work.target, sizeof(work.target))))
{
calc_diff(&g_work, 0); calc_diff(&g_work, 0);
if (!have_stratum) if (!have_stratum)
global_diff = g_work.difficulty; global_diff = g_work.difficulty;
@ -1073,6 +1135,7 @@ static void *miner_thread(void *userdata)
} }
memcpy(work.target, g_work.target, sizeof(work.target)); memcpy(work.target, g_work.target, sizeof(work.target));
work.difficulty = g_work.difficulty; work.difficulty = g_work.difficulty;
work.height = g_work.height;
nonceptr[0] = (UINT32_MAX / opt_n_threads) * thr_id; // 0 if single thr nonceptr[0] = (UINT32_MAX / opt_n_threads) * thr_id; // 0 if single thr
/* on new target, ignoring nonce, clear sent data (hashlog) */ /* on new target, ignoring nonce, clear sent data (hashlog) */
if (memcmp(work.target, g_work.target, sizeof(work.target))) { if (memcmp(work.target, g_work.target, sizeof(work.target))) {
@ -1409,7 +1472,18 @@ static void *miner_thread(void *userdata)
if (rc && !opt_benchmark) { if (rc && !opt_benchmark) {
if (!submit_work(mythr, &work)) if (!submit_work(mythr, &work))
break; break;
// second nonce found, submit too
// prevent stale work in solo
// we can't submit twice a block!
if (!have_stratum) {
pthread_mutex_lock(&g_work_lock);
// will force getwork
g_work_time = 0;
pthread_mutex_unlock(&g_work_lock);
continue;
}
// second nonce found, submit too (on pool only!)
if (rc > 1 && work.data[21]) { if (rc > 1 && work.data[21]) {
work.data[19] = work.data[21]; work.data[19] = work.data[21];
work.data[21] = 0; work.data[21] = 0;
@ -1427,15 +1501,6 @@ out:
return NULL; return NULL;
} }
static void restart_threads(void)
{
if (opt_debug)
applog(LOG_DEBUG,"%s", __FUNCTION__);
for (int i = 0; i < opt_n_threads; i++)
work_restart[i].restart = 1;
}
static void *longpoll_thread(void *userdata) static void *longpoll_thread(void *userdata)
{ {
struct thr_info *mythr = (struct thr_info *)userdata; struct thr_info *mythr = (struct thr_info *)userdata;

33
util.cpp

@ -337,8 +337,9 @@ json_t *json_rpc_call(CURL *curl, const char *url,
struct upload_buffer upload_data; struct upload_buffer upload_data;
json_error_t err; json_error_t err;
struct curl_slist *headers = NULL; struct curl_slist *headers = NULL;
char* httpdata;
char len_hdr[64], hashrate_hdr[64]; char len_hdr[64], hashrate_hdr[64];
char curl_err_str[CURL_ERROR_SIZE]; char curl_err_str[CURL_ERROR_SIZE] = { 0 };
long timeout = longpoll ? opt_timeout : 30; long timeout = longpoll ? opt_timeout : 30;
struct header_info hi = { 0 }; struct header_info hi = { 0 };
bool lp_scanning = longpoll_scan && !have_longpoll; bool lp_scanning = longpoll_scan && !have_longpoll;
@ -351,7 +352,7 @@ json_t *json_rpc_call(CURL *curl, const char *url,
if (opt_cert) if (opt_cert)
curl_easy_setopt(curl, CURLOPT_CAINFO, opt_cert); curl_easy_setopt(curl, CURLOPT_CAINFO, opt_cert);
curl_easy_setopt(curl, CURLOPT_ENCODING, ""); curl_easy_setopt(curl, CURLOPT_ENCODING, "");
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 0);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1); curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, all_data_cb); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, all_data_cb);
@ -404,10 +405,11 @@ json_t *json_rpc_call(CURL *curl, const char *url,
if (curl_err != NULL) if (curl_err != NULL)
*curl_err = rc; *curl_err = rc;
if (rc) { if (rc) {
if (!(longpoll && rc == CURLE_OPERATION_TIMEDOUT)) if (!(longpoll && rc == CURLE_OPERATION_TIMEDOUT)) {
applog(LOG_ERR, "HTTP request failed: %s", curl_err_str); applog(LOG_ERR, "HTTP request failed: %s", curl_err_str);
goto err_out; goto err_out;
} }
}
/* If X-Stratum was found, activate Stratum */ /* If X-Stratum was found, activate Stratum */
if (want_stratum && hi.stratum_url && if (want_stratum && hi.stratum_url &&
@ -425,14 +427,27 @@ json_t *json_rpc_call(CURL *curl, const char *url,
hi.lp_path = NULL; hi.lp_path = NULL;
} }
if (!all_data.buf) { if (!all_data.buf || !all_data.len) {
applog(LOG_ERR, "Empty data received in json_rpc_call."); applog(LOG_ERR, "Empty data received in json_rpc_call.");
goto err_out; goto err_out;
} }
val = JSON_LOADS((const char*)all_data.buf, &err); httpdata = (char*) all_data.buf;
if (*httpdata != '{' && *httpdata != '[') {
long errcode = 0;
CURLcode c = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &errcode);
if (c == CURLE_OK && errcode == 401) {
applog(LOG_ERR, "You are not authorized, check your login and password.");
goto err_out;
}
}
val = JSON_LOADS(httpdata, &err);
if (!val) { if (!val) {
applog(LOG_ERR, "JSON decode failed(%d): %s", err.line, err.text); applog(LOG_ERR, "JSON decode failed(%d): %s", err.line, err.text);
if (opt_protocol)
applog(LOG_DEBUG, "%s", httpdata);
goto err_out; goto err_out;
} }
@ -451,8 +466,14 @@ json_t *json_rpc_call(CURL *curl, const char *url,
(err_val && !json_is_null(err_val))) { (err_val && !json_is_null(err_val))) {
char *s; char *s;
if (err_val) if (err_val) {
json_t *msg = json_object_get(err_val, "message");
s = json_dumps(err_val, JSON_INDENT(3)); s = json_dumps(err_val, JSON_INDENT(3));
if (json_is_string(msg)) {
free(s);
s = strdup(json_string_value(msg));
}
}
else else
s = strdup("(unknown reason)"); s = strdup("(unknown reason)");

Loading…
Cancel
Save