kanoi 10 years ago
parent
commit
37b9c17fef
  1. 168
      src/generator.c
  2. 27
      src/stratifier.c

168
src/generator.c

@ -122,6 +122,60 @@ struct proxy_instance {
typedef struct proxy_instance proxy_instance_t; typedef struct proxy_instance proxy_instance_t;
static bool server_alive(ckpool_t *ckp, server_instance_t *si, bool pinging)
{
char *userpass = NULL;
bool ret = false;
connsock_t *cs;
gbtbase_t *gbt;
cs = &si->cs;
if (!extract_sockaddr(si->url, &cs->url, &cs->port)) {
LOGWARNING("Failed to extract address from %s", si->url);
return ret;
}
userpass = strdup(si->auth);
realloc_strcat(&userpass, ":");
realloc_strcat(&userpass, si->pass);
cs->auth = http_base64(userpass);
dealloc(userpass);
if (!cs->auth) {
LOGWARNING("Failed to create base64 auth from %s", userpass);
return ret;
}
cs->fd = connect_socket(cs->url, cs->port);
if (cs->fd < 0) {
if (!pinging)
LOGWARNING("Failed to connect socket to %s:%s !", cs->url, cs->port);
return ret;
}
/* Test we can connect, authorise and get a block template */
gbt = ckzalloc(sizeof(gbtbase_t));
si->data = gbt;
if (!gen_gbtbase(cs, gbt)) {
if (!pinging) {
LOGINFO("Failed to get test block template from %s:%s!",
cs->url, cs->port);
}
goto out_close;
}
clear_gbtbase(gbt);
if (!validate_address(cs, ckp->btcaddress)) {
LOGWARNING("Invalid btcaddress: %s !", ckp->btcaddress);
goto out_close;
}
ret = true;
out_close:
if (!ret)
close(cs->fd);
else
keep_sockalive(cs->fd);
return ret;
}
/* Find the highest priority server alive and return it */
static server_instance_t *live_server(ckpool_t *ckp) static server_instance_t *live_server(ckpool_t *ckp)
{ {
server_instance_t *alive = NULL; server_instance_t *alive = NULL;
@ -134,49 +188,12 @@ retry:
goto out; goto out;
for (i = 0; i < ckp->btcds; i++) { for (i = 0; i < ckp->btcds; i++) {
server_instance_t *si; server_instance_t *si = ckp->servers[i];
char *userpass = NULL;
gbtbase_t *gbt;
si = ckp->servers[i];
cs = &si->cs;
if (!extract_sockaddr(si->url, &cs->url, &cs->port)) {
LOGWARNING("Failed to extract address from %s", si->url);
continue;
}
userpass = strdup(si->auth);
realloc_strcat(&userpass, ":");
realloc_strcat(&userpass, si->pass);
cs->auth = http_base64(userpass);
dealloc(userpass);
if (!cs->auth) {
LOGWARNING("Failed to create base64 auth from %s", userpass);
continue;
}
cs->fd = connect_socket(cs->url, cs->port);
if (cs->fd < 0) {
LOGWARNING("Failed to connect socket to %s:%s !", cs->url, cs->port);
continue;
}
keep_sockalive(cs->fd); if (server_alive(ckp, si, false)) {
alive = si;
/* Test we can connect, authorise and get a block template */ break;
gbt = ckzalloc(sizeof(gbtbase_t));
si->data = gbt;
if (!gen_gbtbase(cs, gbt)) {
LOGINFO("Failed to get test block template from %s:%s!",
cs->url, cs->port);
continue;
}
clear_gbtbase(gbt);
if (!validate_address(cs, ckp->btcaddress)) {
LOGWARNING("Invalid btcaddress: %s !", ckp->btcaddress);
continue;
} }
alive = si;
break;
} }
if (!alive) { if (!alive) {
LOGWARNING("CRITICAL: No bitcoinds active!"); LOGWARNING("CRITICAL: No bitcoinds active!");
@ -1253,6 +1270,46 @@ static void passthrough_add_send(proxy_instance_t *proxi, const char *msg)
ckmsgq_add(proxi->passsends, pm); ckmsgq_add(proxi->passsends, pm);
} }
static bool proxy_alive(ckpool_t *ckp, server_instance_t *si, proxy_instance_t *proxi,
connsock_t *cs, bool pinging)
{
if (!extract_sockaddr(si->url, &cs->url, &cs->port)) {
LOGWARNING("Failed to extract address from %s", si->url);
return false;
}
if (!connect_proxy(cs)) {
if (!pinging) {
LOGINFO("Failed to connect to %s:%s in proxy_mode!",
cs->url, cs->port);
}
return false;
}
if (ckp->passthrough) {
if (!passthrough_stratum(cs, proxi)) {
LOGWARNING("Failed initial passthrough to %s:%s !",
cs->url, cs->port);
return false;
}
return true;
}
/* Test we can connect, authorise and get stratum information */
if (!subscribe_stratum(cs, proxi)) {
if (!pinging) {
LOGINFO("Failed initial subscribe to %s:%s !",
cs->url, cs->port);
}
return false;
}
if (!auth_stratum(cs, proxi)) {
if (!pinging) {
LOGWARNING("Failed initial authorise to %s:%s with %s:%s !",
cs->url, cs->port, si->auth, si->pass);
}
return false;
}
return true;
}
/* Cycle through the available proxies and find the first alive one */ /* Cycle through the available proxies and find the first alive one */
static proxy_instance_t *live_proxy(ckpool_t *ckp) static proxy_instance_t *live_proxy(ckpool_t *ckp)
{ {
@ -1272,37 +1329,10 @@ retry:
si = ckp->servers[i]; si = ckp->servers[i];
proxi = si->data; proxi = si->data;
cs = proxi->cs; cs = proxi->cs;
if (!extract_sockaddr(si->url, &cs->url, &cs->port)) { if (proxy_alive(ckp, si, proxi, cs, false)) {
LOGWARNING("Failed to extract address from %s", si->url);
continue;
}
if (!connect_proxy(cs)) {
LOGINFO("Failed to connect to %s:%s in proxy_mode!",
cs->url, cs->port);
continue;
}
if (ckp->passthrough) {
if (!passthrough_stratum(cs, proxi)) {
LOGWARNING("Failed initial passthrough to %s:%s !",
cs->url, cs->port);
continue;
}
alive = proxi; alive = proxi;
break; break;
} }
/* Test we can connect, authorise and get stratum information */
if (!subscribe_stratum(cs, proxi)) {
LOGINFO("Failed initial subscribe to %s:%s !",
cs->url, cs->port);
continue;
}
if (!auth_stratum(cs, proxi)) {
LOGWARNING("Failed initial authorise to %s:%s with %s:%s !",
cs->url, cs->port, si->auth, si->pass);
continue;
}
alive = proxi;
break;
} }
if (!alive) { if (!alive) {
send_proc(ckp->stratifier, "dropall"); send_proc(ckp->stratifier, "dropall");

27
src/stratifier.c

@ -79,7 +79,7 @@ static pool_stats_t stats;
static pthread_mutex_t stats_lock; static pthread_mutex_t stats_lock;
static uint64_t enonce1_64; static uint64_t enonce1_64 = 1;
struct workbase { struct workbase {
/* Hash table data */ /* Hash table data */
@ -159,7 +159,7 @@ static struct {
static int64_t workbase_id; static int64_t workbase_id;
static int64_t blockchange_id; static int64_t blockchange_id;
static char lasthash[68]; static char lasthash[68], lastswaphash[68];
struct json_params { struct json_params {
json_t *params; json_t *params;
@ -556,10 +556,14 @@ static void add_base(ckpool_t *ckp, workbase_t *wb, bool *new_block)
ck_wlock(&workbase_lock); ck_wlock(&workbase_lock);
wb->id = workbase_id++; wb->id = workbase_id++;
if (strncmp(wb->prevhash, lasthash, 64)) { if (strncmp(wb->prevhash, lasthash, 64)) {
char bin[32], swap[32];
*new_block = true; *new_block = true;
memcpy(lasthash, wb->prevhash, 65); memcpy(lasthash, wb->prevhash, 65);
hex2bin(bin, lasthash, 32);
swap_256(swap, bin);
__bin2hex(lastswaphash, swap, 32);
blockchange_id = wb->id; blockchange_id = wb->id;
} }
if (*new_block && ckp->logshares) { if (*new_block && ckp->logshares) {
@ -1027,7 +1031,7 @@ static void drop_client(int64_t id)
HASH_DEL(stratum_instances, client); HASH_DEL(stratum_instances, client);
HASH_FIND(hh, disconnected_instances, &client->enonce1_64, sizeof(uint64_t), old_client); HASH_FIND(hh, disconnected_instances, &client->enonce1_64, sizeof(uint64_t), old_client);
/* Only keep around one copy of the old client */ /* Only keep around one copy of the old client */
if (!old_client) if (!old_client && client->enonce1_64)
HASH_ADD(hh, disconnected_instances, enonce1_64, sizeof(uint64_t), client); HASH_ADD(hh, disconnected_instances, enonce1_64, sizeof(uint64_t), client);
else // Keep around instance so we don't get a dereference else // Keep around instance so we don't get a dereference
HASH_ADD(hh, dead_instances, enonce1_64, sizeof(uint64_t), client); HASH_ADD(hh, dead_instances, enonce1_64, sizeof(uint64_t), client);
@ -1193,7 +1197,7 @@ out:
static void *blockupdate(void *arg) static void *blockupdate(void *arg)
{ {
ckpool_t *ckp = (ckpool_t *)arg; ckpool_t *ckp = (ckpool_t *)arg;
char *buf = NULL, hash[68]; char *buf = NULL;
char request[8]; char request[8];
pthread_detach(pthread_self()); pthread_detach(pthread_self());
@ -1204,14 +1208,12 @@ static void *blockupdate(void *arg)
else else
sprintf(request, "getlast"); sprintf(request, "getlast");
memset(hash, 0, 68);
while (42) { while (42) {
dealloc(buf); dealloc(buf);
buf = send_recv_generator(ckp, request, GEN_LAX); buf = send_recv_generator(ckp, request, GEN_LAX);
if (buf && strcmp(buf, hash) && !cmdmatch(buf, "failed")) { if (buf && strcmp(buf, lastswaphash) && !cmdmatch(buf, "failed")) {
strcpy(hash, buf); LOGNOTICE("Block hash changed to %s", buf);
LOGNOTICE("Block hash changed to %s", hash); update_base(ckp, GEN_PRIORITY);
send_proc(ckp->stratifier, "update");
} else } else
cksleep_ms(ckp->blockpoll); cksleep_ms(ckp->blockpoll);
} }
@ -1469,6 +1471,10 @@ static json_t *parse_authorise(stratum_instance_t *client, json_t *params_val, j
*err_val = json_string("params missing array entries"); *err_val = json_string("params missing array entries");
goto out; goto out;
} }
if (unlikely(!client->useragent)) {
*err_val = json_string("Failed subscription");
goto out;
}
buf = json_string_value(json_array_get(params_val, 0)); buf = json_string_value(json_array_get(params_val, 0));
if (!buf) { if (!buf) {
*err_val = json_string("Invalid workername parameter"); *err_val = json_string("Invalid workername parameter");
@ -1905,6 +1911,7 @@ static json_t *parse_submit(stratum_instance_t *client, json_t *json_msg,
ck_rlock(&workbase_lock); ck_rlock(&workbase_lock);
HASH_FIND_I64(workbases, &id, wb); HASH_FIND_I64(workbases, &id, wb);
if (unlikely(!wb)) { if (unlikely(!wb)) {
id = current_workbase->id;
err = SE_INVALID_JOBID; err = SE_INVALID_JOBID;
json_set_string(json_msg, "reject-reason", SHARE_ERR(err)); json_set_string(json_msg, "reject-reason", SHARE_ERR(err));
strcpy(idstring, job_id); strcpy(idstring, job_id);

Loading…
Cancel
Save