diff --git a/stratum/coinbase.cpp b/stratum/coinbase.cpp index adb9c37..5c33974 100644 --- a/stratum/coinbase.cpp +++ b/stratum/coinbase.cpp @@ -110,18 +110,26 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * if (strlen(coind->charity_address) == 0) sprintf(coind->charity_address, "BCDrF1hWdKTmrjXXVFTezPjKBmGigmaXg5"); } + else if(strcmp(coind->symbol, "DCR") == 0) { + coind->reward_mul = 6; // coinbase value is wrong, reward_mul should be 6 + coind->charity_percent = 0; + coind->charity_amount = available; + available *= coind->reward_mul; + if (strlen(coind->charity_address) == 0) + sprintf(coind->charity_address, "Dcur2mcGjmENx4DhNqDctW5wJCVyT3Qeqkx"); + } // 2 txs are required on these coins, one for foundation (dev fees) if(coind->charity_percent) { - char charity_payee[512] = { 0 }; + char script_payee[1024]; + char charity_payee[256] = { 0 }; const char *payee = json_get_string(json_result, "payee"); - if (payee) snprintf(charity_payee, 511, "%s", payee); + if (payee) snprintf(charity_payee, 255, "%s", payee); else sprintf(charity_payee, "%s", coind->charity_address); if (strlen(charity_payee) == 0) stratumlog("ERROR %s has no charity_address set!\n", coind->name); - char script_payee[1024]; base58_decode(charity_payee, script_payee); json_int_t charity_amount = (available * coind->charity_percent) / 100; @@ -137,13 +145,34 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * return; } + else if(coind->charity_amount && !strcmp(coind->symbol, "DCR")) + { + char script_payee[1024]; + char charity_payee[256] = { 0 }; + const char *payee = json_get_string(json_result, "payee"); + if (payee) snprintf(charity_payee, 255, "%s", payee); + else sprintf(charity_payee, "%s", coind->charity_address); + if (strlen(charity_payee) == 0) + stratumlog("ERROR %s has no charity_address set!\n", coind->name); + + base58_decode(charity_payee, script_payee); + + strcat(templ->coinb2, "02"); + job_pack_tx(coind, templ->coinb2, coind->charity_amount, script_payee); + job_pack_tx(coind, templ->coinb2, available, NULL); + strcat(templ->coinb2, "00000000"); // locktime + + coind->reward = (double)available/100000000; + return; + } + if(strcmp(coind->symbol, "VNL") == 0) { - char charity_payee[512]; + char charity_payee[256]; json_value* incentive = json_get_object(json_result, "incentive"); if (incentive) { const char* payee = json_get_string(incentive, "address"); - if (payee) snprintf(charity_payee, 511, "%s", payee); + if (payee) snprintf(charity_payee, 255, "%s", payee); else sprintf(charity_payee, "%s", coind->charity_address); bool enforced = json_get_bool(incentive, "enforced"); @@ -168,9 +197,9 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value * if(coind->hasmasternodes) /* DASH style */ { - char charity_payee[512] = { 0 }; + char charity_payee[256] = { 0 }; const char *payee = json_get_string(json_result, "payee"); - if (payee) snprintf(charity_payee, 511, "%s", payee); + if (payee) snprintf(charity_payee, 255, "%s", payee); json_int_t charity_amount = json_get_int(json_result, "payee_amount"); bool charity_payments = json_get_bool(json_result, "masternode_payments"); diff --git a/stratum/coind_template.cpp b/stratum/coind_template.cpp index a825f5f..cb64ef1 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, const char *header_hex) +static int decred_parse_header(YAAMP_JOB_TEMPLATE *templ, const char *header_hex, bool getwork) { struct __attribute__((__packed__)) { uint32_t version; @@ -123,14 +123,15 @@ static int coind_parse_decred_header(YAAMP_JOB_TEMPLATE *templ, const char *head binlify((unsigned char*) &header, header_hex); templ->height = header.height; - sprintf(templ->version, "%08x", bswap32(header.version)); + // reversed to tell its not a normal stratum coinbase + sprintf(templ->version, "%08x", getwork ? bswap32(header.version) : header.version); sprintf(templ->ntime, "%08x", header.ntime); sprintf(templ->nbits, "%08x", header.nbits); - //hexlify(templ->prevhash_hex, (const unsigned char*) header.prevblock, 32); 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]); + uint32_t* prev32 = (uint32_t*) header.prevblock; + for(int i=0; i < 8; i++) + sprintf(&templ->prevhash_hex[i*8], "%08x", getwork ? prev32[7-i] : bswap32(prev32[7-i])); ser_string_be2(templ->prevhash_hex, templ->prevhash_be, 8); // store all other stuff @@ -139,7 +140,8 @@ static int coind_parse_decred_header(YAAMP_JOB_TEMPLATE *templ, const char *head return 0; } -static YAAMP_JOB_TEMPLATE *coind_create_template_decred(YAAMP_COIND *coind) +// decred getwork over stratum +static YAAMP_JOB_TEMPLATE *decred_create_worktemplate(YAAMP_COIND *coind) { int retry_max = 3; retry: @@ -175,7 +177,7 @@ retry: templ->created = time(NULL); - coind_parse_decred_header(templ, header_hex); + decred_parse_header(templ, header_hex, true); json_value_free(gw); // bypass coinbase and merkle for now... send without nonce/extradata @@ -194,6 +196,22 @@ retry: return templ; } +// for future decred real stratum +static void decred_fix_template(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value *json) +{ + const char *header_hex = json_get_string(json, "header"); + if (!header_hex || !strlen(header_hex)) { + stratumlog("decred error, no block header in json!\n"); + return; + } + + // todo ? + // "mintime": 1455511962, + // "maxtime": 1455522081, + + decred_parse_header(templ, header_hex, false); +} + //////////////////////////////////////////////////////////////////////////////////////////////////////////// YAAMP_JOB_TEMPLATE *coind_create_template(YAAMP_COIND *coind) @@ -205,14 +223,18 @@ YAAMP_JOB_TEMPLATE *coind_create_template(YAAMP_COIND *coind) if(!strcmp(coind->symbol, "PPC")) strcpy(params, "[]"); json_value *json = rpc_call(&coind->rpc, "getblocktemplate", params); - if(!json || json->type == json_null) + if(!json || json_is_null(json)) { - coind_error(coind, "getblocktemplate"); + // coind_error() reset auto_ready, and DCR gbt can fail + if (strcmp(coind->symbol, "DCR") == 0) + debuglog("decred getblocktemplate failed\n"); + else + coind_error(coind, "getblocktemplate"); return NULL; } json_value *json_result = json_get_object(json, "result"); - if(!json_result || json_result->type == json_null) + if(!json_result || json_is_null(json_result)) { coind_error(coind, "getblocktemplate result"); json_value_free(json); @@ -251,7 +273,11 @@ YAAMP_JOB_TEMPLATE *coind_create_template(YAAMP_COIND *coind) const char *flags = json_get_string(json_coinbaseaux, "flags"); strcpy(templ->flags, flags ? flags : ""); - if (!templ->height || !bits || !prev) { + if (!strcmp(coind->symbol, "DCR")) { + decred_fix_template(coind, templ, json_result); + } + + if (!templ->height || !templ->nbits || !strlen(templ->prevhash_hex)) { 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); } @@ -346,7 +372,7 @@ void coind_create_job(YAAMP_COIND *coind, bool force) // DCR gbt block header is not compatible with getwork submit, so... if (coind->usegetwork && !strcmp(coind->symbol, "DCR")) - templ = coind_create_template_decred(coind); + templ = decred_create_worktemplate(coind); else templ = coind_create_template(coind);