Skip to content

Commit

Permalink
blocks: add note block iterator
Browse files Browse the repository at this point in the history
This adds an api that walks along and pulls compact note block data out of
nostrdb.
  • Loading branch information
jb55 committed Dec 28, 2023
1 parent a841b44 commit 03b4d71
Show file tree
Hide file tree
Showing 9 changed files with 283 additions and 155 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ CFLAGS = -Wall -Wno-misleading-indentation -Wno-unused-function -Werror -O2 -g -
HEADERS = deps/lmdb/lmdb.h deps/secp256k1/include/secp256k1.h src/sha256.h src/nostrdb.h src/cursor.h src/hex.h src/jsmn.h src/config.h src/sha256.h src/random.h src/memchr.h src/cpu.h src/nostr_bech32.h src/block.h src/str_block.h $(C_BINDINGS)
FLATCC_SRCS=deps/flatcc/src/runtime/json_parser.c deps/flatcc/src/runtime/verifier.c deps/flatcc/src/runtime/builder.c deps/flatcc/src/runtime/emitter.c deps/flatcc/src/runtime/refmap.c
BOLT11_SRCS = src/bolt11/bolt11.c src/bolt11/bech32.c src/bolt11/tal.c src/bolt11/talstr.c src/bolt11/take.c src/bolt11/list.c src/bolt11/utf8.c src/bolt11/amount.c src/bolt11/hash_u5.c
SRCS = src/nostrdb.c src/sha256.c src/invoice.c src/nostr_bech32.c src/content_parser.c $(BOLT11_SRCS) $(FLATCC_SRCS)
SRCS = src/nostrdb.c src/sha256.c src/invoice.c src/nostr_bech32.c src/content_parser.c src/block.c $(BOLT11_SRCS) $(FLATCC_SRCS)
LDS = $(OBJS) $(ARS)
OBJS = $(SRCS:.c=.o)
DEPS = $(OBJS) $(HEADERS) $(ARS)
Expand Down
184 changes: 184 additions & 0 deletions src/block.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@


#include "nostrdb.h"
#include "block.h"
#include <stdlib.h>

struct ndb_block_iterator {
const char *content;
struct ndb_blocks *blocks;
struct ndb_block block;
struct cursor cur;
};

int push_str_block(struct cursor *buf, const char *content, struct ndb_str_block *block) {
return cursor_push_varint(buf, block->str - content) &&
cursor_push_varint(buf, block->len);
}

int pull_str_block(struct cursor *buf, const char *content, struct ndb_str_block *block) {
uint32_t start;
if (!cursor_pull_varint_u32(buf, &start))
return 0;

block->str = content + start;

return cursor_pull_varint_u32(buf, &block->len);
}

static int pull_nostr_bech32_type(struct cursor *cur, enum nostr_bech32_type *type)
{
uint64_t inttype;
if (!cursor_pull_varint(cur, &inttype))
return 0;

if (inttype > NOSTR_BECH32_KNOWN_TYPES)
return 0;

*type = inttype;
return 1;
}


static int pull_bech32_mention(const char *content, struct cursor *cur, struct ndb_mention_bech32_block *block) {
uint16_t size;
unsigned char *start;
enum nostr_bech32_type type;

start = cur->p;

if (!pull_str_block(cur, content, &block->str))
return 0;

if (!cursor_pull_u16(cur, &size))
return 0;

if (!pull_nostr_bech32_type(cur, &type))
return 0;

if (!parse_nostr_bech32_buffer(cur, type, &block->bech32))
return 0;

cur->p = start + size;
return 1;
}

static int pull_invoice(const char *content, struct cursor *cur,
struct ndb_invoice_block *block)
{
if (!pull_str_block(cur, content, &block->invstr))
return 0;

return ndb_decode_invoice(cur, &block->invoice);
}

static int pull_block_type(struct cursor *cur, enum ndb_block_type *type)
{
uint32_t itype;
*type = 0;
if (!cursor_pull_varint_u32(cur, &itype))
return 0;

if (itype <= 0 || itype > NDB_NUM_BLOCK_TYPES)
return 0;

*type = itype;
return 1;
}

