stratum: prepare real decred stratum

not finished, commited to test on another server

but, remains the problem of decred custom header fields... stakeroot etc
which should be passed to the miner..
This commit is contained in:
Tanguy Pruvot 2016-02-15 06:52:39 +01:00
parent e2f982300c
commit 9cbd9bf5e3
2 changed files with 74 additions and 19 deletions

View file

@ -110,18 +110,26 @@ void coinbase_create(YAAMP_COIND *coind, YAAMP_JOB_TEMPLATE *templ, json_value *
if (strlen(coind->charity_address) == 0) if (strlen(coind->charity_address) == 0)
sprintf(coind->charity_address, "BCDrF1hWdKTmrjXXVFTezPjKBmGigmaXg5"); 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) // 2 txs are required on these coins, one for foundation (dev fees)
if(coind->charity_percent) 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"); 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); else sprintf(charity_payee, "%s", coind->charity_address);
if (strlen(charity_payee) == 0) if (strlen(charity_payee) == 0)
stratumlog("ERROR %s has no charity_address set!\n", coind->name); stratumlog("ERROR %s has no charity_address set!\n", coind->name);
char script_payee[1024];
base58_decode(charity_payee, script_payee); base58_decode(charity_payee, script_payee);
json_int_t charity_amount = (available * coind->charity_percent) / 100; 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; 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) if(strcmp(coind->symbol, "VNL") == 0)
{ {
char charity_payee[512]; char charity_payee[256];
json_value* incentive = json_get_object(json_result, "incentive"); json_value* incentive = json_get_object(json_result, "incentive");
if (incentive) { if (incentive) {
const char* payee = json_get_string(incentive, "address"); 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); else sprintf(charity_payee, "%s", coind->charity_address);
bool enforced = json_get_bool(incentive, "enforced"); 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 */ if(coind->hasmasternodes) /* DASH style */
{ {
char charity_payee[512] = { 0 }; char charity_payee[256] = { 0 };
const char *payee = json_get_string(json_result, "payee"); 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"); json_int_t charity_amount = json_get_int(json_result, "payee_amount");
bool charity_payments = json_get_bool(json_result, "masternode_payments"); bool charity_payments = json_get_bool(json_result, "masternode_payments");

View file

@ -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__)) { struct __attribute__((__packed__)) {
uint32_t version; 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); binlify((unsigned char*) &header, header_hex);
templ->height = header.height; 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->ntime, "%08x", header.ntime);
sprintf(templ->nbits, "%08x", header.nbits); sprintf(templ->nbits, "%08x", header.nbits);
//hexlify(templ->prevhash_hex, (const unsigned char*) header.prevblock, 32);
templ->prevhash_hex[64] = '\0'; templ->prevhash_hex[64] = '\0';
for(int i=0; i < 32; i++) uint32_t* prev32 = (uint32_t*) header.prevblock;
sprintf(templ->prevhash_hex + (i*2), "%02x", (uint8_t) header.prevblock[31-i]); 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); ser_string_be2(templ->prevhash_hex, templ->prevhash_be, 8);
// store all other stuff // store all other stuff
@ -139,7 +140,8 @@ static int coind_parse_decred_header(YAAMP_JOB_TEMPLATE *templ, const char *head
return 0; 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; int retry_max = 3;
retry: retry:
@ -175,7 +177,7 @@ retry:
templ->created = time(NULL); templ->created = time(NULL);
coind_parse_decred_header(templ, header_hex); decred_parse_header(templ, header_hex, true);
json_value_free(gw); json_value_free(gw);
// bypass coinbase and merkle for now... send without nonce/extradata // bypass coinbase and merkle for now... send without nonce/extradata
@ -194,6 +196,22 @@ retry:
return templ; 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) 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, "[]"); if(!strcmp(coind->symbol, "PPC")) strcpy(params, "[]");
json_value *json = rpc_call(&coind->rpc, "getblocktemplate", params); json_value *json = rpc_call(&coind->rpc, "getblocktemplate", params);
if(!json || json->type == json_null) if(!json || json_is_null(json))
{ {
// 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"); coind_error(coind, "getblocktemplate");
return NULL; return NULL;
} }
json_value *json_result = json_get_object(json, "result"); 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"); coind_error(coind, "getblocktemplate result");
json_value_free(json); 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"); const char *flags = json_get_string(json_coinbaseaux, "flags");
strcpy(templ->flags, flags ? 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", 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); 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... // DCR gbt block header is not compatible with getwork submit, so...
if (coind->usegetwork && !strcmp(coind->symbol, "DCR")) if (coind->usegetwork && !strcmp(coind->symbol, "DCR"))
templ = coind_create_template_decred(coind); templ = decred_create_worktemplate(coind);
else else
templ = coind_create_template(coind); templ = coind_create_template(coind);