From 7f217df04fafbf8787a071094aa6b83be2ad01be Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Mon, 30 Mar 2026 11:47:36 +0200 Subject: [PATCH] feat(miner): scale displayed hashrate units dynamically --- launcher.c | 16 ++++++++++++---- mining_loop.c | 4 +++- utils.c | 42 ++++++++++++++++++++++++++++++++++++++++++ utils.h | 2 ++ 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/launcher.c b/launcher.c index 2e530be..360a9ad 100644 --- a/launcher.c +++ b/launcher.c @@ -53,6 +53,7 @@ static void dashboard_print(DashboardState *st, int n) { long long total_attempts = 0; time_t now_t = time(NULL); char ts[64]; + char total_rate_buf[32]; if (st->lines_printed > 0) { clear_lines(st->lines_printed); @@ -64,13 +65,16 @@ static void dashboard_print(DashboardState *st, int n) { } strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S", localtime(&now_t)); + format_hashrate_khs(total_rate, total_rate_buf, sizeof(total_rate_buf)); printf("%s | MINING STATUS\n", ts); printf("========================================\n"); - printf("Total: %.2f kH/s | Attempts: %lld\n", total_rate, total_attempts); + printf("Total: %s | Attempts: %lld\n", total_rate_buf, total_attempts); printf("----------------------------------------\n"); for (i = 0; i < n; i++) { - printf("Worker %-2d: %.2f kH/s | Attempts: %lld\n", i, st->rates[i], st->attempts[i]); + char worker_rate_buf[32]; + format_hashrate_khs(st->rates[i], worker_rate_buf, sizeof(worker_rate_buf)); + printf("Worker %-2d: %s | Attempts: %lld\n", i, worker_rate_buf, st->attempts[i]); } st->lines_printed = 4 + n; @@ -228,6 +232,8 @@ static int aggregate_loop(WorkerProc *workers, int n) { double elapsed = now_seconds() - st.start_t; long long total_attempts = 0; double avg_rate; + char winner_rate_buf[32]; + char avg_rate_buf[32]; if (st.lines_printed > 0) { clear_lines(st.lines_printed); @@ -238,6 +244,7 @@ static int aggregate_loop(WorkerProc *workers, int n) { } avg_rate = (elapsed > 0.0) ? (double)total_attempts / elapsed / 1000.0 : 0.0; + format_hashrate_khs(avg_rate, avg_rate_buf, sizeof(avg_rate_buf)); printf("==============================================================================\n"); printf("[OK] BLOCK FOUND AND SUBMITTED\n"); @@ -246,9 +253,10 @@ static int aggregate_loop(WorkerProc *workers, int n) { printf(" Worker: %d\n", st.winner_idx); } if (st.has_winner_rate) { - printf(" Worker hashrate: %.2f kH/s\n", st.winner_rate); + format_hashrate_khs(st.winner_rate, winner_rate_buf, sizeof(winner_rate_buf)); + printf(" Worker hashrate: %s\n", winner_rate_buf); } - printf(" Average total hashrate: %.2f kH/s\n", avg_rate); + printf(" Average total hashrate: %s\n", avg_rate_buf); printf(" Total attempts: %lld\n", total_attempts); printf("==============================================================================\n"); diff --git a/mining_loop.c b/mining_loop.c index b2ed8eb..18df51b 100644 --- a/mining_loop.c +++ b/mining_loop.c @@ -53,6 +53,7 @@ static void emit_eventf(int fd, const char *fmt, ...) { static void status_callback(long long attempts, double hashrate_hz, void *ctx_ptr) { StatusCtx *ctx = (StatusCtx *)ctx_ptr; + char rate_buf[32]; if (ctx->event_fd >= 0) { emit_eventf(ctx->event_fd, "status %d %.6f %lld\n", ctx->worker_idx, hashrate_hz / 1000.0, attempts); @@ -60,7 +61,8 @@ static void status_callback(long long attempts, double hashrate_hz, void *ctx_pt } if (ctx->single_mode) { - printf("\r[main] hashrate: %.2f kH/s | attempts: %lld", hashrate_hz / 1000.0, attempts); + format_hashrate_hz(hashrate_hz, rate_buf, sizeof(rate_buf)); + printf("\r[main] hashrate: %s | attempts: %lld", rate_buf, attempts); fflush(stdout); } } diff --git a/utils.c b/utils.c index ccca70b..4036e1a 100644 --- a/utils.c +++ b/utils.c @@ -15,6 +15,48 @@ static char to_hex_digit(unsigned int v) { return (char)('a' + (v - 10U)); } +static void format_hashrate_core(double rate_hs, char *out, size_t out_len) { + static const char *units[] = {"H/s", "kH/s", "MH/s", "GH/s", "TH/s", "PH/s", "EH/s"}; + size_t unit_idx = 0; + const size_t unit_count = sizeof(units) / sizeof(units[0]); + double value; + + if (out == NULL || out_len == 0) { + return; + } + + if (!(rate_hs >= 0.0)) { + rate_hs = 0.0; + } + value = rate_hs; + + while (value >= 999.95 && unit_idx + 1 < unit_count) { + value /= 1000.0; + unit_idx++; + } + + while (value > 0.0 && value < 1.0 && unit_idx > 0) { + value *= 1000.0; + unit_idx--; + } + + if (value >= 100.0) { + snprintf(out, out_len, "%.0f %s", value, units[unit_idx]); + } else if (value >= 10.0) { + snprintf(out, out_len, "%.1f %s", value, units[unit_idx]); + } else { + snprintf(out, out_len, "%.2f %s", value, units[unit_idx]); + } +} + +void format_hashrate_hz(double rate_hz, char *out, size_t out_len) { + format_hashrate_core(rate_hz, out, out_len); +} + +void format_hashrate_khs(double rate_khs, char *out, size_t out_len) { + format_hashrate_core(rate_khs * 1000.0, out, out_len); +} + void sb_init(StrBuf *sb) { sb->data = NULL; sb->len = 0; diff --git a/utils.h b/utils.h index 14f8e48..ea9f0d8 100644 --- a/utils.h +++ b/utils.h @@ -33,5 +33,7 @@ char *decode_nbits_hex(uint32_t nbits); char *calculate_target_hex(const char *bits_hex, double difficulty_factor, const char *network); char *hex_add_width(const char *base_hex, int add_value); +void format_hashrate_hz(double rate_hz, char *out, size_t out_len); +void format_hashrate_khs(double rate_khs, char *out, size_t out_len); #endif