kanoi 10 years ago
parent
commit
2701772c98
  1. 9
      README
  2. 8
      ckpool.conf
  3. 21
      src/ckpool.c
  4. 2
      src/ckpool.h
  5. 72
      src/generator.c
  6. 4
      src/stratifier.c

9
README

@ -219,7 +219,9 @@ The options recognised are as follows:
"btcd" : This is an array of bitcoind(s) with the options url, auth and pass "btcd" : This is an array of bitcoind(s) with the options url, auth and pass
which match the configured bitcoind. This is mandatory in pool mode. which match the configured bitcoind. This is mandatory in pool mode. The
optional boolean field notify tells ckpool this btcd is using the notifier
and does not need to be polled for block changes.
"proxy" : This is an array in the same format as btcd above but is used in "proxy" : This is an array in the same format as btcd above but is used in
proxy and passthrough mode to set the upstream pool and is mandatory. proxy and passthrough mode to set the upstream pool and is mandatory.
@ -230,8 +232,9 @@ proxy and passthrough mode to set the upstream pool and is mandatory.
blocks. blocks.
"blockpoll" : This is the frequency in milliseconds for how often to check for "blockpoll" : This is the frequency in milliseconds for how often to check for
new network blocks and is 5000 by default. It is intended to be a backup only new network blocks and is 100 by default. It is intended to be a backup only
for when the notifier is not set up or a sanity check for it. for when the notifier is not set up and only polls if the "notify" field is
not set on a btcd.
"update_interval" : This is the frequency that stratum updates are sent out to "update_interval" : This is the frequency that stratum updates are sent out to
miners and is set to 30 seconds by default to help perpetuate transactions for miners and is set to 30 seconds by default to help perpetuate transactions for

8
ckpool.conf

@ -3,17 +3,19 @@
{ {
"url" : "localhost:8332", "url" : "localhost:8332",
"auth" : "user", "auth" : "user",
"pass" : "pass" "pass" : "pass",
"notify" : true
}, },
{ {
"url" : "backup:8332", "url" : "backup:8332",
"auth" : "user", "auth" : "user",
"pass" : "pass" "pass" : "pass",
"notify" : false
} }
], ],
"btcaddress" : "14BMjogz69qe8hk9thyzbmR5pg34mVKB1e", "btcaddress" : "14BMjogz69qe8hk9thyzbmR5pg34mVKB1e",
"btcsig" : "/mined by ck/", "btcsig" : "/mined by ck/",
"blockpoll" : 5000, "blockpoll" : 100,
"update_interval" : 30, "update_interval" : 30,
"serverurl" : "ckpool.org:3333", "serverurl" : "ckpool.org:3333",
"mindiff" : 1, "mindiff" : 1,

21
src/ckpool.c

@ -888,6 +888,21 @@ static void json_get_int(int *store, json_t *val, const char *res)
*store = json_integer_value(entry); *store = json_integer_value(entry);
} }
static void json_get_bool(bool *store, json_t *val, const char *res)
{
json_t *entry = json_object_get(val, res);
if (!entry) {
LOGDEBUG("Json did not find entry %s", res);
return;
}
if (!json_is_boolean(entry)) {
LOGWARNING("Json entry %s is not a boolean", res);
return;
}
*store = json_is_true(entry);
}
static void parse_btcds(ckpool_t *ckp, json_t *arr_val, int arr_size) static void parse_btcds(ckpool_t *ckp, json_t *arr_val, int arr_size)
{ {
json_t *val; json_t *val;
@ -897,11 +912,13 @@ static void parse_btcds(ckpool_t *ckp, json_t *arr_val, int arr_size)
ckp->btcdurl = ckzalloc(sizeof(char *) * arr_size); ckp->btcdurl = ckzalloc(sizeof(char *) * arr_size);
ckp->btcdauth = ckzalloc(sizeof(char *) * arr_size); ckp->btcdauth = ckzalloc(sizeof(char *) * arr_size);
ckp->btcdpass = ckzalloc(sizeof(char *) * arr_size); ckp->btcdpass = ckzalloc(sizeof(char *) * arr_size);
ckp->btcdnotify = ckzalloc(sizeof(bool *) * arr_size);
for (i = 0; i < arr_size; i++) { for (i = 0; i < arr_size; i++) {
val = json_array_get(arr_val, i); val = json_array_get(arr_val, i);
json_get_string(&ckp->btcdurl[i], val, "url"); json_get_string(&ckp->btcdurl[i], val, "url");
json_get_string(&ckp->btcdauth[i], val, "auth"); json_get_string(&ckp->btcdauth[i], val, "auth");
json_get_string(&ckp->btcdpass[i], val, "pass"); json_get_string(&ckp->btcdpass[i], val, "pass");
json_get_bool(&ckp->btcdnotify[i], val, "notify");
} }
} }
@ -1207,10 +1224,8 @@ int main(int argc, char **argv)
ckp.donaddress = "14BMjogz69qe8hk9thyzbmR5pg34mVKB1e"; ckp.donaddress = "14BMjogz69qe8hk9thyzbmR5pg34mVKB1e";
if (!ckp.btcaddress) if (!ckp.btcaddress)
ckp.btcaddress = ckp.donaddress; ckp.btcaddress = ckp.donaddress;
/* Default blockpoll is sanity check only when notifier is not used or
* fails */
if (!ckp.blockpoll) if (!ckp.blockpoll)
ckp.blockpoll = 5000; ckp.blockpoll = 100;
if (!ckp.update_interval) if (!ckp.update_interval)
ckp.update_interval = 30; ckp.update_interval = 30;
if (!ckp.mindiff) if (!ckp.mindiff)

