|
|
|
@ -149,6 +149,18 @@ static stratum_instance_t *stratum_instances;
|
|
|
|
|
|
|
|
|
|
static cklock_t instance_lock; |
|
|
|
|
|
|
|
|
|
struct share { |
|
|
|
|
UT_hash_handle hh; |
|
|
|
|
char hash[32]; |
|
|
|
|
int workbase_id; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
typedef struct share share_t; |
|
|
|
|
|
|
|
|
|
static share_t *shares; |
|
|
|
|
|
|
|
|
|
static cklock_t share_lock; |
|
|
|
|
|
|
|
|
|
/* No error checking with these, make sure we know they're valid already! */ |
|
|
|
|
static inline void json_strcpy(char *buf, json_t *val, const char *key) |
|
|
|
|
{ |
|
|
|
@ -780,9 +792,9 @@ static void add_submit_success(stratum_instance_t *client, int diff)
|
|
|
|
|
add_submit(client, diff); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void add_submit_fail(stratum_instance_t *client, int diff) |
|
|
|
|
static void add_submit_fail(stratum_instance_t __maybe_unused *client) |
|
|
|
|
{ |
|
|
|
|
add_submit(client, diff); |
|
|
|
|
/* FIXME Do something here? */ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* We should already be holding the workbase_lock */ |
|
|
|
@ -825,7 +837,7 @@ static void test_blocksolve(workbase_t *wb, const uchar *data, double diff, cons
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static double submission_diff(stratum_instance_t *client, workbase_t *wb, const char *nonce2, |
|
|
|
|
uint32_t ntime32, const char *nonce) |
|
|
|
|
uint32_t ntime32, const char *nonce, char *return_hash) |
|
|
|
|
{ |
|
|
|
|
unsigned char merkle_root[32], merkle_sha[64]; |
|
|
|
|
char coinbase[256], data[80], share[68]; |
|
|
|
@ -881,9 +893,8 @@ static double submission_diff(stratum_instance_t *client, workbase_t *wb, const
|
|
|
|
|
test_blocksolve(wb, swap, ret, coinbase, cblen); |
|
|
|
|
|
|
|
|
|
/* Generate hex string of hash for logging */ |
|
|
|
|
data32 = (uint32_t *)hash1; |
|
|
|
|
bswap_256(hash1, hash); |
|
|
|
|
__bin2hex(share, hash1, 32); |
|
|
|
|
bswap_256(return_hash, hash); |
|
|
|
|
__bin2hex(share, return_hash, 32); |
|
|
|
|
|
|
|
|
|
LOGINFO("Client %d share diff %.1f : %s", client->id, ret, share); |
|
|
|
|
|
|
|
|
@ -891,15 +902,38 @@ static double submission_diff(stratum_instance_t *client, workbase_t *wb, const
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static bool new_share(const char *hash, int wb_id) |
|
|
|
|
{ |
|
|
|
|
share_t *share, *match = NULL; |
|
|
|
|
bool ret = false; |
|
|
|
|
|
|
|
|
|
ck_ilock(&share_lock); |
|
|
|
|
HASH_FIND(hh, shares, hash, 32, match); |
|
|
|
|
if (match) |
|
|
|
|
goto out_unlock; |
|
|
|
|
share = ckzalloc(sizeof(share_t)); |
|
|
|
|
memcpy(share->hash, hash, 32); |
|
|
|
|
share->workbase_id = wb_id; |
|
|
|
|
ck_ulock(&share_lock); |
|
|
|
|
HASH_ADD(hh, shares, hash, 32, share); |
|
|
|
|
ck_dwilock(&share_lock); |
|
|
|
|
ret = true; |
|
|
|
|
out_unlock: |
|
|
|
|
ck_uilock(&share_lock); |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static json_t *parse_submit(stratum_instance_t *client, json_t *json_msg, |
|
|
|
|
json_t *params_val, json_t **err_val) |
|
|
|
|
{ |
|
|
|
|
const char *user, *job_id, *nonce2, *ntime, *nonce; |
|
|
|
|
int diff, id, wb_id = 0; |
|
|
|
|
double sdiff = -1; |
|
|
|
|
uint32_t ntime32; |
|
|
|
|
bool ret = false; |
|
|
|
|
workbase_t *wb; |
|
|
|
|
int diff, id; |
|
|
|
|
char hash[32]; |
|
|
|
|
|
|
|
|
|
if (unlikely(!json_is_array(params_val))) { |
|
|
|
|
*err_val = json_string("params not an array"); |
|
|
|
@ -960,8 +994,9 @@ static json_t *parse_submit(stratum_instance_t *client, json_t *json_msg,
|
|
|
|
|
json_object_set_nocheck(json_msg, "reject-reason", json_string("Ntime out of range")); |
|
|
|
|
goto out_unlock; |
|
|
|
|
} |
|
|
|
|
sdiff = submission_diff(client, wb, nonce2, ntime32, nonce); |
|
|
|
|
sdiff = submission_diff(client, wb, nonce2, ntime32, nonce, hash); |
|
|
|
|
out_unlock: |
|
|
|
|
wb_id = workbase_id; |
|
|
|
|
ck_runlock(&workbase_lock); |
|
|
|
|
|
|
|
|
|
/* Accept the lower of new and old diffs until the next update */ |
|
|
|
@ -970,10 +1005,15 @@ out_unlock:
|
|
|
|
|
else |
|
|
|
|
diff = client->diff; |
|
|
|
|
if (sdiff >= diff) { |
|
|
|
|
add_submit_success(client, diff); |
|
|
|
|
ret = true; |
|
|
|
|
if (new_share(hash, wb_id)) { |
|
|
|
|
add_submit_success(client, diff); |
|
|
|
|
ret = true; |
|
|
|
|
} else { |
|
|
|
|
add_submit_fail(client); |
|
|
|
|
json_object_set_nocheck(json_msg, "reject-reason", json_string("Duplicate")); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
add_submit_fail(client, diff); |
|
|
|
|
add_submit_fail(client); |
|
|
|
|
if (sdiff >= 0) |
|
|
|
|
json_object_set_nocheck(json_msg, "reject-reason", json_string("Above target")); |
|
|
|
|
} |
|
|
|
@ -1229,6 +1269,8 @@ int stratifier(proc_instance_t *pi)
|
|
|
|
|
cklock_init(&workbase_lock); |
|
|
|
|
create_pthread(&pth_blockupdate, blockupdate, ckp); |
|
|
|
|
|
|
|
|
|
cklock_init(&share_lock); |
|
|
|
|
|
|
|
|
|
strat_loop(ckp, pi); |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|