mirror of
git://jb55.com/damus
synced 2024-10-04 19:00:42 +00:00
ndb: update nostrdb
This include various fixes for parsing and key decoding
This commit is contained in:
parent
88306d00a3
commit
07dfa3b1fb
@ -18,6 +18,7 @@ struct ndb_json_parser {
|
||||
struct ndb_builder builder;
|
||||
jsmn_parser json_parser;
|
||||
jsmntok_t *toks, *toks_end;
|
||||
int i;
|
||||
int num_tokens;
|
||||
};
|
||||
|
||||
@ -102,6 +103,8 @@ static inline int ndb_json_parser_parse(struct ndb_json_parser *p)
|
||||
p->num_tokens =
|
||||
jsmn_parse(&p->json_parser, p->json, p->json_len, p->toks, cap);
|
||||
|
||||
p->i = 0;
|
||||
|
||||
return p->num_tokens;
|
||||
}
|
||||
|
||||
@ -242,7 +245,7 @@ static int ndb_event_commitment(struct ndb_note *ev, unsigned char *buf, int buf
|
||||
struct cursor cur;
|
||||
int ok;
|
||||
|
||||
if (!hex_encode(ev->pubkey, sizeof(ev->pubkey), pubkey, 32))
|
||||
if (!hex_encode(ev->pubkey, sizeof(ev->pubkey), pubkey, sizeof(pubkey)))
|
||||
return 0;
|
||||
|
||||
make_cursor(buf, buf + buflen, &cur);
|
||||
@ -351,7 +354,9 @@ int ndb_builder_finalize(struct ndb_builder *builder, struct ndb_note **note,
|
||||
unsigned char *end = builder->mem.end;
|
||||
unsigned char *start = (unsigned char*)(*note) + total_size;
|
||||
|
||||
if (!ndb_calculate_id(*note, start, end - start))
|
||||
ndb_builder_set_pubkey(builder, keypair->pubkey);
|
||||
|
||||
if (!ndb_calculate_id(builder->note, start, end - start))
|
||||
return 0;
|
||||
|
||||
if (!ndb_sign_id(keypair, (*note)->id, (*note)->sig))
|
||||
@ -645,92 +650,181 @@ static int parse_unsigned_int(const char *start, int len, unsigned int *num)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int ndb_note_from_json(const char *json, int len, struct ndb_note **note,
|
||||
int ndb_ws_event_from_json(const char *json, int len, struct ndb_tce *tce,
|
||||
unsigned char *buf, int bufsize)
|
||||
{
|
||||
jsmntok_t *tok = NULL;
|
||||
unsigned char hexbuf[64];
|
||||
|
||||
int i, tok_len, res;
|
||||
const char *start;
|
||||
int tok_len, res;
|
||||
struct ndb_json_parser parser;
|
||||
|
||||
tce->subid_len = 0;
|
||||
tce->subid = "";
|
||||
|
||||
ndb_json_parser_init(&parser, json, len, buf, bufsize);
|
||||
res = ndb_json_parser_parse(&parser);
|
||||
if (res < 0)
|
||||
if ((res = ndb_json_parser_parse(&parser)) < 0)
|
||||
return res;
|
||||
|
||||
if (parser.num_tokens < 1 || parser.toks[0].type != JSMN_OBJECT)
|
||||
if (parser.num_tokens < 3 || parser.toks[0].type != JSMN_ARRAY)
|
||||
return 0;
|
||||
|
||||
for (i = 1; i < parser.num_tokens; i++) {
|
||||
tok = &parser.toks[i];
|
||||
parser.i = 1;
|
||||
tok = &parser.toks[parser.i++];
|
||||
tok_len = toksize(tok);
|
||||
if (tok->type != JSMN_STRING)
|
||||
return 0;
|
||||
|
||||
if (tok_len == 5 && !memcmp("EVENT", json + tok->start, 5)) {
|
||||
tce->evtype = NDB_TCE_EVENT;
|
||||
struct ndb_event *ev = &tce->event;
|
||||
|
||||
tok = &parser.toks[parser.i++];
|
||||
if (tok->type != JSMN_STRING)
|
||||
return 0;
|
||||
|
||||
tce->subid = json + tok->start;
|
||||
tce->subid_len = toksize(tok);
|
||||
|
||||
return ndb_parse_json_note(&parser, &ev->note);
|
||||
} else if (tok_len == 4 && !memcmp("EOSE", json + tok->start, 4)) {
|
||||
tce->evtype = NDB_TCE_EOSE;
|
||||
|
||||
tok = &parser.toks[parser.i++];
|
||||
if (tok->type != JSMN_STRING)
|
||||
return 0;
|
||||
|
||||
tce->subid = json + tok->start;
|
||||
tce->subid_len = toksize(tok);
|
||||
return 1;
|
||||
} else if (tok_len == 2 && !memcmp("OK", json + tok->start, 2)) {
|
||||
if (parser.num_tokens != 5)
|
||||
return 0;
|
||||
|
||||
struct ndb_command_result *cr = &tce->command_result;
|
||||
|
||||
tce->evtype = NDB_TCE_OK;
|
||||
|
||||
tok = &parser.toks[parser.i++];
|
||||
if (tok->type != JSMN_STRING)
|
||||
return 0;
|
||||
|
||||
tce->subid = json + tok->start;
|
||||
tce->subid_len = toksize(tok);
|
||||
|
||||
tok = &parser.toks[parser.i++];
|
||||
if (tok->type != JSMN_PRIMITIVE || toksize(tok) == 0)
|
||||
return 0;
|
||||
|
||||
cr->ok = (json + tok->start)[0] == 't';
|
||||
|
||||
tok = &parser.toks[parser.i++];
|
||||
if (tok->type != JSMN_STRING)
|
||||
return 0;
|
||||
|
||||
tce->command_result.msg = json + tok->start;
|
||||
tce->command_result.msglen = toksize(tok);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ndb_parse_json_note(struct ndb_json_parser *parser, struct ndb_note **note)
|
||||
{
|
||||
jsmntok_t *tok = NULL;
|
||||
unsigned char hexbuf[64];
|
||||
const char *json = parser->json;
|
||||
const char *start;
|
||||
int i, tok_len;
|
||||
|
||||
if (parser->toks[parser->i].type != JSMN_OBJECT)
|
||||
return 0;
|
||||
|
||||
// TODO: build id buffer and verify at end
|
||||
|
||||
for (i = parser->i + 1; i < parser->num_tokens; i++) {
|
||||
tok = &parser->toks[i];
|
||||
start = json + tok->start;
|
||||
tok_len = toksize(tok);
|
||||
|
||||
//printf("toplevel %.*s %d\n", tok_len, json + tok->start, tok->type);
|
||||
if (tok_len == 0 || i + 1 >= parser.num_tokens)
|
||||
if (tok_len == 0 || i + 1 >= parser->num_tokens)
|
||||
continue;
|
||||
|
||||
if (start[0] == 'p' && jsoneq(json, tok, tok_len, "pubkey")) {
|
||||
// pubkey
|
||||
tok = &parser.toks[i+1];
|
||||
tok = &parser->toks[i+1];
|
||||
hex_decode(json + tok->start, toksize(tok), hexbuf, sizeof(hexbuf));
|
||||
ndb_builder_set_pubkey(&parser.builder, hexbuf);
|
||||
ndb_builder_set_pubkey(&parser->builder, hexbuf);
|
||||
} else if (tok_len == 2 && start[0] == 'i' && start[1] == 'd') {
|
||||
// id
|
||||
tok = &parser.toks[i+1];
|
||||
tok = &parser->toks[i+1];
|
||||
hex_decode(json + tok->start, toksize(tok), hexbuf, sizeof(hexbuf));
|
||||
// TODO: validate id
|
||||
ndb_builder_set_id(&parser.builder, hexbuf);
|
||||
ndb_builder_set_id(&parser->builder, hexbuf);
|
||||
} else if (tok_len == 3 && start[0] == 's' && start[1] == 'i' && start[2] == 'g') {
|
||||
// sig
|
||||
tok = &parser.toks[i+1];
|
||||
tok = &parser->toks[i+1];
|
||||
hex_decode(json + tok->start, toksize(tok), hexbuf, sizeof(hexbuf));
|
||||
ndb_builder_set_sig(&parser.builder, hexbuf);
|
||||
ndb_builder_set_sig(&parser->builder, hexbuf);
|
||||
} else if (start[0] == 'k' && jsoneq(json, tok, tok_len, "kind")) {
|
||||
// kind
|
||||
tok = &parser.toks[i+1];
|
||||
tok = &parser->toks[i+1];
|
||||
start = json + tok->start;
|
||||
if (tok->type != JSMN_PRIMITIVE || tok_len <= 0)
|
||||
return 0;
|
||||
if (!parse_unsigned_int(start, toksize(tok),
|
||||
&parser.builder.note->kind))
|
||||
&parser->builder.note->kind))
|
||||
return 0;
|
||||
} else if (start[0] == 'c') {
|
||||
if (jsoneq(json, tok, tok_len, "created_at")) {
|
||||
// created_at
|
||||
tok = &parser.toks[i+1];
|
||||
tok = &parser->toks[i+1];
|
||||
start = json + tok->start;
|
||||
if (tok->type != JSMN_PRIMITIVE || tok_len <= 0)
|
||||
return 0;
|
||||
if (!parse_unsigned_int(start, toksize(tok),
|
||||
&parser.builder.note->created_at))
|
||||
&parser->builder.note->created_at))
|
||||
return 0;
|
||||
} else if (jsoneq(json, tok, tok_len, "content")) {
|
||||
// content
|
||||
tok = &parser.toks[i+1];
|
||||
tok = &parser->toks[i+1];
|
||||
union ndb_packed_str pstr;
|
||||
tok_len = toksize(tok);
|
||||
int written, pack_ids = 0;
|
||||
if (!ndb_builder_make_json_str(&parser.builder,
|
||||
if (!ndb_builder_make_json_str(&parser->builder,
|
||||
json + tok->start,
|
||||
tok_len, &pstr,
|
||||
&written, pack_ids)) {
|
||||
return 0;
|
||||
}
|
||||
parser.builder.note->content_length = written;
|
||||
parser.builder.note->content = pstr;
|
||||
parser->builder.note->content_length = written;
|
||||
parser->builder.note->content = pstr;
|
||||
}
|
||||
} else if (start[0] == 't' && jsoneq(json, tok, tok_len, "tags")) {
|
||||
tok = &parser.toks[i+1];
|
||||
ndb_builder_process_json_tags(&parser, tok);
|
||||
tok = &parser->toks[i+1];
|
||||
ndb_builder_process_json_tags(parser, tok);
|
||||
i += tok->size;
|
||||
}
|
||||
}
|
||||
|
||||
return ndb_builder_finalize(&parser.builder, note, NULL);
|
||||
return ndb_builder_finalize(&parser->builder, note, NULL);
|
||||
}
|
||||
|
||||
int ndb_note_from_json(const char *json, int len, struct ndb_note **note,
|
||||
unsigned char *buf, int bufsize)
|
||||
{
|
||||
struct ndb_json_parser parser;
|
||||
int res;
|
||||
|
||||
ndb_json_parser_init(&parser, json, len, buf, bufsize);
|
||||
if ((res = ndb_json_parser_parse(&parser)) < 0)
|
||||
return res;
|
||||
|
||||
if (parser.num_tokens < 1)
|
||||
return 0;
|
||||
|
||||
return ndb_parse_json_note(&parser, note);
|
||||
}
|
||||
|
||||
void ndb_builder_set_pubkey(struct ndb_builder *builder, unsigned char *pubkey)
|
||||
|
@ -4,6 +4,19 @@
|
||||
#include <inttypes.h>
|
||||
#include "cursor.h"
|
||||
|
||||
#define NDB_PACKED_STR 0x1
|
||||
#define NDB_PACKED_ID 0x2
|
||||
|
||||
struct ndb_json_parser;
|
||||
|
||||
// To-client event types
|
||||
enum tce_type {
|
||||
NDB_TCE_EVENT = 0x1,
|
||||
NDB_TCE_OK = 0x2,
|
||||
NDB_TCE_NOTICE = 0x3,
|
||||
NDB_TCE_EOSE = 0x4,
|
||||
};
|
||||
|
||||
struct ndb_str {
|
||||
unsigned char flag;
|
||||
union {
|
||||
@ -12,9 +25,36 @@ struct ndb_str {
|
||||
};
|
||||
};
|
||||
|
||||
struct ndb_event {
|
||||
struct ndb_note *note;
|
||||
};
|
||||
|
||||
struct ndb_command_result {
|
||||
int ok;
|
||||
const char *msg;
|
||||
int msglen;
|
||||
};
|
||||
|
||||
|
||||
// To-client event
|
||||
struct ndb_tce {
|
||||
enum tce_type evtype;
|
||||
const char *subid;
|
||||
int subid_len;
|
||||
|
||||
union {
|
||||
struct ndb_event event;
|
||||
struct ndb_command_result command_result;
|
||||
};
|
||||
};
|
||||
|
||||
struct ndb_keypair {
|
||||
unsigned char pubkey[32];
|
||||
unsigned char secret[32];
|
||||
|
||||
// this corresponds to secp256k1's keypair type. it's guaranteed to
|
||||
// be 96 bytes according to their docs. I don't want to depend on
|
||||
// the secp256k1 header here so we just use raw bytes.
|
||||
unsigned char pair[96];
|
||||
};
|
||||
|
||||
@ -22,9 +62,6 @@ struct ndb_keypair {
|
||||
// representation
|
||||
#pragma pack(push, 1)
|
||||
|
||||
/// We can store byte data in the string table, so
|
||||
#define NDB_PACKED_STR 0x1
|
||||
#define NDB_PACKED_ID 0x2
|
||||
|
||||
union ndb_packed_str {
|
||||
struct {
|
||||
@ -91,6 +128,9 @@ int ndb_create_keypair(struct ndb_keypair *key);
|
||||
int ndb_decode_key(const char *secstr, struct ndb_keypair *keypair);
|
||||
|
||||
// BUILDER
|
||||
|
||||
int ndb_parse_json_note(struct ndb_json_parser *, struct ndb_note **);
|
||||
int ndb_ws_event_from_json(const char *json, int len, struct ndb_tce *tce, unsigned char *buf, int bufsize);
|
||||
int ndb_note_from_json(const char *json, int len, struct ndb_note **, unsigned char *buf, int buflen);
|
||||
int ndb_builder_init(struct ndb_builder *builder, unsigned char *buf, int bufsize);
|
||||
int ndb_builder_finalize(struct ndb_builder *builder, struct ndb_note **note, struct ndb_keypair *privkey);
|
||||
|
Loading…
Reference in New Issue
Block a user