2
src/ckpool.h

@ -71,6 +71,7 @@ struct server_instance {
char *url; char *url;
char *auth; char *auth;
char *pass; char *pass;
bool notify;
connsock_t cs; connsock_t cs;
void *data; // Private data void *data; // Private data
@ -143,6 +144,7 @@ struct ckpool_instance {
char **btcdurl; char **btcdurl;
char **btcdauth; char **btcdauth;
char **btcdpass; char **btcdpass;
bool *btcdnotify;
int blockpoll; // How frequently in ms to poll bitcoind for block updates int blockpoll; // How frequently in ms to poll bitcoind for block updates
/* Difficulty settings */ /* Difficulty settings */

72
src/generator.c

@ -122,6 +122,8 @@ struct proxy_instance {
typedef struct proxy_instance proxy_instance_t; typedef struct proxy_instance proxy_instance_t;
static ckmsgq_t *srvchk; // Server check message queue
static bool server_alive(ckpool_t *ckp, server_instance_t *si, bool pinging) static bool server_alive(ckpool_t *ckp, server_instance_t *si, bool pinging)
{ {
char *userpass = NULL; char *userpass = NULL;
@ -252,6 +254,8 @@ reconnect:
} }
retry: retry:
ckmsgq_add(srvchk, si);
do { do {
selret = wait_read_select(us->sockd, 5); selret = wait_read_select(us->sockd, 5);
if (!selret && !ping_main(ckp)) { if (!selret && !ping_main(ckp)) {
@ -299,10 +303,12 @@ retry:
clear_gbtbase(gbt); clear_gbtbase(gbt);
} }
} else if (cmdmatch(buf, "getbest")) { } else if (cmdmatch(buf, "getbest")) {
if (!get_bestblockhash(cs, hash)) { if (si->notify)
send_unix_msg(sockd, "notify");
else if (!get_bestblockhash(cs, hash)) {
LOGINFO("No best block hash support from %s:%s", LOGINFO("No best block hash support from %s:%s",
cs->url, cs->port); cs->url, cs->port);
send_unix_msg(sockd, "Failed"); send_unix_msg(sockd, "failed");
} else { } else {
if (unlikely(!started)) { if (unlikely(!started)) {
started = true; started = true;
@ -311,15 +317,17 @@ retry:
send_unix_msg(sockd, hash); send_unix_msg(sockd, hash);
} }
} else if (cmdmatch(buf, "getlast")) { } else if (cmdmatch(buf, "getlast")) {
int height = get_blockcount(cs); int height;
if (height == -1) { if (si->notify)
send_unix_msg(sockd, "Failed"); send_unix_msg(sockd, "notify");
else if ((height = get_blockcount(cs)) == -1) {
send_unix_msg(sockd, "failed");
goto reconnect; goto reconnect;
} else { } else {
LOGDEBUG("Height: %d", height); LOGDEBUG("Height: %d", height);
if (!get_blockhash(cs, height, hash)) { if (!get_blockhash(cs, height, hash)) {
send_unix_msg(sockd, "Failed"); send_unix_msg(sockd, "failed");
goto reconnect; goto reconnect;
} else { } else {
if (unlikely(!started)) { if (unlikely(!started)) {
@ -340,6 +348,8 @@ retry:
send_unix_msg(sockd, "true"); send_unix_msg(sockd, "true");
else else
send_unix_msg(sockd, "false"); send_unix_msg(sockd, "false");
} else if (cmdmatch(buf, "fallback")) {
goto reconnect;
} else if (cmdmatch(buf, "loglevel")) { } else if (cmdmatch(buf, "loglevel")) {
sscanf(buf, "loglevel=%d", &ckp->loglevel); sscanf(buf, "loglevel=%d", &ckp->loglevel);
} else if (cmdmatch(buf, "ping")) { } else if (cmdmatch(buf, "ping")) {
@ -1460,6 +1470,8 @@ retry:
LOGWARNING("Block rejected locally."); LOGWARNING("Block rejected locally.");
} else } else
LOGNOTICE("No backup btcd to send block to ourselves"); LOGNOTICE("No backup btcd to send block to ourselves");
} else if (cmdmatch(buf, "fallback")) {
goto reconnect;
} else if (cmdmatch(buf, "loglevel")) { } else if (cmdmatch(buf, "loglevel")) {
sscanf(buf, "loglevel=%d", &ckp->loglevel); sscanf(buf, "loglevel=%d", &ckp->loglevel);
} else if (cmdmatch(buf, "ping")) { } else if (cmdmatch(buf, "ping")) {
@ -1497,6 +1509,7 @@ static int server_mode(ckpool_t *ckp, proc_instance_t *pi)
si->url = ckp->btcdurl[i]; si->url = ckp->btcdurl[i];
si->auth = ckp->btcdauth[i]; si->auth = ckp->btcdauth[i];
si->pass = ckp->btcdpass[i]; si->pass = ckp->btcdpass[i];
si->notify = ckp->btcdnotify[i];
} }
ret = gen_loop(pi); ret = gen_loop(pi);
@ -1612,6 +1625,51 @@ static int proxy_mode(ckpool_t *ckp, proc_instance_t *pi)
return ret; return ret;
} }
/* Tell the watchdog what the current server instance is and decide if we
* should check to see if the higher priority servers are alive and fallback */
static void server_watchdog(ckpool_t *ckp, server_instance_t *cursi)
{
static time_t last_t = 0;
bool alive = false;
time_t now_t;
int i, srvs;
/* Rate limit to checking only once every 5 seconds */
now_t = time(NULL);
if (now_t <= last_t + 5)
return;
last_t = now_t;
/* Is this the highest priority server already? */
if (cursi == ckp->servers[0])
return;
if (ckp->proxy)
srvs = ckp->proxies;
else
srvs = ckp->btcds;
for (i = 0; i < srvs; i++) {
server_instance_t *si = ckp->servers[i];
/* Have we reached the current server? */
if (si == cursi)
return;
if (ckp->proxy) {
proxy_instance_t *proxi = si->data;
connsock_t *cs = proxi->cs;
alive = proxy_alive(ckp, si, proxi, cs, true);
} else
alive = server_alive(ckp, si, true);
if (alive)
break;
}
if (alive)
send_proc(ckp->generator, "fallback");
}
int generator(proc_instance_t *pi) int generator(proc_instance_t *pi)
{ {
ckpool_t *ckp = pi->ckp; ckpool_t *ckp = pi->ckp;
@ -1619,6 +1677,8 @@ int generator(proc_instance_t *pi)
LOGWARNING("%s generator starting", ckp->name); LOGWARNING("%s generator starting", ckp->name);
srvchk = create_ckmsgq(ckp, "srvchk", &server_watchdog);
if (ckp->proxy) if (ckp->proxy)
ret = proxy_mode(ckp, pi); ret = proxy_mode(ckp, pi);
else else

4
src/stratifier.c

@ -1211,7 +1211,9 @@ static void *blockupdate(void *arg)
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, lastswaphash) && !cmdmatch(buf, "failed")) { if (buf && cmdmatch(buf, "notify"))
cksleep_ms(5000);
else if (buf && strcmp(buf, lastswaphash) && !cmdmatch(buf, "failed")) {
LOGNOTICE("Block hash changed to %s", buf); LOGNOTICE("Block hash changed to %s", buf);
update_base(ckp, GEN_PRIORITY); update_base(ckp, GEN_PRIORITY);
} else } else

Loading…
Cancel
Save