Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,9 @@ blocknotify=wget -q -O /dev/null http://datum-gateway-host-ip:7152/NOTIFY

- By default, if the connection with the pool is lost and fails to reconnect, the Gateway will disconnect all stratum clients. This way miners can use their built-in failover and switch to non-DATUM mining, or an alternate/backup Gateway.
- Accepted/rejected share counts on mining hardware may not perfectly match with the pool. The delta may vary depending on the Gateway's configuration. This is because shares are first accepted or rejected as valid for your local template based on your local node, and then again accepted or rejected based on the pool's requirements, latency to the pool (stale work), latency between your node and the network (stale work), etc. Stratum v1 has no mechanism to report back to the miner that previously accepted work is now rejected, and it doesn't make sense to wait for the pool before responding, either.
- **Share Statistics**: The "Shares Accepted" and "Shares Rejected" counters on the web dashboard behave differently depending on the mining mode:
- **Pooled Mining Mode** (`pooled_mining_only: true`): Shows shares accepted/rejected by the pool
- **Solo Mining Mode** (`pooled_mining_only: false`): Shows shares accepted/rejected from your connected stratum miners, providing visibility into your mining activity even when not connected to a pool

**Most importantly**, please note that this is currently a public **BETA** release. While best efforts have been made to ensure this software is as stable and as useful as possible, you may still encounter issues.

Expand Down
16 changes: 14 additions & 2 deletions src/datum_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,22 @@ static void html_leading_zeros(char * const buffer, const size_t buffer_size, co
}

void datum_api_var_DATUM_SHARES_ACCEPTED(char *buffer, size_t buffer_size, const T_DATUM_API_DASH_VARS *vardata) {
snprintf(buffer, buffer_size, "%llu (%llu diff)", (unsigned long long)datum_accepted_share_count, (unsigned long long)datum_accepted_share_diff);
// Show pool shares when in pooled mode, stratum client shares when in solo mode
// This allows solo miners to see their actual mining activity instead of zeros
if (datum_config.datum_pooled_mining_only) {
snprintf(buffer, buffer_size, "%llu (%llu diff)", (unsigned long long)datum_accepted_share_count, (unsigned long long)datum_accepted_share_diff);
} else {
snprintf(buffer, buffer_size, "%llu (%llu diff)", (unsigned long long)stratum_client_accepted_share_count, (unsigned long long)stratum_client_accepted_share_diff);
}
}
void datum_api_var_DATUM_SHARES_REJECTED(char *buffer, size_t buffer_size, const T_DATUM_API_DASH_VARS *vardata) {
snprintf(buffer, buffer_size, "%llu (%llu diff)", (unsigned long long)datum_rejected_share_count, (unsigned long long)datum_rejected_share_diff);
// Show pool shares when in pooled mode, stratum client shares when in solo mode
// This allows solo miners to see their actual mining activity instead of zeros
if (datum_config.datum_pooled_mining_only) {
snprintf(buffer, buffer_size, "%llu (%llu diff)", (unsigned long long)datum_rejected_share_count, (unsigned long long)datum_rejected_share_diff);
} else {
snprintf(buffer, buffer_size, "%llu (%llu diff)", (unsigned long long)stratum_client_rejected_share_count, (unsigned long long)stratum_client_rejected_share_diff);
}
}
void datum_api_var_DATUM_CONNECTION_STATUS(char *buffer, size_t buffer_size, const T_DATUM_API_DASH_VARS *vardata) {
const char *colour = "lime";
Expand Down
27 changes: 27 additions & 0 deletions src/datum_stratum.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ bool stratum_latest_empty_ready_for_full = 0;
uint64_t stratum_latest_empty_job_index = 0;
uint64_t stratum_latest_empty_sent_count = 0;

// Global counters for total shares from stratum clients
// These counters track all share submissions from connected miners,
// providing accurate statistics for solo mining operations where pool
// share counters would remain at zero.
uint64_t stratum_client_accepted_share_count = 0;
uint64_t stratum_client_accepted_share_diff = 0;
uint64_t stratum_client_rejected_share_count = 0;
uint64_t stratum_client_rejected_share_diff = 0;

pthread_rwlock_t need_coinbaser_rwlocks[MAX_STRATUM_JOBS];
bool need_coinbaser_rwlocks_init_done = false;

Expand Down Expand Up @@ -1268,6 +1277,8 @@ int client_mining_submit(T_DATUM_CLIENT_DATA *c, uint64_t id, json_t *params_obj
send_rejected_stale_block(c, id);
m->share_count_rejected++;
m->share_diff_rejected += job_diff;
__atomic_add_fetch(&stratum_client_rejected_share_count, 1, __ATOMIC_RELAXED);
__atomic_add_fetch(&stratum_client_rejected_share_diff, job_diff, __ATOMIC_RELAXED);
return 0;
}

Expand All @@ -1277,13 +1288,17 @@ int client_mining_submit(T_DATUM_CLIENT_DATA *c, uint64_t id, json_t *params_obj
send_rejected_time_too_old(c, id);
m->share_count_rejected++;
m->share_diff_rejected += job_diff;
__atomic_add_fetch(&stratum_client_rejected_share_count, 1, __ATOMIC_RELAXED);
__atomic_add_fetch(&stratum_client_rejected_share_diff, job_diff, __ATOMIC_RELAXED);
return 0;
}

if (ntime_val > (job->block_template->curtime + 7200)) {
send_rejected_time_too_new(c, id);
m->share_count_rejected++;
m->share_diff_rejected += job_diff;
__atomic_add_fetch(&stratum_client_rejected_share_count, 1, __ATOMIC_RELAXED);
__atomic_add_fetch(&stratum_client_rejected_share_diff, job_diff, __ATOMIC_RELAXED);
return 0;
}

Expand All @@ -1295,6 +1310,8 @@ int client_mining_submit(T_DATUM_CLIENT_DATA *c, uint64_t id, json_t *params_obj
send_rejected_high_hash_error(c, id);
m->share_count_rejected++;
m->share_diff_rejected += job_diff;
__atomic_add_fetch(&stratum_client_rejected_share_count, 1, __ATOMIC_RELAXED);
__atomic_add_fetch(&stratum_client_rejected_share_diff, job_diff, __ATOMIC_RELAXED);
return 0;
}
} else {
Expand All @@ -1304,6 +1321,8 @@ int client_mining_submit(T_DATUM_CLIENT_DATA *c, uint64_t id, json_t *params_obj
send_rejected_high_hash_error(c, id);
m->share_count_rejected++;
m->share_diff_rejected += job_diff;
__atomic_add_fetch(&stratum_client_rejected_share_count, 1, __ATOMIC_RELAXED);
__atomic_add_fetch(&stratum_client_rejected_share_diff, job_diff, __ATOMIC_RELAXED);
return 0;
}
}
Expand All @@ -1314,6 +1333,8 @@ int client_mining_submit(T_DATUM_CLIENT_DATA *c, uint64_t id, json_t *params_obj
send_rejected_stale(c, id);
m->share_count_rejected++;
m->share_diff_rejected += job_diff;
__atomic_add_fetch(&stratum_client_rejected_share_count, 1, __ATOMIC_RELAXED);
__atomic_add_fetch(&stratum_client_rejected_share_diff, job_diff, __ATOMIC_RELAXED);
return 0;
}

