Line data Source code
1 : #ifndef HEADER_fd_src_discof_repair_fd_blockdb_h 2 : #define HEADER_fd_src_discof_repair_fd_blockdb_h 3 : 4 : /* fd_blockdb stores metadata of completed blocks, keyed by 5 : (slot, block_id), for serving Alpenglow block id repair requests. 6 : Entries live in a fixed array and are overwritten oldest-first. */ 7 : 8 : #include "../../flamenco/fd_flamenco_base.h" 9 : #include "../../disco/shred/fd_fec_set.h" 10 : #include "../../ballet/bmtree/fd_bmtree.h" 11 : 12 0 : #define FD_BLOCKDB_ALIGN (128UL) 13 : 14 : /* The double-merkle tree has at most FD_FEC_BLK_MAX+1 leaves (FEC roots 15 : plus the parent-info leaf), so at most 11 layers and 10 proof nodes. */ 16 : 17 0 : #define FD_BLOCKDB_TREE_LAYER_MAX (11UL) 18 : #define FD_BLOCKDB_PROOF_NODE_MAX (FD_BLOCKDB_TREE_LAYER_MAX-1UL) 19 : 20 : struct fd_blockdb_key { 21 : ulong slot; 22 : fd_hash_t block_id; 23 : }; 24 : typedef struct fd_blockdb_key fd_blockdb_key_t; 25 : 26 : FD_STATIC_ASSERT( sizeof(fd_blockdb_key_t)==40UL, fd_blockdb_key_t ); 27 : 28 : /* merkle_roots holds the first FD_SHRED_MERKLE_NODE_SZ bytes of each FEC 29 : set's merkle root, the only bytes the block id commits to. Only the 30 : first fec_set_cnt entries are meaningful. */ 31 : 32 : struct fd_blockdb_blk { 33 : fd_blockdb_key_t key; 34 : ulong parent_slot; 35 : fd_hash_t parent_block_id; 36 : uint fec_set_cnt; 37 : uint next; /* map chain */ 38 : uint prev; /* map chain */ 39 : uchar merkle_roots[ FD_FEC_BLK_MAX ][ FD_SHRED_MERKLE_NODE_SZ ]; 40 : }; 41 : typedef struct fd_blockdb_blk fd_blockdb_blk_t; 42 : 43 : struct fd_blockdb { 44 : ulong ele_max; 45 : ulong seq; /* total inserts, next slot is seq%ele_max */ 46 : fd_blockdb_blk_t * ele; 47 : void * map; 48 : void * tree; /* scratch for building proofs */ 49 : }; 50 : typedef struct fd_blockdb fd_blockdb_t; 51 : 52 : FD_PROTOTYPES_BEGIN 53 : 54 : FD_FN_CONST static inline ulong 55 0 : fd_blockdb_align( void ) { 56 0 : return FD_BLOCKDB_ALIGN; 57 0 : } 58 : 59 : /* fd_blockdb_footprint returns the footprint for ele_max entries, or 0 60 : if ele_max is zero or not less than UINT_MAX. */ 61 : 62 : ulong 63 : fd_blockdb_footprint( ulong ele_max ); 64 : 65 : void * 66 : fd_blockdb_new( void * shmem, 67 : ulong ele_max, 68 : ulong seed ); 69 : 70 : fd_blockdb_t * 71 : fd_blockdb_join( void * shblockdb ); 72 : 73 : void * 74 : fd_blockdb_leave( fd_blockdb_t const * blockdb ); 75 : 76 : void * 77 : fd_blockdb_delete( void * shblockdb ); 78 : 79 : /* fd_blockdb_insert stores a block, overwriting the oldest entry when 80 : full. Re-inserting an existing key updates it in place. 81 : merkle_roots points to fec_set_cnt 20B roots. Returns NULL if 82 : fec_set_cnt is 0 or exceeds FD_FEC_BLK_MAX. */ 83 : 84 : fd_blockdb_blk_t * 85 : fd_blockdb_insert( fd_blockdb_t * blockdb, 86 : ulong slot, 87 : fd_hash_t const * block_id, 88 : ulong parent_slot, 89 : fd_hash_t const * parent_block_id, 90 : uint fec_set_cnt, 91 : uchar const * merkle_roots ); 92 : 93 : /* fd_blockdb_query returns the entry for (slot, block_id), or NULL. 94 : The pointer is invalidated by the next insert. */ 95 : 96 : fd_blockdb_blk_t const * 97 : fd_blockdb_query( fd_blockdb_t const * blockdb, 98 : ulong slot, 99 : fd_hash_t const * block_id ); 100 : 101 : /* fd_blockdb_proof writes blk's double-merkle inclusion proof for leaf 102 : leaf_idx to proof, as 20B nodes from leaf to root. Leaves are the FEC 103 : roots, then the parent-info leaf at fec_set_cnt. Returns the node 104 : count, or -1 if leaf_idx>fec_set_cnt. */ 105 : 106 : int 107 : fd_blockdb_proof( fd_blockdb_t * blockdb, 108 : fd_blockdb_blk_t const * blk, 109 : ulong leaf_idx, 110 : uchar proof[ FD_BLOCKDB_PROOF_NODE_MAX*FD_SHRED_MERKLE_NODE_SZ ] ); 111 : 112 : FD_PROTOTYPES_END 113 : 114 : #endif /* HEADER_fd_src_discof_repair_fd_blockdb_h */