upleb.uk

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

summaryrefslogtreecommitdiff
path: root/components/wisp_relay/storage_engine.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/storage_engine.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/storage_engine.h')
-rw-r--r--components/wisp_relay/storage_engine.h88
1 files changed, 88 insertions, 0 deletions
diff --git a/components/wisp_relay/storage_engine.h b/components/wisp_relay/storage_engine.h
new file mode 100644
index 0000000..4e17113
--- /dev/null
+++ b/components/wisp_relay/storage_engine.h
@@ -0,0 +1,88 @@
1#ifndef STORAGE_ENGINE_H
2#define STORAGE_ENGINE_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 "freertos/task.h"
10
11#define STORAGE_MAX_EVENTS 5000
12#define STORAGE_MAX_EVENT_SIZE 8192
13#define STORAGE_INDEX_ENTRIES 5000
14#define STORAGE_PARTITION_LABEL "relay_store"
15
16typedef enum {
17 STORAGE_OK = 0,
18 STORAGE_ERR_NOT_INITIALIZED,
19 STORAGE_ERR_FULL,
20 STORAGE_ERR_DUPLICATE,
21 STORAGE_ERR_NOT_FOUND,
22 STORAGE_ERR_IO,
23 STORAGE_ERR_NO_MEM,
24 STORAGE_ERR_SERIALIZE
25} storage_error_t;
26
27#define STORAGE_FLAG_DELETED 0x01
28
29typedef struct __attribute__((packed)) {
30 uint8_t event_id[32];
31 uint32_t created_at;
32 uint32_t expires_at;
33 uint32_t file_index;
34 uint16_t kind;
35 uint8_t pubkey_prefix[4];
36 uint8_t flags;
37 uint8_t reserved;
38} storage_index_entry_t;
39
40typedef struct {
41 uint32_t total_events;
42 uint32_t total_bytes;
43 uint32_t free_bytes;
44 uint32_t oldest_event_ts;
45 uint32_t newest_event_ts;
46} storage_stats_t;
47
48typedef struct storage_engine {
49 storage_index_entry_t *index;
50 uint16_t index_count;
51 uint16_t max_index_entries;
52 uint32_t next_file_index;
53 SemaphoreHandle_t lock;
54 TaskHandle_t cleanup_task;
55 bool initialized;
56 bool cleanup_stop;
57 char mount_point[16];
58 uint32_t default_ttl_sec;
59} storage_engine_t;
60
61esp_err_t storage_init(storage_engine_t *engine, uint32_t default_ttl_sec);
62void storage_destroy(storage_engine_t *engine);
63
64storage_error_t storage_save_event_json(storage_engine_t *engine,
65 const char *event_json,
66 size_t event_json_len);
67
68storage_error_t storage_query_events_json(storage_engine_t *engine,
69 int kind,
70 const char *author_hex,
71 int limit,
72 char ***results,
73 uint16_t *count);
74
75void storage_free_query_results(char **results, uint16_t count);
76
77bool storage_event_exists(storage_engine_t *engine, const uint8_t event_id[32]);
78
79storage_error_t storage_delete_event(storage_engine_t *engine, const uint8_t event_id[32]);
80
81int storage_purge_expired(storage_engine_t *engine);
82int storage_compact_index(storage_engine_t *engine);
83
84void storage_get_stats(storage_engine_t *engine, storage_stats_t *stats);
85
86esp_err_t storage_start_cleanup_task(storage_engine_t *engine);
87
88#endif