mirror of
https://github.com/GOSTSec/ccminer
synced 2025-01-22 12:34:17 +00:00
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>
This commit is contained in:
parent
49a73971c4
commit
70743eb48d
87
ccminer.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;
|
||||||
|
39
util.cpp
39
util.cpp
@ -333,14 +333,15 @@ json_t *json_rpc_call(CURL *curl, const char *url,
|
|||||||
{
|
{
|
||||||
json_t *val, *err_val, *res_val;
|
json_t *val, *err_val, *res_val;
|
||||||
int rc;
|
int rc;
|
||||||
struct data_buffer all_data = {0};
|
struct data_buffer all_data = { 0 };
|
||||||
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;
|
||||||
|
|
||||||
/* it is assumed that 'curl' is freshly [re]initialized at this pt */
|
/* 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,
|
|||||||
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,9 +405,10 @@ 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 */
|
||||||
@ -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…
x
Reference in New Issue
Block a user