Browse Source

Look for unique ID accepted shares in the connector in redirector mode

master
Con Kolivas 10 years ago
parent
commit
ec9e730b1f
  1. 2
      src/ckpool.c
  2. 106
      src/connector.c

2
src/ckpool.c

@ -1103,7 +1103,7 @@ bool json_get_int64(int64_t *store, const json_t *val, const char *res)
goto out; goto out;
} }
if (!json_is_integer(entry)) { if (!json_is_integer(entry)) {
LOGWARNING("Json entry %s is not an integer", res); LOGINFO("Json entry %s is not an integer", res);
goto out; goto out;
} }
*store = json_integer_value(entry); *store = json_integer_value(entry);

106
src/connector.c

@ -25,6 +25,7 @@
typedef struct client_instance client_instance_t; typedef struct client_instance client_instance_t;
typedef struct sender_send sender_send_t; typedef struct sender_send sender_send_t;
typedef struct share share_t;
struct client_instance { struct client_instance {
/* For clients hashtable */ /* For clients hashtable */
@ -56,7 +57,11 @@ struct client_instance {
/* Are we currently sending a blocked message from this client */ /* Are we currently sending a blocked message from this client */
sender_send_t *sending; sender_send_t *sending;
/* Is this the parent passthrough client */
bool passthrough; bool passthrough;
share_t *shares;
}; };
struct sender_send { struct sender_send {
@ -69,6 +74,14 @@ struct sender_send {
int ofs; int ofs;
}; };
struct share {
share_t *next;
share_t *prev;
time_t submitted;
int64_t id;
};
/* Private data for the connector */ /* Private data for the connector */
struct connector_data { struct connector_data {
ckpool_t *ckp; ckpool_t *ckp;
@ -348,6 +361,47 @@ static int invalidate_client(ckpool_t *ckp, cdata_t *cdata, client_instance_t *c
static void send_client(cdata_t *cdata, int64_t id, char *buf); static void send_client(cdata_t *cdata, int64_t id, char *buf);
/* Look for shares being submitted via a redirector and add them to a linked
* list for looking up the responses */
static void parse_redirector_share(client_instance_t *client, const char *msg, const json_t *val)
{
share_t *share, *tmp;
time_t now;
int64_t id;
if (!json_get_int64(&id, val, "id")) {
LOGNOTICE("Failed to find redirector share id");
return;
}
/* If this is not a share, delete any matching ID messages so we
* don't falsely assume the client has had an accepted share based on
* a true result to a different message. */
if (!strstr(msg, "mining.submit")) {
LOGDEBUG("Redirector client %"PRId64" non share message: %s", client->id, msg);
DL_FOREACH_SAFE(client->shares, share, tmp) {
if (share->id == id) {
DL_DELETE(client->shares, share);
dealloc(share);
}
}
return;
}
share = ckzalloc(sizeof(share_t));
now = time(NULL);
share->submitted = now;
share->id = id;
DL_APPEND(client->shares, share);
LOGINFO("Redirector adding client %"PRId64" share id: %"PRId64, client->id, id);
/* Age old shares. */
DL_FOREACH_SAFE(client->shares, share, tmp) {
if (now > share->submitted + 120) {
DL_DELETE(client->shares, share);
dealloc(share);
}
}
}
/* Client is holding a reference count from being on the epoll list */ /* Client is holding a reference count from being on the epoll list */
static void parse_client_msg(cdata_t *cdata, client_instance_t *client) static void parse_client_msg(cdata_t *cdata, client_instance_t *client)
{ {
@ -400,14 +454,17 @@ reparse:
invalidate_client(ckp, cdata, client); invalidate_client(ckp, cdata, client);
return; return;
} else { } else {
int64_t passthrough_id;
char *s; char *s;
if (client->passthrough) { if (client->passthrough) {
int64_t passthrough_id;
json_getdel_int64(&passthrough_id, val, "client_id"); json_getdel_int64(&passthrough_id, val, "client_id");
passthrough_id = (client->id << 32) | passthrough_id; passthrough_id = (client->id << 32) | passthrough_id;
json_object_set_new_nocheck(val, "client_id", json_integer(passthrough_id)); json_object_set_new_nocheck(val, "client_id", json_integer(passthrough_id));
} else { } else {
if (ckp->redirector && strstr(msg, "mining.submit"))
parse_redirector_share(client, msg, val);
json_object_set_new_nocheck(val, "client_id", json_integer(client->id)); json_object_set_new_nocheck(val, "client_id", json_integer(client->id));
json_object_set_new_nocheck(val, "address", json_string(client->address_name)); json_object_set_new_nocheck(val, "address", json_string(client->address_name));
} }
@ -640,6 +697,51 @@ static void *sender(void *arg)
return NULL; return NULL;
} }
static void test_redirector_shares(ckpool_t *ckp, client_instance_t *client, const char *buf)
{
json_t *val = json_loads(buf, 0, NULL);
share_t *share, *found = NULL;
int64_t id;
if (!val) {
LOGNOTICE("Invalid json response to client %"PRId64, client->id);
return;
}
if (!json_get_int64(&id, val, "id")) {
LOGINFO("Failed to find response id");
goto out;
}
DL_FOREACH(client->shares, share) {
if (share->id == id) {
LOGDEBUG("Found matching share %"PRId64" in trs for client %"PRId64,
id, client->id);
DL_DELETE(client->shares, share);
found = share;
break;
}
}
if (found) {
bool result = false;
dealloc(found);
if (!json_get_bool(&result, val, "result")) {
LOGINFO("Failed to find result in trs share");
goto out;
}
if (!json_is_null(json_object_get(val, "error"))) {
LOGINFO("Got error for trs share");
goto out;
}
if (!result) {
LOGDEBUG("Rejected trs share");
goto out;
}
LOGWARNING("Found accepted share for client %"PRId64, client->id);
}
out:
json_decref(val);
}
/* Send a client by id a heap allocated buffer, allowing this function to /* Send a client by id a heap allocated buffer, allowing this function to
* free the ram. */ * free the ram. */
static void send_client(cdata_t *cdata, const int64_t id, char *buf) static void send_client(cdata_t *cdata, const int64_t id, char *buf)
@ -690,6 +792,8 @@ static void send_client(cdata_t *cdata, const int64_t id, char *buf)
free(buf); free(buf);
return; return;
} }
if (ckp->redirector)
test_redirector_shares(ckp, client, buf);
} }
sender_send = ckzalloc(sizeof(sender_send_t)); sender_send = ckzalloc(sizeof(sender_send_t));

Loading…
Cancel
Save