upleb.uk

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

summaryrefslogtreecommitdiff
path: root/components/wisp_relay/sub_manager.h
diff options
context:
space:
mode:
authorYour Name <you@example.com>2026-05-19 02:31:19 +0530
committerYour Name <you@example.com>2026-05-19 02:32:41 +0530
commit81f2dc52dc42d01c89dff45a5407ec40b8863052 (patch)
tree15018c2438639ca89dc6d33a5144c10d0b1c2af0 /components/wisp_relay/sub_manager.h
parent75688d55b3c8d13c8c9a50da9668ec408f684cb3 (diff)
feat: local Nostr relay with relay selection, sync, and integration tests
Local Nostr relay (NIP-01) on port 4869 with LittleFS 4MB storage. All events published locally first, then synced to public relays via REQ-diff. Relay selection via NIP-11 HTTP probing with NIP-77 scoring and auto-failover. Components: - wisp_relay: 16-file local relay (ws_server, storage_engine, sub_manager, broadcaster, relay_validator, router, handlers, rate_limiter, nip11, deletion, flash_monitor, relay_types) - esp_littlefs: LittleFS VFS integration (git submodule) - negentropy: for future NIP-77 binary sync (git submodule) New source files: - local_relay.c/h: thin wrapper for relay init/start/publish - relay_selector.c/h: NIP-11 probe + scoring + auto-failover - sync_manager.c/h: REQ-diff sync (primary 30min, fallback 6h) Bug fixes: - config.c: use-after-free (cJSON_Delete before seed_relays/sync parsing) - local_relay: moved init to app_main for boot-time start (not gated on STA IP) Flash layout: 4MB LittleFS partition at 0x500000 for relay_store Test results (Board B, live hardware): - Smoke: ping + HTTP 4869 + NIP-11: PASS - NIP-11 info document: 10/11 PASS - WS pub/sub (connect, REQ/EOSE, EVENT/OK, CLOSE, concurrent): 6/6 PASS - Unit tests (relay_validator + relay_selector): 13/13 PASS Hardware test make targets in physical-router-test-automation/: - make relay-build, relay-flash-b, relay-test-smoke/nip11/pubsub/sync/full
Diffstat (limited to 'components/wisp_relay/sub_manager.h')
-rw-r--r--components/wisp_relay/sub_manager.h92
1 files changed, 92 insertions, 0 deletions
diff --git a/components/wisp_relay/sub_manager.h b/components/wisp_relay/sub_manager.h
new file mode 100644
index 0000000..64afb04
--- /dev/null
+++ b/components/wisp_relay/sub_manager.h
@@ -0,0 +1,92 @@
1#ifndef SUB_MANAGER_H
2#define SUB_MANAGER_H
3
4#include <stdbool.h>
5#include <stdint.h>
6#include "esp_err.h"
7#include "freertos/FreeRTOS.h"
8#include "freertos/semphr.h"
9#include "relay_types.h"
10
11#define SUB_MAX_TOTAL 64
12#define SUB_MAX_PER_CONN 8
13#define SUB_MAX_FILTERS 4
14#define SUB_MAX_ID_LEN 64
15
16#define SUB_MAX_FILTER_IDS 20
17#define SUB_MAX_FILTER_AUTHORS 20
18#define SUB_MAX_FILTER_KINDS 20
19#define SUB_MAX_FILTER_ETAGS 20
20#define SUB_MAX_FILTER_PTAGS 20
21
22typedef enum {
23 SUB_OK = 0,
24 SUB_ERR_INVALID,
25 SUB_ERR_TOO_MANY_FILTERS,
26 SUB_ERR_MEMORY,
27 SUB_ERR_NOT_FOUND,
28} sub_error_t;
29
30typedef struct {
31 char *ids[SUB_MAX_FILTER_IDS];
32 size_t ids_count;
33 char *authors[SUB_MAX_FILTER_AUTHORS];
34 size_t authors_count;
35 int32_t kinds[SUB_MAX_FILTER_KINDS];
36 size_t kinds_count;
37 char *e_tags[SUB_MAX_FILTER_ETAGS];
38 size_t e_tags_count;
39 char *p_tags[SUB_MAX_FILTER_PTAGS];
40 size_t p_tags_count;
41 int64_t since;
42 int64_t until;
43 int limit;
44} sub_filter_t;
45
46typedef struct {
47 char sub_id[SUB_MAX_ID_LEN + 1];
48 int conn_fd;
49 sub_filter_t filters[SUB_MAX_FILTERS];
50 uint8_t filter_count;
51 uint16_t events_sent;
52 bool active;
53} subscription_t;
54
55typedef struct sub_manager {
56 subscription_t subs[SUB_MAX_TOTAL];
57 SemaphoreHandle_t lock;
58 uint16_t active_count;
59} sub_manager_t;
60
61typedef struct {
62 int conn_fd;
63 char sub_id[SUB_MAX_ID_LEN + 1];
64} sub_match_entry_t;
65
66typedef struct {
67 sub_match_entry_t matches[SUB_MAX_TOTAL];
68 uint8_t count;
69} sub_match_result_t;
70
71esp_err_t sub_manager_init(sub_manager_t *mgr);
72void sub_manager_destroy(sub_manager_t *mgr);
73
74sub_error_t sub_manager_add(sub_manager_t *mgr, int conn_fd,
75 const char *sub_id,
76 const sub_filter_t *filters,
77 size_t filter_count);
78
79sub_error_t sub_manager_remove(sub_manager_t *mgr, int conn_fd,
80 const char *sub_id);
81
82void sub_manager_remove_all(sub_manager_t *mgr, int conn_fd);
83
84void sub_manager_match_json(sub_manager_t *mgr, const char *event_json,
85 size_t event_len, int event_kind,
86 const char *event_pubkey_hex,
87 uint64_t event_created_at,
88 sub_match_result_t *result);
89
90uint8_t sub_manager_count(sub_manager_t *mgr, int conn_fd);
91
92#endif