upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/components/tollgate_core/src
diff options
context:
space:
mode:
Diffstat (limited to 'components/tollgate_core/src')
-rw-r--r--components/tollgate_core/src/tollgate_core_client.c146
-rw-r--r--components/tollgate_core/src/tollgate_core_client.h51
-rw-r--r--components/tollgate_core/src/tollgate_core_mint_health.c91
-rw-r--r--components/tollgate_core/src/tollgate_core_mint_health.h50
-rw-r--r--components/tollgate_core/src/tollgate_core_portal.c149
-rw-r--r--components/tollgate_core/src/tollgate_core_portal.h34
-rw-r--r--components/tollgate_core/src/tollgate_core_stratum_client.c91
-rw-r--r--components/tollgate_core/src/tollgate_core_stratum_client.h50
8 files changed, 662 insertions, 0 deletions
diff --git a/components/tollgate_core/src/tollgate_core_client.c b/components/tollgate_core/src/tollgate_core_client.c
new file mode 100644
index 0000000..9e8508a
--- /dev/null
+++ b/components/tollgate_core/src/tollgate_core_client.c
@@ -0,0 +1,146 @@
1#include "tollgate_core_client.h"
2#include "cJSON.h"
3#include <string.h>
4#include <stdlib.h>
5
6bool tollgate_core_client_parse_discovery(const char *json_str, tollgate_discovery_t *out)
7{
8 cJSON *root = cJSON_Parse(json_str);
9 if (!root) return false;
10
11 cJSON *kind = cJSON_GetObjectItemCaseSensitive(root, "kind");
12 if (!kind || !cJSON_IsNumber(kind) || kind->valueint != 10021) {
13 cJSON_Delete(root);
14 return false;
15 }
16
17 memset(out, 0, sizeof(tollgate_discovery_t));
18 out->is_tollgate = true;
19
20 cJSON *tags = cJSON_GetObjectItemCaseSensitive(root, "tags");
21 if (!tags || !cJSON_IsArray(tags)) {
22 cJSON_Delete(root);
23 return true;
24 }
25
26 int tag_count = cJSON_GetArraySize(tags);
27 for (int i = 0; i < tag_count; i++) {
28 cJSON *tag = cJSON_GetArrayItem(tags, i);
29 if (!tag || !cJSON_IsArray(tag)) continue;
30
31 int tag_len = cJSON_GetArraySize(tag);
32 if (tag_len < 2) continue;
33
34 cJSON *tag_name = cJSON_GetArrayItem(tag, 0);
35 if (!tag_name || !cJSON_IsString(tag_name)) continue;
36
37 if (strcmp(tag_name->valuestring, "metric") == 0) {
38 cJSON *val = cJSON_GetArrayItem(tag, 1);
39 if (val && cJSON_IsString(val)) {
40 strncpy(out->metric, val->valuestring, sizeof(out->metric) - 1);
41 }
42 } else if (strcmp(tag_name->valuestring, "step_size") == 0) {
43 cJSON *val = cJSON_GetArrayItem(tag, 1);
44 if (val && cJSON_IsString(val)) {
45 out->step_size_ms = atoi(val->valuestring);
46 }
47 } else if (strcmp(tag_name->valuestring, "price_per_step") == 0 && tag_len >= 4) {
48 cJSON *payment_type = cJSON_GetArrayItem(tag, 2);
49
50 if (cJSON_IsString(payment_type) && strcmp(payment_type->valuestring, "mining") == 0 && tag_len >= 5) {
51 out->mining_available = true;
52 cJSON *port_val = cJSON_GetArrayItem(tag, 3);
53 if (port_val && cJSON_IsString(port_val)) {
54 out->mining_port = (uint16_t)atoi(port_val->valuestring);
55 }
56 } else {
57 cJSON *amount = cJSON_GetArrayItem(tag, 2);
58 cJSON *mint = cJSON_GetArrayItem(tag, 4);
59
60 if (amount && cJSON_IsString(amount)) {
61 out->price_per_step = atoi(amount->valuestring);
62 }
63 if (mint && cJSON_IsString(mint)) {
64 strncpy(out->mint_url, mint->valuestring, sizeof(out->mint_url) - 1);
65 }
66 }
67 }
68 }
69
70 cJSON_Delete(root);
71 return true;
72}
73
74bool tollgate_core_client_parse_session(const char *json_str, int64_t *allotment_ms_out)
75{
76 cJSON *root = cJSON_Parse(json_str);
77 if (!root) return false;
78
79 cJSON *kind = cJSON_GetObjectItemCaseSensitive(root, "kind");
80 if (!kind || !cJSON_IsNumber(kind)) {
81 cJSON_Delete(root);
82 return false;
83 }
84
85 if (kind->valueint != 1022) {
86 cJSON_Delete(root);
87 return false;
88 }
89
90 cJSON *tags = cJSON_GetObjectItemCaseSensitive(root, "tags");
91 if (tags && cJSON_IsArray(tags)) {
92 int tag_count = cJSON_GetArraySize(tags);
93 for (int i = 0; i < tag_count; i++) {
94 cJSON *tag = cJSON_GetArrayItem(tags, i);
95 if (!tag || !cJSON_IsArray(tag)) continue;
96 cJSON *tag_name = cJSON_GetArrayItem(tag, 0);
97 if (tag_name && cJSON_IsString(tag_name) && strcmp(tag_name->valuestring, "allotment") == 0) {
98 cJSON *val = cJSON_GetArrayItem(tag, 1);
99 if (val && cJSON_IsString(val)) {
100 *allotment_ms_out = atoll(val->valuestring);
101 }
102 }
103 }
104 }
105
106 cJSON_Delete(root);
107 return true;
108}
109
110bool tollgate_core_client_parse_usage(const char *resp, int64_t *remaining_out, int64_t *total_out)
111{
112 char remaining_str[32] = {0};
113 char total_str[32] = {0};
114 const char *slash = strchr(resp, '/');
115 if (!slash) return false;
116
117 size_t rlen = slash - resp;
118 if (rlen >= sizeof(remaining_str)) return false;
119 memcpy(remaining_str, resp, rlen);
120 strncpy(total_str, slash + 1, sizeof(total_str) - 1);
121
122 *remaining_out = atoll(remaining_str);
123 *total_out = atoll(total_str);
124 return true;
125}
126
127bool tollgate_core_client_should_renew(int64_t remaining_ms, int64_t allotment_ms, int threshold_pct)
128{
129 if (threshold_pct <= 0) threshold_pct = 20;
130 if (allotment_ms <= 0 || remaining_ms < 0) return false;
131
132 int remaining_pct = (int)((remaining_ms * 100) / allotment_ms);
133 return remaining_pct <= threshold_pct;
134}
135
136int tollgate_core_client_calc_price_per_min(int price_per_step, int step_size_ms)
137{
138 if (step_size_ms <= 0) step_size_ms = 1;
139 return price_per_step * 60000 / step_size_ms;
140}
141
142int tollgate_core_client_calc_steps(int steps_to_buy, int price_per_step, int discovery_price)
143{
144 if (steps_to_buy <= 0) steps_to_buy = 1;
145 return steps_to_buy * discovery_price;
146}
diff --git a/components/tollgate_core/src/tollgate_core_client.h b/components/tollgate_core/src/tollgate_core_client.h
new file mode 100644
index 0000000..32b90e6
--- /dev/null
+++ b/components/tollgate_core/src/tollgate_core_client.h
@@ -0,0 +1,51 @@
1#ifndef TOLLGATE_CORE_CLIENT_H
2#define TOLLGATE_CORE_CLIENT_H
3
4#include <stdint.h>
5#include <stdbool.h>
6
7#define TG_CLIENT_MAX_MINT_URL 256
8#define TG_CLIENT_MAX_METRIC 32
9#define TG_CLIENT_MAX_GW_IP_LEN 16
10
11typedef enum {
12 TG_CLIENT_IDLE,
13 TG_CLIENT_DETECTING,
14 TG_CLIENT_NO_TOLLGATE,
15 TG_CLIENT_NEEDS_PAY,
16 TG_CLIENT_PAYING,
17 TG_CLIENT_PAID,
18 TG_CLIENT_RENEWING,
19 TG_CLIENT_MINING,
20 TG_CLIENT_ERROR
21} tollgate_client_state_t;
22
23typedef struct {
24 bool is_tollgate;
25 int price_per_step;
26 int step_size_ms;
27 char mint_url[TG_CLIENT_MAX_MINT_URL];
28 char metric[TG_CLIENT_MAX_METRIC];
29 bool mining_available;
30 uint16_t mining_port;
31} tollgate_discovery_t;
32
33typedef struct {
34 const char *ssid;
35 int price_per_step;
36 uint32_t step_size;
37} tollgate_client_market_entry_t;
38
39bool tollgate_core_client_parse_discovery(const char *json_str, tollgate_discovery_t *out);
40
41bool tollgate_core_client_parse_session(const char *json_str, int64_t *allotment_ms_out);
42
43bool tollgate_core_client_parse_usage(const char *resp, int64_t *remaining_out, int64_t *total_out);
44
45bool tollgate_core_client_should_renew(int64_t remaining_ms, int64_t allotment_ms, int threshold_pct);
46
47int tollgate_core_client_calc_price_per_min(int price_per_step, int step_size_ms);
48
49int tollgate_core_client_calc_steps(int steps_to_buy, int price_per_step, int discovery_price);
50
51#endif
diff --git a/components/tollgate_core/src/tollgate_core_mint_health.c b/components/tollgate_core/src/tollgate_core_mint_health.c
new file mode 100644
index 0000000..c810003
--- /dev/null
+++ b/components/tollgate_core/src/tollgate_core_mint_health.c
@@ -0,0 +1,91 @@
1#include "tollgate_core_mint_health.h"
2#include <string.h>
3
4void tollgate_core_mint_health_init(const char urls[][256], int count)
5{
6}
7
8void tollgate_core_mint_health_update(tollgate_mint_health_t *state,
9 int mint_index,
10 bool probe_ok,
11 int http_status,
12 int err_code,
13 int64_t probe_time_ms)
14{
15 if (!state || mint_index < 0 || mint_index >= state->count) return;
16
17 tollgate_mint_status_t *m = &state->mints[mint_index];
18 m->last_probe_ms = probe_time_ms;
19 m->last_http_status = probe_ok ? http_status : 0;
20 m->last_err = probe_ok ? 0 : err_code;
21
22 if (probe_ok) {
23 m->consecutive_successes++;
24 if (m->consecutive_successes >= TG_MINT_HEALTH_RECOVERY_THRESHOLD) {
25 m->reachable = true;
26 }
27 } else {
28 m->reachable = false;
29 m->consecutive_successes = 0;
30 }
31}
32
33void tollgate_core_mint_health_update_initial(tollgate_mint_health_t *state,
34 int mint_index,
35 bool probe_ok,
36 int http_status,
37 int err_code,
38 int64_t probe_time_ms)
39{
40 if (!state || mint_index < 0 || mint_index >= state->count) return;
41
42 tollgate_mint_status_t *m = &state->mints[mint_index];
43 m->last_probe_ms = probe_time_ms;
44 m->last_http_status = probe_ok ? http_status : 0;
45 m->last_err = probe_ok ? 0 : err_code;
46
47 if (probe_ok) {
48 m->consecutive_successes = TG_MINT_HEALTH_RECOVERY_THRESHOLD;
49 m->reachable = true;
50 } else {
51 m->consecutive_successes = 0;
52 m->reachable = false;
53 }
54}
55
56bool tollgate_core_mint_health_is_reachable(const tollgate_mint_health_t *state,
57 const char *url)
58{
59 if (!state || !url) return false;
60 for (int i = 0; i < state->count; i++) {
61 if (strcmp(state->mints[i].url, url) == 0 || strstr(url, state->mints[i].url) != NULL) {
62 return state->mints[i].reachable;
63 }
64 }
65 return false;
66}
67
68void tollgate_core_mint_health_mark_unreachable(tollgate_mint_health_t *state,
69 const char *url)
70{
71 if (!state || !url) return;
72 for (int i = 0; i < state->count; i++) {
73 if (strcmp(state->mints[i].url, url) == 0 || strstr(url, state->mints[i].url) != NULL) {
74 if (state->mints[i].reachable) {
75 state->mints[i].reachable = false;
76 state->mints[i].consecutive_successes = 0;
77 }
78 break;
79 }
80 }
81}
82
83int tollgate_core_mint_health_count_reachable(const tollgate_mint_health_t *state)
84{
85 if (!state) return 0;
86 int count = 0;
87 for (int i = 0; i < state->count; i++) {
88 if (state->mints[i].reachable) count++;
89 }
90 return count;
91}
diff --git a/components/tollgate_core/src/tollgate_core_mint_health.h b/components/tollgate_core/src/tollgate_core_mint_health.h
new file mode 100644
index 0000000..4435a14
--- /dev/null
+++ b/components/tollgate_core/src/tollgate_core_mint_health.h
@@ -0,0 +1,50 @@
1#ifndef TOLLGATE_CORE_MINT_HEALTH_H
2#define TOLLGATE_CORE_MINT_HEALTH_H
3
4#include <stdint.h>
5#include <stdbool.h>
6
7#define TG_MINT_HEALTH_MAX 8
8#define TG_MINT_HEALTH_RECOVERY_THRESHOLD 3
9
10typedef struct {
11 char url[256];
12 bool reachable;
13 uint8_t consecutive_successes;
14 int64_t last_probe_ms;
15 int last_http_status;
16 int last_err;
17} tollgate_mint_status_t;
18
19typedef struct {
20 tollgate_mint_status_t mints[TG_MINT_HEALTH_MAX];
21 int count;
22} tollgate_mint_health_t;
23
24typedef void (*tollgate_mint_health_changed_fn)(int old_reachable, int new_reachable);
25
26void tollgate_core_mint_health_init(const char urls[][256], int count);
27
28void tollgate_core_mint_health_update(tollgate_mint_health_t *state,
29 int mint_index,
30 bool probe_ok,
31 int http_status,
32 int err_code,
33 int64_t probe_time_ms);
34
35void tollgate_core_mint_health_update_initial(tollgate_mint_health_t *state,
36 int mint_index,
37 bool probe_ok,
38 int http_status,
39 int err_code,
40 int64_t probe_time_ms);
41
42bool tollgate_core_mint_health_is_reachable(const tollgate_mint_health_t *state,
43 const char *url);
44
45void tollgate_core_mint_health_mark_unreachable(tollgate_mint_health_t *state,
46 const char *url);
47
48int tollgate_core_mint_health_count_reachable(const tollgate_mint_health_t *state);
49
50#endif
diff --git a/components/tollgate_core/src/tollgate_core_portal.c b/components/tollgate_core/src/tollgate_core_portal.c
new file mode 100644
index 0000000..ef2ae1e
--- /dev/null
+++ b/components/tollgate_core/src/tollgate_core_portal.c
@@ -0,0 +1,149 @@
1#include "tollgate_core_portal.h"
2#include <string.h>
3#include <stdio.h>
4#include <stdlib.h>
5
6static const char *CAPTIVE_URIS[] = {
7 "/generate_204",
8 "/hotspot-detect.html",
9 "/canonical.html",
10 "/success.txt",
11 "/ncsi.txt",
12 "/connecttest.txt",
13 "/wpad.dat",
14 NULL
15};
16
17char *tollgate_core_portal_template_replace(const char *tpl, const char *key, const char *val)
18{
19 const char *p;
20 size_t klen = strlen(key);
21 size_t vlen = strlen(val);
22 size_t tlen = strlen(tpl);
23 size_t extra = 0;
24
25 p = tpl;
26 while ((p = strstr(p, key)) != NULL) {
27 extra += vlen - klen;
28 p += klen;
29 }
30
31 size_t out_size = tlen + extra + 1;
32 char *out = malloc(out_size);
33 if (!out) return NULL;
34
35 char *dst = out;
36 p = tpl;
37 while (*p) {
38 const char *found = strstr(p, key);
39 if (found) {
40 memcpy(dst, p, found - p);
41 dst += found - p;
42 memcpy(dst, val, vlen);
43 dst += vlen;
44 p = found + klen;
45 } else {
46 strcpy(dst, p);
47 dst += strlen(p);
48 break;
49 }
50 }
51 *dst = '\0';
52 return out;
53}
54
55char *tollgate_core_portal_render(const char *tpl,
56 const tollgate_portal_sub_t *subs,
57 int nsubs)
58{
59 size_t tpl_len = strlen(tpl);
60
61 size_t extra = 0;
62 for (int i = 0; i < nsubs; i++) {
63 const char *p = tpl;
64 size_t klen = strlen(subs[i].key);
65 while ((p = strstr(p, subs[i].key)) != NULL) {
66 extra += strlen(subs[i].val) - klen;
67 p += klen;
68 }
69 }
70
71 size_t out_size = tpl_len + extra + 1;
72 char *html = malloc(out_size);
73 if (!html) return NULL;
74
75 char *out = html;
76 const char *src = tpl;
77 while (*src) {
78 const char *earliest = NULL;
79 int ei = -1;
80 for (int i = 0; i < nsubs; i++) {
81 const char *found = strstr(src, subs[i].key);
82 if (found && (earliest == NULL || found < earliest)) {
83 earliest = found;
84 ei = i;
85 }
86 }
87 if (earliest) {
88 size_t vlen = strlen(subs[ei].val);
89 memcpy(out, src, earliest - src);
90 out += earliest - src;
91 memcpy(out, subs[ei].val, vlen);
92 out += vlen;
93 src = earliest + strlen(subs[ei].key);
94 } else {
95 strcpy(out, src);
96 out += strlen(src);
97 break;
98 }
99 }
100 *out = '\0';
101 return html;
102}
103
104bool tollgate_core_portal_calc_usage(const tg_session_t *session,
105 const char *metric,
106 int64_t now_ms,
107 int64_t *remaining_out,
108 int64_t *total_out)
109{
110 if (!session || !session->active) return false;
111
112 bool is_bytes = (strcmp(metric, "bytes") == 0);
113
114 if (is_bytes) {
115 int64_t remaining = (int64_t)session->allotment_bytes - (int64_t)session->bytes_consumed;
116 if (remaining < 0) remaining = 0;
117 *remaining_out = remaining;
118 *total_out = (int64_t)session->allotment_bytes;
119 } else {
120 int64_t elapsed = now_ms - session->start_time_ms;
121 int64_t remaining = (int64_t)session->allotment_ms - elapsed;
122 if (remaining < 0) remaining = 0;
123 *remaining_out = remaining;
124 *total_out = (int64_t)session->allotment_ms;
125 }
126 return true;
127}
128
129int tollgate_core_portal_format_usage(const tg_session_t *session,
130 const char *metric,
131 int64_t now_ms,
132 char *buf,
133 size_t buf_size)
134{
135 int64_t remaining = 0, total = 0;
136 if (!tollgate_core_portal_calc_usage(session, metric, now_ms, &remaining, &total)) {
137 return snprintf(buf, buf_size, "-1/-1");
138 }
139 return snprintf(buf, buf_size, "%lld/%llu", (long long)remaining, (unsigned long long)total);
140}
141
142bool tollgate_core_portal_is_captive_uri(const char *uri)
143{
144 if (!uri) return false;
145 for (int i = 0; CAPTIVE_URIS[i] != NULL; i++) {
146 if (strcmp(uri, CAPTIVE_URIS[i]) == 0) return true;
147 }
148 return false;
149}
diff --git a/components/tollgate_core/src/tollgate_core_portal.h b/components/tollgate_core/src/tollgate_core_portal.h
new file mode 100644
index 0000000..20c0552
--- /dev/null
+++ b/components/tollgate_core/src/tollgate_core_portal.h
@@ -0,0 +1,34 @@
1#ifndef TOLLGATE_CORE_PORTAL_H
2#define TOLLGATE_CORE_PORTAL_H
3
4#include "tollgate_core_session.h"
5#include <stdint.h>
6#include <stddef.h>
7#include <stdbool.h>
8
9typedef struct {
10 const char *key;
11 const char *val;
12} tollgate_portal_sub_t;
13
14char *tollgate_core_portal_template_replace(const char *tpl, const char *key, const char *val);
15
16char *tollgate_core_portal_render(const char *tpl,
17 const tollgate_portal_sub_t *subs,
18 int nsubs);
19
20bool tollgate_core_portal_calc_usage(const tg_session_t *session,
21 const char *metric,
22 int64_t now_ms,
23 int64_t *remaining_out,
24 int64_t *total_out);
25
26int tollgate_core_portal_format_usage(const tg_session_t *session,
27 const char *metric,
28 int64_t now_ms,
29 char *buf,
30 size_t buf_size);
31
32bool tollgate_core_portal_is_captive_uri(const char *uri);
33
34#endif
diff --git a/components/tollgate_core/src/tollgate_core_stratum_client.c b/components/tollgate_core/src/tollgate_core_stratum_client.c
new file mode 100644
index 0000000..8cf22da
--- /dev/null
+++ b/components/tollgate_core/src/tollgate_core_stratum_client.c
@@ -0,0 +1,91 @@
1#include "tollgate_core_stratum_client.h"
2#include "cJSON.h"
3#include <string.h>
4#include <stdio.h>
5#include <stdlib.h>
6
7void tollgate_core_stratum_hex_to_bytes(const char *hex, uint8_t *out, int len)
8{
9 for (int i = 0; i < len && hex[i * 2] && hex[i * 2 + 1]; i++) {
10 char byte[3] = {hex[i * 2], hex[i * 2 + 1], 0};
11 out[i] = (uint8_t)strtoul(byte, NULL, 16);
12 }
13}
14
15bool tollgate_core_stratum_parse_notify(const void *params_json,
16 tollgate_stratum_job_t *job,
17 uint32_t *out_nbits)
18{
19 const cJSON *params = (const cJSON *)params_json;
20 if (!params || !cJSON_IsArray(params) || cJSON_GetArraySize(params) < 6) return false;
21
22 const cJSON *p_job_id = cJSON_GetArrayItem(params, 0);
23 const cJSON *p_prevhash = cJSON_GetArrayItem(params, 1);
24 const cJSON *p_version = cJSON_GetArrayItem(params, 5);
25 const cJSON *p_nbits = cJSON_GetArrayItem(params, 6);
26 const cJSON *p_ntime = cJSON_GetArrayItem(params, 7);
27
28 if (!p_job_id || !p_prevhash || !p_nbits) return false;
29
30 memset(job, 0, sizeof(*job));
31 job->job_id = (uint32_t)atoi(p_job_id->valuestring);
32 job->valid = true;
33
34 tollgate_core_stratum_hex_to_bytes(p_prevhash->valuestring, job->prevhash, 32);
35
36 if (p_version && cJSON_IsString(p_version)) {
37 job->version = (uint32_t)strtoul(p_version->valuestring, NULL, 16);
38 }
39 if (p_nbits && cJSON_IsString(p_nbits)) {
40 job->nbits = (uint32_t)strtoul(p_nbits->valuestring, NULL, 16);
41 if (out_nbits) *out_nbits = job->nbits;
42 }
43 if (p_ntime && cJSON_IsString(p_ntime)) {
44 job->ntime = (uint32_t)strtoul(p_ntime->valuestring, NULL, 16);
45 }
46
47 memset(job->target, 0xFF, 32);
48 job->target_len = 32;
49
50 return true;
51}
52
53bool tollgate_core_stratum_parse_difficulty(const void *params_json,
54 uint64_t *difficulty_out)
55{
56 const cJSON *params = (const cJSON *)params_json;
57 if (!params || !cJSON_IsArray(params) || cJSON_GetArraySize(params) < 1) return false;
58
59 const cJSON *diff = cJSON_GetArrayItem(params, 0);
60 if (diff && cJSON_IsNumber(diff)) {
61 *difficulty_out = (uint64_t)diff->valuedouble;
62 return true;
63 }
64 return false;
65}
66
67int tollgate_core_stratum_build_subscribe(char *buf, size_t buf_size, uint32_t req_id)
68{
69 return snprintf(buf, buf_size,
70 "{\"id\":%lu,\"method\":\"mining.subscribe\",\"params\":[\"TollGate/1.0\"]}\n",
71 (unsigned long)req_id);
72}
73
74int tollgate_core_stratum_build_authorize(char *buf, size_t buf_size, uint32_t req_id,
75 const char *user, const char *pass)
76{
77 return snprintf(buf, buf_size,
78 "{\"id\":%lu,\"method\":\"mining.authorize\",\"params\":[\"%s\",\"%s\"]}\n",
79 (unsigned long)req_id, user, pass);
80}
81
82int tollgate_core_stratum_build_submit(char *buf, size_t buf_size, uint32_t req_id,
83 const char *user, uint32_t job_id,
84 uint32_t ntime, uint32_t nonce, uint32_t version)
85{
86 return snprintf(buf, buf_size,
87 "{\"id\":%lu,\"method\":\"mining.submit\",\"params\":[\"%s\",\"%lu\",\"%08lx\",\"%08lx\",\"%08lx\"]}\n",
88 (unsigned long)req_id, user,
89 (unsigned long)job_id, (unsigned long)ntime,
90 (unsigned long)nonce, (unsigned long)version);
91}
diff --git a/components/tollgate_core/src/tollgate_core_stratum_client.h b/components/tollgate_core/src/tollgate_core_stratum_client.h
new file mode 100644
index 0000000..fdcce1c
--- /dev/null
+++ b/components/tollgate_core/src/tollgate_core_stratum_client.h
@@ -0,0 +1,50 @@
1#ifndef TOLLGATE_CORE_STRATUM_CLIENT_H
2#define TOLLGATE_CORE_STRATUM_CLIENT_H
3
4#include <stdint.h>
5#include <stddef.h>
6#include <stdbool.h>
7
8#define TG_STRATUM_MAX_JOB_ID_LEN 32
9
10typedef struct {
11 uint32_t job_id;
12 uint8_t prevhash[32];
13 uint8_t merkle_root[32];
14 uint32_t ntime;
15 uint32_t nbits;
16 uint32_t version;
17 uint8_t target[32];
18 int target_len;
19 bool valid;
20} tollgate_stratum_job_t;
21
22typedef struct {
23 bool connected;
24 char pool_host[128];
25 uint16_t pool_port;
26 uint32_t nbits;
27 uint64_t difficulty;
28 uint64_t shares_accepted;
29 uint64_t shares_rejected;
30} tollgate_stratum_client_state_t;
31
32void tollgate_core_stratum_hex_to_bytes(const char *hex, uint8_t *out, int len);
33
34bool tollgate_core_stratum_parse_notify(const void *params_json,
35 tollgate_stratum_job_t *job,
36 uint32_t *out_nbits);
37
38bool tollgate_core_stratum_parse_difficulty(const void *params_json,
39 uint64_t *difficulty_out);
40
41int tollgate_core_stratum_build_subscribe(char *buf, size_t buf_size, uint32_t req_id);
42
43int tollgate_core_stratum_build_authorize(char *buf, size_t buf_size, uint32_t req_id,
44 const char *user, const char *pass);
45
46int tollgate_core_stratum_build_submit(char *buf, size_t buf_size, uint32_t req_id,
47 const char *user, uint32_t job_id,
48 uint32_t ntime, uint32_t nonce, uint32_t version);
49
50#endif