upleb.uk

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

summaryrefslogtreecommitdiff
path: root/PLAN_TOLLGATE_CORE_EXTRACTION.md
diff options
context:
space:
mode:
authorYour Name <you@example.com>2026-05-23 02:18:41 +0530
committerYour Name <you@example.com>2026-05-23 02:18:41 +0530
commit10c69b0ddc34a1fafada3f8b68a622b4aa2bea77 (patch)
treeee85d02a1569adc70364b6acaea0beb0b4038526 /PLAN_TOLLGATE_CORE_EXTRACTION.md
parent969dfe9ea52ed304ae44d7f7adbc5219f90497dd (diff)
chore: fix unit test build rules, add relay_selector+relay_validator tests, persist core extraction planHEADmaster
Diffstat (limited to 'PLAN_TOLLGATE_CORE_EXTRACTION.md')
-rw-r--r--PLAN_TOLLGATE_CORE_EXTRACTION.md281
1 files changed, 281 insertions, 0 deletions
diff --git a/PLAN_TOLLGATE_CORE_EXTRACTION.md b/PLAN_TOLLGATE_CORE_EXTRACTION.md
new file mode 100644
index 0000000..28b9ac3
--- /dev/null
+++ b/PLAN_TOLLGATE_CORE_EXTRACTION.md
@@ -0,0 +1,281 @@
1# TollGate Core Extraction Plan
2
3## Goal
4
5Extract TollGate business logic into a **reusable standalone C library** (`tollgate_core/`) wrapped by a **thin ESP-IDF component** (`components/tollgate_esp/`), so that:
6
7- **BitAxe/NerdQAxePlus** gets: full captive portal + Stratum V1 mining + eCash payment + session management
8- **ESP32-TollGate** gets: all of the above + Nostr identity + relay + CVM + display
9- **Desktop/CI** gets: pure logic tests with no ESP-IDF stubs needed
10
11---
12
13## Architecture Overview
14
15```
16┌─────────────────────────────────────────────────────────┐
17│ Consumer Application (main/) │
18│ esp32-tollgate: tollgate_main.c, tollgate_api.c, etc. │
19│ esp-miner: main.cpp, asic_result_task.cpp │
20└────────────────────┬────────────────────────────────────┘
21
22 ┌────────────┴─────────────┐
23 │ components/tollgate_esp │ ← ESP-IDF component wrapper
24 │ (implements platform_t │ via idf_component.yml
25 │ using ESP-IDF APIs) │
26 └────────────┬────────────┘
27
28 ┌────────────────┴────────────────┐
29 │ tollgate_core/ │ ← Standalone C library
30 │ (zero ESP-IDF deps) │
31 │ │
32 │ Layer 0: Pure Logic │
33 │ cashu_decode, allotment, │
34 │ session state machine, │
35 │ mining_payment economics │
36 │ │
37 │ Layer 1: Protocol Logic │
38 │ DNS parser + server logic, │
39 │ Stratum V1 protocol, │
40 │ beacon IE builder/parser │
41 │ │
42 │ Layer 2: Platform-dependent │
43 │ (via tollgate_platform.h) │
44 │ HTTP client, task creation, │
45 │ socket I/O, time source, │
46 │ logging, wallet operations │
47 └─────────────────────────────────┘
48```
49
50## Module Classification
51
52| Module | Layer | Goes into tollgate_core? | Notes |
53|--------|-------|--------------------------|-------|
54| `cashu.c` — token decode, allotment math | 0 | **Yes** | Pure C + cJSON + mbedtls base64/sha256 |
55| `session.c` — lifecycle, expiry, extend | 0 | **Yes** | Pure state machine, time via callback |
56| `mining_payment.c` — hashprice, allotment | 0 | **Yes** | Pure math (nbits→difficulty→hashprice→allotment) |
57| `dns_server.c` — DNS protocol, per-client auth | 1 | **Yes** | Protocol parser pure; socket IO via platform |
58| `stratum_proxy.c` — SV1 TCP server | 1 | **Yes** | JSON protocol pure; TCP via platform |
59| `stratum_client.c` — SV1 pool client | 1 | **Yes** | JSON protocol pure; TCP via platform |
60| `beacon_price.c` — WiFi IE builder/parser | 1 | **Yes** | IE struct packing pure; esp_wifi_set_vendor_ie via platform |
61| `market.c` — IE scanner, cheapest finder | 1 | **Yes** | IE parser + price comparison pure; scan results via platform |
62| `firewall.c` — client allowlist, NAT filter | 2 | **Yes** | Allowlist logic pure; lwIP hook + MAC resolve via platform |
63| `config.c` — JSON config parsing | — | **No** | Stays in consumer. Core takes config via `platform_t` |
64| `identity.c` — HMAC derivation from nsec | — | **No** | Nostr-specific, stays in esp32-tollgate |
65| `nostr_event.c` — Schnorr signing | — | **No** | Nostr-specific |
66| `wifistr.c` — kind 38787 events | — | **No** | Nostr-specific |
67| `cvm_server.c` — MCP over Nostr | — | **No** | Nostr-specific |
68| `relay_selector.c` — NIP-11 probing | — | **No** | Nostr-specific |
69| `sync_manager.c` — REQ-diff sync | — | **No** | Nostr-specific |
70| `local_relay.c` — NIP-01 server | — | **No** | Nostr-specific |
71| `display.c` — TFT rendering | — | **No** | Hardware-specific |
72| `tollgate_client.c` — downstream auto-pay | — | **No** | Consumes core API, but isn't core itself |
73| `nucula_lib` — wallet C++ impl | — | **No** | External dep; core uses wallet via platform callback |
74| `mint_health.c` — health probe + wallet queue | — | **Partial** | Health state machine extractable; wallet queue stays in consumer |
75
76## Platform Interface (`tollgate_platform.h`)
77
78```c
79typedef struct {
80 // --- Config access ---
81 uint16_t (*get_price_sats)(void);
82 int32_t (*get_step_ms)(void);
83 int64_t (*get_step_bytes)(void);
84 const char* (*get_mint_url)(void);
85 const char* (*get_metric)(void);
86
87 // --- Time ---
88 int64_t (*get_time_ms)(void);
89
90 // --- Logging ---
91 void (*log_info)(const char *tag, const char *fmt, ...);
92 void (*log_warn)(const char *tag, const char *fmt, ...);
93 void (*log_error)(const char *tag, const char *fmt, ...);
94
95 // --- Wallet (can be NULL — accepts payment without spending) ---
96 bool (*wallet_receive)(const char *token);
97 bool (*wallet_send)(uint64_t amount, char *buf, size_t buf_len);
98 uint64_t (*wallet_balance)(void);
99
100 // --- HTTP client (for checkstate) ---
101 int (*http_post)(const char *url, const char *headers,
102 const char *body, int body_len,
103 char *resp, int resp_len);
104
105 // --- Task/thread creation ---
106 bool (*create_task)(void (*fn)(void*), void *arg,
107 const char *name, int stack_bytes, int priority);
108
109 // --- Socket I/O (for DNS + Stratum) ---
110 int (*socket_udp)(void);
111 int (*socket_tcp)(void);
112 int (*socket_bind)(int fd, uint32_t ip, uint16_t port);
113 int (*socket_listen)(int fd, int backlog);
114 int (*socket_accept)(int fd, uint32_t *client_ip, uint16_t *client_port);
115 int (*socket_recvfrom)(int fd, void *buf, int len,
116 uint32_t *src_ip, uint16_t *src_port);
117 int (*socket_sendto)(int fd, const void *buf, int len,
118 uint32_t dest_ip, uint16_t dest_port);
119 int (*socket_read)(int fd, void *buf, int len);
120 int (*socket_write)(int fd, const void *buf, int len);
121 void (*socket_close)(int fd);
122 void (*socket_set_recv_timeout)(int fd, int ms);
123
124 // --- WiFi/MAC (for firewall + beacon + market) ---
125 bool (*get_sta_mac_ip_list)(void *list_out, int max, int *count_out);
126 bool (*set_vendor_ie)(bool enable, const void *ie_data, int ie_len);
127 int (*arp_get_mac)(uint32_t ip, uint8_t *mac_out);
128 void (*napt_enable)(uint32_t ip, bool enable);
129
130 // --- Mining config ---
131 bool (*mining_enabled)(void);
132 const char* (*get_stratum_host)(void);
133 uint16_t (*get_stratum_port)(void);
134 const char* (*get_stratum_user)(void);
135 const char* (*get_stratum_pass)(void);
136 uint16_t (*get_mining_port)(void);
137 uint64_t (*get_hashprice_override)(void);
138
139 // --- Random ---
140 void (*fill_random)(void *buf, int len);
141
142} tollgate_platform_t;
143```
144
145## Directory Structure
146
147```
148tollgate_core/ ← standalone C library (CMakeLists.txt, no ESP-IDF)
149 CMakeLists.txt
150 include/
151 tollgate_core.h
152 tollgate_platform.h
153 src/
154 tollgate_core.c
155 tollgate_cashu.c/h
156 tollgate_session.c/h
157 tollgate_dns.c/h
158 tollgate_firewall.c/h
159 tollgate_mining.c/h
160 tollgate_stratum_client.c/h
161 tollgate_stratum_proxy.c/h
162 tollgate_beacon.c/h
163 tollgate_market.c/h
164
165components/tollgate_esp/ ← ESP-IDF component wrapper
166 CMakeLists.txt
167 idf_component.yml
168 src/
169 tollgate_esp_platform.c
170 tollgate_esp_http.c
171 tollgate_esp_sockets.c
172 tollgate_esp_wifi.c
173 tollgate_esp_wallet.c
174 tollgate_esp_tasks.c
175
176main/ ← esp32-tollgate specific (shrinks)
177 tollgate_main.c, tollgate_api.c, captive_portal.c
178 config.c, identity.c, nostr_event.c, wifistr.c
179 cvm_server.c, mcp_handler.c, local_relay.c
180 relay_selector.c, sync_manager.c
181 display.c, font.c
182 mint_health.c, tollgate_client.c
183```
184
185---
186
187## Implementation Phases
188
189### Phase 0: Housekeeping
190
191- [x] Archive stale branches to `/home/c03rad0r/mining-work-backup/` as git bundles
192- [x] Commit `PLAN_pytest_migration.md`
193- [x] Fix `nucula_src` submodule drift
194- [ ] Fix missing unit test build rules (`test_relay_selector.c`, `test_relay_validator.c`)
195- [ ] Remove broken test binaries from TESTS list (`test_display`, `test_negentropy_adapter`)
196- [ ] Run `make test-unit` — confirm green baseline
197- [ ] Create branch `feature/tollgate-core-v2` from master
198
199### Phase 1: Create Skeleton
200
201- [ ] Create `tollgate_core/` directory with `CMakeLists.txt`, `include/`, `src/`
202- [ ] Define `tollgate_platform.h` interface (all callbacks)
203- [ ] Define `tollgate_core.h` public API
204- [ ] Create empty `tollgate_core.c` with `tollgate_core_init()`, `tollgate_core_tick()`
205- [ ] Create `components/tollgate_esp/` skeleton with empty `tollgate_esp_platform.c`
206- [ ] Wire into `main/CMakeLists.txt` as dependency
207- [ ] Verify: project builds, runs on hardware, no behavioral change
208
209### Phase 2: Extract Layer 0 — Pure Logic
210
211- [ ] `tollgate_cashu.c` — token decode, allotment math, checkstate (via platform HTTP)
212- [ ] `tollgate_session.c` — lifecycle, expiry, extend, bytes/time support
213- [ ] `tollgate_mining.c` — hashprice, nbits→difficulty, shares-to-allotment, client stats
214- [ ] Port unit tests to test `tollgate_core/` directly (no ESP-IDF stubs)
215- [ ] Verify: `make test-unit` passes with new tests
216
217### Phase 3: Extract Layer 1 — Protocol Logic
218
219- [ ] `tollgate_dns.c` — DNS protocol parser, hijack, forward, per-client auth
220- [ ] `tollgate_firewall.c` — client allowlist, NAT filter, lwIP hook
221- [ ] `tollgate_stratum_client.c` — SV1 pool client (subscribe, authorize, submit)
222- [ ] `tollgate_stratum_proxy.c` — SV1 local proxy (TCP server, job broadcast)
223- [ ] `tollgate_beacon.c` — Vendor IE builder/parser
224- [ ] `tollgate_market.c` — price scanner, LRU entries, cheapest finder
225- [ ] Wire `tollgate_core.c` orchestrator to all subsystems
226- [ ] Verify: Build on hardware, run all integration tests
227
228### Phase 4: ESP-IDF Wrapper
229
230- [ ] `tollgate_esp_platform.c` — implement all `tollgate_platform_t` callbacks
231- [ ] `components/tollgate_esp/CMakeLists.txt` — REQUIRES tollgate_core + ESP-IDF
232- [ ] `components/tollgate_esp/idf_component.yml` — IDF Component Registry
233- [ ] Verify: Full build + flash + all tests pass on Board A
234
235### Phase 5: Wire main/ to Use tollgate_core
236
237- [ ] Update `main/tollgate_main.c` — replace direct calls with tollgate_core API
238- [ ] Update `main/tollgate_api.c` — payment → `tollgate_core_process_payment()`
239- [ ] Update `main/captive_portal.c` — grant/reset → tollgate_core calls
240- [ ] Remove old `main/session.c`, `main/firewall.c`, `main/dns_server.c`, `main/cashu.c`, etc.
241- [ ] Verify: `make test-unit` passes, flash to board, run `make pytest-all-a`
242
243### Phase 6: NerdQAxePlus Integration
244
245- [ ] Update `main/tollgate_platform.cpp` to implement new `tollgate_platform_t`
246- [ ] Wire `asic_result_task.cpp` → `tollgate_core_process_share()`
247- [ ] Wire `main.cpp` → `tollgate_core_init()` + `tollgate_core_dns_start()` + `tollgate_core_tick()`
248- [ ] Verify: `BOARD=NERDAXE TOLLGATE=1 idf.py build` passes
249
250### Phase 7: Publishing + CI
251
252- [ ] Publish `tollgate_esp` component to IDF Component Registry
253- [ ] Add CI pipeline: build tollgate_core with host gcc + run pure-logic tests
254- [ ] Add CI pipeline: build tollgate_esp for ESP32-S3 target
255- [ ] Update documentation
256
257---
258
259## Risks and Mitigations
260
261| Risk | Impact | Mitigation |
262|------|--------|------------|
263| RAM budget — tollgate_core statics consume more memory | Board crashes | Profile before/after with `heap_caps_get_free_size`. Keep static arrays same size. |
264| Platform callback overhead on hot path (firewall) | Performance | Firewall filter already a function pointer. No extra overhead. |
265| nucula_lib coupling — C++ but core is C | Build complexity | Wallet stays behind platform callback. Core never includes nucula headers. |
266| Existing branches have useful work | Lost effort | Archived to `/home/c03rad0r/mining-work-backup/` as git bundles. |
267| Test breakage during extraction | Regression | Run full test suite after each phase. Commit after each green phase. |
268
269## Estimated Time
270
271| Phase | Description | Time |
272|-------|-------------|------|
273| 0 | Housekeeping | 30 min |
274| 1 | Skeleton | 2 hours |
275| 2 | Layer 0: Pure logic | 4 hours |
276| 3 | Layer 1: Protocol logic | 6 hours |
277| 4 | ESP-IDF wrapper | 4 hours |
278| 5 | Wire main/ | 6 hours |
279| 6 | NerdQAxePlus integration | 4 hours |
280| 7 | Publishing + CI | 2 hours |
281| **Total** | | **~29 hours** |