static int pull_block(const char *content, struct cursor *cur, struct ndb_block *block)
{
unsigned char *start = cur->p;

if (!pull_block_type(cur, &block->type))
return 0;

switch (block->type) {
case BLOCK_HASHTAG:
case BLOCK_TEXT:
case BLOCK_URL:
if (!pull_str_block(cur, content, &block->block.str))
goto fail;
break;

case BLOCK_MENTION_INDEX:
if (!cursor_pull_varint_u32(cur, &block->block.mention_index))
goto fail;
break;

case BLOCK_MENTION_BECH32:
if (!pull_bech32_mention(content, cur, &block->block.mention_bech32))
goto fail;
break;

case BLOCK_INVOICE:
// we only push invoice strs here
if (!pull_invoice(content, cur, &block->block.invoice))
goto fail;
break;
}

return 1;
fail:
cur->p = start;
return 0;
}


enum ndb_block_type ndb_get_block_type(struct ndb_block *block) {
return block->type;
}

// BLOCK ITERATORS
struct ndb_block_iterator *ndb_blocks_iterate_start(const char *content, struct ndb_blocks *blocks) {
struct ndb_block_iterator *iter = malloc(sizeof(*iter));
if (!iter)
return NULL;

iter->blocks = blocks;
iter->content = content;

make_cursor((unsigned char *)blocks->blocks,
blocks->blocks + blocks->blocks_size, &iter->cur);

return iter;
}

void ndb_blocks_iterate_free(struct ndb_block_iterator *iter)
{
if (iter)
free(iter);
}

struct ndb_block *ndb_blocks_iterate_next(struct ndb_block_iterator *iter)
{
while (iter->cur.p < iter->cur.end) {
if (!pull_block(iter->content, &iter->cur, &iter->block))
return NULL;
else
return &iter->block;
}

return NULL;
}

// STR BLOCKS
struct ndb_str_block *ndb_block_str(struct ndb_block *block)
{
switch (block->type) {
case BLOCK_HASHTAG:
case BLOCK_TEXT:
case BLOCK_URL:
return &block->block.str;
case BLOCK_MENTION_INDEX:
return NULL;
case BLOCK_MENTION_BECH32:
return &block->block.mention_bech32.str;
case BLOCK_INVOICE:
return &block->block.invoice.invstr;
}

return NULL;
}
//const char *ndb_str_block_ptr(struct ndb_str_block *);
//uint32_t ndb_str_block_len(struct ndb_str_block *);
29 changes: 12 additions & 17 deletions src/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,49 @@

#include "invoice.h"
#include "str_block.h"
#include "cursor.h"
#include "nostr_bech32.h"
#include "nostrdb.h"
#include <inttypes.h>

#pragma pack(push, 1)

struct ndb_note_blocks {
struct ndb_blocks {
unsigned char version;
unsigned char padding[3];

uint32_t words;
uint32_t num_blocks;
uint32_t blocks_size;
// future expansion
uint32_t reserved[4];
uint32_t reserved[2];
unsigned char blocks[0]; // see ndb_block definition
};

#pragma pack(pop)

enum block_type {
BLOCK_HASHTAG = 1,
BLOCK_TEXT = 2,
BLOCK_MENTION_INDEX = 3,
BLOCK_MENTION_BECH32 = 4,
BLOCK_URL = 5,
BLOCK_INVOICE = 6,
};


struct ndb_mention_bech32_block {
struct str_block str;
struct ndb_str_block str;
struct nostr_bech32 bech32;
};

struct ndb_invoice_block {
struct str_block invstr;
struct ndb_str_block invstr;
struct ndb_invoice invoice;
};

struct note_block {
enum block_type type;
struct ndb_block {
enum ndb_block_type type;
union {
struct str_block str;
struct ndb_str_block str;
struct ndb_invoice_block invoice;
struct ndb_mention_bech32_block mention_bech32;
uint32_t mention_index;
} block;
};

int push_str_block(struct cursor *buf, const char *content, struct ndb_str_block *block);
int pull_str_block(struct cursor *buf, const char *content, struct ndb_str_block *block);


#endif // NDB_BLOCK_H
Loading

0 comments on commit 03b4d71

Please sign in to comment.