Expand All @@ -1323,6 +1344,8 @@ int client_mining_submit(T_DATUM_CLIENT_DATA *c, uint64_t id, json_t *params_obj
send_rejected_duplicate(c, id);
m->share_count_rejected++;
m->share_diff_rejected += job_diff;
__atomic_add_fetch(&stratum_client_rejected_share_count, 1, __ATOMIC_RELAXED);
__atomic_add_fetch(&stratum_client_rejected_share_diff, job_diff, __ATOMIC_RELAXED);
return 0;
}

Expand All @@ -1342,6 +1365,10 @@ int client_mining_submit(T_DATUM_CLIENT_DATA *c, uint64_t id, json_t *params_obj
m->share_diff_accepted += job_diff;
m->share_count_accepted++;

// update global stratum client totals (used for solo mining display)
__atomic_add_fetch(&stratum_client_accepted_share_count, 1, __ATOMIC_RELAXED);
__atomic_add_fetch(&stratum_client_accepted_share_diff, job_diff, __ATOMIC_RELAXED);

// update since-snap totals
m->share_count_since_snap++;
m->share_diff_since_snap += job_diff;
Expand Down
10 changes: 10 additions & 0 deletions src/datum_stratum.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,4 +290,14 @@ extern T_DATUM_SOCKET_APP *global_stratum_app;
extern pthread_rwlock_t need_coinbaser_rwlocks[MAX_STRATUM_JOBS];
extern bool need_coinbaser_rwlocks_init_done;

// Global counters for total shares from stratum clients
// These track all shares submitted by miners connected to the stratum server,
// regardless of whether they're forwarded to a pool or used for solo mining.
// In solo mining mode, these counters are displayed on the web dashboard instead
// of the pool share counters, providing visibility into miner activity.
extern uint64_t stratum_client_accepted_share_count;
extern uint64_t stratum_client_accepted_share_diff;
extern uint64_t stratum_client_rejected_share_count;
extern uint64_t stratum_client_rejected_share_diff;

#endif
Loading