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>
2upstream
Tanguy Pruvot 10 years ago
parent
commit
70743eb48d
  1. 87
      ccminer.cpp
  2. 37
      util.cpp

87
ccminer.cpp

@ -192,6 +192,7 @@ bool want_longpoll = true; @@ -192,6 +192,7 @@ bool want_longpoll = true;
bool have_longpoll = false;
bool want_stratum = true;
bool have_stratum = false;
bool allow_gbt = true;
static bool submit_old = false;
bool use_syslog = false;
bool use_colors = true;
@ -661,6 +662,55 @@ static bool submit_upstream_work(CURL *curl, struct work *work) @@ -661,6 +662,55 @@ static bool submit_upstream_work(CURL *curl, struct work *work)
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 =
"{\"method\": \"getwork\", \"params\": [], \"id\":0}\r\n";
@ -695,6 +745,8 @@ static bool get_upstream_work(CURL *curl, struct work *work) @@ -695,6 +745,8 @@ static bool get_upstream_work(CURL *curl, struct work *work)
json_decref(val);
get_blocktemplate(curl, work);
return rc;
}
@ -985,6 +1037,15 @@ static void stratum_gen_work(struct stratum_ctx *sctx, struct work *work) @@ -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)
{
struct thr_info *mythr = (struct thr_info *)userdata;
@ -1063,7 +1124,8 @@ static void *miner_thread(void *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);
if (!have_stratum)
global_diff = g_work.difficulty;
@ -1073,6 +1135,7 @@ static void *miner_thread(void *userdata) @@ -1073,6 +1135,7 @@ static void *miner_thread(void *userdata)
}
memcpy(work.target, g_work.target, sizeof(work.target));
work.difficulty = g_work.difficulty;
work.height = g_work.height;
nonceptr[0] = (UINT32_MAX / opt_n_threads) * thr_id; // 0 if single thr
/* on new target, ignoring nonce, clear sent data (hashlog) */
if (memcmp(work.target, g_work.target, sizeof(work.target))) {
@ -1409,7 +1472,18 @@ static void *miner_thread(void *userdata) @@ -1409,7 +1472,18 @@ static void *miner_thread(void *userdata)
if (rc && !opt_benchmark) {
if (!submit_work(mythr, &work))
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]) {
work.data[19] = work.data[21];
work.data[21] = 0;
@ -1427,15 +1501,6 @@ out: @@ -1427,15 +1501,6 @@ out:
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)
{
struct thr_info *mythr = (struct thr_info *)userdata;

37
util.cpp

@ -333,14 +333,15 @@ json_t *json_rpc_call(CURL *curl, const char *url, @@ -333,14 +333,15 @@ json_t *json_rpc_call(CURL *curl, const char *url,
{
json_t *val, *err_val, *res_val;
int rc;
struct data_buffer all_data = {0};
struct data_buffer all_data = { 0 };
struct upload_buffer upload_data;
json_error_t err;
struct curl_slist *headers = NULL;
char* httpdata;
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;
struct header_info hi = {0};
struct header_info hi = { 0 };
bool lp_scanning = longpoll_scan && !have_longpoll;
/* it is assumed that 'curl' is freshly [re]initialized at this pt */
@ -351,7 +352,7 @@ json_t *json_rpc_call(CURL *curl, const char *url, @@ -351,7 +352,7 @@ json_t *json_rpc_call(CURL *curl, const char *url,
if (opt_cert)
curl_easy_setopt(curl, CURLOPT_CAINFO, opt_cert);
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_TCP_NODELAY, 1);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, all_data_cb);
@ -404,10 +405,11 @@ json_t *json_rpc_call(CURL *curl, const char *url, @@ -404,10 +405,11 @@ json_t *json_rpc_call(CURL *curl, const char *url,
if (curl_err != NULL)
*curl_err = 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);
goto err_out;
}
}
/* If X-Stratum was found, activate Stratum */
if (want_stratum && hi.stratum_url &&
@ -425,14 +427,27 @@ json_t *json_rpc_call(CURL *curl, const char *url, @@ -425,14 +427,27 @@ json_t *json_rpc_call(CURL *curl, const char *url,
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.");
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) {
applog(LOG_ERR, "JSON decode failed(%d): %s", err.line, err.text);
if (opt_protocol)
applog(LOG_DEBUG, "%s", httpdata);
goto err_out;
}
@ -451,8 +466,14 @@ json_t *json_rpc_call(CURL *curl, const char *url, @@ -451,8 +466,14 @@ json_t *json_rpc_call(CURL *curl, const char *url,
(err_val && !json_is_null(err_val))) {
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));
if (json_is_string(msg)) {
free(s);
s = strdup(json_string_value(msg));
}
}
else
s = strdup("(unknown reason)");

Loading…
Cancel
Save