diff --git a/components/stratum/CMakeLists.txt b/components/stratum/CMakeLists.txt index dc8069ea..e3360efc 100644 --- a/components/stratum/CMakeLists.txt +++ b/components/stratum/CMakeLists.txt @@ -11,4 +11,5 @@ REQUIRES "json" "mbedtls" "app_update" + "esp_timer" ) \ No newline at end of file diff --git a/components/stratum/include/stratum_api.h b/components/stratum/include/stratum_api.h index b9f47423..ca143e5c 100644 --- a/components/stratum/include/stratum_api.h +++ b/components/stratum/include/stratum_api.h @@ -4,11 +4,14 @@ #include "cJSON.h" #include #include +#include + #define MAX_MERKLE_BRANCHES 32 #define HASH_SIZE 32 #define COINBASE_SIZE 100 #define COINBASE2_SIZE 128 +#define MAX_REQUEST_IDS 1024 typedef enum { @@ -60,6 +63,12 @@ typedef struct char * error_str; } StratumApiV1Message; +typedef struct { + int64_t timestamp_us; + bool tracking; +} RequestTiming; + + void STRATUM_V1_initialize_buffer(); char *STRATUM_V1_receive_jsonrpc_line(int sockfd); @@ -68,6 +77,8 @@ int STRATUM_V1_subscribe(int socket, int send_uid, const char * model); void STRATUM_V1_parse(StratumApiV1Message *message, const char *stratum_json); +void STRATUM_V1_stamp_tx(int request_id); + void STRATUM_V1_free_mining_notify(mining_notify *params); int STRATUM_V1_authorize(int socket, int send_uid, const char *username, const char *pass); @@ -80,4 +91,6 @@ int STRATUM_V1_submit_share(int socket, int send_uid, const char *username, cons const char *extranonce_2, const uint32_t ntime, const uint32_t nonce, const uint32_t version); +double STRATUM_V1_get_response_time_ms(int request_id); + #endif // STRATUM_API_H \ No newline at end of file diff --git a/components/stratum/stratum_api.c b/components/stratum/stratum_api.c index abfb9679..ba4c4df4 100644 --- a/components/stratum/stratum_api.c +++ b/components/stratum/stratum_api.c @@ -10,14 +10,64 @@ #include "esp_ota_ops.h" #include "lwip/sockets.h" #include "utils.h" +#include "esp_timer.h" #include #include +#include +#include #define BUFFER_SIZE 1024 static const char * TAG = "stratum_api"; static char * json_rpc_buffer = NULL; static size_t json_rpc_buffer_size = 0; +static int last_parsed_request_id = -1; + +static RequestTiming request_timings[MAX_REQUEST_IDS]; +static bool initialized = false; + +static void init_request_timings() { + if (!initialized) { + for (int i = 0; i < MAX_REQUEST_IDS; i++) { + request_timings[i].timestamp_us = 0; + request_timings[i].tracking = false; + } + initialized = true; + } +} + +static RequestTiming* get_request_timing(int request_id) { + if (request_id < 0) return NULL; + int index = request_id % MAX_REQUEST_IDS; + return &request_timings[index]; +} + +void STRATUM_V1_stamp_tx(int request_id) +{ + init_request_timings(); + if (request_id >= 1) { + RequestTiming *timing = get_request_timing(request_id); + if (timing) { + timing->timestamp_us = esp_timer_get_time(); + timing->tracking = true; + } + } +} + +double STRATUM_V1_get_response_time_ms(int request_id) +{ + init_request_timings(); + if (request_id < 0) return -1.0; + + RequestTiming *timing = get_request_timing(request_id); + if (!timing || !timing->tracking) { + return -1.0; + } + + double response_time = (esp_timer_get_time() - timing->timestamp_us) / 1000.0; + timing->tracking = false; + return response_time; +} static void debug_stratum_tx(const char *); int _parse_stratum_subscribe_result_message(const char * result_json_str, char ** extranonce, int * extranonce2_len); @@ -110,6 +160,7 @@ void STRATUM_V1_parse(StratumApiV1Message * message, const char * stratum_json) int64_t parsed_id = -1; if (id_json != NULL && cJSON_IsNumber(id_json)) { parsed_id = id_json->valueint; + last_parsed_request_id = parsed_id; } message->message_id = parsed_id; @@ -375,6 +426,7 @@ int STRATUM_V1_configure_version_rolling(int socket, int send_uid, uint32_t * ve static void debug_stratum_tx(const char * msg) { + STRATUM_V1_stamp_tx(last_parsed_request_id); //remove the trailing newline char * newline = strchr(msg, '\n'); if (newline != NULL) { diff --git a/main/global_state.h b/main/global_state.h index 59b36858..9c4210fe 100644 --- a/main/global_state.h +++ b/main/global_state.h @@ -53,6 +53,7 @@ typedef struct char * fallback_pool_url; uint16_t pool_port; uint16_t fallback_pool_port; + double response_time; char * pool_user; char * fallback_pool_user; char * pool_pass; diff --git a/main/http_server/axe-os/src/app/components/home/home.component.html b/main/http_server/axe-os/src/app/components/home/home.component.html index b44939a8..8a493638 100644 --- a/main/http_server/axe-os/src/app/components/home/home.component.html +++ b/main/http_server/axe-os/src/app/components/home/home.component.html @@ -278,6 +278,15 @@ {{ activePoolUser.substring(activePoolUser.length - 20) }} + +
+
+ Share Response Time: +
+
+ {{ info.responseTime }} ms +
+
diff --git a/main/http_server/axe-os/src/app/components/home/home.component.scss b/main/http_server/axe-os/src/app/components/home/home.component.scss index 6a2e95b2..2d649c6e 100644 --- a/main/http_server/axe-os/src/app/components/home/home.component.scss +++ b/main/http_server/axe-os/src/app/components/home/home.component.scss @@ -3,7 +3,7 @@ } .col-fixed-width { - min-width: 50px; + min-width: 150px; } .break-all { word-break: break-all; @@ -29,4 +29,4 @@ flex-grow: 0; flex-shrink: 0; } -} \ No newline at end of file +} diff --git a/main/http_server/axe-os/src/app/components/home/home.component.ts b/main/http_server/axe-os/src/app/components/home/home.component.ts index 0331eafa..f100862b 100644 --- a/main/http_server/axe-os/src/app/components/home/home.component.ts +++ b/main/http_server/axe-os/src/app/components/home/home.component.ts @@ -38,6 +38,7 @@ export class HomeComponent { public activePoolPort!: number; public activePoolUser!: string; public activePoolLabel!: 'Primary' | 'Fallback'; + public responseTime!: number; @ViewChild('chart') private chart?: UIChart @@ -266,6 +267,7 @@ export class HomeComponent { this.activePoolURL = isFallback ? info.fallbackStratumURL : info.stratumURL; this.activePoolUser = isFallback ? info.fallbackStratumUser : info.stratumUser; this.activePoolPort = isFallback ? info.fallbackStratumPort : info.stratumPort; + this.responseTime = info.responseTime; }), map(info => { info.power = parseFloat(info.power.toFixed(1)) diff --git a/main/http_server/axe-os/src/app/services/system.service.ts b/main/http_server/axe-os/src/app/services/system.service.ts index c079d1bc..c4b98f28 100644 --- a/main/http_server/axe-os/src/app/services/system.service.ts +++ b/main/http_server/axe-os/src/app/services/system.service.ts @@ -56,6 +56,7 @@ export class SystemService { stratumPort: 21496, fallbackStratumURL: "test.public-pool.io", fallbackStratumPort: 21497, + responseTime: 10, stratumUser: "bc1q99n3pu025yyu0jlywpmwzalyhm36tg5u37w20d.bitaxe-U1", fallbackStratumUser: "bc1q99n3pu025yyu0jlywpmwzalyhm36tg5u37w20d.bitaxe-U1", isUsingFallbackStratum: true, diff --git a/main/http_server/axe-os/src/models/ISystemInfo.ts b/main/http_server/axe-os/src/models/ISystemInfo.ts index 0fbaf9c2..3dc86381 100644 --- a/main/http_server/axe-os/src/models/ISystemInfo.ts +++ b/main/http_server/axe-os/src/models/ISystemInfo.ts @@ -38,6 +38,7 @@ export interface ISystemInfo { ASICModel: eASICModel, stratumURL: string, stratumPort: number, + responseTime: number, fallbackStratumURL: string, fallbackStratumPort: number, isUsingFallbackStratum: boolean, diff --git a/main/http_server/http_server.c b/main/http_server/http_server.c index 1f52f0fe..0d758501 100644 --- a/main/http_server/http_server.c +++ b/main/http_server/http_server.c @@ -637,6 +637,7 @@ static esp_err_t GET_system_info(httpd_req_t * req) cJSON_AddStringToObject(root, "fallbackStratumURL", fallbackStratumURL); cJSON_AddNumberToObject(root, "stratumPort", nvs_config_get_u16(NVS_CONFIG_STRATUM_PORT, CONFIG_STRATUM_PORT)); cJSON_AddNumberToObject(root, "fallbackStratumPort", nvs_config_get_u16(NVS_CONFIG_FALLBACK_STRATUM_PORT, CONFIG_FALLBACK_STRATUM_PORT)); + cJSON_AddNumberToObject(root, "responseTime", GLOBAL_STATE->SYSTEM_MODULE.response_time); cJSON_AddStringToObject(root, "stratumUser", stratumUser); cJSON_AddStringToObject(root, "fallbackStratumUser", fallbackStratumUser); diff --git a/main/tasks/stratum_task.c b/main/tasks/stratum_task.c index 528034f9..d43f2b85 100644 --- a/main/tasks/stratum_task.c +++ b/main/tasks/stratum_task.c @@ -10,6 +10,9 @@ #include "esp_wifi.h" #include #include +#include +#include "esp_timer.h" +#include #define PORT CONFIG_STRATUM_PORT #define STRATUM_URL CONFIG_STRATUM_URL @@ -193,6 +196,7 @@ void stratum_task(void * pvParameters) int retry_attempts = 0; int retry_critical_attempts = 0; + xTaskCreate(stratum_primary_heartbeat, "stratum primary heartbeat", 8192, pvParameters, 1, NULL); ESP_LOGI(TAG, "Opening connection to pool: %s:%d", stratum_url, port); @@ -296,6 +300,7 @@ void stratum_task(void * pvParameters) int authorize_message_id = GLOBAL_STATE->send_uid++; //mining.authorize - ID: 3 STRATUM_V1_authorize(GLOBAL_STATE->sock, authorize_message_id, username, password); + STRATUM_V1_stamp_tx(authorize_message_id); // Everything is set up, lets make sure we don't abandon work unnecessarily. GLOBAL_STATE->abandon_work = 0; @@ -309,6 +314,12 @@ void stratum_task(void * pvParameters) break; } + double response_time_ms = STRATUM_V1_get_response_time_ms(stratum_api_v1_message.message_id); + if (response_time_ms >= 0) { + ESP_LOGI(TAG, "Stratum response time: %.2f ms", response_time_ms); + GLOBAL_STATE->SYSTEM_MODULE.response_time = response_time_ms; + } + ESP_LOGI(TAG, "rx: %s", line); // debug incoming stratum messages STRATUM_V1_parse(&stratum_api_v1_message, line); free(line);