static void submit_work(CURL *curl, struct work *work) { char *hexstr = NULL; json_t *val, *res; char s[345], timestr[64]; time_t now; struct tm *tm; now = time(NULL); /* build hex string */ hexstr = bin2hex(work->data, sizeof(work->data)); if (!hexstr) { fprintf(stderr, "submit_work OOM\n"); goto out; } /* build JSON-RPC request */ sprintf(s, "{\"method\": \"getwork\", \"params\": [ \"%s\" ], \"id\":1}\r\n", hexstr); if (opt_debug) fprintf(stderr, "DBG: sending RPC call:\n%s", s); /* issue JSON-RPC request */ val = json_rpc_call(curl, rpc_url, userpass, s); if (!val) { fprintf(stderr, "submit_work json_rpc_call failed\n"); goto out; } res = json_object_get(val, "result"); tm = localtime(&now); strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", tm); printf("%s: PROOF OF WORK RESULT: %s\n", timestr, json_is_true(res) ? "true (yay!!!)" : "false (booooo)"); if (opt_log) { FILE *f = fopen(opt_log,"a"); fprintf(f, "%s: PROOF OF WORK RESULT: %s\n", timestr, json_is_true(res) ? "true (yay!!!)" : "false (booooo)"); fprintf(f, "%s: DATA: %s\n", timestr, hexstr); fclose(f); } json_decref(val); out: free(hexstr); }
json_t *hodl_longpoll_rpc_call( CURL *curl, int *err, char* lp_url ) { json_t *val; char *req = NULL; if ( have_gbt ) { req = malloc( strlen( gbt_lp_req ) + strlen( lp_id ) + 1 ); sprintf( req, gbt_lp_req, lp_id ); } val = json_rpc_call( curl, lp_url, rpc_userpass, req ? req : getwork_req, err, JSON_RPC_LONGPOLL ); free( req ); return val; }
static bool submit_upstream_work(CURL *curl, const struct work *work) { char *hexstr = NULL; json_t *val, *res, *err; char s[345]; bool rc = false; /* build hex string */ hexstr = bin2hex(work->data, 88); if (unlikely(!hexstr)) { applog(LOG_ERR, "submit_upstream_work OOM"); goto out; } /* build JSON-RPC request */ sprintf(s, "{\"method\": \"getwork\", \"params\": [ \"%s\" ], \"id\":1}\r\n", hexstr); if (opt_debug) applog(LOG_DEBUG, "DBG: sending RPC call: %s", s); /* issue JSON-RPC request */ val = json_rpc_call(curl, rpc_url, rpc_userpass, s, false, false); if (unlikely(!val)) { applog(LOG_ERR, "submit_upstream_work json_rpc_call failed"); goto out; } res = json_object_get(val, "result"); err = json_object_get(val, "error"); if (json_is_true(res)) { applog(LOG_INFO, "PROOF OF WORK RESULT: Accepted"); } else if (json_is_array(err) && json_array_size(err) >= 1 && json_is_string(json_array_get(err, 0))) { applog(LOG_INFO, "PROOF OF WORK RESULT: Rejected (%s)", json_string_value(json_array_get(err, 0))); } else { applog(LOG_INFO, "PROOF OF WORK RESULT: Rejected"); } json_decref(val); rc = true; out: free(hexstr); return rc; }
static bool get_upstream_work(CURL *curl, struct work *work) { json_t *val; bool rc; val = json_rpc_call(curl, rpc_url, rpc_userpass, rpc_req, want_longpoll, false); if (!val) return false; rc = work_decode(json_object_get(val, "result"), work); json_decref(val); return rc; }
static bool get_work(CURL *curl, struct work *work) { static const char *rpc_req = "{\"method\": \"getwork\", \"params\": [], \"id\":0}\r\n"; json_t *val; bool rc; val = json_rpc_call(curl, rpc_url, userpass, rpc_req); if (!val) return false; rc = work_decode(json_object_get(val, "result"), work); json_decref(val); return rc; }
static void *longpoll_thread(void *userdata) { struct thr_info *mythr = userdata; CURL *curl = NULL; char *copy_start, *hdr_path, *lp_url = NULL; bool need_slash = false; int failures = 0; hdr_path = tq_pop(mythr->q, NULL); if (!hdr_path) goto out; /* full URL */ if (strstr(hdr_path, "://")) { lp_url = hdr_path; hdr_path = NULL; } /* absolute path, on current server */ else { copy_start = (*hdr_path == '/') ? (hdr_path + 1) : hdr_path; if (rpc_url[strlen(rpc_url) - 1] != '/') need_slash = true; lp_url = malloc(strlen(rpc_url) + strlen(copy_start) + 2); if (!lp_url) goto out; sprintf(lp_url, "%s%s%s", rpc_url, need_slash ? "/" : "", copy_start); } applog(LOG_INFO, "Long-polling activated for %s", lp_url); curl = curl_easy_init(); if (unlikely(!curl)) { applog(LOG_ERR, "CURL initialization failed"); goto out; } while (1) { json_t *val; val = json_rpc_call(curl, lp_url, rpc_userpass, rpc_req, false, true); if (likely(val)) { failures = 0; json_decref(val); applog(LOG_INFO, "LONGPOLL detected new block"); restart_threads(); } else { if (failures++ < 10) { sleep(30); applog(LOG_ERR, "longpoll failed, sleeping for 30s"); } else { applog(LOG_ERR, "longpoll failed, ending thread"); goto out; } } } out: free(hdr_path); free(lp_url); tq_freeze(mythr->q); if (curl) curl_easy_cleanup(curl); return NULL; }