phi2 changes to handle lux smart contracts

adds a smart contract roots field (stateroot+utxoroot) to mining.notify

like lbry do with their claimtrie.

These fields are optional, means there are 2 variants of the phi2 algo

Signed-off-by: Tanguy Pruvot <tanguy.pruvot@gmail.com>
This commit is contained in:
Tanguy Pruvot 2018-06-21 17:27:33 +02:00
parent 9038f0941a
commit 27176b2e09
6 changed files with 61 additions and 24 deletions

View file

@ -16,9 +16,9 @@
void phi2_hash(const char* input, char* output, uint32_t len) void phi2_hash(const char* input, char* output, uint32_t len)
{ {
unsigned char _ALIGN(128) hash[128] = { 0 }; unsigned char _ALIGN(128) hash[64];
unsigned char _ALIGN(128) hashA[64] = { 0 }; unsigned char _ALIGN(128) hashA[64];
unsigned char _ALIGN(128) hashB[64] = { 0 }; unsigned char _ALIGN(128) hashB[64];
sph_cubehash512_context ctx_cubehash; sph_cubehash512_context ctx_cubehash;
sph_jh512_context ctx_jh; sph_jh512_context ctx_jh;
@ -27,7 +27,7 @@ void phi2_hash(const char* input, char* output, uint32_t len)
sph_skein512_context ctx_skein; sph_skein512_context ctx_skein;
sph_cubehash512_init(&ctx_cubehash); sph_cubehash512_init(&ctx_cubehash);
sph_cubehash512(&ctx_cubehash, input, 80); sph_cubehash512(&ctx_cubehash, input, len);
sph_cubehash512_close(&ctx_cubehash, (void*)hashB); sph_cubehash512_close(&ctx_cubehash, (void*)hashB);
LYRA2(&hashA[ 0], 32, &hashB[ 0], 32, &hashB[ 0], 32, 1, 8, 8); LYRA2(&hashA[ 0], 32, &hashB[ 0], 32, &hashB[ 0], 32, 1, 8, 8);

View file

@ -31,10 +31,14 @@ void build_submit_values(YAAMP_JOB_VALUES *submitvalues, YAAMP_JOB_TEMPLATE *tem
#ifdef MERKLE_DEBUGLOG #ifdef MERKLE_DEBUGLOG
printf("merkle root %s\n", merkleroot.c_str()); printf("merkle root %s\n", merkleroot.c_str());
#endif #endif
if (!strcmp(g_current_algo->name, "lbry")) { if (!strcmp(g_stratum_algo, "lbry")) {
sprintf(submitvalues->header, "%s%s%s%s%s%s%s", templ->version, templ->prevhash_be, submitvalues->merkleroot_be, sprintf(submitvalues->header, "%s%s%s%s%s%s%s", templ->version, templ->prevhash_be, submitvalues->merkleroot_be,
templ->claim_be, ntime, templ->nbits, nonce); templ->claim_be, ntime, templ->nbits, nonce);
ser_string_be(submitvalues->header, submitvalues->header_be, 32 + 20); ser_string_be(submitvalues->header, submitvalues->header_be, 112/4);
} else if (strlen(templ->extradata_be) == 128) { // LUX SC
sprintf(submitvalues->header, "%s%s%s%s%s%s%s", templ->version, templ->prevhash_be, submitvalues->merkleroot_be,
ntime, templ->nbits, nonce, templ->extradata_be);
ser_string_be(submitvalues->header, submitvalues->header_be, 36); // 80+64 / sizeof(u32)
} else { } else {
sprintf(submitvalues->header, "%s%s%s%s%s%s", templ->version, templ->prevhash_be, submitvalues->merkleroot_be, sprintf(submitvalues->header, "%s%s%s%s%s%s", templ->version, templ->prevhash_be, submitvalues->merkleroot_be,
ntime, templ->nbits, nonce); ntime, templ->nbits, nonce);
@ -355,15 +359,11 @@ bool client_submit(YAAMP_CLIENT *client, json_value *json_params)
return false; return false;
} }
char extranonce2[32]; char extranonce2[32] = { 0 };
char ntime[32]; char extra[160] = { 0 };
char nonce[32]; char nonce[80] = { 0 };
char vote[8]; char ntime[32] = { 0 };
char vote[8] = { 0 };
memset(extranonce2, 0, 32);
memset(ntime, 0, 32);
memset(nonce, 0, 32);
memset(vote, 0, 8);
if (!json_params->u.array.values[1]->u.string.ptr || strlen(json_params->u.array.values[1]->u.string.ptr) > 32) { if (!json_params->u.array.values[1]->u.string.ptr || strlen(json_params->u.array.values[1]->u.string.ptr) > 32) {
clientlog(client, "bad json, wrong jobid len"); clientlog(client, "bad json, wrong jobid len");
@ -378,15 +378,28 @@ bool client_submit(YAAMP_CLIENT *client, json_value *json_params)
if (json_params->u.array.length == 6) if (json_params->u.array.length == 6)
strncpy(vote, json_params->u.array.values[5]->u.string.ptr, 7); strncpy(vote, json_params->u.array.values[5]->u.string.ptr, 7);
if (g_debuglog_hash) {
debuglog("submit %s (uid %d) %d, %s, %s, %s\n", client->sock->ip, client->userid, jobid, extranonce2, ntime, nonce);
}
string_lower(extranonce2); string_lower(extranonce2);
string_lower(ntime); string_lower(ntime);
string_lower(nonce); string_lower(nonce);
string_lower(vote); string_lower(vote);
if (json_params->u.array.length == 6) {
if (strstr(g_stratum_algo, "phi")) {
// lux optional field, smart contral root hashes (not mandatory on shares submit)
strncpy(extra, json_params->u.array.values[5]->u.string.ptr, 128);
string_lower(extra);
} else {
// heavycoin vote
strncpy(vote, json_params->u.array.values[5]->u.string.ptr, 7);
string_lower(vote);
}
}
if (g_debuglog_hash) {
debuglog("submit %s (uid %d) %d, %s, t=%s, n=%s, extra=%s\n", client->sock->ip, client->userid,
jobid, extranonce2, ntime, nonce, extra);
}
YAAMP_JOB *job = (YAAMP_JOB *)object_find(&g_list_job, jobid, true); YAAMP_JOB *job = (YAAMP_JOB *)object_find(&g_list_job, jobid, true);
if(!job) if(!job)
{ {
@ -413,7 +426,7 @@ bool client_submit(YAAMP_CLIENT *client, json_value *json_params)
if(strcmp(ntime, templ->ntime)) if(strcmp(ntime, templ->ntime))
{ {
if (!ntime_valid_range(ntime)) { if (!ishexa(ntime, 8) || !ntime_valid_range(ntime)) {
client_submit_error(client, job, 23, "Invalid time rolling", extranonce2, ntime, nonce); client_submit_error(client, job, 23, "Invalid time rolling", extranonce2, ntime, nonce);
return true; return true;
} }

View file

@ -333,6 +333,18 @@ YAAMP_JOB_TEMPLATE *coind_create_template(YAAMP_COIND *coind)
} }
} }
const char *sc_root = json_get_string(json_result, "stateroot");
const char *sc_utxo = json_get_string(json_result, "utxoroot");
if (sc_root && sc_utxo) {
// LUX Smart Contracts, 144-bytes block headers
strcpy(&templ->extradata_hex[ 0], sc_root); // 32-bytes hash (64 in hexa)
strcpy(&templ->extradata_hex[64], sc_utxo); // 32-bytes hash too
// same weird byte order as previousblockhash field
ser_string_be2(sc_root, &templ->extradata_be[ 0], 8);
ser_string_be2(sc_utxo, &templ->extradata_be[64], 8);
}
if (strcmp(coind->rpcencoding, "DCR") == 0) { if (strcmp(coind->rpcencoding, "DCR") == 0) {
decred_fix_template(coind, templ, json_result); decred_fix_template(coind, templ, json_result);
} }

View file

@ -24,9 +24,13 @@ struct YAAMP_JOB_TEMPLATE
int created; int created;
char flags[64]; char flags[64];
char prevhash_hex[1024]; char prevhash_hex[512];
char prevhash_be[1024]; char prevhash_be[512];
char extradata_hex[512];
char extradata_be[512];
// todo: can use extra field
char claim_hex[128]; char claim_hex[128];
char claim_be[128]; char claim_be[128];

View file

@ -16,14 +16,22 @@ static void job_mining_notify_buffer(YAAMP_JOB *job, char *buffer)
{ {
YAAMP_JOB_TEMPLATE *templ = job->templ; YAAMP_JOB_TEMPLATE *templ = job->templ;
if (!strcmp(g_current_algo->name, "lbry")) { if (!strcmp(g_stratum_algo, "lbry")) {
sprintf(buffer, "{\"id\":null,\"method\":\"mining.notify\",\"params\":[" sprintf(buffer, "{\"id\":null,\"method\":\"mining.notify\",\"params\":["
"\"%x\",\"%s\",\"%s\",\"%s\",\"%s\",[%s],\"%s\",\"%s\",\"%s\",true]}\n", "\"%x\",\"%s\",\"%s\",\"%s\",\"%s\",[%s],\"%s\",\"%s\",\"%s\",true]}\n",
job->id, templ->prevhash_be, templ->claim_be, templ->coinb1, templ->coinb2, job->id, templ->prevhash_be, templ->claim_be, templ->coinb1, templ->coinb2,
templ->txmerkles, templ->version, templ->nbits, templ->ntime); templ->txmerkles, templ->version, templ->nbits, templ->ntime);
return; return;
} else if (strlen(templ->extradata_hex) == 128) {
// LUX smart contract state hashes (like lbry extra field, here the 2 root hashes in one)
sprintf(buffer, "{\"id\":null,\"method\":\"mining.notify\",\"params\":["
"\"%x\",\"%s\",\"%s\",\"%s\",\"%s\",[%s],\"%s\",\"%s\",\"%s\",true]}\n",
job->id, templ->prevhash_be, templ->extradata_be, templ->coinb1, templ->coinb2,
templ->txmerkles, templ->version, templ->nbits, templ->ntime);
return;
} }
// standard stratum
sprintf(buffer, "{\"id\":null,\"method\":\"mining.notify\",\"params\":[\"%x\",\"%s\",\"%s\",\"%s\",[%s],\"%s\",\"%s\",\"%s\",true]}\n", sprintf(buffer, "{\"id\":null,\"method\":\"mining.notify\",\"params\":[\"%x\",\"%s\",\"%s\",\"%s\",[%s],\"%s\",\"%s\",\"%s\",true]}\n",
job->id, templ->prevhash_be, templ->coinb1, templ->coinb2, templ->txmerkles, templ->version, templ->nbits, templ->ntime); job->id, templ->prevhash_be, templ->coinb1, templ->coinb2, templ->txmerkles, templ->version, templ->nbits, templ->ntime);
} }

View file

@ -62,7 +62,7 @@ void remote_create_job(YAAMP_REMOTE *remote, json_value *json_params)
YAAMP_JOB_TEMPLATE *templ = new YAAMP_JOB_TEMPLATE; YAAMP_JOB_TEMPLATE *templ = new YAAMP_JOB_TEMPLATE;
memset(templ, 0, sizeof(YAAMP_JOB_TEMPLATE)); memset(templ, 0, sizeof(YAAMP_JOB_TEMPLATE));
strncpy(templ->prevhash_be, json_params->u.array.values[1]->u.string.ptr, 1023); strncpy(templ->prevhash_be, json_params->u.array.values[1]->u.string.ptr, sizeof(templ->prevhash_be)-1);
strncpy(templ->coinb1, json_params->u.array.values[2]->u.string.ptr, 1023); strncpy(templ->coinb1, json_params->u.array.values[2]->u.string.ptr, 1023);
strncpy(templ->coinb2, json_params->u.array.values[3]->u.string.ptr, 1023); strncpy(templ->coinb2, json_params->u.array.values[3]->u.string.ptr, 1023);