Browse Source

Add reconnect support by matching enonce1 returned by the session id, reusing it if it exists

master
Con Kolivas 11 years ago
parent
commit
13cd35d776
  1. 72
      src/stratifier.c

72
src/stratifier.c

@ -122,7 +122,7 @@ struct stratum_instance {
int id; int id;
char enonce1[20]; char enonce1[20];
char enonce1bin[8]; uint64_t enonce1_64;
int diff; /* Current diff */ int diff; /* Current diff */
int old_diff; /* Previous diff */ int old_diff; /* Previous diff */
@ -369,19 +369,43 @@ static stratum_instance_t *__instance_by_id(int id)
static stratum_instance_t *__stratum_add_instance(int id) static stratum_instance_t *__stratum_add_instance(int id)
{ {
stratum_instance_t *instance = ckzalloc(sizeof(stratum_instance_t)); stratum_instance_t *instance = ckzalloc(sizeof(stratum_instance_t));
uint64_t *u64;
u64 = (uint64_t *)instance->enonce1bin;
*u64 = htobe64(enonce1_64++);
__bin2hex(instance->enonce1, instance->enonce1bin, 8);
instance->id = id; instance->id = id;
instance->diff = instance->old_diff = 1; instance->diff = instance->old_diff = 1;
tv_time(&instance->ldc); tv_time(&instance->ldc);
LOGDEBUG("Added instance %d with enonce1 %s", id, instance->enonce1); LOGINFO("Added instance %d", id);
HASH_ADD_INT(stratum_instances, id, instance); HASH_ADD_INT(stratum_instances, id, instance);
return instance; return instance;
} }
static bool sessionid_exists(const char *sessionid, int id)
{
stratum_instance_t *instance, *tmp;
uint64_t session64;
bool ret = false;
if (!sessionid)
goto out;
if (strlen(sessionid) != 16)
goto out;
/* Number is in BE but we don't swap either of them */
hex2bin(&session64, sessionid, 8);
ck_rlock(&instance_lock);
HASH_ITER(hh, stratum_instances, instance, tmp) {
if (instance->id == id)
continue;
if (instance->enonce1_64 == session64) {
ret = true;
break;
}
}
ck_runlock(&instance_lock);
out:
return ret;
}
static void stratum_add_recvd(json_t *val) static void stratum_add_recvd(json_t *val)
{ {
stratum_msg_t *msg; stratum_msg_t *msg;
@ -527,7 +551,7 @@ retry:
json_t *val = json_loads(buf, 0, NULL); json_t *val = json_loads(buf, 0, NULL);
if (!val) { if (!val) {
LOGDEBUG("Received unrecognised message: %s", buf); LOGWARNING("Received unrecognised message: %s", buf);
} else } else
stratum_add_recvd(val); stratum_add_recvd(val);
goto retry; goto retry;
@ -557,7 +581,7 @@ static void *blockupdate(void *arg)
buf = send_recv_proc(&ckp->generator, request); buf = send_recv_proc(&ckp->generator, request);
if (buf && strcmp(buf, hash) && strncasecmp(buf, "Failed", 6)) { if (buf && strcmp(buf, hash) && strncasecmp(buf, "Failed", 6)) {
strcpy(hash, buf); strcpy(hash, buf);
LOGINFO("Detected hash change to %s", hash); LOGNOTICE("Block hash changed to %s", hash);
send_proc(&ckp->stratifier, "update"); send_proc(&ckp->stratifier, "update");
} else } else
cksleep_ms(ckp->blockpoll); cksleep_ms(ckp->blockpoll);
@ -565,10 +589,11 @@ static void *blockupdate(void *arg)
return NULL; return NULL;
} }
/* Extranonce1 must be set here */
static json_t *parse_subscribe(int client_id, json_t *params_val) static json_t *parse_subscribe(int client_id, json_t *params_val)
{ {
stratum_instance_t *client = NULL; stratum_instance_t *client = NULL;
char *enonce1; bool old_match = false;
int arr_size; int arr_size;
json_t *ret; json_t *ret;
int n2len; int n2len;
@ -597,20 +622,37 @@ static json_t *parse_subscribe(int client_id, json_t *params_val)
buf = json_string_value(json_array_get(params_val, 1)); buf = json_string_value(json_array_get(params_val, 1));
LOGDEBUG("Found old session id %s", buf); LOGDEBUG("Found old session id %s", buf);
/* Add matching here */ /* Add matching here */
if (sessionid_exists(buf, client_id)) {
hex2bin(&client->enonce1_64, buf, 8);
strcpy(client->enonce1, buf);
old_match = true;
}
} }
} }
enonce1 = strdup(client->enonce1); if (!old_match) {
/* Create a new extranonce1 based on non-endian swapped
* uint64_t pointer */
ck_wlock(&instance_lock);
client->enonce1_64 = enonce1_64++;
ck_wunlock(&instance_lock);
__bin2hex(client->enonce1, &client->enonce1_64, 8);
LOGNOTICE("Set new subscription %d to new enonce1 %s", client->id,
client->enonce1);
} else {
LOGNOTICE("Set new subscription %d to old matched enonce1 %s", client->id,
client->enonce1);
}
ck_rlock(&workbase_lock); ck_rlock(&workbase_lock);
if (likely(workbases)) if (likely(workbases))
n2len = workbases->enonce2varlen; n2len = workbases->enonce2varlen;
else else
n2len = 8; n2len = 8;
ret = json_pack("[[[s,s]],s,i]", "mining.notify", enonce1, enonce1, n2len); ret = json_pack("[[[s,s]],s,i]", "mining.notify", client->enonce1, client->enonce1,
n2len);
ck_runlock(&workbase_lock); ck_runlock(&workbase_lock);
free(enonce1);
return ret; return ret;
} }
@ -649,7 +691,7 @@ static json_t *parse_authorize(stratum_instance_t *client, json_t *params_val, j
*err_val = json_string("User not found"); *err_val = json_string("User not found");
goto out; goto out;
} }
LOGINFO("Authorised user %s", buf); LOGNOTICE("Authorised user %s", buf);
client->workername = strdup(buf); client->workername = strdup(buf);
client->user_id = user_id; client->user_id = user_id;
client->authorised = true; client->authorised = true;
@ -794,7 +836,7 @@ static double submission_diff(stratum_instance_t *client, workbase_t *wb, const
memcpy(coinbase, wb->coinb1bin, wb->coinb1len); memcpy(coinbase, wb->coinb1bin, wb->coinb1len);
cblen += wb->coinb1len; cblen += wb->coinb1len;
memcpy(coinbase + cblen, client->enonce1bin, wb->enonce1varlen); memcpy(coinbase + cblen, &client->enonce1_64, wb->enonce1varlen);
cblen += wb->enonce1varlen; cblen += wb->enonce1varlen;
hex2bin(coinbase + cblen, nonce2, wb->enonce2varlen); hex2bin(coinbase + cblen, nonce2, wb->enonce2varlen);
cblen += wb->enonce2varlen; cblen += wb->enonce2varlen;

Loading…
Cancel
Save