Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/datum_blocktemplates.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ T_DATUM_TEMPLATE_DATA *template_data = NULL;
int next_template_index = 0;

const char *datum_blocktemplates_error = NULL;
atomic_uint_fast64_t g_last_block_template_monotonic_secs = 0;

int datum_template_init(void) {
char *temp = NULL, *ptr = NULL;
Expand Down Expand Up @@ -401,6 +402,7 @@ void *datum_gateway_template_thread(void *args) {
T_DATUM_TEMPLATE_DATA *t;
bool was_notified = false;
int wnc = 0;
uint64_t fetch_start_time_monotonic;
uint64_t last_block_change = 0;
pthread_t pthread_datum_gateway_fallback_notifier;
tcurl = curl_easy_init();
Expand Down Expand Up @@ -445,6 +447,7 @@ void *datum_gateway_template_thread(void *args) {

// fetch latest template
snprintf(gbt_req, sizeof(gbt_req), "{\"method\":\"getblocktemplate\",\"params\":[{\"rules\":[\"segwit\"]}],\"id\":%"PRIu64"}",(uint64_t)((uint64_t)time(NULL)<<(uint64_t)8)|(uint64_t)(i&255));
fetch_start_time_monotonic = monotonic_time_seconds();
gbt = bitcoind_json_rpc_call(tcurl, &datum_config, gbt_req);

if (!gbt) {
Expand All @@ -462,6 +465,7 @@ void *datum_gateway_template_thread(void *args) {
t = datum_gbt_parser(res_val);

if (t) {
g_last_block_template_monotonic_secs = fetch_start_time_monotonic;
datum_blocktemplates_error = NULL;
DLOG_DEBUG("height: %lu / value: %"PRIu64, (unsigned long)t->height, t->coinbasevalue);
DLOG_DEBUG("--- prevhash: %s", t->previousblockhash);
Expand Down
3 changes: 3 additions & 0 deletions src/datum_blocktemplates.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
#ifndef _DATUM_BLOCKTEMPLATE_H_
#define _DATUM_BLOCKTEMPLATE_H_

#include <stdatomic.h>

#ifndef uint64_t
#include <stdint.h>
#endif
Expand Down Expand Up @@ -187,6 +189,7 @@ typedef struct {
} T_DATUM_TEMPLATE_DATA;

extern const char *datum_blocktemplates_error;
extern atomic_uint_fast64_t g_last_block_template_monotonic_secs;

int datum_template_init(void);
T_DATUM_TEMPLATE_DATA *datum_gbt_parser(json_t *gbt);
Expand Down
7 changes: 7 additions & 0 deletions src/datum_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ const T_DATUM_CONFIG_ITEM datum_config_options[] = {
.required = true, .ptr = datum_config.bitcoind_rpcurl, .max_string_len = sizeof(datum_config.bitcoind_rpcurl) },
{ .var_type = DATUM_CONF_INT, .category = "bitcoind", .name = "work_update_seconds", .description = "How many seconds between normal work updates? (5-120, 40 suggested)",
.required = false, .ptr = &datum_config.bitcoind_work_update_seconds, .default_int = 40 },
{ .var_type = DATUM_CONF_INT, .category = "bitcoind", .name = "work_update_stale_limit", .description = "Disconnect miners if template hasn't been updated in how many seconds? (400-600 suggested)",
.required = false, .ptr = &datum_config.bitcoind_work_update_stale_limit, .default_int = 600 },
{ .var_type = DATUM_CONF_BOOL, .category = "bitcoind", .name = "notify_fallback", .description = "Fall back to less efficient methods for new block notifications. Can disable if you use blocknotify.",
.example_default = true,
.required = false, .ptr = &datum_config.bitcoind_notify_fallback, .default_bool = true },
Expand Down Expand Up @@ -412,6 +414,11 @@ int datum_read_config(const char *conffile) {
}
#endif

if (datum_config.bitcoind_work_update_stale_limit < datum_config.bitcoind_work_update_seconds + 5) {
DLOG_FATAL("bitcoind work update stale limit must be at least the work update interval plus 5 seconds.");
return 0;
}

if (datum_config.stratum_v1_max_threads > MAX_THREADS) {
DLOG_FATAL("Maximum threads must be less than %d.", MAX_THREADS);
return 0;
Expand Down
1 change: 1 addition & 0 deletions src/datum_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ typedef struct {
char bitcoind_rpcpassword[128];
char bitcoind_rpcurl[256];
int bitcoind_work_update_seconds;
int bitcoind_work_update_stale_limit;
bool bitcoind_notify_fallback;

char stratum_v1_listen_addr[128];
Expand Down
13 changes: 13 additions & 0 deletions src/datum_gateway.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ int main(const int argc, const char * const * const argv) {
struct sigaction sa;
uint64_t last_datum_protocol_connect_tsms = 0;
bool rejecting_stratum = false;
bool rejecting_stale_template = false;
uint32_t next_reconnect_attempt_ms = 5000;

// listen for block notifications
Expand Down Expand Up @@ -253,6 +254,18 @@ int main(const int argc, const char * const * const argv) {
}
}

const uint64_t now_monotonic_secs = monotonic_time_seconds();

if (g_last_block_template_monotonic_secs + datum_config.bitcoind_work_update_stale_limit < now_monotonic_secs) {
if (!rejecting_stale_template) {
DLOG_ERROR("Failed to update block template in %d seconds! Shutting down Stratum v1 server until template updated.", (int)(now_monotonic_secs - g_last_block_template_monotonic_secs));
rejecting_stale_template = true;
datum_stratum_v1_shutdown_all();
}
} else {
rejecting_stale_template = false;
}

if (datum_config.datum_pooled_mining_only && (fail_retries >= 2) && (!datum_protocol_is_active())) {
if (!rejecting_stratum) {
DLOG_WARN("Configured for pooled mining only, and connection lost to DATUM server! Shutting down Stratum v1 server until DATUM connection reestablished.");
Expand Down
13 changes: 11 additions & 2 deletions src/datum_sockets.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#include <arpa/inet.h>
#include <netinet/tcp.h>

#include "datum_blocktemplates.h"
#include "datum_conf.h"
#include "datum_gateway.h"
#include "datum_protocol.h"
Expand Down Expand Up @@ -646,6 +647,7 @@ void *datum_gateway_listener_thread(void *arg) {
bool rejecting_now = false;
uint64_t last_reject_msg_tsms = 0, curtime_tsms = 0;
uint64_t reject_count = 0;
const char *reject_reason;

T_DATUM_SOCKET_APP *app = (T_DATUM_SOCKET_APP *)arg;

Expand Down Expand Up @@ -708,8 +710,15 @@ void *datum_gateway_listener_thread(void *arg) {
for (;;) {
nfds = epoll_wait(epollfd, events, MAX_EVENTS, 100);
if (nfds) {
curtime_tsms = monotonic_time_seconds();
if (datum_config.datum_pooled_mining_only && (!datum_protocol_is_active())) {
curtime_tsms = current_time_millis(); // we only need this if we're rejecting connections
reject_reason = "DATUM not connected and configured for pooled mining only!";
} else if (g_last_block_template_monotonic_secs + datum_config.bitcoind_work_update_stale_limit < curtime_tsms) {
reject_reason = "Failing to update block template!";
} else {
reject_reason = NULL;
}
if (reject_reason) {
if (!rejecting_now) {
last_reject_msg_tsms = curtime_tsms - 5000; // first disconnect triggers msg
}
Expand All @@ -729,7 +738,7 @@ void *datum_gateway_listener_thread(void *arg) {
if (rejecting_now) {
reject_count++;
if ((curtime_tsms - last_reject_msg_tsms) > 5000) {
DLOG_INFO("DATUM not connected and configured for pooled mining only! Rejecting connection. (%llu connections rejected since last noted)", (unsigned long long)reject_count);
DLOG_INFO("%s Rejecting connection. (%llu connections rejected since last noted)", reject_reason, (unsigned long long)reject_count);
last_reject_msg_tsms = curtime_tsms;
reject_count = 0;
}
Expand Down