Skip to content

Commit 4e75ac7

Browse files
committed
support note id calculation
1 parent 576617e commit 4e75ac7

File tree

3 files changed

+171
-0
lines changed

3 files changed

+171
-0
lines changed

nostrdb.c

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "jsmn.h"
44
#include "hex.h"
55
#include "cursor.h"
6+
#include "sha256.h"
67
#include <stdlib.h>
78
#include <limits.h>
89

@@ -118,6 +119,166 @@ static int cursor_push_unescaped_char(struct cursor *cur, char c1, char c2)
118119
}
119120
}
120121

122+
static int cursor_push_escaped_char(struct cursor *cur, char c)
123+
{
124+
switch (c) {
125+
case '"': return cursor_push_str(cur, "\\\"");
126+
case '\\': return cursor_push_str(cur, "\\\\");
127+
case '\b': return cursor_push_str(cur, "\\b");
128+
case '\f': return cursor_push_str(cur, "\\f");
129+
case '\n': return cursor_push_str(cur, "\\n");
130+
case '\r': return cursor_push_str(cur, "\\r");
131+
case '\t': return cursor_push_str(cur, "\\t");
132+
// TODO: \u hex hex hex hex
133+
}
134+
return cursor_push_byte(cur, c);
135+
}
136+
137+
static int cursor_push_hex_str(struct cursor *cur, unsigned char *buf, int len)
138+
{
139+
int i;
140+
141+
if (len % 2 != 0)
142+
return 0;
143+
144+
if (!cursor_push_byte(cur, '"'))
145+
return 0;
146+
147+
for (i = 0; i < len; i++) {
148+
unsigned int c = ((const unsigned char *)buf)[i];
149+
if (!cursor_push_byte(cur, hexchar(c >> 4)))
150+
return 0;
151+
if (!cursor_push_byte(cur, hexchar(c & 0xF)))
152+
return 0;
153+
}
154+
155+
if (!cursor_push_byte(cur, '"'))
156+
return 0;
157+
158+
return 1;
159+
}
160+
161+
static int cursor_push_jsonstr(struct cursor *cur, const char *str)
162+
{
163+
int i;
164+
int len;
165+
166+
len = strlen(str);
167+
168+
if (!cursor_push_byte(cur, '"'))
169+
return 0;
170+
171+
for (i = 0; i < len; i++) {
172+
if (!cursor_push_escaped_char(cur, str[i]))
173+
return 0;
174+
}
175+
176+
if (!cursor_push_byte(cur, '"'))
177+
return 0;
178+
179+
return 1;
180+
}
181+
182+
183+
static inline int cursor_push_json_tag_str(struct cursor *cur, struct ndb_str str)
184+
{
185+
if (str.flag == NDB_PACKED_ID)
186+
return cursor_push_hex_str(cur, str.id, 32);
187+
188+
return cursor_push_jsonstr(cur, str.str);
189+
}
190+
191+
static int cursor_push_json_tag(struct cursor *cur, struct ndb_note *note,
192+
struct ndb_tag *tag)
193+
{
194+
int i;
195+
196+
if (!cursor_push_byte(cur, '['))
197+
return 0;
198+
199+
for (i = 0; i < tag->count; i++) {
200+
if (!cursor_push_json_tag_str(cur, ndb_note_str(note, &tag->strs[i])))
201+
return 0;
202+
if (i != tag->count-1 && !cursor_push_byte(cur, ','))
203+
return 0;
204+
}
205+
206+
return cursor_push_byte(cur, ']');
207+
}
208+
209+
static int cursor_push_json_tags(struct cursor *cur, struct ndb_note *note)
210+
{
211+
int i;
212+
struct ndb_iterator iter, *it = &iter;
213+
ndb_tags_iterate_start(note, it);
214+
215+
if (!cursor_push_byte(cur, '['))
216+
return 0;
217+
218+
i = 0;
219+
while (ndb_tags_iterate_next(it)) {
220+
if (!cursor_push_json_tag(cur, note, it->tag))
221+
return 0;
222+
if (i != note->tags.count-1 && !cursor_push_str(cur, ","))
223+
return 0;
224+
i++;
225+
}
226+
227+
if (!cursor_push_byte(cur, ']'))
228+
return 0;
229+
230+
return 1;
231+
}
232+
233+
static int ndb_event_commitment(struct ndb_note *ev, unsigned char *buf, int buflen)
234+
{
235+
char timebuf[16] = {0};
236+
char kindbuf[16] = {0};
237+
char pubkey[65];
238+
struct cursor cur;
239+
int ok;
240+
241+
if (!hex_encode(ev->pubkey, sizeof(ev->pubkey), pubkey, 32))
242+
return 0;
243+
244+
make_cursor(buf, buf + buflen, &cur);
245+
246+
snprintf(timebuf, sizeof(timebuf), "%d", ev->created_at);
247+
snprintf(kindbuf, sizeof(kindbuf), "%d", ev->kind);
248+
249+
ok =
250+
cursor_push_str(&cur, "[0,\"") &&
251+
cursor_push_str(&cur, pubkey) &&
252+
cursor_push_str(&cur, "\",") &&
253+
cursor_push_str(&cur, timebuf) &&
254+
cursor_push_str(&cur, ",") &&
255+
cursor_push_str(&cur, kindbuf) &&
256+
cursor_push_str(&cur, ",") &&
257+
cursor_push_json_tags(&cur, ev) &&
258+
cursor_push_str(&cur, ",") &&
259+
cursor_push_jsonstr(&cur, ndb_note_str(ev, &ev->content).str) &&
260+
cursor_push_str(&cur, "]");
261+
262+
if (!ok)
263+
return 0;
264+
265+
return cur.p - cur.start;
266+
}
267+
268+
int ndb_calculate_note_id(struct ndb_note *note, unsigned char *buf, int buflen) {
269+
int len;
270+
271+
if (!(len = ndb_event_commitment(note, buf, buflen)))
272+
return 0;
273+
274+
//fprintf(stderr, "%.*s\n", len, buf);
275+
276+
sha256((struct sha256*)note->id, buf, len);
277+
278+
return 1;
279+
}
280+
281+
121282
int ndb_builder_finalize(struct ndb_builder *builder, struct ndb_note **note)
122283
{
123284
int strings_len = builder->strings.p - builder->strings.start;

nostrdb.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ struct ndb_iterator {
7777
int index;
7878
};
7979

80+
// HELPERS
81+
int ndb_calculate_note_id(struct ndb_note *note, unsigned char *buf, int buflen);
82+
// BYE HELPERS
83+
8084
// HI BUILDER
8185
int ndb_note_from_json(const char *json, int len, struct ndb_note **, unsigned char *buf, int buflen);
8286
int ndb_builder_init(struct ndb_builder *builder, unsigned char *buf, int bufsize);

test.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ static void print_tag(struct ndb_note *note, struct ndb_tag *tag) {
116116
static void test_parse_contact_list()
117117
{
118118
int size, written = 0;
119+
unsigned char id[32];
119120
static const int alloc_size = 2 << 18;
120121
unsigned char *json = malloc(alloc_size);
121122
unsigned char *buf = malloc(alloc_size);
@@ -128,6 +129,11 @@ static void test_parse_contact_list()
128129
assert(size > 0);
129130
assert(size == 34322);
130131

132+
memcpy(id, note->id, 32);
133+
memset(note->id, 0, 32);
134+
assert(ndb_calculate_note_id(note, json, alloc_size));
135+
assert(!memcmp(note->id, id, 32));
136+
131137
const char* expected_content =
132138
"{\"wss://nos.lol\":{\"write\":true,\"read\":true},"
133139
"\"wss://relay.damus.io\":{\"write\":true,\"read\":true},"

0 commit comments

Comments
 (0)