diff options
| author | Your Name <you@example.com> | 2026-05-23 15:26:52 +0530 |
|---|---|---|
| committer | Your Name <you@example.com> | 2026-05-23 15:26:52 +0530 |
| commit | be4d490e96de3d20cc6c9921f09534cde0ca0765 (patch) | |
| tree | 624cdbaff079e14a26fc22f7741a1452b54555b9 /main/stratum_client.c | |
| parent | 4ce93d0470e8ab2402486c893f50bfdf216752e6 (diff) | |
Phase 8c-8f: Extract portal, stratum_client, mint_health, client into tollgate_core
New component modules:
- tollgate_core_portal.c/h: template rendering, usage calc, captive URI detection
- tollgate_core_stratum_client.c/h: Stratum V1 JSON protocol parsing, message building
- tollgate_core_mint_health.c/h: mint health state tracking, recovery threshold logic
- tollgate_core_client.c/h: discovery/session/usage JSON parsing, renewal check, price calc
Main shims updated to delegate pure logic to component:
- captive_portal.c: uses tollgate_core_portal_render(), format_usage(), is_captive_uri()
- stratum_client.c: uses tollgate_core_stratum_parse_notify/build_*()
- mint_health.c: uses tollgate_core_mint_health_update/is_reachable/mark_unreachable()
- tollgate_client.c: uses tollgate_core_client_parse_*/should_renew/calc_price_per_min()
4 new unit tests (test_portal, test_stratum_client, test_mint_health_core, test_client_core)
All 25 unit tests pass. ESP-IDF build passes (68% partition free).
Diffstat (limited to 'main/stratum_client.c')
| -rw-r--r-- | main/stratum_client.c | 95 |
1 files changed, 36 insertions, 59 deletions
diff --git a/main/stratum_client.c b/main/stratum_client.c index a308a5b..14f0880 100644 --- a/main/stratum_client.c +++ b/main/stratum_client.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #include "stratum_client.h" | 1 | #include "stratum_client.h" |
| 2 | #include "stratum_proxy.h" | 2 | #include "stratum_proxy.h" |
| 3 | #include "tollgate_core_mining.h" | 3 | #include "tollgate_core_mining.h" |
| 4 | #include "tollgate_core_stratum_client.h" | ||
| 4 | #include "config.h" | 5 | #include "config.h" |
| 5 | #include "esp_log.h" | 6 | #include "esp_log.h" |
| 6 | #include "esp_transport.h" | 7 | #include "esp_transport.h" |
| @@ -66,76 +67,53 @@ static esp_err_t stratum_connect(const char *host, uint16_t port) | |||
| 66 | static void send_subscribe(void) | 67 | static void send_subscribe(void) |
| 67 | { | 68 | { |
| 68 | char subscribe[256]; | 69 | char subscribe[256]; |
| 69 | snprintf(subscribe, sizeof(subscribe), | 70 | int len = tollgate_core_stratum_build_subscribe(subscribe, sizeof(subscribe), s_req_id++); |
| 70 | "{\"id\":%lu,\"method\":\"mining.subscribe\",\"params\":[\"TollGate/1.0\"]}\n", | 71 | if (len > 0) { |
| 71 | (unsigned long)s_req_id++); | 72 | esp_transport_write(s_transport, subscribe, len, 5000); |
| 72 | esp_transport_write(s_transport, subscribe, strlen(subscribe), 5000); | 73 | ESP_LOGI(TAG, "Sent mining.subscribe"); |
| 73 | ESP_LOGI(TAG, "Sent mining.subscribe"); | 74 | } |
| 74 | } | 75 | } |
| 75 | 76 | ||
| 76 | static void send_authorize(void) | 77 | static void send_authorize(void) |
| 77 | { | 78 | { |
| 78 | const tollgate_config_t *cfg = tollgate_config_get(); | 79 | const tollgate_config_t *cfg = tollgate_config_get(); |
| 79 | char authorize[512]; | 80 | char authorize[512]; |
| 80 | snprintf(authorize, sizeof(authorize), | 81 | int len = tollgate_core_stratum_build_authorize(authorize, sizeof(authorize), |
| 81 | "{\"id\":%lu,\"method\":\"mining.authorize\",\"params\":[\"%s\",\"%s\"]}\n", | 82 | s_req_id++, cfg->stratum_user, cfg->stratum_pass); |
| 82 | (unsigned long)s_req_id++, cfg->stratum_user, cfg->stratum_pass); | 83 | if (len > 0) { |
| 83 | esp_transport_write(s_transport, authorize, strlen(authorize), 5000); | 84 | esp_transport_write(s_transport, authorize, len, 5000); |
| 84 | ESP_LOGI(TAG, "Sent mining.authorize for user=%s", cfg->stratum_user); | 85 | ESP_LOGI(TAG, "Sent mining.authorize for user=%s", cfg->stratum_user); |
| 85 | } | ||
| 86 | |||
| 87 | static void hex_to_bytes(const char *hex, uint8_t *out, int len) | ||
| 88 | { | ||
| 89 | for (int i = 0; i < len && hex[i * 2] && hex[i * 2 + 1]; i++) { | ||
| 90 | char byte[3] = {hex[i * 2], hex[i * 2 + 1], 0}; | ||
| 91 | out[i] = (uint8_t)strtoul(byte, NULL, 16); | ||
| 92 | } | 86 | } |
| 93 | } | 87 | } |
| 94 | 88 | ||
| 95 | static void handle_mining_notify(cJSON *params) | 89 | static void handle_mining_notify(cJSON *params) |
| 96 | { | 90 | { |
| 97 | if (!params || !cJSON_IsArray(params) || cJSON_GetArraySize(params) < 6) return; | 91 | tollgate_stratum_job_t job = {0}; |
| 98 | 92 | uint32_t nbits = 0; | |
| 99 | cJSON *p_job_id = cJSON_GetArrayItem(params, 0); | 93 | if (!tollgate_core_stratum_parse_notify(params, &job, &nbits)) return; |
| 100 | cJSON *p_prevhash = cJSON_GetArrayItem(params, 1); | 94 | |
| 101 | cJSON *p_version = cJSON_GetArrayItem(params, 5); | 95 | stratum_job_t proxy_job = {0}; |
| 102 | cJSON *p_nbits = cJSON_GetArrayItem(params, 6); | 96 | proxy_job.job_id = job.job_id; |
| 103 | cJSON *p_ntime = cJSON_GetArrayItem(params, 7); | 97 | memcpy(proxy_job.prevhash, job.prevhash, 32); |
| 104 | 98 | proxy_job.version = job.version; | |
| 105 | if (!p_job_id || !p_prevhash || !p_nbits) return; | 99 | proxy_job.nbits = job.nbits; |
| 106 | 100 | proxy_job.ntime = job.ntime; | |
| 107 | stratum_job_t job = {0}; | 101 | memcpy(proxy_job.target, job.target, 32); |
| 108 | job.job_id = (uint32_t)atoi(p_job_id->valuestring); | 102 | proxy_job.target_len = job.target_len; |
| 109 | job.valid = true; | 103 | proxy_job.valid = job.valid; |
| 110 | 104 | ||
| 111 | hex_to_bytes(p_prevhash->valuestring, job.prevhash, 32); | 105 | tollgate_core_mining_set_current_nbits(proxy_job.nbits); |
| 112 | 106 | stratum_proxy_set_job(&proxy_job); | |
| 113 | if (p_version && cJSON_IsString(p_version)) { | 107 | |
| 114 | job.version = (uint32_t)strtoul(p_version->valuestring, NULL, 16); | 108 | if (nbits) s_state.nbits = nbits; |
| 115 | } | ||
| 116 | if (p_nbits && cJSON_IsString(p_nbits)) { | ||
| 117 | job.nbits = (uint32_t)strtoul(p_nbits->valuestring, NULL, 16); | ||
| 118 | s_state.nbits = job.nbits; | ||
| 119 | } | ||
| 120 | if (p_ntime && cJSON_IsString(p_ntime)) { | ||
| 121 | job.ntime = (uint32_t)strtoul(p_ntime->valuestring, NULL, 16); | ||
| 122 | } | ||
| 123 | |||
| 124 | memset(job.target, 0xFF, 32); | ||
| 125 | job.target_len = 32; | ||
| 126 | |||
| 127 | tollgate_core_mining_set_current_nbits(job.nbits); | ||
| 128 | stratum_proxy_set_job(&job); | ||
| 129 | |||
| 130 | ESP_LOGI(TAG, "New mining job: id=%lu, nbits=0x%08lx", (unsigned long)job.job_id, (unsigned long)job.nbits); | 109 | ESP_LOGI(TAG, "New mining job: id=%lu, nbits=0x%08lx", (unsigned long)job.job_id, (unsigned long)job.nbits); |
| 131 | } | 110 | } |
| 132 | 111 | ||
| 133 | static void handle_mining_set_difficulty(cJSON *params) | 112 | static void handle_mining_set_difficulty(cJSON *params) |
| 134 | { | 113 | { |
| 135 | if (!params || !cJSON_IsArray(params) || cJSON_GetArraySize(params) < 1) return; | 114 | uint64_t diff = 0; |
| 136 | cJSON *diff = cJSON_GetArrayItem(params, 0); | 115 | if (tollgate_core_stratum_parse_difficulty(params, &diff)) { |
| 137 | if (diff && cJSON_IsNumber(diff)) { | 116 | s_state.difficulty = diff; |
| 138 | s_state.difficulty = (uint64_t)diff->valuedouble; | ||
| 139 | ESP_LOGI(TAG, "Pool set difficulty: %llu", (unsigned long long)s_state.difficulty); | 117 | ESP_LOGI(TAG, "Pool set difficulty: %llu", (unsigned long long)s_state.difficulty); |
| 140 | } | 118 | } |
| 141 | } | 119 | } |
| @@ -243,12 +221,11 @@ esp_err_t stratum_client_submit_share(uint32_t job_id, uint32_t nonce, uint32_t | |||
| 243 | const tollgate_config_t *cfg = tollgate_config_get(); | 221 | const tollgate_config_t *cfg = tollgate_config_get(); |
| 244 | 222 | ||
| 245 | char submit[512]; | 223 | char submit[512]; |
| 246 | snprintf(submit, sizeof(submit), | 224 | int len = tollgate_core_stratum_build_submit(submit, sizeof(submit), s_req_id++, |
| 247 | "{\"id\":%lu,\"method\":\"mining.submit\",\"params\":[\"%s\",\"%lu\",\"%08lx\",\"%08lx\",\"%08lx\"]}\n", | 225 | cfg->stratum_user, job_id, ntime, nonce, version); |
| 248 | (unsigned long)s_req_id++, cfg->stratum_user, | 226 | if (len <= 0) return ESP_FAIL; |
| 249 | (unsigned long)job_id, (unsigned long)ntime, (unsigned long)nonce, (unsigned long)version); | ||
| 250 | 227 | ||
| 251 | int written = esp_transport_write(s_transport, submit, strlen(submit), 5000); | 228 | int written = esp_transport_write(s_transport, submit, len, 5000); |
| 252 | if (written < 0) { | 229 | if (written < 0) { |
| 253 | ESP_LOGW(TAG, "Failed to submit share"); | 230 | ESP_LOGW(TAG, "Failed to submit share"); |
| 254 | s_state.shares_rejected++; | 231 | s_state.shares_rejected++; |