LCOV - code coverage report
Current view: top level - discof/restore/utils - fd_slot_delta_parser.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 306 329 93.0 %
Date: 2026-06-29 05:51:35 Functions: 14 15 93.3 %

          Line data    Source code
       1             : #include "fd_slot_delta_parser.h"
       2             : 
       3             : #define SLOT_DELTA_PARSER_DEBUG 0
       4             : 
       5         222 : #define STATE_SLOT_DELTAS_LEN                                    ( 0)
       6         312 : #define STATE_SLOT_DELTA_SLOT                                    ( 1)
       7         297 : #define STATE_SLOT_DELTA_IS_ROOT                                 ( 2)
       8         228 : #define STATE_SLOT_DELTA_STATUS_LEN                              ( 3)
       9         252 : #define STATE_STATUS_BLOCKHASH                                   ( 4)
      10         312 : #define STATE_STATUS_TXN_IDX                                     ( 5)
      11         240 : #define STATE_CACHE_STATUS_LEN                                   ( 6)
      12         444 : #define STATE_CACHE_STATUS_KEY_SLICE                             ( 7)
      13         444 : #define STATE_CACHE_STATUS_RESULT                                ( 8)
      14         336 : #define STATE_CACHE_STATUS_RESULT_ERR                            ( 9)
      15         192 : #define STATE_CACHE_STATUS_RESULT_ERR_INSTR_IDX                  (10)
      16         192 : #define STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR                  (11)
      17          72 : #define STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM           (12)
      18          48 : #define STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM_BORSH_LEN (13)
      19          45 : #define STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM_BORSH_ERR (14)
      20          72 : #define STATE_CACHE_STATUS_RESULT_ERR_IDX                        (15)
      21          93 : #define STATE_DONE                                               (16)
      22             : 
      23           3 : #define FD_SLOT_DELTA_PARSER_SLOT_SET_MAX_ENTRIES (512UL)
      24             : 
      25             : struct fd_slot_delta_parser_private {
      26             :   int     state;                       /* parser state machine */
      27             :   int     entry_avail;                 /* whether a parsed entry is available */
      28             :   int     group_avail;                 /* whether a parsed group is available */
      29             : 
      30             :   uchar * dst;                         /* where to store the next parsed value */
      31             :   ulong   dst_cur;                     /* offset into dst */
      32             :   ulong   dst_sz;                      /* size of dst */
      33             : 
      34             :   ulong   len;                         /* number of slot delta entries */
      35             :   int     is_root;                     /* whether the current slot delta entry is rooted */
      36             :   ulong   txnhash_offset;              /* offset into the txncache for the current slot delta entry */
      37             :   ulong   slot_delta_status_len;       /* number of blockhashes in the slot delta entry */
      38             :   ulong   cache_status_len;            /* number of txns associated with the blockhash */
      39             :   ulong   borsh_io_error_len;          /* used to parse a variable len borsh_io_error string */
      40             :   uint    error_discriminant;          /* stores the error discriminant of a txn result */
      41             :   uchar   error;                       /* stores the error code of a txn result */
      42             : 
      43             :   fd_slot_entry_t * slot_pool;         /* pool backing a slot hashset */
      44             :   slot_set_t *      slot_set;          /* slot hash set to detect duplicate slots */
      45             :   ulong             slot_pool_ele_cnt; /* count of slots in pool */
      46             :   fd_sstxncache_entry_t entry[1];      /* parsed slot delta entry */
      47             : };
      48             : 
      49             : static inline ulong
      50         903 : state_size( fd_slot_delta_parser_t * parser ) {
      51         903 :   switch( parser->state ) {
      52          45 :     case STATE_SLOT_DELTAS_LEN:                                    return sizeof(ulong);
      53          63 :     case STATE_SLOT_DELTA_SLOT:                                    return sizeof(ulong);
      54          60 :     case STATE_SLOT_DELTA_IS_ROOT:                                 return sizeof(uchar);
      55          57 :     case STATE_SLOT_DELTA_STATUS_LEN:                              return sizeof(ulong);
      56          63 :     case STATE_STATUS_BLOCKHASH:                                   return 32UL;
      57          63 :     case STATE_STATUS_TXN_IDX:                                     return sizeof(ulong);
      58          60 :     case STATE_CACHE_STATUS_LEN:                                   return sizeof(ulong);
      59         111 :     case STATE_CACHE_STATUS_KEY_SLICE:                             return 20UL;
      60         111 :     case STATE_CACHE_STATUS_RESULT:                                return sizeof(uint);
      61          84 :     case STATE_CACHE_STATUS_RESULT_ERR:                            return sizeof(uint);
      62          48 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_IDX:                  return sizeof(uchar);
      63          48 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR:                  return sizeof(uint);
      64          18 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM:           return sizeof(uint);
      65          12 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM_BORSH_LEN: return sizeof(ulong);
      66          12 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM_BORSH_ERR: return parser->borsh_io_error_len;
      67          18 :     case STATE_CACHE_STATUS_RESULT_ERR_IDX:                        return sizeof(uchar);
      68          30 :     case STATE_DONE:                                               return 0UL;
      69           0 :     default: FD_LOG_ERR(( "unknown state %d", parser->state ));
      70         903 :   }
      71         903 : }
      72             : 
      73             : static inline uchar *
      74         903 : state_dst( fd_slot_delta_parser_t * parser ) {
      75         903 :   switch( parser->state ) {
      76          45 :     case STATE_SLOT_DELTAS_LEN:                                    return (uchar*)&parser->len;
      77          63 :     case STATE_SLOT_DELTA_SLOT:                                    return (uchar*)&parser->entry->slot;
      78          60 :     case STATE_SLOT_DELTA_IS_ROOT:                                 return (uchar*)&parser->is_root;
      79          57 :     case STATE_SLOT_DELTA_STATUS_LEN:                              return (uchar*)&parser->slot_delta_status_len;
      80          63 :     case STATE_STATUS_BLOCKHASH:                                   return parser->entry->blockhash;
      81          63 :     case STATE_STATUS_TXN_IDX:                                     return (uchar*)&parser->txnhash_offset;
      82          60 :     case STATE_CACHE_STATUS_LEN:                                   return (uchar*)&parser->cache_status_len;
      83         111 :     case STATE_CACHE_STATUS_KEY_SLICE:                             return parser->entry->txnhash;
      84         111 :     case STATE_CACHE_STATUS_RESULT:                                return (uchar*)&parser->error_discriminant;
      85          84 :     case STATE_CACHE_STATUS_RESULT_ERR:                            return (uchar*)&parser->error_discriminant;
      86          48 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_IDX:                  return NULL;
      87          48 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR:                  return (uchar*)&parser->error_discriminant;
      88          18 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM:           return (uchar*)&parser->error_discriminant;
      89          12 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM_BORSH_LEN: return (uchar*)&parser->borsh_io_error_len;
      90          12 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM_BORSH_ERR: return NULL;
      91          18 :     case STATE_CACHE_STATUS_RESULT_ERR_IDX:                        return (uchar*)&parser->error;
      92          30 :     case STATE_DONE:                                               return NULL;
      93           0 :     default: FD_LOG_ERR(( "unknown state %d", parser->state ));
      94         903 :   }
      95         903 : }
      96             : 
      97             : #if SLOT_DELTA_PARSER_DEBUG
      98             : static inline void
      99             : state_log( fd_slot_delta_parser_t * parser ) {
     100             :   switch( parser->state ) {
     101             :     case STATE_SLOT_DELTAS_LEN:        FD_LOG_NOTICE(( "STATE_SLOT_DELTAS_LEN:        %lu", parser->len ));                                         break;
     102             :     case STATE_SLOT_DELTA_SLOT:        FD_LOG_NOTICE(( "STATE_SLOT_DELTA_SLOT:        %lu", parser->entry->slot ));                                 break;
     103             :     case STATE_SLOT_DELTA_IS_ROOT:     FD_LOG_NOTICE(( "STATE_SLOT_DELTA_IS_ROOT:     %d",  parser->is_root ));                                     break;
     104             :     case STATE_SLOT_DELTA_STATUS_LEN:  FD_LOG_NOTICE(( "STATE_SLOT_DELTA_STATUS_LEN:  %lu", parser->slot_delta_status_len ));                       break;
     105             :     case STATE_STATUS_BLOCKHASH: {
     106             :       FD_BASE58_ENCODE_32_BYTES( parser->entry->blockhash, blockhash_b58 );
     107             :       /*                             */FD_LOG_NOTICE(( "STATE_STATUS_BLOCKHASH:       %s",  blockhash_b58 ));
     108             :       break;
     109             :     }
     110             :     case STATE_CACHE_STATUS_LEN:       FD_LOG_NOTICE(( "STATE_CACHE_STATUS_LEN:       %lu", parser->cache_status_len ));                            break;
     111             :     default: break;
     112             :   }
     113             : }
     114             : #endif
     115             : 
     116             : static inline int
     117         870 : state_validate( fd_slot_delta_parser_t * parser ) {
     118         870 :   switch( parser->state ) {
     119          45 :     case STATE_SLOT_DELTAS_LEN:
     120          45 :       if( FD_UNLIKELY( parser->len>FD_SLOT_DELTA_MAX_ENTRIES ) ) {
     121             :         /* https://github.com/anza-xyz/agave/blob/v3.1.8/runtime/src/snapshot_bank_utils.rs#L535 */
     122           3 :         FD_LOG_WARNING(( "slot delta validation failed: %s (%d)", fd_slot_delta_parser_advance_str( FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_TOO_MANY_ENTRIES ), FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_TOO_MANY_ENTRIES ));
     123           3 :         return FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_TOO_MANY_ENTRIES;
     124           3 :       }
     125          42 :       break;
     126          63 :     case STATE_SLOT_DELTA_SLOT: {
     127          63 :       ulong slot_idx = slot_set_idx_query_const( parser->slot_set, &parser->entry->slot, ULONG_MAX, parser->slot_pool );
     128             :       /* https://github.com/anza-xyz/agave/blob/v3.1.8/runtime/src/snapshot_bank_utils.rs#L558 */
     129          63 :       if( FD_UNLIKELY( slot_idx!=ULONG_MAX ) ) {
     130           3 :         FD_LOG_WARNING(( "slot delta validation failed: %s (%d)", fd_slot_delta_parser_advance_str( FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_SLOT_HASH_MULTIPLE_ENTRIES ), FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_SLOT_HASH_MULTIPLE_ENTRIES ));
     131           3 :         return FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_SLOT_HASH_MULTIPLE_ENTRIES;
     132           3 :       }
     133             : 
     134          60 :       if( FD_UNLIKELY( parser->slot_pool_ele_cnt>=FD_SLOT_DELTA_MAX_ENTRIES ) ) {
     135             :         /* https://github.com/anza-xyz/agave/blob/v3.1.8/runtime/src/snapshot_bank_utils.rs#L535 */
     136           0 :         FD_LOG_WARNING(( "slot delta validation failed: %s (%d)", fd_slot_delta_parser_advance_str( FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_TOO_MANY_ENTRIES ), FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_TOO_MANY_ENTRIES ));
     137           0 :         return FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_TOO_MANY_ENTRIES;
     138           0 :       }
     139             : 
     140          60 :       fd_slot_entry_t * slot_entry = &parser->slot_pool[ parser->slot_pool_ele_cnt++ ];
     141          60 :       slot_entry->slot             = parser->entry->slot;
     142          60 :       slot_set_ele_insert( parser->slot_set, slot_entry, parser->slot_pool );
     143          60 :       break;
     144          60 :     }
     145          60 :     case STATE_SLOT_DELTA_IS_ROOT:
     146          60 :       if( FD_UNLIKELY( !parser->is_root) ) {
     147             :         /* https://github.com/anza-xyz/agave/blob/v3.1.8/runtime/src/snapshot_bank_utils.rs#L545 */
     148           3 :         FD_LOG_WARNING(( "slot delta validation failed: %s (%d)", fd_slot_delta_parser_advance_str( FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_SLOT_IS_NOT_ROOT ), FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_SLOT_IS_NOT_ROOT ));
     149           3 :         return FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_SLOT_IS_NOT_ROOT;
     150           3 :       }
     151          57 :       break;
     152          63 :     case STATE_STATUS_TXN_IDX:
     153          63 :       if( FD_UNLIKELY( parser->txnhash_offset>FD_SLOT_DELTA_MAX_TXNHASH_OFFSET ) ) {
     154           3 :         FD_LOG_WARNING(( "slot delta validation failed: %s (%d)",
     155           3 :                          fd_slot_delta_parser_advance_str( FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_INVALID_TXNHASH_OFFSET ),
     156           3 :                          FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_INVALID_TXNHASH_OFFSET ));
     157           3 :         return FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_INVALID_TXNHASH_OFFSET;
     158           3 :       }
     159          60 :       break;
     160         639 :     default: break;
     161         870 :   }
     162             : 
     163         858 :   return 0;
     164         870 : }
     165             : 
     166             : static inline void
     167         132 : loop( fd_slot_delta_parser_t * parser ) {
     168         132 :   if( FD_LIKELY( parser->cache_status_len ) ) {
     169          66 :     parser->state = STATE_CACHE_STATUS_KEY_SLICE;
     170          66 :   } else if( FD_LIKELY( parser->slot_delta_status_len ) ) {
     171          15 :     parser->state = STATE_STATUS_BLOCKHASH;
     172          51 :   } else if( FD_LIKELY( parser->len ) ) {
     173          24 :     parser->state = STATE_SLOT_DELTA_SLOT;
     174          27 :   } else {
     175          27 :     parser->state = STATE_DONE;
     176          27 :   }
     177         132 : }
     178             : 
     179             : static inline void
     180         108 : result_loop( fd_slot_delta_parser_t * parser ) {
     181         108 :   parser->entry_avail = 1;
     182         108 :   loop( parser );
     183         108 : }
     184             : 
     185             : static inline void
     186         858 : state_process( fd_slot_delta_parser_t * parser ) {
     187         858 :   FD_TEST( parser->state!=STATE_DONE );
     188             : 
     189         858 :   switch( parser->state ) {
     190          42 :     case STATE_SLOT_DELTAS_LEN:
     191          42 :       if( FD_UNLIKELY( !parser->len ) ) parser->state = STATE_DONE;
     192          39 :       else                              parser->state = STATE_SLOT_DELTA_SLOT;
     193          42 :       break;
     194          60 :     case STATE_SLOT_DELTA_SLOT:
     195          60 :       parser->state = STATE_SLOT_DELTA_IS_ROOT;
     196          60 :       parser->len--;
     197          60 :       break;
     198          57 :     case STATE_SLOT_DELTA_IS_ROOT:
     199          57 :       parser->state = STATE_SLOT_DELTA_STATUS_LEN;
     200          57 :       break;
     201          57 :     case STATE_SLOT_DELTA_STATUS_LEN:
     202          57 :       if( FD_UNLIKELY( !parser->slot_delta_status_len ) ) loop( parser );
     203          48 :       else                                                parser->state = STATE_STATUS_BLOCKHASH;
     204          57 :       break;
     205          63 :     case STATE_STATUS_BLOCKHASH:
     206          63 :       parser->state = STATE_STATUS_TXN_IDX;
     207          63 :       parser->slot_delta_status_len--;
     208          63 :       break;
     209          60 :     case STATE_STATUS_TXN_IDX:
     210          60 :       parser->state       = STATE_CACHE_STATUS_LEN;
     211          60 :       parser->group_avail = 1;
     212          60 :       break;
     213          60 :     case STATE_CACHE_STATUS_LEN:
     214          60 :       if( FD_UNLIKELY( !parser->cache_status_len ) ) loop( parser );
     215          45 :       else                                           parser->state = STATE_CACHE_STATUS_KEY_SLICE;
     216          60 :       break;
     217         111 :     case STATE_CACHE_STATUS_KEY_SLICE:
     218         111 :       parser->state = STATE_CACHE_STATUS_RESULT;
     219         111 :       parser->cache_status_len--;
     220         111 :       break;
     221         111 :     case STATE_CACHE_STATUS_RESULT:
     222         111 :       if( FD_LIKELY( !parser->error_discriminant ) ) {
     223          27 :         parser->entry->result = 0;
     224          27 :         result_loop( parser );
     225          27 :       }
     226          84 :       else {
     227          84 :         parser->state = STATE_CACHE_STATUS_RESULT_ERR;
     228          84 :       }
     229         111 :       break;
     230          84 :     case STATE_CACHE_STATUS_RESULT_ERR:
     231          84 :       if( FD_UNLIKELY( parser->error_discriminant==8U ) ) {
     232          48 :         parser->state = STATE_CACHE_STATUS_RESULT_ERR_INSTR_IDX;
     233          48 :       } else if( FD_UNLIKELY( parser->error_discriminant==30U || parser->error_discriminant==31U || parser->error_discriminant==35U ) ) {
     234          18 :         parser->state = STATE_CACHE_STATUS_RESULT_ERR_IDX;
     235          18 :       } else {
     236          18 :         parser->entry->result = (uchar)parser->error_discriminant;
     237          18 :         result_loop( parser );
     238          18 :       }
     239          84 :     break;
     240          48 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_IDX:
     241          48 :       parser->state = STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR;
     242          48 :       break;
     243          48 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR:
     244          48 :       if( FD_UNLIKELY( parser->error_discriminant==25U ) ) {
     245          18 :         parser->state = STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM;
     246          30 :       } else if( FD_UNLIKELY( parser->error_discriminant==44U ) ) {
     247          12 :         parser->state = STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM_BORSH_LEN;
     248          18 :       } else {
     249          18 :         parser->entry->result = (uchar)parser->error_discriminant;
     250          18 :         result_loop( parser );
     251          18 :       }
     252          48 :       break;
     253          18 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM:
     254          18 :       parser->entry->result = (uchar)parser->error_discriminant;
     255          18 :       result_loop( parser );
     256          18 :       break;
     257          12 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM_BORSH_LEN:
     258          12 :       parser->state = STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM_BORSH_ERR;
     259          12 :       break;
     260           9 :     case STATE_CACHE_STATUS_RESULT_ERR_INSTR_ERR_CUSTOM_BORSH_ERR:
     261           9 :       parser->entry->result = (uchar)parser->error_discriminant;
     262           9 :       result_loop( parser );
     263           9 :       break;
     264          18 :     case STATE_CACHE_STATUS_RESULT_ERR_IDX:
     265          18 :       parser->entry->result = (uchar)parser->error;
     266          18 :       result_loop( parser );
     267          18 :       break;
     268           0 :     default: FD_LOG_ERR(( "unknown state %d", parser->state ));
     269         858 :   }
     270         858 : }
     271             : 
     272             : FD_FN_CONST ulong
     273          24 : fd_slot_delta_parser_align( void ) {
     274          24 :   return fd_ulong_max( fd_ulong_max( alignof(fd_slot_delta_parser_t), slot_pool_align() ), slot_set_align() );
     275          24 : }
     276             : 
     277             : FD_FN_CONST ulong
     278           6 : fd_slot_delta_parser_footprint( void ) {
     279           6 :   ulong l = FD_LAYOUT_INIT;
     280           6 :   l = FD_LAYOUT_APPEND( l,  alignof(fd_slot_delta_parser_t), sizeof(fd_slot_delta_parser_t)                                  );
     281           6 :   l = FD_LAYOUT_APPEND( l,  slot_pool_align(),               slot_pool_footprint( FD_SLOT_DELTA_MAX_ENTRIES )                );
     282           6 :   l = FD_LAYOUT_APPEND( l,  slot_set_align(),                slot_set_footprint( FD_SLOT_DELTA_PARSER_SLOT_SET_MAX_ENTRIES ) );
     283           6 :   return FD_LAYOUT_FINI( l, fd_slot_delta_parser_align() );
     284           6 : }
     285             : 
     286             : void *
     287           3 : fd_slot_delta_parser_new( void * shmem ) {
     288           3 :   if( FD_UNLIKELY( !shmem ) ) {
     289           0 :     FD_LOG_WARNING(( "NULL shmem" ));
     290           0 :     return NULL;
     291           0 :   }
     292             : 
     293           3 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_slot_delta_parser_align() ) ) ) {
     294           0 :     FD_LOG_WARNING(( "unaligned shmem" ));
     295           0 :     return NULL;
     296           0 :   }
     297             : 
     298           3 :   FD_SCRATCH_ALLOC_INIT( l, shmem );
     299           3 :   fd_slot_delta_parser_t * parser = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_slot_delta_parser_t), sizeof(fd_slot_delta_parser_t)                                  );
     300           3 :   void * slot_pool_mem            = FD_SCRATCH_ALLOC_APPEND( l, slot_pool_align(),               slot_pool_footprint( FD_SLOT_DELTA_MAX_ENTRIES )                );
     301           3 :   void * slot_set_mem             = FD_SCRATCH_ALLOC_APPEND( l, slot_set_align(),                slot_set_footprint( FD_SLOT_DELTA_PARSER_SLOT_SET_MAX_ENTRIES ) );
     302           3 :   FD_TEST( FD_SCRATCH_ALLOC_FINI( l, fd_slot_delta_parser_align() ) == (ulong)shmem + fd_slot_delta_parser_footprint() );
     303             : 
     304           3 :   parser->slot_pool = slot_pool_join( slot_pool_new( slot_pool_mem, FD_SLOT_DELTA_MAX_ENTRIES ) );
     305           3 :   FD_TEST( parser->slot_pool );
     306             : 
     307           3 :   parser->slot_set = slot_set_join( slot_set_new( slot_set_mem, FD_SLOT_DELTA_PARSER_SLOT_SET_MAX_ENTRIES, 1UL ) );
     308           3 :   FD_TEST( parser->slot_set );
     309             : 
     310         903 :   for( ulong i=0UL; i<slot_pool_max( parser->slot_pool ); i++ ) {
     311         900 :     fd_slot_entry_t * slot_entry = &parser->slot_pool[ i ];
     312         900 :     slot_entry->slot = ULONG_MAX;
     313         900 :   }
     314             : 
     315           3 :   parser->entry_avail       = 0;
     316           3 :   parser->group_avail       = 0;
     317           3 :   parser->slot_pool_ele_cnt = 0UL;
     318           3 :   parser->state             = STATE_DONE;
     319             : 
     320           3 :   return parser;
     321           3 : }
     322             : 
     323             : fd_slot_delta_parser_t *
     324           3 : fd_slot_delta_parser_join( void * shmem ) {
     325           3 :   return shmem;
     326           3 : }
     327             : 
     328             : void *
     329           3 : fd_slot_delta_parser_leave( fd_slot_delta_parser_t * parser ) {
     330           3 :   return (void *)parser;
     331           3 : }
     332             : 
     333             : void *
     334           3 : fd_slot_delta_parser_delete( void * shmem ) {
     335           3 :   return shmem;
     336           3 : }
     337             : 
     338             : void
     339          45 : fd_slot_delta_parser_init( fd_slot_delta_parser_t * parser ) {
     340          45 :   parser->state     = STATE_SLOT_DELTAS_LEN;
     341          45 :   parser->len       = 0UL;
     342          45 :   parser->is_root   = 0;
     343             : 
     344          45 :   parser->slot_delta_status_len = 0UL;
     345          45 :   parser->cache_status_len      = 0UL;
     346          45 :   parser->borsh_io_error_len    = 0UL;
     347          45 :   parser->error_discriminant    = 0U;
     348             : 
     349         105 :   for( ulong i=0UL; i<parser->slot_pool_ele_cnt; i++ ) {
     350          60 :     fd_slot_entry_t * slot_entry = &parser->slot_pool[ i ];
     351          60 :     slot_set_ele_remove_fast( parser->slot_set, slot_entry, parser->slot_pool );
     352          60 :     slot_entry->slot = ULONG_MAX;
     353          60 :   }
     354             : 
     355          45 :   parser->slot_pool_ele_cnt = 0UL;
     356             : 
     357          45 :   parser->dst       = state_dst( parser );
     358          45 :   parser->dst_sz    = state_size( parser );
     359          45 :   parser->dst_cur   = 0UL;
     360             : 
     361          45 :   parser->entry_avail = 0;
     362          45 :   parser->group_avail = 0;
     363          45 : }
     364             : 
     365             : int
     366             : fd_slot_delta_parser_consume( fd_slot_delta_parser_t *                parser,
     367             :                               uchar const *                           buf,
     368             :                               ulong                                   bufsz,
     369         195 :                               fd_slot_delta_parser_advance_result_t * result ) {
     370         195 :   uchar const * data    = buf;
     371         195 :   ulong         data_sz = bufsz;
     372         885 :   while( data_sz ) {
     373         870 :     if( FD_UNLIKELY( parser->state==STATE_DONE ) ) break;
     374             : 
     375         870 :     ulong consume = fd_ulong_min( data_sz, parser->dst_sz-parser->dst_cur );
     376             : 
     377         870 :     if( FD_LIKELY( parser->dst && consume ) ) {
     378         813 :       memcpy( parser->dst+parser->dst_cur, data, consume );
     379         813 :     }
     380             : 
     381         870 :     parser->dst_cur += consume;
     382         870 :     data            += consume;
     383         870 :     data_sz         -= consume;
     384             : 
     385             : #if SLOT_DELTA_PARSER_DEBUG
     386             :     state_log( parser );
     387             : #endif
     388             : 
     389         870 :     if( FD_LIKELY( parser->dst_cur==parser->dst_sz ) ) {
     390         870 :       int err = state_validate( parser );
     391         870 :       if( FD_UNLIKELY( err ) ) {
     392          12 :         result->bytes_consumed = (ulong)(data - buf);
     393          12 :         return err;
     394          12 :       }
     395             : 
     396         858 :       state_process( parser );
     397             : 
     398         858 :       parser->dst     = state_dst( parser );
     399         858 :       parser->dst_sz  = state_size( parser );
     400         858 :       parser->dst_cur = 0UL;
     401             : 
     402         858 :       if( FD_LIKELY( parser->group_avail ) ) {
     403          60 :         FD_TEST( parser->entry_avail==0 );
     404          60 :         parser->group_avail          = 0;
     405          60 :         result->entry                = NULL;
     406          60 :         result->group.blockhash      = parser->entry->blockhash;
     407          60 :         result->group.txnhash_offset = parser->txnhash_offset;
     408          60 :         result->bytes_consumed       = (ulong)(data - buf);
     409          60 :         return FD_SLOT_DELTA_PARSER_ADVANCE_GROUP;
     410         798 :       } else if( FD_LIKELY( parser->entry_avail ) ) {
     411         108 :         FD_TEST( parser->group_avail==0 );
     412         108 :         parser->entry_avail    = 0;
     413         108 :         result->entry          = parser->entry;
     414         108 :         result->bytes_consumed = (ulong)(data - buf);
     415         108 :         return FD_SLOT_DELTA_PARSER_ADVANCE_ENTRY;
     416         108 :       }
     417         858 :     }
     418         870 :   }
     419             : 
     420          15 :   if( FD_UNLIKELY( data_sz ) ) {
     421           0 :     FD_LOG_WARNING(( "excess data in buffer" ));
     422           0 :     result->bytes_consumed = (ulong)(data - buf);
     423           0 :     return FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_EXCESS_DATA_IN_BUFFER;
     424           0 :   }
     425             : 
     426          15 :   result->bytes_consumed = (ulong)(data - buf);
     427          15 :   if( FD_LIKELY( parser->state==STATE_DONE ) ) return FD_SLOT_DELTA_PARSER_ADVANCE_DONE;
     428             : 
     429           6 :   if( FD_UNLIKELY( !bufsz ) ) {
     430           3 :     FD_LOG_WARNING(( "unexpected end of data while parsing slot delta, state=%d, dst_cur=%lu, dst_sz=%lu",
     431           3 :                      parser->state, parser->dst_cur, parser->dst_sz ));
     432           3 :     return FD_SLOT_DELTA_PARSER_ADVANCE_ERROR_UNEXPECTED_EOF;
     433           3 :   }
     434             : 
     435           3 :   return FD_SLOT_DELTA_PARSER_ADVANCE_AGAIN;
     436           6 : }
     437             : 
     438             : fd_slot_delta_slot_set_t
     439           0 : fd_slot_delta_parser_slot_set( fd_slot_delta_parser_t * parser ) {
     440           0 :   return (fd_slot_delta_slot_set_t){
     441           0 :     .map  = parser->slot_set,
     442           0 :     .pool = parser->slot_pool,
     443           0 :     .ele_cnt   = parser->slot_pool_ele_cnt
     444           0 :   };
     445           0 : }

Generated by: LCOV version 1.14