|
|
|
@ -191,7 +191,7 @@ struct user_instance {
|
|
|
|
|
UT_hash_handle hh; |
|
|
|
|
char username[128]; |
|
|
|
|
int64_t id; |
|
|
|
|
bool new_user; |
|
|
|
|
char *secondaryuserid; |
|
|
|
|
|
|
|
|
|
int workers; |
|
|
|
|
}; |
|
|
|
@ -231,7 +231,6 @@ struct stratum_instance {
|
|
|
|
|
user_instance_t *user_instance; |
|
|
|
|
char *useragent; |
|
|
|
|
char *workername; |
|
|
|
|
char *secondaryuserid; |
|
|
|
|
int64_t user_id; |
|
|
|
|
|
|
|
|
|
ckpool_t *ckp; |
|
|
|
@ -433,11 +432,15 @@ static void _ckdbq_add(ckpool_t *ckp, const int idtype, json_t *val, const char
|
|
|
|
|
{ |
|
|
|
|
static time_t time_counter; |
|
|
|
|
static int counter = 0; |
|
|
|
|
|
|
|
|
|
char *json_msg; |
|
|
|
|
time_t now_t; |
|
|
|
|
char ch; |
|
|
|
|
|
|
|
|
|
if (unlikely(!val)) { |
|
|
|
|
LOGWARNING("Invalid json sent to ckdbq_add from %s %s:%d", file, func, line); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
now_t = time(NULL); |
|
|
|
|
if (now_t != time_counter) { |
|
|
|
|
/* Rate limit to 1 update per second */ |
|
|
|
@ -447,11 +450,6 @@ static void _ckdbq_add(ckpool_t *ckp, const int idtype, json_t *val, const char
|
|
|
|
|
fflush(stdout); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!val) { |
|
|
|
|
LOGWARNING("Invalid json sent to ckdbq_add from %s %s:%d", file, func, line); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (ckp->standalone) |
|
|
|
|
return json_decref(val); |
|
|
|
|
|
|
|
|
@ -473,7 +471,7 @@ static void send_workinfo(ckpool_t *ckp, workbase_t *wb)
|
|
|
|
|
|
|
|
|
|
sprintf(cdfield, "%lu,%lu", wb->gentime.tv_sec, wb->gentime.tv_nsec); |
|
|
|
|
|
|
|
|
|
val = json_pack("{sI,ss,ss,ss,ss,ss,ss,ss,ss,sI,so,ss,ss,ss,ss}", |
|
|
|
|
JSON_CPACK(val, "{sI,ss,ss,ss,ss,ss,ss,ss,ss,sI,so,ss,ss,ss,ss}", |
|
|
|
|
"workinfoid", wb->id, |
|
|
|
|
"poolinstance", ckp->name, |
|
|
|
|
"transactiontree", wb->txn_hashes, |
|
|
|
@ -501,7 +499,7 @@ static void send_ageworkinfo(ckpool_t *ckp, int64_t id)
|
|
|
|
|
ts_realtime(&ts_now); |
|
|
|
|
sprintf(cdfield, "%lu,%lu", ts_now.tv_sec, ts_now.tv_nsec); |
|
|
|
|
|
|
|
|
|
val = json_pack("{sI,ss,ss,ss,ss,ss}", |
|
|
|
|
JSON_CPACK(val, "{sI,ss,ss,ss,ss,ss}", |
|
|
|
|
"workinfoid", id, |
|
|
|
|
"poolinstance", ckp->name, |
|
|
|
|
"createdate", cdfield, |
|
|
|
@ -966,7 +964,7 @@ static void stratum_broadcast_message(const char *msg)
|
|
|
|
|
{ |
|
|
|
|
json_t *json_msg; |
|
|
|
|
|
|
|
|
|
json_msg = json_pack("{sosss[s]}", "id", json_null(), "method", "client.show_message", |
|
|
|
|
JSON_CPACK(json_msg, "{sosss[s]}", "id", json_null(), "method", "client.show_message", |
|
|
|
|
"params", msg); |
|
|
|
|
stratum_broadcast(json_msg); |
|
|
|
|
} |
|
|
|
@ -985,7 +983,7 @@ static void block_solve(ckpool_t *ckp)
|
|
|
|
|
ASPRINTF(&msg, "Block %d solved by %s!", current_workbase->height, ckp->name); |
|
|
|
|
/* We send blank settings to ckdb with only the matching data from what we submitted
|
|
|
|
|
* to say the block has been confirmed. */ |
|
|
|
|
val = json_pack("{si,ss,sI,ss,ss,si,ss,ss,ss,sI,ss,ss,ss,ss}", |
|
|
|
|
JSON_CPACK(val, "{si,ss,sI,ss,ss,si,ss,ss,ss,sI,ss,ss,ss,ss}", |
|
|
|
|
"height", current_workbase->height, |
|
|
|
|
"confirmed", "1", |
|
|
|
|
"workinfoid", current_workbase->id, |
|
|
|
@ -1226,7 +1224,7 @@ static json_t *parse_subscribe(int64_t client_id, json_t *params_val)
|
|
|
|
|
n2len = workbases->enonce2varlen; |
|
|
|
|
else |
|
|
|
|
n2len = 8; |
|
|
|
|
ret = json_pack("[[[s,s]],s,i]", "mining.notify", client->enonce1, client->enonce1, |
|
|
|
|
JSON_CPACK(ret, "[[[s,s]],s,i]", "mining.notify", client->enonce1, client->enonce1, |
|
|
|
|
n2len); |
|
|
|
|
ck_runlock(&workbase_lock); |
|
|
|
|
|
|
|
|
@ -1248,10 +1246,9 @@ static user_instance_t *authorise_user(const char *workername)
|
|
|
|
|
ck_ilock(&instance_lock); |
|
|
|
|
HASH_FIND_STR(user_instances, username, instance); |
|
|
|
|
if (!instance) { |
|
|
|
|
/* New user instance */ |
|
|
|
|
/* New user instance. Secondary user id will be NULL */ |
|
|
|
|
instance = ckzalloc(sizeof(user_instance_t)); |
|
|
|
|
strcpy(instance->username, username); |
|
|
|
|
instance->new_user = true; |
|
|
|
|
|
|
|
|
|
ck_ulock(&instance_lock); |
|
|
|
|
instance->id = user_instance_id++; |
|
|
|
@ -1269,6 +1266,7 @@ static user_instance_t *authorise_user(const char *workername)
|
|
|
|
|
* thread so it won't hold anything up but other authorisations. */ |
|
|
|
|
static int send_recv_auth(stratum_instance_t *client) |
|
|
|
|
{ |
|
|
|
|
user_instance_t *user_instance = client->user_instance; |
|
|
|
|
ckpool_t *ckp = client->ckp; |
|
|
|
|
char *buf, *json_msg; |
|
|
|
|
char cdfield[64]; |
|
|
|
@ -1279,8 +1277,8 @@ static int send_recv_auth(stratum_instance_t *client)
|
|
|
|
|
ts_realtime(&now); |
|
|
|
|
sprintf(cdfield, "%lu,%lu", now.tv_sec, now.tv_nsec); |
|
|
|
|
|
|
|
|
|
val = json_pack("{ss,ss,ss,ss,sI,ss,sb,ss,ss,ss,ss}", |
|
|
|
|
"username", client->user_instance->username, |
|
|
|
|
JSON_CPACK(val, "{ss,ss,ss,ss,sI,ss,sb,ss,ss,ss,ss}", |
|
|
|
|
"username", user_instance->username, |
|
|
|
|
"workername", client->workername, |
|
|
|
|
"poolinstance", ckp->name, |
|
|
|
|
"useragent", client->useragent, |
|
|
|
@ -1305,10 +1303,11 @@ static int send_recv_auth(stratum_instance_t *client)
|
|
|
|
|
secondaryuserid = response; |
|
|
|
|
strsep(&secondaryuserid, "."); |
|
|
|
|
LOGINFO("User %s Worker %s got auth response: %s suid: %s", |
|
|
|
|
client->user_instance->username, client->workername, |
|
|
|
|
user_instance->username, client->workername, |
|
|
|
|
response, secondaryuserid); |
|
|
|
|
if (!safecmp(response, "ok") && secondaryuserid) { |
|
|
|
|
client->secondaryuserid = strdup(secondaryuserid); |
|
|
|
|
if (!user_instance->secondaryuserid) |
|
|
|
|
user_instance->secondaryuserid = strdup(secondaryuserid); |
|
|
|
|
ret = 0; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
@ -1332,7 +1331,7 @@ static void queue_delayed_auth(stratum_instance_t *client)
|
|
|
|
|
ts_realtime(&now); |
|
|
|
|
sprintf(cdfield, "%lu,%lu", now.tv_sec, now.tv_nsec); |
|
|
|
|
|
|
|
|
|
val = json_pack("{ss,ss,ss,ss,sI,ss,sb,ss,ss,ss,ss}", |
|
|
|
|
JSON_CPACK(val, "{ss,ss,ss,ss,sI,ss,sb,ss,ss,ss,ss}", |
|
|
|
|
"username", client->user_instance->username, |
|
|
|
|
"workername", client->workername, |
|
|
|
|
"poolinstance", ckp->name, |
|
|
|
@ -1393,7 +1392,7 @@ static json_t *parse_authorise(stratum_instance_t *client, json_t *params_val, j
|
|
|
|
|
*errnum = send_recv_auth(client); |
|
|
|
|
if (!*errnum) |
|
|
|
|
ret = true; |
|
|
|
|
else if (*errnum < 0 && !user_instance->new_user) { |
|
|
|
|
else if (*errnum < 0 && user_instance->secondaryuserid) { |
|
|
|
|
/* This user has already been authorised but ckdb is
|
|
|
|
|
* offline so we assume they already exist but add the |
|
|
|
|
* auth request to the queued messages. */ |
|
|
|
@ -1402,10 +1401,8 @@ static json_t *parse_authorise(stratum_instance_t *client, json_t *params_val, j
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
client->authorised = ret; |
|
|
|
|
if (client->authorised) { |
|
|
|
|
if (client->authorised) |
|
|
|
|
inc_worker(user_instance); |
|
|
|
|
user_instance->new_user = false; |
|
|
|
|
} |
|
|
|
|
out: |
|
|
|
|
return json_boolean(ret); |
|
|
|
|
} |
|
|
|
@ -1414,7 +1411,7 @@ static void stratum_send_diff(stratum_instance_t *client)
|
|
|
|
|
{ |
|
|
|
|
json_t *json_msg; |
|
|
|
|
|
|
|
|
|
json_msg = json_pack("{s[I]soss}", "params", client->diff, "id", json_null(), |
|
|
|
|
JSON_CPACK(json_msg, "{s[I]soss}", "params", client->diff, "id", json_null(), |
|
|
|
|
"method", "mining.set_difficulty"); |
|
|
|
|
stratum_add_send(json_msg, client->id); |
|
|
|
|
} |
|
|
|
@ -1423,7 +1420,7 @@ static void stratum_send_message(stratum_instance_t *client, const char *msg)
|
|
|
|
|
{ |
|
|
|
|
json_t *json_msg; |
|
|
|
|
|
|
|
|
|
json_msg = json_pack("{sosss[s]}", "id", json_null(), "method", "client.show_message", |
|
|
|
|
JSON_CPACK(json_msg, "{sosss[s]}", "id", json_null(), "method", "client.show_message", |
|
|
|
|
"params", msg); |
|
|
|
|
stratum_add_send(json_msg, client->id); |
|
|
|
|
} |
|
|
|
@ -1587,7 +1584,7 @@ test_blocksolve(stratum_instance_t *client, workbase_t *wb, const uchar *data, c
|
|
|
|
|
|
|
|
|
|
flip_32(swap, hash); |
|
|
|
|
__bin2hex(blockhash, swap, 32); |
|
|
|
|
val = json_pack("{si,ss,ss,sI,ss,ss,sI,ss,ss,ss,sI,ss,ss,ss,ss}", |
|
|
|
|
JSON_CPACK(val, "{si,ss,ss,sI,ss,ss,sI,ss,ss,ss,sI,ss,ss,ss,ss}", |
|
|
|
|
"height", wb->height, |
|
|
|
|
"blockhash", blockhash, |
|
|
|
|
"confirmed", "n", |
|
|
|
@ -1698,7 +1695,7 @@ static void submit_share(stratum_instance_t *client, int64_t jobid, const char *
|
|
|
|
|
char *msg; |
|
|
|
|
|
|
|
|
|
sprintf(enonce2, "%s%s", client->enonce1var, nonce2); |
|
|
|
|
json_msg = json_pack("{sisssssssIsi}", "jobid", jobid, "nonce2", enonce2, |
|
|
|
|
JSON_CPACK(json_msg, "{sisssssssIsi}", "jobid", jobid, "nonce2", enonce2, |
|
|
|
|
"ntime", ntime, "nonce", nonce, "client_id", client->id, |
|
|
|
|
"msg_id", msg_id); |
|
|
|
|
msg = json_dumps(json_msg, 0); |
|
|
|
@ -1713,6 +1710,7 @@ static json_t *parse_submit(stratum_instance_t *client, json_t *json_msg,
|
|
|
|
|
json_t *params_val, json_t **err_val) |
|
|
|
|
{ |
|
|
|
|
bool share = false, result = false, invalid = true, submit = false; |
|
|
|
|
user_instance_t *user_instance = client->user_instance; |
|
|
|
|
const char *user, *job_id, *nonce2, *ntime, *nonce; |
|
|
|
|
double diff = client->diff, wdiff = 0, sdiff = -1; |
|
|
|
|
char hexhash[68] = {}, sharehash[32], cdfield[64]; |
|
|
|
@ -1856,7 +1854,7 @@ out_unlock:
|
|
|
|
|
json_set_int(val, "workinfoid", id); |
|
|
|
|
json_set_int(val, "clientid", client->id); |
|
|
|
|
json_set_string(val, "enonce1", client->enonce1); |
|
|
|
|
json_set_string(val, "secondaryuserid", client->secondaryuserid); |
|
|
|
|
json_set_string(val, "secondaryuserid", user_instance->secondaryuserid); |
|
|
|
|
json_set_string(val, "nonce2", nonce2); |
|
|
|
|
json_set_string(val, "nonce", nonce); |
|
|
|
|
json_set_string(val, "ntime", ntime); |
|
|
|
@ -1872,7 +1870,7 @@ out_unlock:
|
|
|
|
|
json_set_string(val, "createcode", __func__); |
|
|
|
|
json_set_string(val, "createinet", ckp->serverurl); |
|
|
|
|
json_set_string(val, "workername", client->workername); |
|
|
|
|
json_set_string(val, "username", client->user_instance->username); |
|
|
|
|
json_set_string(val, "username", user_instance->username); |
|
|
|
|
|
|
|
|
|
if (ckp->logshares) { |
|
|
|
|
fp = fopen(fname, "a"); |
|
|
|
@ -1890,13 +1888,13 @@ out_unlock:
|
|
|
|
|
ckdbq_add(ckp, ID_SHARES, val); |
|
|
|
|
out: |
|
|
|
|
if (!share) { |
|
|
|
|
val = json_pack("{sI,ss,ss,sI,ss,ss,so,si,ss,ss,ss,ss}", |
|
|
|
|
JSON_CPACK(val, "{sI,ss,ss,sI,ss,ss,so,si,ss,ss,ss,ss}", |
|
|
|
|
"clientid", client->id, |
|
|
|
|
"secondaryuserid", client->secondaryuserid, |
|
|
|
|
"secondaryuserid", user_instance->secondaryuserid, |
|
|
|
|
"enonce1", client->enonce1, |
|
|
|
|
"workinfoid", current_workbase->id, |
|
|
|
|
"workername", client->workername, |
|
|
|
|
"username", client->user_instance->username, |
|
|
|
|
"username", user_instance->username, |
|
|
|
|
"error", json_copy(*err_val), |
|
|
|
|
"errn", err, |
|
|
|
|
"createdate", cdfield, |
|
|
|
@ -1915,7 +1913,7 @@ static json_t *__stratum_notify(bool clean)
|
|
|
|
|
{ |
|
|
|
|
json_t *val; |
|
|
|
|
|
|
|
|
|
val = json_pack("{s:[ssssosssb],s:o,s:s}", |
|
|
|
|
JSON_CPACK(val, "{s:[ssssosssb],s:o,s:s}", |
|
|
|
|
"params", |
|
|
|
|
current_workbase->idstring, |
|
|
|
|
current_workbase->prevhash, |
|
|
|
@ -1958,7 +1956,7 @@ static void send_json_err(int64_t client_id, json_t *id_val, const char *err_msg
|
|
|
|
|
{ |
|
|
|
|
json_t *val; |
|
|
|
|
|
|
|
|
|
val = json_pack("{soss}", "id", json_copy(id_val), "error", err_msg); |
|
|
|
|
JSON_CPACK(val, "{soss}", "id", json_copy(id_val), "error", err_msg); |
|
|
|
|
stratum_add_send(val, client_id); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -2318,7 +2316,7 @@ static void update_userstats(ckpool_t *ckp)
|
|
|
|
|
ghs5 = client->dsps5 * nonces; |
|
|
|
|
ghs60 = client->dsps60 * nonces; |
|
|
|
|
ghs1440 = client->dsps1440 * nonces; |
|
|
|
|
val = json_pack("{ss,sI,si,ss,ss,sf,sf,sf,sf,sb,ss,ss,ss,ss}", |
|
|
|
|
JSON_CPACK(val, "{ss,sI,si,ss,ss,sf,sf,sf,sf,sb,ss,ss,ss,ss}", |
|
|
|
|
"poolinstance", ckp->name, |
|
|
|
|
"instanceid", client->id, |
|
|
|
|
"elapsed", elapsed, |
|
|
|
@ -2406,7 +2404,7 @@ static void *statsupdate(void *arg)
|
|
|
|
|
if (unlikely(!fp)) |
|
|
|
|
LOGERR("Failed to fopen %s", fname); |
|
|
|
|
|
|
|
|
|
val = json_pack("{si,si,si}", |
|
|
|
|
JSON_CPACK(val, "{si,si,si}", |
|
|
|
|
"runtime", diff.tv_sec, |
|
|
|
|
"Users", stats.users, |
|
|
|
|
"Workers", stats.workers); |
|
|
|
@ -2416,7 +2414,7 @@ static void *statsupdate(void *arg)
|
|
|
|
|
fprintf(fp, "%s\n", s); |
|
|
|
|
dealloc(s); |
|
|
|
|
|
|
|
|
|
val = json_pack("{ss,ss,ss,ss,ss,ss}", |
|
|
|
|
JSON_CPACK(val, "{ss,ss,ss,ss,ss,ss}", |
|
|
|
|
"hashrate1m", suffix1, |
|
|
|
|
"hashrate5m", suffix5, |
|
|
|
|
"hashrate15m", suffix15, |
|
|
|
@ -2429,7 +2427,7 @@ static void *statsupdate(void *arg)
|
|
|
|
|
fprintf(fp, "%s\n", s); |
|
|
|
|
dealloc(s); |
|
|
|
|
|
|
|
|
|
val = json_pack("{sf,sf,sf,sf}", |
|
|
|
|
JSON_CPACK(val, "{sf,sf,sf,sf}", |
|
|
|
|
"SPS1m", sps1, |
|
|
|
|
"SPS5m", sps5, |
|
|
|
|
"SPS15m", sps15, |
|
|
|
@ -2469,7 +2467,7 @@ static void *statsupdate(void *arg)
|
|
|
|
|
ghs = client->dsps1440 * nonces; |
|
|
|
|
suffix_string(ghs, suffix1440, 16, 0); |
|
|
|
|
|
|
|
|
|
val = json_pack("{ss,ss,ss,ss}", |
|
|
|
|
JSON_CPACK(val, "{ss,ss,ss,ss}", |
|
|
|
|
"hashrate1m", suffix1, |
|
|
|
|
"hashrate5m", suffix5, |
|
|
|
|
"hashrate1hr", suffix60, |
|
|
|
@ -2495,7 +2493,7 @@ static void *statsupdate(void *arg)
|
|
|
|
|
|
|
|
|
|
ts_realtime(&ts_now); |
|
|
|
|
sprintf(cdfield, "%lu,%lu", ts_now.tv_sec, ts_now.tv_nsec); |
|
|
|
|
val = json_pack("{ss,si,si,si,sf,sf,sf,sf,ss,ss,ss,ss}", |
|
|
|
|
JSON_CPACK(val, "{ss,si,si,si,sf,sf,sf,sf,ss,ss,ss,ss}", |
|
|
|
|
"poolinstance", ckp->name, |
|
|
|
|
"elapsed", diff.tv_sec, |
|
|
|
|
"users", stats.users, |
|
|
|
|