diff --git a/README b/README index 37ac5285..0d06c3c5 100644 --- a/README +++ b/README @@ -176,7 +176,9 @@ maximum debug is level 7. -N will start ckpool in passthrough node mode where it behaves like a passthrough but requires a locally running bitcoind and can submit blocks itself in addition to passing the shares back to the upstream pool. It also -monitors hashrate and requires more resources than a simple passthrough. +monitors hashrate and requires more resources than a simple passthrough. Be +aware that upstream pools must specify dedicated IPs/ports that accept +incoming node requests with the nodeserver directive described below. -n will change the ckpool process name to that specified, allowing multiple different named instances to be running. By default the variant @@ -266,6 +268,11 @@ new network blocks and is 100 by default. It is intended to be a backup only for when the notifier is not set up and only polls if the "notify" field is not set on a btcd. +"nodeserver" : This takes the same format as the serverurl array and specifies +additional IPs/ports to bind to that will accept incoming requests for mining +node communications. It is recommended to selectively isolate this address +to minimise unnecessary communications with unauthorised nodes. + "nonce1length" : This is optional allowing the extranonce1 length to be chosen from 2 to 8. Default 4 diff --git a/ckpool.conf b/ckpool.conf index 394fe05b..251ab290 100644 --- a/ckpool.conf +++ b/ckpool.conf @@ -23,7 +23,10 @@ "ckpool.org:3333", "node.ckpool.org:3333", "node.ckpool.org:80" - ], +], +"nodeserver" : [ + "ckpool.org:3335" +], "mindiff" : 1, "startdiff" : 42, "maxdiff" : 0, diff --git a/src/ckpool.c b/src/ckpool.c index 6178b225..dad5a817 100644 --- a/src/ckpool.c +++ b/src/ckpool.c @@ -1283,7 +1283,7 @@ static bool parse_serverurls(ckpool_t *ckp, const json_t *arr_val) if (!arr_val) goto out; if (!json_is_array(arr_val)) { - LOGWARNING("Unable to parse serverurl entries as an array"); + LOGINFO("Unable to parse serverurl entries as an array"); goto out; } arr_size = json_array_size(arr_val); @@ -1293,6 +1293,7 @@ static bool parse_serverurls(ckpool_t *ckp, const json_t *arr_val) } ckp->serverurls = arr_size; ckp->serverurl = ckalloc(sizeof(char *) * arr_size); + ckp->nodeserver = ckzalloc(sizeof(bool) * arr_size); for (i = 0; i < arr_size; i++) { json_t *val = json_array_get(arr_val, i); @@ -1304,6 +1305,34 @@ out: return ret; } +static void parse_nodeservers(ckpool_t *ckp, const json_t *arr_val) +{ + int arr_size, i, j, total_urls; + + if (!arr_val) + return; + if (!json_is_array(arr_val)) { + LOGWARNING("Unable to parse nodeservers entries as an array"); + return; + } + arr_size = json_array_size(arr_val); + if (!arr_size) { + LOGWARNING("Nodeserver array empty"); + return; + } + total_urls = ckp->serverurls + arr_size; + ckp->serverurl = realloc(ckp->serverurl, sizeof(char *) * total_urls); + ckp->nodeserver = realloc(ckp->nodeserver, sizeof(bool) * total_urls); + for (i = 0, j = ckp->serverurls; j < total_urls; i++, j++) { + json_t *val = json_array_get(arr_val, i); + + if (!_json_get_string(&ckp->serverurl[j], val, "nodeserver")) + LOGWARNING("Invalid nodeserver entry number %d", i); + ckp->nodeserver[j] = true; + } + ckp->serverurls = total_urls; +} + static bool parse_redirecturls(ckpool_t *ckp, const json_t *arr_val) { bool ret = false; @@ -1379,6 +1408,8 @@ static void parse_config(ckpool_t *ckp) ckp->serverurls = 1; } } + arr_val = json_object_get(json_conf, "nodeserver"); + parse_nodeservers(ckp, arr_val); json_get_int64(&ckp->mindiff, json_conf, "mindiff"); json_get_int64(&ckp->startdiff, json_conf, "startdiff"); json_get_int64(&ckp->maxdiff, json_conf, "maxdiff"); diff --git a/src/ckpool.h b/src/ckpool.h index f2afd133..c0dad52e 100644 --- a/src/ckpool.h +++ b/src/ckpool.h @@ -226,6 +226,8 @@ struct ckpool_instance { server_instance_t **servers; char **serverurl; // Array of URLs to bind our server/proxy to int serverurls; // Number of server bindings + bool *nodeserver; // If this server URL serves node information + int update_interval; // Seconds between stratum updates /* Proxy options */ diff --git a/src/stratifier.c b/src/stratifier.c index 011cefc9..adc66442 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -5174,7 +5174,7 @@ static void init_client(sdata_t *sdata, const stratum_instance_t *client, const stratum_send_update(sdata, client_id, true); } -static void add_mining_node(sdata_t *sdata, stratum_instance_t *client) +static void add_mining_node(ckpool_t *ckp, sdata_t *sdata, stratum_instance_t *client) { client->node = true; @@ -5182,7 +5182,8 @@ static void add_mining_node(sdata_t *sdata, stratum_instance_t *client) DL_APPEND(sdata->node_instances, client); ck_wunlock(&sdata->instance_lock); - LOGWARNING("Added client %"PRId64" %s as mining node!", client->id, client->address); + LOGWARNING("Added client %"PRId64" %s as mining node on server %d:%s", client->id, + client->address, client->server, ckp->serverurl[client->server]); } /* Enter with client holding ref count */ @@ -5238,9 +5239,16 @@ static void parse_method(ckpool_t *ckp, sdata_t *sdata, stratum_instance_t *clie /* Add this client as a passthrough in the connector and * add it to the list of mining nodes in the stratifier */ - add_mining_node(sdata, client); - snprintf(buf, 255, "passthrough=%"PRId64, client_id); - send_proc(ckp->connector, buf); + if (!ckp->nodeserver[client->server]) { + LOGNOTICE("Dropping client %"PRId64" %s trying to authorise as node on non node server %d", + client_id, client->address, client->server); + connector_drop_client(ckp, client_id); + drop_client(ckp, sdata, client_id); + } else { + add_mining_node(ckp, sdata, client); + snprintf(buf, 255, "passthrough=%"PRId64, client_id); + send_proc(ckp->connector, buf); + } return; }