|
|
@ -1517,6 +1517,8 @@ static void submit_share(stratum_instance_t *client, int64_t jobid, const char * |
|
|
|
free(msg); |
|
|
|
free(msg); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define JSON_ERR(err) json_string(SHARE_ERR(err)) |
|
|
|
|
|
|
|
|
|
|
|
static json_t *parse_submit(stratum_instance_t *client, json_t *json_msg, |
|
|
|
static json_t *parse_submit(stratum_instance_t *client, json_t *json_msg, |
|
|
|
json_t *params_val, json_t **err_val) |
|
|
|
json_t *params_val, json_t **err_val) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -1524,6 +1526,7 @@ static json_t *parse_submit(stratum_instance_t *client, json_t *json_msg, |
|
|
|
char hexhash[68] = {}, sharehash[32], cdfield[64], *logdir; |
|
|
|
char hexhash[68] = {}, sharehash[32], cdfield[64], *logdir; |
|
|
|
const char *user, *job_id, *nonce2, *ntime, *nonce; |
|
|
|
const char *user, *job_id, *nonce2, *ntime, *nonce; |
|
|
|
double diff, wdiff = 0, sdiff = -1; |
|
|
|
double diff, wdiff = 0, sdiff = -1; |
|
|
|
|
|
|
|
enum share_err err = SE_NONE; |
|
|
|
char idstring[20]; |
|
|
|
char idstring[20]; |
|
|
|
uint32_t ntime32; |
|
|
|
uint32_t ntime32; |
|
|
|
char *fname, *s; |
|
|
|
char *fname, *s; |
|
|
@ -1539,40 +1542,48 @@ static json_t *parse_submit(stratum_instance_t *client, json_t *json_msg, |
|
|
|
sprintf(cdfield, "%lu.%lu", now.tv_sec, now.tv_nsec); |
|
|
|
sprintf(cdfield, "%lu.%lu", now.tv_sec, now.tv_nsec); |
|
|
|
|
|
|
|
|
|
|
|
if (unlikely(!json_is_array(params_val))) { |
|
|
|
if (unlikely(!json_is_array(params_val))) { |
|
|
|
*err_val = json_string("params not an array"); |
|
|
|
err = SE_NOT_ARRAY; |
|
|
|
|
|
|
|
*err_val = JSON_ERR(err); |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
} |
|
|
|
if (unlikely(json_array_size(params_val) != 5)) { |
|
|
|
if (unlikely(json_array_size(params_val) != 5)) { |
|
|
|
*err_val = json_string("Invalid array size"); |
|
|
|
err = SE_INVALID_SIZE; |
|
|
|
|
|
|
|
*err_val = JSON_ERR(err); |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
} |
|
|
|
user = json_string_value(json_array_get(params_val, 0)); |
|
|
|
user = json_string_value(json_array_get(params_val, 0)); |
|
|
|
if (unlikely(!user || !strlen(user))) { |
|
|
|
if (unlikely(!user || !strlen(user))) { |
|
|
|
*err_val = json_string("No username"); |
|
|
|
err = SE_NO_USERNAME; |
|
|
|
|
|
|
|
*err_val = JSON_ERR(err); |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
} |
|
|
|
job_id = json_string_value(json_array_get(params_val, 1)); |
|
|
|
job_id = json_string_value(json_array_get(params_val, 1)); |
|
|
|
if (unlikely(!job_id || !strlen(job_id))) { |
|
|
|
if (unlikely(!job_id || !strlen(job_id))) { |
|
|
|
*err_val = json_string("No job_id"); |
|
|
|
err = SE_NO_JOBID; |
|
|
|
|
|
|
|
*err_val = JSON_ERR(err); |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
} |
|
|
|
nonce2 = json_string_value(json_array_get(params_val, 2)); |
|
|
|
nonce2 = json_string_value(json_array_get(params_val, 2)); |
|
|
|
if (unlikely(!nonce2 || !strlen(nonce2))) { |
|
|
|
if (unlikely(!nonce2 || !strlen(nonce2))) { |
|
|
|
*err_val = json_string("No nonce2"); |
|
|
|
err = SE_NO_NONCE2; |
|
|
|
|
|
|
|
*err_val = JSON_ERR(err); |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
} |
|
|
|
ntime = json_string_value(json_array_get(params_val, 3)); |
|
|
|
ntime = json_string_value(json_array_get(params_val, 3)); |
|
|
|
if (unlikely(!ntime || !strlen(ntime))) { |
|
|
|
if (unlikely(!ntime || !strlen(ntime))) { |
|
|
|
*err_val = json_string("No ntime"); |
|
|
|
err = SE_NO_NTIME; |
|
|
|
|
|
|
|
*err_val = JSON_ERR(err); |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
} |
|
|
|
nonce = json_string_value(json_array_get(params_val, 4)); |
|
|
|
nonce = json_string_value(json_array_get(params_val, 4)); |
|
|
|
if (unlikely(!nonce || !strlen(nonce))) { |
|
|
|
if (unlikely(!nonce || !strlen(nonce))) { |
|
|
|
*err_val = json_string("No nonce"); |
|
|
|
err = SE_NO_NONCE; |
|
|
|
|
|
|
|
*err_val = JSON_ERR(err); |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
} |
|
|
|
if (strcmp(user, client->workername)) { |
|
|
|
if (strcmp(user, client->workername)) { |
|
|
|
*err_val = json_string("Worker mismatch"); |
|
|
|
err = SE_WORKER_MISMATCH; |
|
|
|
|
|
|
|
*err_val = JSON_ERR(err); |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
} |
|
|
|
sscanf(job_id, "%lx", &id); |
|
|
|
sscanf(job_id, "%lx", &id); |
|
|
@ -1583,7 +1594,8 @@ static json_t *parse_submit(stratum_instance_t *client, json_t *json_msg, |
|
|
|
ck_rlock(&workbase_lock); |
|
|
|
ck_rlock(&workbase_lock); |
|
|
|
HASH_FIND_INT(workbases, &id, wb); |
|
|
|
HASH_FIND_INT(workbases, &id, wb); |
|
|
|
if (unlikely(!wb)) { |
|
|
|
if (unlikely(!wb)) { |
|
|
|
json_set_string(json_msg, "reject-reason", "Invalid JobID"); |
|
|
|
err = SE_INVALID_JOBID; |
|
|
|
|
|
|
|
json_set_string(json_msg, "reject-reason", SHARE_ERR(err)); |
|
|
|
strcpy(idstring, job_id); |
|
|
|
strcpy(idstring, job_id); |
|
|
|
logdir = current_workbase->logdir; |
|
|
|
logdir = current_workbase->logdir; |
|
|
|
goto out_unlock; |
|
|
|
goto out_unlock; |
|
|
@ -1596,16 +1608,19 @@ static json_t *parse_submit(stratum_instance_t *client, json_t *json_msg, |
|
|
|
__bin2hex(hexhash, sharehash, 32); |
|
|
|
__bin2hex(hexhash, sharehash, 32); |
|
|
|
|
|
|
|
|
|
|
|
if (id < blockchange_id) { |
|
|
|
if (id < blockchange_id) { |
|
|
|
json_set_string(json_msg, "reject-reason", "Stale"); |
|
|
|
err = SE_STALE; |
|
|
|
|
|
|
|
json_set_string(json_msg, "reject-reason", SHARE_ERR(err)); |
|
|
|
goto out_unlock; |
|
|
|
goto out_unlock; |
|
|
|
} |
|
|
|
} |
|
|
|
if ((int)strlen(nonce2) != wb->enonce2varlen * 2) { |
|
|
|
if ((int)strlen(nonce2) != wb->enonce2varlen * 2) { |
|
|
|
*err_val = json_string("Invalid nonce2 length"); |
|
|
|
err = SE_INVALID_NONCE2; |
|
|
|
|
|
|
|
*err_val = JSON_ERR(err); |
|
|
|
goto out_unlock; |
|
|
|
goto out_unlock; |
|
|
|
} |
|
|
|
} |
|
|
|
/* Ntime cannot be less, but allow forward ntime rolling up to max */ |
|
|
|
/* Ntime cannot be less, but allow forward ntime rolling up to max */ |
|
|
|
if (ntime32 < wb->ntime32 || ntime32 > wb->ntime32 + 7000) { |
|
|
|
if (ntime32 < wb->ntime32 || ntime32 > wb->ntime32 + 7000) { |
|
|
|
json_set_string(json_msg, "reject-reason", "Ntime out of range"); |
|
|
|
err = SE_NTIME_INVALID; |
|
|
|
|
|
|
|
json_set_string(json_msg, "reject-reason", SHARE_ERR(err)); |
|
|
|
goto out_unlock; |
|
|
|
goto out_unlock; |
|
|
|
} |
|
|
|
} |
|
|
|
invalid = false; |
|
|
|
invalid = false; |
|
|
@ -1632,14 +1647,16 @@ out_unlock: |
|
|
|
client->id, sdiff, diff, wdiffsuffix, hexhash); |
|
|
|
client->id, sdiff, diff, wdiffsuffix, hexhash); |
|
|
|
result = true; |
|
|
|
result = true; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
json_set_string(json_msg, "reject-reason", "Duplicate"); |
|
|
|
err = SE_DUPE; |
|
|
|
|
|
|
|
json_set_string(json_msg, "reject-reason", SHARE_ERR(err)); |
|
|
|
LOGINFO("Rejected client %d dupe diff %.1f/%.0f/%s: %s", |
|
|
|
LOGINFO("Rejected client %d dupe diff %.1f/%.0f/%s: %s", |
|
|
|
client->id, sdiff, diff, wdiffsuffix, hexhash); |
|
|
|
client->id, sdiff, diff, wdiffsuffix, hexhash); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
err = SE_HIGH_DIFF; |
|
|
|
LOGINFO("Rejected client %d high diff %.1f/%.0f/%s: %s", |
|
|
|
LOGINFO("Rejected client %d high diff %.1f/%.0f/%s: %s", |
|
|
|
client->id, sdiff, diff, wdiffsuffix, hexhash); |
|
|
|
client->id, sdiff, diff, wdiffsuffix, hexhash); |
|
|
|
json_set_string(json_msg, "reject-reason", "Above target"); |
|
|
|
json_set_string(json_msg, "reject-reason", SHARE_ERR(err)); |
|
|
|
} |
|
|
|
} |
|
|
|
} else |
|
|
|
} else |
|
|
|
LOGINFO("Rejected client %d invalid share", client->id); |
|
|
|
LOGINFO("Rejected client %d invalid share", client->id); |
|
|
|