Browse Source

Store the notify data coming from the proxifier to the stratifier and create the basic work templates

master
Con Kolivas 11 years ago
parent
commit
da383b8735
  1. 156
      src/stratifier.c

156
src/stratifier.c

@ -142,10 +142,13 @@ static struct {
double diff; double diff;
char enonce1[32]; char enonce1[32];
uchar enonce1bin[16];
int enonce1constlen;
int nonce2len; int nonce2len;
int subnonce2len; int enonce2constlen;
uint32_t subnonce2; uint32_t subnonce2;
int enonce2varlen;
} proxy_base; } proxy_base;
static uint64_t workbase_id; static uint64_t workbase_id;
@ -340,14 +343,60 @@ static void purge_share_hashtable(uint64_t wb_id)
LOGINFO("Cleared %d shares from share hashtable", purged); LOGINFO("Cleared %d shares from share hashtable", purged);
} }
static void add_base(ckpool_t *ckp, workbase_t *wb, bool *new_block)
{
workbase_t *tmp, *tmpa;
int len, ret;
wb->gentime = time(NULL);
len = strlen(ckp->logdir) + 8 + 1 + 16;
wb->logdir = ckalloc(len);
ck_wlock(&workbase_lock);
wb->id = workbase_id++;
if (strncmp(wb->prevhash, lasthash, 64)) {
*new_block = true;
memcpy(lasthash, wb->prevhash, 65);
blockchange_id = wb->id;
}
if (*new_block) {
sprintf(wb->logdir, "%s%08x/", ckp->logdir, wb->height);
ret = mkdir(wb->logdir, 0700);
if (unlikely(ret && errno != EEXIST))
quit(1, "Failed to create log directory %s", wb->logdir);
}
sprintf(wb->idstring, "%016lx", wb->id);
/* Do not store the trailing slash for the subdir */
sprintf(wb->logdir, "%s%08x/%s", ckp->logdir, wb->height, wb->idstring);
ret = mkdir(wb->logdir, 0700);
if (unlikely(ret && errno != EEXIST))
quit(1, "Failed to create log directory %s", wb->logdir);
HASH_ITER(hh, workbases, tmp, tmpa) {
if (HASH_COUNT(workbases) < 3)
break;
/* Age old workbases older than 10 minutes old */
if (tmp->gentime < wb->gentime - 600) {
HASH_DEL(workbases, tmp);
clear_workbase(tmp);
}
}
HASH_ADD_INT(workbases, id, wb);
current_workbase = wb;
ck_wunlock(&workbase_lock);
if (*new_block)
purge_share_hashtable(wb->id);
}
/* This function assumes it will only receive a valid json gbt base template /* This function assumes it will only receive a valid json gbt base template
* since checking should have been done earlier, and creates the base template * since checking should have been done earlier, and creates the base template
* for generating work templates. */ * for generating work templates. */
static void update_base(ckpool_t *ckp) static void update_base(ckpool_t *ckp)
{ {
workbase_t *wb, *tmp, *tmpa;
bool new_block = false; bool new_block = false;
int len, ret; workbase_t *wb;
json_t *val; json_t *val;
char *buf; char *buf;
@ -396,46 +445,8 @@ static void update_base(ckpool_t *ckp)
} }
json_decref(val); json_decref(val);
generate_coinbase(ckp, wb); generate_coinbase(ckp, wb);
wb->gentime = time(NULL);
len = strlen(ckp->logdir) + 8 + 1 + 16; add_base(ckp, wb, &new_block);
wb->logdir = ckalloc(len);
ck_wlock(&workbase_lock);
wb->id = workbase_id++;
if (strncmp(wb->prevhash, lasthash, 64)) {
new_block = true;
memcpy(lasthash, wb->prevhash, 65);
blockchange_id = wb->id;
}
if (new_block) {
sprintf(wb->logdir, "%s%08x/", ckp->logdir, wb->height);
ret = mkdir(wb->logdir, 0700);
if (unlikely(ret && errno != EEXIST))
quit(1, "Failed to create log directory %s", wb->logdir);
}
sprintf(wb->idstring, "%016lx", wb->id);
/* Do not store the trailing slash for the subdir */
sprintf(wb->logdir, "%s%08x/%s", ckp->logdir, wb->height, wb->idstring);
ret = mkdir(wb->logdir, 0700);
if (unlikely(ret && errno != EEXIST))
quit(1, "Failed to create log directory %s", wb->logdir);
HASH_ITER(hh, workbases, tmp, tmpa) {
if (HASH_COUNT(workbases) < 3)
break;
/* Age old workbases older than 10 minutes old */
if (tmp->gentime < wb->gentime - 600) {
HASH_DEL(workbases, tmp);
clear_workbase(tmp);
}
}
HASH_ADD_INT(workbases, id, wb);
current_workbase = wb;
ck_wunlock(&workbase_lock);
if (new_block)
purge_share_hashtable(wb->id);
stratum_broadcast_update(new_block); stratum_broadcast_update(new_block);
} }
@ -459,11 +470,14 @@ static bool update_subscribe(ckpool_t *ckp)
proxy_base.diff = 1; proxy_base.diff = 1;
/* Length is checked by generator */ /* Length is checked by generator */
strcpy(proxy_base.enonce1, json_string_value(json_object_get(val, "enonce1"))); strcpy(proxy_base.enonce1, json_string_value(json_object_get(val, "enonce1")));
proxy_base.enonce1constlen = strlen(proxy_base.enonce1) / 2;
hex2bin(proxy_base.enonce1bin, proxy_base.enonce1, proxy_base.enonce1constlen);
proxy_base.nonce2len = json_integer_value(json_object_get(val, "nonce2len")); proxy_base.nonce2len = json_integer_value(json_object_get(val, "nonce2len"));
if (proxy_base.nonce2len > 5) if (proxy_base.nonce2len > 5)
proxy_base.subnonce2len = 4; proxy_base.enonce2constlen = 4;
else else
proxy_base.subnonce2len = 2; proxy_base.enonce2constlen = 2;
proxy_base.enonce2varlen = proxy_base.nonce2len - proxy_base.enonce2constlen;
ck_wunlock(&workbase_lock); ck_wunlock(&workbase_lock);
json_decref(val); json_decref(val);
@ -472,15 +486,65 @@ static bool update_subscribe(ckpool_t *ckp)
static void update_notify(ckpool_t *ckp) static void update_notify(ckpool_t *ckp)
{ {
bool new_block = false, clean;
char header[228];
workbase_t *wb;
json_t *val;
char *buf; char *buf;
int i;
buf = send_recv_proc(ckp->generator, "getnotify"); buf = send_recv_proc(ckp->generator, "getnotify");
if (unlikely(!buf)) { if (unlikely(!buf)) {
LOGWARNING("Failed to get notify from generator in update_notify"); LOGWARNING("Failed to get notify from generator in update_notify");
return; return;
} }
LOGWARNING("Notify was %s", buf);
free(buf); LOGDEBUG("Update notify: %s", buf);
wb = ckzalloc(sizeof(workbase_t));
wb->ckp = ckp;
val = json_loads(buf, 0, NULL);
dealloc(buf);
json_uint64cpy(&wb->id, val, "jobid");
json_strcpy(wb->prevhash, val, "prevhash");
json_strcpy(wb->coinb1, val, "coinbase1");
wb->coinb1len = strlen(wb->coinb1) / 2;
hex2bin(wb->coinb1bin, wb->coinb1, wb->coinb1len);
json_strcpy(wb->coinb2, val, "coinbase2");
wb->coinb2len = strlen(wb->coinb2) / 2;
hex2bin(wb->coinb2bin, wb->coinb2, wb->coinb2len);
wb->merkle_array = json_copy(json_object_get(val, "merklehash"));
wb->merkles = json_array_size(wb->merkle_array);
for (i = 0; i < wb->merkles; i++) {
strcpy(&wb->merklehash[i][0], json_string_value(json_array_get(wb->merkle_array, i)));
hex2bin(&wb->merklebin[i][0], &wb->merklehash[i][0], 32);
}
json_strcpy(wb->bbversion, val, "bbversion");
json_strcpy(wb->nbit, val, "nbit");
json_strcpy(wb->ntime, val, "ntime");
clean = json_is_true(json_object_get(val, "clean"));
json_decref(val);
wb->gentime = time(NULL);
wb->enonce1varlen = 0;
snprintf(header, 225, "%s%s%s%s%s%s%s",
wb->bbversion, wb->prevhash,
"0000000000000000000000000000000000000000000000000000000000000000",
wb->ntime, wb->nbit,
"00000000", /* nonce */
workpadding);
LOGDEBUG("Header: %s", header);
hex2bin(wb->headerbin, header, 112);
ck_rlock(&workbase_lock);
strcpy(wb->enonce1const, proxy_base.enonce1);
memcpy(wb->enonce1constbin, proxy_base.enonce1bin, proxy_base.enonce1constlen);
wb->enonce1varlen = wb->enonce2constlen = proxy_base.enonce2constlen;
wb->enonce2varlen = proxy_base.enonce2varlen;
ck_runlock(&workbase_lock);
add_base(ckp, wb, &new_block);
stratum_broadcast_update(new_block | clean);
} }
/* Enter with instance_lock held */ /* Enter with instance_lock held */

Loading…
Cancel
Save