Merge branch 'master' of https://bitbucket.org/ckolivas/ckpool
This commit is contained in:
commit
37b9c17fef
168
src/generator.c
168
src/generator.c
@ -122,6 +122,60 @@ struct proxy_instance {
|
||||
|
||||
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)
|
||||
{
|
||||
server_instance_t *alive = NULL;
|
||||
@ -134,49 +188,12 @@ retry:
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < ckp->btcds; i++) {
|
||||
server_instance_t *si;
|
||||
char *userpass = NULL;
|
||||
gbtbase_t *gbt;
|
||||
server_instance_t *si = ckp->servers[i];
|
||||
|
||||
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;
|
||||
if (server_alive(ckp, si, false)) {
|
||||
alive = si;
|
||||
break;
|
||||
}
|
||||
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);
|
||||
|
||||
/* Test we can connect, authorise and get a block template */
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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 */
|
||||
static proxy_instance_t *live_proxy(ckpool_t *ckp)
|
||||
{
|
||||
@ -1272,37 +1329,10 @@ retry:
|
||||
si = ckp->servers[i];
|
||||
proxi = si->data;
|
||||
cs = proxi->cs;
|
||||
if (!extract_sockaddr(si->url, &cs->url, &cs->port)) {
|
||||
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;
|
||||
}
|
||||
if (proxy_alive(ckp, si, proxi, cs, false)) {
|
||||
alive = proxi;
|
||||
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) {
|
||||
send_proc(ckp->stratifier, "dropall");
|
||||
|
||||
@ -79,7 +79,7 @@ static pool_stats_t stats;
|
||||
|
||||
static pthread_mutex_t stats_lock;
|
||||
|
||||
static uint64_t enonce1_64;
|
||||
static uint64_t enonce1_64 = 1;
|
||||
|
||||
struct workbase {
|
||||
/* Hash table data */
|
||||
@ -159,7 +159,7 @@ static struct {
|
||||
|
||||
static int64_t workbase_id;
|
||||
static int64_t blockchange_id;
|
||||
static char lasthash[68];
|
||||
static char lasthash[68], lastswaphash[68];
|
||||
|
||||
struct json_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);
|
||||
wb->id = workbase_id++;
|
||||
|
||||
if (strncmp(wb->prevhash, lasthash, 64)) {
|
||||
char bin[32], swap[32];
|
||||
|
||||
*new_block = true;
|
||||
memcpy(lasthash, wb->prevhash, 65);
|
||||
hex2bin(bin, lasthash, 32);
|
||||
swap_256(swap, bin);
|
||||
__bin2hex(lastswaphash, swap, 32);
|
||||
blockchange_id = wb->id;
|
||||
}
|
||||
if (*new_block && ckp->logshares) {
|
||||
@ -1027,7 +1031,7 @@ static void drop_client(int64_t id)
|
||||
HASH_DEL(stratum_instances, client);
|
||||
HASH_FIND(hh, disconnected_instances, &client->enonce1_64, sizeof(uint64_t), 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);
|
||||
else // Keep around instance so we don't get a dereference
|
||||
HASH_ADD(hh, dead_instances, enonce1_64, sizeof(uint64_t), client);
|
||||
@ -1193,7 +1197,7 @@ out:
|
||||
static void *blockupdate(void *arg)
|
||||
{
|
||||
ckpool_t *ckp = (ckpool_t *)arg;
|
||||
char *buf = NULL, hash[68];
|
||||
char *buf = NULL;
|
||||
char request[8];
|
||||
|
||||
pthread_detach(pthread_self());
|
||||
@ -1204,14 +1208,12 @@ static void *blockupdate(void *arg)
|
||||
else
|
||||
sprintf(request, "getlast");
|
||||
|
||||
memset(hash, 0, 68);
|
||||
while (42) {
|
||||
dealloc(buf);
|
||||
buf = send_recv_generator(ckp, request, GEN_LAX);
|
||||
if (buf && strcmp(buf, hash) && !cmdmatch(buf, "failed")) {
|
||||
strcpy(hash, buf);
|
||||
LOGNOTICE("Block hash changed to %s", hash);
|
||||
send_proc(ckp->stratifier, "update");
|
||||
if (buf && strcmp(buf, lastswaphash) && !cmdmatch(buf, "failed")) {
|
||||
LOGNOTICE("Block hash changed to %s", buf);
|
||||
update_base(ckp, GEN_PRIORITY);
|
||||
} else
|
||||
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");
|
||||
goto out;
|
||||
}
|
||||
if (unlikely(!client->useragent)) {
|
||||
*err_val = json_string("Failed subscription");
|
||||
goto out;
|
||||
}
|
||||
buf = json_string_value(json_array_get(params_val, 0));
|
||||
if (!buf) {
|
||||
*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);
|
||||
HASH_FIND_I64(workbases, &id, wb);
|
||||
if (unlikely(!wb)) {
|
||||
id = current_workbase->id;
|
||||
err = SE_INVALID_JOBID;
|
||||
json_set_string(json_msg, "reject-reason", SHARE_ERR(err));
|
||||
strcpy(idstring, job_id);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user