From 97e8dea4749949791f7ce5533d6f8826e4970f7b Mon Sep 17 00:00:00 2001 From: Tanguy Pruvot Date: Fri, 12 Feb 2016 22:02:44 +0100 Subject: [PATCH] decred: use getwork... sigh --- stratum/coinbase.cpp | 6 ---- stratum/coind_submit.cpp | 21 +++++++++++- stratum/coind_template.cpp | 66 ++++++++++++++++++++++++++++++++------ stratum/rpc.cpp | 4 +++ stratum/rpc_curl.cpp | 8 +++-- 5 files changed, 86 insertions(+), 19 deletions(-) diff --git a/stratum/coinbase.cpp b/stratum/coinbase.cpp index f54d660..adb9c37 100644 --- a/stratum/coinbase.cpp +++ b/stratum/coinbase.cpp @@ -196,12 +196,6 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * job_pack_tx(coind, templ->coinb2, available, NULL); strcat(templ->coinb2, "00000000"); // locktime - if(!strcmp(coind->symbol, "DCR")) { - // bypass coinbase and merkle for now... sent without changes - const unsigned char *hdr = (unsigned char *) &templ->header[36]; - hexlify(templ->coinb1, hdr, 192 - 80); - } - //if(coind->txmessage) // strcat(templ->coinb2, "00"); diff --git a/stratum/coind_submit.cpp b/stratum/coind_submit.cpp index cc00a04..066ea35 100644 --- a/stratum/coind_submit.cpp +++ b/stratum/coind_submit.cpp @@ -1,6 +1,23 @@ #include "stratum.h" +bool coind_submitwork(YAAMP_COIND *coind, const char *block) +{ + int paramlen = strlen(block); + + char *params = (char *)malloc(paramlen+1024); + if(!params) return false; + + sprintf(params, "[\"%s\"]", block); + json_value *json_res = rpc_call(&coind->rpc, "getwork", params); + free(params); + + bool b = json_res && json_res->type == json_boolean && json_res->u.boolean; + json_value_free(json_res); + + return b; +} + bool coind_submitblock(YAAMP_COIND *coind, const char *block) { int paramlen = strlen(block); @@ -71,7 +88,9 @@ bool coind_submit(YAAMP_COIND *coind, const char *block) { bool b; - if(coind->hassubmitblock) + if(!strcmp(coind->symbol,"DCR")) + b = coind_submitwork(coind, block); + else if(coind->hassubmitblock) b = coind_submitblock(coind, block); else b = coind_submitblocktemplate(coind, block); diff --git a/stratum/coind_template.cpp b/stratum/coind_template.cpp index 5bced9d..4c79f48 100644 --- a/stratum/coind_template.cpp +++ b/stratum/coind_template.cpp @@ -95,7 +95,7 @@ YAAMP_JOB_TEMPLATE *coind_create_template_memorypool(YAAMP_COIND *coind) //////////////////////////////////////////////////////////////////////////////////////////////////////////// -static int coind_parse_decred_header(YAAMP_JOB_TEMPLATE *templ, json_value *json) +static int coind_parse_decred_header(YAAMP_JOB_TEMPLATE *templ, const char *header_hex) { struct __attribute__((__packed__)) { uint32_t version; @@ -115,11 +115,9 @@ static int coind_parse_decred_header(YAAMP_JOB_TEMPLATE *templ, json_value *json uint32_t ntime; uint32_t nonce; unsigned char extra[36]; + uint32_t hashtag[3]; } header; - const char *header_hex = json_get_string(json, "header"); - if (!header_hex) return -1; - //debuglog("HEADER: %s\n", header_hex); binlify((unsigned char*) &header, header_hex); @@ -133,6 +131,7 @@ static int coind_parse_decred_header(YAAMP_JOB_TEMPLATE *templ, json_value *json templ->prevhash_hex[64] = '\0'; for(int i=0; i < 32; i++) sprintf(templ->prevhash_hex + (i*2), "%02x", (uint8_t) header.prevblock[31-i]); + ser_string_be2(templ->prevhash_hex, templ->prevhash_be, 8); // store all other stuff memcpy(templ->header, &header, sizeof(header)); @@ -140,6 +139,50 @@ static int coind_parse_decred_header(YAAMP_JOB_TEMPLATE *templ, json_value *json return 0; } +static YAAMP_JOB_TEMPLATE *coind_create_template_decred(YAAMP_COIND *coind) +{ + json_value *gw = rpc_call(&coind->rpc, "getwork", "[]"); + if(!gw || gw->type == json_null) { + coind_error(coind, "getwork"); + return NULL; + } + json_value *gwr = json_get_object(gw, "result"); + if(!gwr || gwr->type == json_null) { + coind_error(coind, "getwork result"); + return NULL; + } + const char *header_hex = json_get_string(gwr, "data"); + if (!header_hex || !strlen(header_hex)) { + coind_error(coind, "getwork data"); + return NULL; + } + + YAAMP_JOB_TEMPLATE *templ = new YAAMP_JOB_TEMPLATE; + memset(templ, 0, sizeof(YAAMP_JOB_TEMPLATE)); + + templ->created = time(NULL); + + coind_parse_decred_header(templ, header_hex); + json_value_free(gw); + + // bypass coinbase and merkle for now... send without nonce/extradata + const unsigned char *hdr = (unsigned char *) &templ->header[36]; + hexlify(templ->coinb1, hdr, 192 - 80); + strcpy(templ->coinb2, ""); + + vector txhashes; + txhashes.push_back(""); + + templ->txmerkles[0] = 0; + templ->txcount = txhashes.size(); + templ->txsteps = merkle_steps(txhashes); + txhashes.clear(); + + return templ; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////// + YAAMP_JOB_TEMPLATE *coind_create_template(YAAMP_COIND *coind) { if(coind->usememorypool) @@ -195,11 +238,7 @@ YAAMP_JOB_TEMPLATE *coind_create_template(YAAMP_COIND *coind) const char *flags = json_get_string(json_coinbaseaux, "flags"); strcpy(templ->flags, flags ? flags : ""); - if (!strcmp(coind->symbol, "DCR")) { - coind_parse_decred_header(templ, json_result); - } - else - if (!templ->height || !prev || !bits) { + if (!templ->height || !bits || !prev) { stratumlog("%s warning, gbt incorrect : version=%s height=%d value=%d bits=%s time=%s prev=%s\n", coind->symbol, templ->version, templ->height, templ->value, templ->nbits, templ->ntime, templ->prevhash_hex); } @@ -289,7 +328,14 @@ void coind_create_job(YAAMP_COIND *coind, bool force) CommonLock(&coind->mutex); - YAAMP_JOB_TEMPLATE *templ = coind_create_template(coind); + YAAMP_JOB_TEMPLATE *templ; + + // DCR gbt block header is not compatible with getwork submit, so... + if (!strcmp(coind->symbol, "DCR")) + templ = coind_create_template_decred(coind); + else + templ = coind_create_template(coind); + if(!templ) { CommonUnlock(&coind->mutex); diff --git a/stratum/rpc.cpp b/stratum/rpc.cpp index f81dce0..5b3f29d 100644 --- a/stratum/rpc.cpp +++ b/stratum/rpc.cpp @@ -278,6 +278,10 @@ json_value *rpc_call(YAAMP_RPC *rpc, char const *method, char const *params) if(s2-s1 > 2000) debuglog("delay rpc_call %s:%d %s in %d ms\n", rpc->host, rpc->port, method, s2-s1); + if (!strcmp(method, "getwork")) { + return json; + } + if(json->type != json_object) { json_value_free(json); diff --git a/stratum/rpc_curl.cpp b/stratum/rpc_curl.cpp index a40cfd6..2cbb590 100644 --- a/stratum/rpc_curl.cpp +++ b/stratum/rpc_curl.cpp @@ -472,13 +472,17 @@ json_value *rpc_curl_call(YAAMP_RPC *rpc, char const *method, char const *params if(s2-s1 > 2000) debuglog("delay rpc_call %s:%d %s in %d ms\n", rpc->host, rpc->port, method, s2-s1); + rpc_curl_close(rpc); + + if (!strcmp(method, "getwork")) { + return json; + } + if(json->type != json_object) { json_value_free(json); return NULL; } - rpc_curl_close(rpc); - return json; }