Browse Source

Create a share hashtable and look for duplicates

master
Con Kolivas 11 years ago
parent
commit
28bd379408
  1. 64
      src/stratifier.c

64
src/stratifier.c

@ -149,6 +149,18 @@ static stratum_instance_t *stratum_instances;
static cklock_t instance_lock; 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! */ /* 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) 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); 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 */ /* 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, 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]; unsigned char merkle_root[32], merkle_sha[64];
char coinbase[256], data[80], share[68]; 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); test_blocksolve(wb, swap, ret, coinbase, cblen);
/* Generate hex string of hash for logging */ /* Generate hex string of hash for logging */
data32 = (uint32_t *)hash1; bswap_256(return_hash, hash);
bswap_256(hash1, hash); __bin2hex(share, return_hash, 32);
__bin2hex(share, hash1, 32);
LOGINFO("Client %d share diff %.1f : %s", client->id, ret, share); 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; 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, 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)
{ {
const char *user, *job_id, *nonce2, *ntime, *nonce; const char *user, *job_id, *nonce2, *ntime, *nonce;
int diff, id, wb_id = 0;
double sdiff = -1; double sdiff = -1;
uint32_t ntime32; uint32_t ntime32;
bool ret = false; bool ret = false;
workbase_t *wb; workbase_t *wb;
int diff, id; char hash[32];
if (unlikely(!json_is_array(params_val))) { if (unlikely(!json_is_array(params_val))) {
*err_val = json_string("params not an array"); *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")); json_object_set_nocheck(json_msg, "reject-reason", json_string("Ntime out of range"));
goto out_unlock; goto out_unlock;
} }
sdiff = submission_diff(client, wb, nonce2, ntime32, nonce); sdiff = submission_diff(client, wb, nonce2, ntime32, nonce, hash);
out_unlock: out_unlock:
wb_id = workbase_id;
ck_runlock(&workbase_lock); ck_runlock(&workbase_lock);
/* Accept the lower of new and old diffs until the next update */ /* Accept the lower of new and old diffs until the next update */
@ -970,10 +1005,15 @@ out_unlock:
else else
diff = client->diff; diff = client->diff;
if (sdiff >= diff) { if (sdiff >= diff) {
add_submit_success(client, diff); if (new_share(hash, wb_id)) {
ret = true; add_submit_success(client, diff);
ret = true;
} else {
add_submit_fail(client);
json_object_set_nocheck(json_msg, "reject-reason", json_string("Duplicate"));
}
} else { } else {
add_submit_fail(client, diff); add_submit_fail(client);
if (sdiff >= 0) if (sdiff >= 0)
json_object_set_nocheck(json_msg, "reject-reason", json_string("Above target")); 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); cklock_init(&workbase_lock);
create_pthread(&pth_blockupdate, blockupdate, ckp); create_pthread(&pth_blockupdate, blockupdate, ckp);
cklock_init(&share_lock);
strat_loop(ckp, pi); strat_loop(ckp, pi);
return ret; return ret;

Loading…
Cancel
Save