LCOV - code coverage report
Current view: top level - discof/repair - fd_blockdb.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 118 0.0 %
Date: 2026-10-22 18:10:43 Functions: 0 8 0.0 %

          Line data    Source code
       1             : #include "fd_blockdb.h"
       2             : #include "../../ballet/sha256/fd_sha256.h"
       3             : 
       4             : #define MAP_NAME                           fd_blockdb_map
       5           0 : #define MAP_ELE_T                          fd_blockdb_blk_t
       6             : #define MAP_KEY_T                          fd_blockdb_key_t
       7           0 : #define MAP_KEY                            key
       8           0 : #define MAP_IDX_T                          uint
       9           0 : #define MAP_NEXT                           next
      10           0 : #define MAP_PREV                           prev
      11           0 : #define MAP_KEY_EQ(k0,k1)                  (!memcmp( (k0), (k1), sizeof(fd_blockdb_key_t) ))
      12           0 : #define MAP_KEY_HASH(key,seed)             fd_hash( (seed), (key), sizeof(fd_blockdb_key_t) )
      13             : #define MAP_OPTIMIZE_RANDOM_ACCESS_REMOVAL 1
      14             : #include "../../util/tmpl/fd_map_chain.c"
      15             : 
      16             : ulong
      17           0 : fd_blockdb_footprint( ulong ele_max ) {
      18           0 :   if( FD_UNLIKELY( !ele_max || ele_max>=UINT_MAX ) ) return 0UL;
      19             : 
      20           0 :   ulong l = FD_LAYOUT_INIT;
      21           0 :   l = FD_LAYOUT_APPEND( l, alignof(fd_blockdb_t),     sizeof(fd_blockdb_t)                                          );
      22           0 :   l = FD_LAYOUT_APPEND( l, alignof(fd_blockdb_blk_t), ele_max*sizeof(fd_blockdb_blk_t)                              );
      23           0 :   l = FD_LAYOUT_APPEND( l, fd_blockdb_map_align(),    fd_blockdb_map_footprint( fd_blockdb_map_chain_cnt_est( ele_max ) ) );
      24           0 :   l = FD_LAYOUT_APPEND( l, FD_BMTREE_COMMIT_ALIGN,    FD_BMTREE_COMMIT_FOOTPRINT( FD_BLOCKDB_TREE_LAYER_MAX )       );
      25           0 :   return FD_LAYOUT_FINI( l, fd_blockdb_align() );
      26           0 : }
      27             : 
      28             : void *
      29             : fd_blockdb_new( void * shmem,
      30             :                 ulong  ele_max,
      31           0 :                 ulong  seed ) {
      32           0 :   if( FD_UNLIKELY( !shmem ) ) {
      33           0 :     FD_LOG_WARNING(( "NULL mem" ));
      34           0 :     return NULL;
      35           0 :   }
      36             : 
      37           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_blockdb_align() ) ) ) {
      38           0 :     FD_LOG_WARNING(( "misaligned mem" ));
      39           0 :     return NULL;
      40           0 :   }
      41             : 
      42           0 :   ulong footprint = fd_blockdb_footprint( ele_max );
      43           0 :   if( FD_UNLIKELY( !footprint ) ) {
      44           0 :     FD_LOG_WARNING(( "bad ele_max (%lu)", ele_max ));
      45           0 :     return NULL;
      46           0 :   }
      47             : 
      48           0 :   ulong chain_cnt = fd_blockdb_map_chain_cnt_est( ele_max );
      49             : 
      50           0 :   FD_SCRATCH_ALLOC_INIT( l, shmem );
      51           0 :   fd_blockdb_t *     blockdb = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_blockdb_t),     sizeof(fd_blockdb_t)                  );
      52           0 :   fd_blockdb_blk_t * ele     = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_blockdb_blk_t), ele_max*sizeof(fd_blockdb_blk_t)      );
      53           0 :   void *             map     = FD_SCRATCH_ALLOC_APPEND( l, fd_blockdb_map_align(),    fd_blockdb_map_footprint( chain_cnt ) );
      54           0 :   void *             tree    = FD_SCRATCH_ALLOC_APPEND( l, FD_BMTREE_COMMIT_ALIGN,    FD_BMTREE_COMMIT_FOOTPRINT( FD_BLOCKDB_TREE_LAYER_MAX ) );
      55           0 :   FD_TEST( FD_SCRATCH_ALLOC_FINI( l, fd_blockdb_align() )==(ulong)shmem + footprint );
      56           0 :   FD_TEST( fd_bmtree_depth( FD_FEC_BLK_MAX+1UL )==FD_BLOCKDB_TREE_LAYER_MAX );
      57             : 
      58           0 :   blockdb->ele_max = ele_max;
      59           0 :   blockdb->seq     = 0UL;
      60           0 :   blockdb->ele     = ele;
      61           0 :   blockdb->tree    = tree;
      62           0 :   blockdb->map     = fd_blockdb_map_new( map, chain_cnt, seed );
      63           0 :   if( FD_UNLIKELY( !blockdb->map ) ) return NULL;
      64             : 
      65           0 :   return shmem;
      66           0 : }
      67             : 
      68             : fd_blockdb_t *
      69           0 : fd_blockdb_join( void * shblockdb ) {
      70           0 :   if( FD_UNLIKELY( !shblockdb ) ) {
      71           0 :     FD_LOG_WARNING(( "NULL blockdb" ));
      72           0 :     return NULL;
      73           0 :   }
      74             : 
      75           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shblockdb, fd_blockdb_align() ) ) ) {
      76           0 :     FD_LOG_WARNING(( "misaligned blockdb" ));
      77           0 :     return NULL;
      78           0 :   }
      79             : 
      80           0 :   fd_blockdb_t * blockdb = (fd_blockdb_t *)shblockdb;
      81           0 :   blockdb->map = fd_blockdb_map_join( blockdb->map );
      82           0 :   if( FD_UNLIKELY( !blockdb->map ) ) return NULL;
      83             : 
      84           0 :   return blockdb;
      85           0 : }
      86             : 
      87             : void *
      88           0 : fd_blockdb_leave( fd_blockdb_t const * blockdb ) {
      89           0 :   if( FD_UNLIKELY( !blockdb ) ) {
      90           0 :     FD_LOG_WARNING(( "NULL blockdb" ));
      91           0 :     return NULL;
      92           0 :   }
      93             : 
      94           0 :   return (void *)blockdb;
      95           0 : }
      96             : 
      97             : void *
      98           0 : fd_blockdb_delete( void * shblockdb ) {
      99           0 :   if( FD_UNLIKELY( !shblockdb ) ) {
     100           0 :     FD_LOG_WARNING(( "NULL blockdb" ));
     101           0 :     return NULL;
     102           0 :   }
     103             : 
     104           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shblockdb, fd_blockdb_align() ) ) ) {
     105           0 :     FD_LOG_WARNING(( "misaligned blockdb" ));
     106           0 :     return NULL;
     107           0 :   }
     108             : 
     109           0 :   return shblockdb;
     110           0 : }
     111             : 
     112             : fd_blockdb_blk_t *
     113             : fd_blockdb_insert( fd_blockdb_t *    blockdb,
     114             :                    ulong             slot,
     115             :                    fd_hash_t const * block_id,
     116             :                    ulong             parent_slot,
     117             :                    fd_hash_t const * parent_block_id,
     118             :                    uint              fec_set_cnt,
     119           0 :                    uchar const *     merkle_roots ) {
     120           0 :   if( FD_UNLIKELY( !fec_set_cnt || fec_set_cnt>FD_FEC_BLK_MAX ) ) return NULL;
     121             : 
     122           0 :   fd_blockdb_map_t * map = (fd_blockdb_map_t *)blockdb->map;
     123           0 :   fd_blockdb_key_t   key = { .slot = slot, .block_id = *block_id };
     124             : 
     125           0 :   fd_blockdb_blk_t * blk = fd_blockdb_map_ele_query( map, &key, NULL, blockdb->ele );
     126           0 :   if( FD_LIKELY( !blk ) ) {
     127             :     /* Take the oldest slot, unlinking its previous occupant once the
     128             :        array has wrapped. */
     129           0 :     blk = blockdb->ele + (blockdb->seq % blockdb->ele_max);
     130           0 :     if( FD_LIKELY( blockdb->seq>=blockdb->ele_max ) ) fd_blockdb_map_ele_remove_fast( map, blk, blockdb->ele );
     131           0 :     blockdb->seq++;
     132           0 :     blk->key = key;
     133           0 :     fd_blockdb_map_ele_insert( map, blk, blockdb->ele );
     134           0 :   }
     135             : 
     136           0 :   blk->parent_slot     = parent_slot;
     137           0 :   blk->parent_block_id = *parent_block_id;
     138           0 :   blk->fec_set_cnt     = fec_set_cnt;
     139           0 :   fd_memcpy( blk->merkle_roots, merkle_roots, fec_set_cnt*FD_SHRED_MERKLE_NODE_SZ );
     140           0 :   return blk;
     141           0 : }
     142             : 
     143             : fd_blockdb_blk_t const *
     144             : fd_blockdb_query( fd_blockdb_t const * blockdb,
     145             :                   ulong                slot,
     146           0 :                   fd_hash_t const *    block_id ) {
     147           0 :   fd_blockdb_key_t key = { .slot = slot, .block_id = *block_id };
     148           0 :   return fd_blockdb_map_ele_query_const( (fd_blockdb_map_t const *)blockdb->map, &key, NULL, blockdb->ele );
     149           0 : }
     150             : 
     151             : int
     152             : fd_blockdb_proof( fd_blockdb_t *           blockdb,
     153             :                   fd_blockdb_blk_t const * blk,
     154             :                   ulong                    leaf_idx,
     155           0 :                   uchar                    proof[ FD_BLOCKDB_PROOF_NODE_MAX*FD_SHRED_MERKLE_NODE_SZ ] ) {
     156           0 :   if( FD_UNLIKELY( leaf_idx>blk->fec_set_cnt ) ) return -1;
     157             : 
     158           0 :   fd_bmtree_commit_t * tree = fd_bmtree_commit_init( blockdb->tree, FD_SHRED_MERKLE_NODE_SZ, FD_BMTREE_LONG_PREFIX_SZ, FD_BLOCKDB_TREE_LAYER_MAX );
     159             : 
     160             :   /* Only the first FD_SHRED_MERKLE_NODE_SZ bytes of a node are hashed,
     161             :      so a zero-padded root prefix is an exact leaf. */
     162           0 :   fd_bmtree_node_t leaf[1] = {0};
     163           0 :   for( uint k=0U; k<blk->fec_set_cnt; k++ ) {
     164           0 :     memcpy( leaf->hash, blk->merkle_roots[ k ], FD_SHRED_MERKLE_NODE_SZ );
     165           0 :     fd_bmtree_commit_append( tree, leaf, 1UL );
     166           0 :   }
     167             : 
     168           0 :   fd_sha256_t sha[1];
     169           0 :   fd_sha256_init  ( sha );
     170           0 :   fd_sha256_append( sha, &blk->parent_slot,       sizeof(ulong)     );
     171           0 :   fd_sha256_append( sha, blk->parent_block_id.uc, sizeof(fd_hash_t) );
     172           0 :   fd_sha256_append( sha, &blk->fec_set_cnt,       sizeof(uint)      );
     173           0 :   fd_sha256_fini  ( sha, leaf->hash );
     174           0 :   fd_bmtree_commit_append( tree, leaf, 1UL );
     175             : 
     176           0 :   fd_bmtree_commit_fini( tree );
     177           0 :   return fd_bmtree_get_proof( tree, proof, leaf_idx );
     178           0 : }

Generated by: LCOV version 1.14