nostrdb

an unfairly fast embedded nostr database backed by lmdb
git clone git://jb55.com/nostrdb
Log | Files | Refs | Submodules | README | LICENSE

commit bfa4fad89015939e13f63fd6cc425018d0be4f34
parent 860878c1662b1df65daaab78ea6118d7dd38ca04
Author: William Casarin <jb55@jb55.com>
Date:   Sat, 23 Dec 2023 15:42:36 -0800

bech32: retab

Diffstat:
Msrc/nostr_bech32.c | 486++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/nostr_bech32.h | 74+++++++++++++++++++++++++++++++++++++-------------------------------------
2 files changed, 280 insertions(+), 280 deletions(-)

diff --git a/src/nostr_bech32.c b/src/nostr_bech32.c @@ -1,8 +1,8 @@ // -// nostr_bech32.c -// damus +// nostr_bech32.c +// damus // -// Created by William Casarin on 2023-04-09. +// Created by William Casarin on 2023-04-09. // #include "nostr_bech32.h" @@ -19,288 +19,288 @@ #define TLV_KNOWN_TLVS 4 struct nostr_tlv { - u8 type; - u8 len; - const u8 *value; + u8 type; + u8 len; + const u8 *value; }; struct nostr_tlvs { - struct nostr_tlv tlvs[MAX_TLVS]; - int num_tlvs; + struct nostr_tlv tlvs[MAX_TLVS]; + int num_tlvs; }; static int parse_nostr_tlv(struct cursor *cur, struct nostr_tlv *tlv) { - // get the tlv tag - if (!pull_byte(cur, &tlv->type)) - return 0; - - // unknown, fail! - if (tlv->type >= TLV_KNOWN_TLVS) - return 0; - - // get the length - if (!pull_byte(cur, &tlv->len)) - return 0; - - // is the reported length greater then our buffer? if so fail - if (cur->p + tlv->len > cur->end) - return 0; - - tlv->value = cur->p; - cur->p += tlv->len; - - return 1; + // get the tlv tag + if (!cursor_pull_byte(cur, &tlv->type)) + return 0; + + // unknown, fail! + if (tlv->type >= TLV_KNOWN_TLVS) + return 0; + + // get the length + if (!cursor_pull_byte(cur, &tlv->len)) + return 0; + + // is the reported length greater then our buffer? if so fail + if (cur->p + tlv->len > cur->end) + return 0; + + tlv->value = cur->p; + cur->p += tlv->len; + + return 1; } static int parse_nostr_tlvs(struct cursor *cur, struct nostr_tlvs *tlvs) { - int i; - tlvs->num_tlvs = 0; - - for (i = 0; i < MAX_TLVS; i++) { - if (parse_nostr_tlv(cur, &tlvs->tlvs[i])) { - tlvs->num_tlvs++; - } else { - break; - } - } - - if (tlvs->num_tlvs == 0) - return 0; - - return 1; + int i; + tlvs->num_tlvs = 0; + + for (i = 0; i < MAX_TLVS; i++) { + if (parse_nostr_tlv(cur, &tlvs->tlvs[i])) { + tlvs->num_tlvs++; + } else { + break; + } + } + + if (tlvs->num_tlvs == 0) + return 0; + + return 1; } static int find_tlv(struct nostr_tlvs *tlvs, u8 type, struct nostr_tlv **tlv) { - *tlv = NULL; - - for (int i = 0; i < tlvs->num_tlvs; i++) { - if (tlvs->tlvs[i].type == type) { - *tlv = &tlvs->tlvs[i]; - return 1; - } - } - - return 0; + *tlv = NULL; + + for (int i = 0; i < tlvs->num_tlvs; i++) { + if (tlvs->tlvs[i].type == type) { + *tlv = &tlvs->tlvs[i]; + return 1; + } + } + + return 0; } static int parse_nostr_bech32_type(const char *prefix, enum nostr_bech32_type *type) { - // Parse type - if (strcmp(prefix, "note") == 0) { - *type = NOSTR_BECH32_NOTE; - return 1; - } else if (strcmp(prefix, "npub") == 0) { - *type = NOSTR_BECH32_NPUB; - return 1; - } else if (strcmp(prefix, "nsec") == 0) { - *type = NOSTR_BECH32_NSEC; - return 1; - } else if (strcmp(prefix, "nprofile") == 0) { - *type = NOSTR_BECH32_NPROFILE; - return 1; - } else if (strcmp(prefix, "nevent") == 0) { - *type = NOSTR_BECH32_NEVENT; - return 1; - } else if (strcmp(prefix, "nrelay") == 0) { - *type = NOSTR_BECH32_NRELAY; - return 1; - } else if (strcmp(prefix, "naddr") == 0) { - *type = NOSTR_BECH32_NADDR; - return 1; - } - - return 0; + // Parse type + if (strcmp(prefix, "note") == 0) { + *type = NOSTR_BECH32_NOTE; + return 1; + } else if (strcmp(prefix, "npub") == 0) { + *type = NOSTR_BECH32_NPUB; + return 1; + } else if (strcmp(prefix, "nsec") == 0) { + *type = NOSTR_BECH32_NSEC; + return 1; + } else if (strcmp(prefix, "nprofile") == 0) { + *type = NOSTR_BECH32_NPROFILE; + return 1; + } else if (strcmp(prefix, "nevent") == 0) { + *type = NOSTR_BECH32_NEVENT; + return 1; + } else if (strcmp(prefix, "nrelay") == 0) { + *type = NOSTR_BECH32_NRELAY; + return 1; + } else if (strcmp(prefix, "naddr") == 0) { + *type = NOSTR_BECH32_NADDR; + return 1; + } + + return 0; } static int parse_nostr_bech32_note(struct cursor *cur, struct bech32_note *note) { - return pull_bytes(cur, 32, &note->event_id); + return pull_bytes(cur, 32, &note->event_id); } static int parse_nostr_bech32_npub(struct cursor *cur, struct bech32_npub *npub) { - return pull_bytes(cur, 32, &npub->pubkey); + return pull_bytes(cur, 32, &npub->pubkey); } static int parse_nostr_bech32_nsec(struct cursor *cur, struct bech32_nsec *nsec) { - return pull_bytes(cur, 32, &nsec->nsec); + return pull_bytes(cur, 32, &nsec->nsec); } static int tlvs_to_relays(struct nostr_tlvs *tlvs, struct relays *relays) { - struct nostr_tlv *tlv; - struct str_block *str; - - relays->num_relays = 0; - - for (int i = 0; i < tlvs->num_tlvs; i++) { - tlv = &tlvs->tlvs[i]; - if (tlv->type != TLV_RELAY) - continue; - - if (relays->num_relays + 1 > MAX_RELAYS) - break; - - str = &relays->relays[relays->num_relays++]; - str->start = (const char*)tlv->value; - str->end = (const char*)(tlv->value + tlv->len); - } - - return 1; + struct nostr_tlv *tlv; + struct str_block *str; + + relays->num_relays = 0; + + for (int i = 0; i < tlvs->num_tlvs; i++) { + tlv = &tlvs->tlvs[i]; + if (tlv->type != TLV_RELAY) + continue; + + if (relays->num_relays + 1 > MAX_RELAYS) + break; + + str = &relays->relays[relays->num_relays++]; + str->start = (const char*)tlv->value; + str->end = (const char*)(tlv->value + tlv->len); + } + + return 1; } static int parse_nostr_bech32_nevent(struct cursor *cur, struct bech32_nevent *nevent) { - struct nostr_tlvs tlvs; - struct nostr_tlv *tlv; - - if (!parse_nostr_tlvs(cur, &tlvs)) - return 0; - - if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv)) - return 0; - - if (tlv->len != 32) - return 0; - - nevent->event_id = tlv->value; - - if (find_tlv(&tlvs, TLV_AUTHOR, &tlv)) { - nevent->pubkey = tlv->value; - } else { - nevent->pubkey = NULL; - } - - return tlvs_to_relays(&tlvs, &nevent->relays); + struct nostr_tlvs tlvs; + struct nostr_tlv *tlv; + + if (!parse_nostr_tlvs(cur, &tlvs)) + return 0; + + if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv)) + return 0; + + if (tlv->len != 32) + return 0; + + nevent->event_id = tlv->value; + + if (find_tlv(&tlvs, TLV_AUTHOR, &tlv)) { + nevent->pubkey = tlv->value; + } else { + nevent->pubkey = NULL; + } + + return tlvs_to_relays(&tlvs, &nevent->relays); } static int parse_nostr_bech32_naddr(struct cursor *cur, struct bech32_naddr *naddr) { - struct nostr_tlvs tlvs; - struct nostr_tlv *tlv; - - if (!parse_nostr_tlvs(cur, &tlvs)) - return 0; - - if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv)) - return 0; - - naddr->identifier.start = (const char*)tlv->value; - naddr->identifier.end = (const char*)tlv->value + tlv->len; - - if (!find_tlv(&tlvs, TLV_AUTHOR, &tlv)) - return 0; - - naddr->pubkey = tlv->value; - - return tlvs_to_relays(&tlvs, &naddr->relays); + struct nostr_tlvs tlvs; + struct nostr_tlv *tlv; + + if (!parse_nostr_tlvs(cur, &tlvs)) + return 0; + + if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv)) + return 0; + + naddr->identifier.start = (const char*)tlv->value; + naddr->identifier.end = (const char*)tlv->value + tlv->len; + + if (!find_tlv(&tlvs, TLV_AUTHOR, &tlv)) + return 0; + + naddr->pubkey = tlv->value; + + return tlvs_to_relays(&tlvs, &naddr->relays); } static int parse_nostr_bech32_nprofile(struct cursor *cur, struct bech32_nprofile *nprofile) { - struct nostr_tlvs tlvs; - struct nostr_tlv *tlv; - - if (!parse_nostr_tlvs(cur, &tlvs)) - return 0; - - if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv)) - return 0; - - if (tlv->len != 32) - return 0; - - nprofile->pubkey = tlv->value; - - return tlvs_to_relays(&tlvs, &nprofile->relays); + struct nostr_tlvs tlvs; + struct nostr_tlv *tlv; + + if (!parse_nostr_tlvs(cur, &tlvs)) + return 0; + + if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv)) + return 0; + + if (tlv->len != 32) + return 0; + + nprofile->pubkey = tlv->value; + + return tlvs_to_relays(&tlvs, &nprofile->relays); } static int parse_nostr_bech32_nrelay(struct cursor *cur, struct bech32_nrelay *nrelay) { - struct nostr_tlvs tlvs; - struct nostr_tlv *tlv; - - if (!parse_nostr_tlvs(cur, &tlvs)) - return 0; - - if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv)) - return 0; - - nrelay->relay.start = (const char*)tlv->value; - nrelay->relay.end = (const char*)tlv->value + tlv->len; - - return 1; + struct nostr_tlvs tlvs; + struct nostr_tlv *tlv; + + if (!parse_nostr_tlvs(cur, &tlvs)) + return 0; + + if (!find_tlv(&tlvs, TLV_SPECIAL, &tlv)) + return 0; + + nrelay->relay.start = (const char*)tlv->value; + nrelay->relay.end = (const char*)tlv->value + tlv->len; + + return 1; } int parse_nostr_bech32(struct cursor *cur, struct nostr_bech32 *obj) { - u8 *start, *end; - - start = cur->p; - - if (!consume_until_non_alphanumeric(cur, 1)) { - cur->p = start; - return 0; - } - - end = cur->p; - - size_t data_len; - size_t input_len = end - start; - if (input_len < 10 || input_len > 10000) { - return 0; - } - - obj->buffer = malloc(input_len * 2); - if (!obj->buffer) - return 0; - - u8 data[input_len]; - char prefix[input_len]; - - if (bech32_decode_len(prefix, data, &data_len, (const char*)start, input_len) == BECH32_ENCODING_NONE) { - cur->p = start; - return 0; - } - - obj->buflen = 0; - if (!bech32_convert_bits(obj->buffer, &obj->buflen, 8, data, data_len, 5, 0)) { - goto fail; - } - - if (!parse_nostr_bech32_type(prefix, &obj->type)) { - goto fail; - } - - struct cursor bcur; - make_cursor(obj->buffer, obj->buffer + obj->buflen, &bcur); - - switch (obj->type) { - case NOSTR_BECH32_NOTE: - if (!parse_nostr_bech32_note(&bcur, &obj->data.note)) - goto fail; - break; - case NOSTR_BECH32_NPUB: - if (!parse_nostr_bech32_npub(&bcur, &obj->data.npub)) - goto fail; - break; - case NOSTR_BECH32_NSEC: - if (!parse_nostr_bech32_nsec(&bcur, &obj->data.nsec)) - goto fail; - break; - case NOSTR_BECH32_NEVENT: - if (!parse_nostr_bech32_nevent(&bcur, &obj->data.nevent)) - goto fail; - break; - case NOSTR_BECH32_NADDR: - if (!parse_nostr_bech32_naddr(&bcur, &obj->data.naddr)) - goto fail; - break; - case NOSTR_BECH32_NPROFILE: - if (!parse_nostr_bech32_nprofile(&bcur, &obj->data.nprofile)) - goto fail; - break; - case NOSTR_BECH32_NRELAY: - if (!parse_nostr_bech32_nrelay(&bcur, &obj->data.nrelay)) - goto fail; - break; - } - - return 1; + u8 *start, *end; + + start = cur->p; + + if (!consume_until_non_alphanumeric(cur, 1)) { + cur->p = start; + return 0; + } + + end = cur->p; + + size_t data_len; + size_t input_len = end - start; + if (input_len < 10 || input_len > 10000) { + return 0; + } + + obj->buffer = malloc(input_len * 2); + if (!obj->buffer) + return 0; + + u8 data[input_len]; + char prefix[input_len]; + + if (bech32_decode_len(prefix, data, &data_len, (const char*)start, input_len) == BECH32_ENCODING_NONE) { + cur->p = start; + return 0; + } + + obj->buflen = 0; + if (!bech32_convert_bits(obj->buffer, &obj->buflen, 8, data, data_len, 5, 0)) { + goto fail; + } + + if (!parse_nostr_bech32_type(prefix, &obj->type)) { + goto fail; + } + + struct cursor bcur; + make_cursor(obj->buffer, obj->buffer + obj->buflen, &bcur); + + switch (obj->type) { + case NOSTR_BECH32_NOTE: + if (!parse_nostr_bech32_note(&bcur, &obj->data.note)) + goto fail; + break; + case NOSTR_BECH32_NPUB: + if (!parse_nostr_bech32_npub(&bcur, &obj->data.npub)) + goto fail; + break; + case NOSTR_BECH32_NSEC: + if (!parse_nostr_bech32_nsec(&bcur, &obj->data.nsec)) + goto fail; + break; + case NOSTR_BECH32_NEVENT: + if (!parse_nostr_bech32_nevent(&bcur, &obj->data.nevent)) + goto fail; + break; + case NOSTR_BECH32_NADDR: + if (!parse_nostr_bech32_naddr(&bcur, &obj->data.naddr)) + goto fail; + break; + case NOSTR_BECH32_NPROFILE: + if (!parse_nostr_bech32_nprofile(&bcur, &obj->data.nprofile)) + goto fail; + break; + case NOSTR_BECH32_NRELAY: + if (!parse_nostr_bech32_nrelay(&bcur, &obj->data.nrelay)) + goto fail; + break; + } + + return 1; fail: - free(obj->buffer); - cur->p = start; - return 0; + free(obj->buffer); + cur->p = start; + return 0; } diff --git a/src/nostr_bech32.h b/src/nostr_bech32.h @@ -1,8 +1,8 @@ // -// nostr_bech32.h -// damus +// nostr_bech32.h +// damus // -// Created by William Casarin on 2023-04-09. +// Created by William Casarin on 2023-04-09. // #ifndef nostr_bech32_h @@ -15,67 +15,67 @@ typedef unsigned char u8; #define MAX_RELAYS 10 struct relays { - struct str_block relays[MAX_RELAYS]; - int num_relays; + struct str_block relays[MAX_RELAYS]; + int num_relays; }; enum nostr_bech32_type { - NOSTR_BECH32_NOTE = 1, - NOSTR_BECH32_NPUB = 2, - NOSTR_BECH32_NPROFILE = 3, - NOSTR_BECH32_NEVENT = 4, - NOSTR_BECH32_NRELAY = 5, - NOSTR_BECH32_NADDR = 6, - NOSTR_BECH32_NSEC = 7, + NOSTR_BECH32_NOTE = 1, + NOSTR_BECH32_NPUB = 2, + NOSTR_BECH32_NPROFILE = 3, + NOSTR_BECH32_NEVENT = 4, + NOSTR_BECH32_NRELAY = 5, + NOSTR_BECH32_NADDR = 6, + NOSTR_BECH32_NSEC = 7, }; struct bech32_note { - const u8 *event_id; + const u8 *event_id; }; struct bech32_npub { - const u8 *pubkey; + const u8 *pubkey; }; struct bech32_nsec { - const u8 *nsec; + const u8 *nsec; }; struct bech32_nevent { - struct relays relays; - const u8 *event_id; - const u8 *pubkey; // optional + struct relays relays; + const u8 *event_id; + const u8 *pubkey; // optional }; struct bech32_nprofile { - struct relays relays; - const u8 *pubkey; + struct relays relays; + const u8 *pubkey; }; struct bech32_naddr { - struct relays relays; - struct str_block identifier; - const u8 *pubkey; + struct relays relays; + struct str_block identifier; + const u8 *pubkey; }; struct bech32_nrelay { - struct str_block relay; + struct str_block relay; }; typedef struct nostr_bech32 { - enum nostr_bech32_type type; - u8 *buffer; // holds strings and tlv stuff - size_t buflen; - - union { - struct bech32_note note; - struct bech32_npub npub; - struct bech32_nsec nsec; - struct bech32_nevent nevent; - struct bech32_nprofile nprofile; - struct bech32_naddr naddr; - struct bech32_nrelay nrelay; - } data; + enum nostr_bech32_type type; + u8 *buffer; // holds strings and tlv stuff + size_t buflen; + + union { + struct bech32_note note; + struct bech32_npub npub; + struct bech32_nsec nsec; + struct bech32_nevent nevent; + struct bech32_nprofile nprofile; + struct bech32_naddr naddr; + struct bech32_nrelay nrelay; + } data; } nostr_bech32_t;