From 5a7349e6fe7dd9914d791a6b56d72a95e1650dd1 Mon Sep 17 00:00:00 2001 From: Maveth-Grok Date: Sun, 11 Oct 2026 10:56:08 -0600 Subject: [PATCH 1/2] coinbaser: Re-ask while a pooled split has fewer than 2 outputs A pooled gateway used to treat any coinbaser answer, including an empty one, as finished and then publish the local one-output coinbase. While the pool link is up, a result under 2 outputs now waits 500ms and asks again. Solo, when the pool link is down, still publishes that one output. --- src/datum_coinbaser.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/datum_coinbaser.c b/src/datum_coinbaser.c index 439b08c8..016a7b24 100644 --- a/src/datum_coinbaser.c +++ b/src/datum_coinbaser.c @@ -911,7 +911,13 @@ void *datum_coinbaser_thread(void *ptr) { s->available_coinbase_outputs_count = 0; i = 0; } - if (i>=0) { + /* Pool mode only: a short list is not done. Ask again instead of + * publishing the local one-output coinbase. Solo (pool link down) + * keeps the stock path and publishes that one output. */ + if (datum_protocol_is_active() && i < 2) { + DLOG_WARN("Coinbaser returned %d outputs (<2); not publishing one-output coinbase, will retry", i); + usleep(500000); + } else if (i>=0) { DLOG_DEBUG("Generating coinbases for up to %d outputs", i); generate_coinbase_txns_for_stratum_job(s, false); if (__builtin_expect(atomic_load_explicit(&need_coinbaser_rwlocks_init_done, memory_order_acquire), 1)) { From 397cccc7ecf35c3149235762e1ca3b9121f1e032 Mon Sep 17 00:00:00 2001 From: Maveth-Grok Date: Sun, 11 Oct 2026 11:18:07 -0600 Subject: [PATCH 2/2] conf: Make coinbaser refetch a datum option, on by default datum.coinbaser_refetch controls the short-split re-ask. It defaults to true. Set it false to publish the one-output coinbase and stop asking until the next job. The pool link being down still publishes that one-output coinbase either way. --- doc/example_datum_gateway_config.json | 3 ++- src/datum_coinbaser.c | 9 +++++---- src/datum_conf.c | 3 +++ src/datum_conf.h | 1 + 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/doc/example_datum_gateway_config.json b/doc/example_datum_gateway_config.json index 667db6d7..6096edec 100644 --- a/doc/example_datum_gateway_config.json +++ b/doc/example_datum_gateway_config.json @@ -31,6 +31,7 @@ "migration_max_seconds": 86400, "pool_pass_workers": true, "pool_pass_full_users": true, - "pooled_mining_only": true + "pooled_mining_only": true, + "coinbaser_refetch": true } } diff --git a/src/datum_coinbaser.c b/src/datum_coinbaser.c index 016a7b24..20b1a0f2 100644 --- a/src/datum_coinbaser.c +++ b/src/datum_coinbaser.c @@ -911,10 +911,11 @@ void *datum_coinbaser_thread(void *ptr) { s->available_coinbase_outputs_count = 0; i = 0; } - /* Pool mode only: a short list is not done. Ask again instead of - * publishing the local one-output coinbase. Solo (pool link down) - * keeps the stock path and publishes that one output. */ - if (datum_protocol_is_active() && i < 2) { + /* Pool mode only, and only when datum.coinbaser_refetch is true + * (the default). A short list is not done: keep the current job + * and ask again. Solo, or refetch disabled, publishes the local + * one-output coinbase and stops asking. */ + if (datum_config.datum_coinbaser_refetch && datum_protocol_is_active() && i < 2) { DLOG_WARN("Coinbaser returned %d outputs (<2); not publishing one-output coinbase, will retry", i); usleep(500000); } else if (i>=0) { diff --git a/src/datum_conf.c b/src/datum_conf.c index 3a890ffc..15dd6238 100644 --- a/src/datum_conf.c +++ b/src/datum_conf.c @@ -198,6 +198,9 @@ const T_DATUM_CONFIG_ITEM datum_config_options[] = { { .var_type = DATUM_CONF_BOOL, .category = "datum", .name = "pooled_mining_only", .description = "If the DATUM pool server becomes unavailable, terminate miner connections (otherwise, 100% of any blocks you find pay mining.pool_address)", .example_default = true, .required = false, .ptr = &datum_config.datum_pooled_mining_only, .default_bool = true }, + { .var_type = DATUM_CONF_BOOL, .category = "datum", .name = "coinbaser_refetch", .description = "While connected to a DATUM pool, if a coinbaser answer has fewer than 2 outputs, keep the current job and ask again. Set false to publish the one-output coinbase and stop asking until the next job. Ignored when the pool link is down.", + .example_default = true, + .required = false, .ptr = &datum_config.datum_coinbaser_refetch, .default_bool = true }, { .var_type = DATUM_CONF_INT, .category = "datum", .name = "protocol_global_timeout", .description = "If no valid messages are received from the DATUM server in this many seconds, give up and try to reconnect", .required = false, .ptr = &datum_config.datum_protocol_global_timeout, .default_int = 60 }, }; diff --git a/src/datum_conf.h b/src/datum_conf.h index f230419c..69f9c5a9 100644 --- a/src/datum_conf.h +++ b/src/datum_conf.h @@ -170,6 +170,7 @@ typedef struct { bool datum_pool_pass_workers; bool datum_pool_pass_full_users; bool datum_pooled_mining_only; + bool datum_coinbaser_refetch; char datum_pool_pubkey[1024]; int datum_protocol_global_timeout; uint64_t datum_protocol_global_timeout_ms;