LCOV - code coverage report
Current view: top level - flamenco/types - fd_types_custom.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 50 182 27.5 %
Date: 2025-03-20 12:08:36 Functions: 5 16 31.2 %

          Line data    Source code
       1             : #include "fd_types_custom.h"
       2             : #include "fd_bincode.h"
       3             : #include "fd_types.h"
       4             : #ifndef SOURCE_fd_src_flamenco_types_fd_types_c
       5             : #error "fd_types_custom.c is part of the fd_types.c compile uint"
       6             : #endif /* !SOURCE_fd_src_flamenco_types_fd_types_c */
       7             : 
       8             : #include <stdio.h>
       9             : 
      10             : int
      11           3 : fd_flamenco_txn_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) {
      12           3 :   *total_sz += sizeof(fd_flamenco_txn_t);
      13           3 :   void const * start_data = ctx->data;
      14           3 :   int err = fd_flamenco_txn_decode_footprint_inner( ctx, total_sz );
      15           3 :   ctx->data = start_data;
      16           3 :   return err;
      17           3 : }
      18             : 
      19             : int
      20           9 : fd_flamenco_txn_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) {
      21           9 :   if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
      22           9 :   ulong bufsz = (ulong)ctx->dataend - (ulong)ctx->data;
      23           9 :   fd_flamenco_txn_t self;
      24           9 :   ulong sz  = 0UL;
      25           9 :   ulong res = fd_txn_parse_core( ctx->data,
      26           9 :                                  bufsz,
      27           9 :                                  self.txn,
      28           9 :                                  NULL,
      29           9 :                                  &sz );
      30           9 :   if( FD_UNLIKELY( !res ) ) {
      31           0 :     return -1000001;
      32           0 :   }
      33           9 :   ctx->data  = (void *)( (ulong)ctx->data + sz );
      34           9 :   *total_sz += sz;
      35           9 :   return 0;
      36           9 : }
      37             : 
      38             : void *
      39           3 : fd_flamenco_txn_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) {
      40           3 :   fd_flamenco_txn_t * self = (fd_flamenco_txn_t *)mem;
      41           3 :   fd_flamenco_txn_new( self );
      42           3 :   void *   alloc_region = (uchar *)mem + sizeof(fd_flamenco_txn_t);
      43           3 :   void * * alloc_mem    = &alloc_region;
      44           3 :   fd_flamenco_txn_decode_inner( mem, alloc_mem, ctx );
      45           3 :   return self;
      46           3 : }
      47             : 
      48             : void
      49           9 : fd_flamenco_txn_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) {
      50           9 :   fd_flamenco_txn_t * self = (fd_flamenco_txn_t *)struct_mem;
      51           9 :   static FD_TL fd_txn_parse_counters_t counters[1];
      52           9 :   ulong bufsz = (ulong)ctx->dataend - (ulong)ctx->data;
      53           9 :   ulong sz    = 0UL;
      54           9 :   ulong res   = fd_txn_parse_core( ctx->data,
      55           9 :                                    bufsz,
      56           9 :                                    self->txn,
      57           9 :                                    counters,
      58           9 :                                    &sz );
      59           9 :   if( FD_UNLIKELY( !res ) ) {
      60           0 :     FD_LOG_ERR(( "Failed to decode txn (fd_txn.c:%lu)",
      61           0 :                  counters->failure_ring[ counters->failure_cnt % FD_TXN_PARSE_COUNTERS_RING_SZ ] ));
      62           0 :     return;
      63           0 :   }
      64           9 :   fd_memcpy( self->raw, ctx->data, sz );
      65           9 :   self->raw_sz = sz;
      66           9 :   ctx->data = (void *)( (ulong)ctx->data + sz );
      67           9 : }
      68             : 
      69             : void *
      70           0 : fd_flamenco_txn_decode_global( void * mem, fd_bincode_decode_ctx_t * ctx ) {
      71           0 :   fd_flamenco_txn_t * self = (fd_flamenco_txn_t *)mem;
      72           0 :   fd_flamenco_txn_new( self );
      73           0 :   void *   alloc_region = (uchar *)mem + sizeof(fd_flamenco_txn_t);
      74           0 :   void * * alloc_mem    = &alloc_region;
      75           0 :   fd_flamenco_txn_decode_inner_global( mem, alloc_mem, ctx );
      76           0 :   return self;
      77           0 : }
      78             : 
      79             : int
      80           0 : fd_flamenco_txn_convert_global_to_local( void const * global_self, fd_flamenco_txn_t * self, fd_bincode_decode_ctx_t * ctx ) {
      81           0 :   FD_LOG_ERR(("TODO: Implement"));
      82           0 : }
      83             : 
      84             : void
      85           0 : fd_flamenco_txn_decode_inner_global( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) {
      86           0 :   FD_LOG_ERR(("TODO: Implement"));
      87           0 : }
      88             : 
      89             : 
      90             : void
      91             : fd_gossip_ip4_addr_walk( void *                       w,
      92             :                          fd_gossip_ip4_addr_t const * self,
      93             :                          fd_types_walk_fn_t           fun,
      94             :                          char const *                 name,
      95          93 :                          uint                         level ) {
      96             : 
      97          93 :   char buf[ 16 ];
      98          93 :   sprintf( buf, FD_IP4_ADDR_FMT, FD_IP4_ADDR_FMT_ARGS( *self ) );
      99          93 :   fun( w, buf, name, FD_FLAMENCO_TYPE_CSTR, "ip4_addr", level );
     100          93 : }
     101             : 
     102             : void
     103             : fd_gossip_ip6_addr_walk( void *                       w,
     104             :                          fd_gossip_ip6_addr_t const * self,
     105             :                          fd_types_walk_fn_t           fun,
     106             :                          char const *                 name,
     107           0 :                          uint                         level ) {
     108             : 
     109           0 :   char buf[ 40 ];
     110           0 :   sprintf( buf,
     111           0 :            "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
     112           0 :            FD_LOG_HEX16_FMT_ARGS( self->us ) );
     113           0 :   fun( w, buf, name, FD_FLAMENCO_TYPE_CSTR, "ip6_addr", level );
     114           0 : }
     115             : 
     116           0 : int fd_tower_sync_encode( fd_tower_sync_t const * self, fd_bincode_encode_ctx_t * ctx ) {
     117           0 :   FD_LOG_ERR(( "todo"));
     118           0 : }
     119             : 
     120           0 : int fd_tower_sync_decode_footprint( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) {
     121           0 :   *total_sz += sizeof(fd_tower_sync_t);
     122           0 :   void const * start_data = ctx->data;
     123           0 :   int err = fd_tower_sync_decode_footprint_inner( ctx, total_sz );
     124           0 :   ctx->data = start_data;
     125           0 :   return err;
     126           0 : }
     127             : 
     128           0 : int fd_tower_sync_decode_footprint_inner( fd_bincode_decode_ctx_t * ctx, ulong * total_sz ) {
     129             :   /* This is a modified version of fd_compact_tower_sync_decode_footprint_inner() */
     130           0 :   int err = 0;
     131           0 :   if( FD_UNLIKELY( ctx->data>ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
     132           0 :   err = fd_bincode_uint64_decode_footprint( ctx );
     133             : 
     134             :   /* The first modification is that we want to grab the value fo the root. */
     135           0 :   ulong root = 0UL;
     136           0 :   fd_bincode_decode_ctx_t root_ctx = { .data = (uchar*)ctx->data - sizeof(ulong), .dataend = ctx->data };
     137           0 :   if( FD_UNLIKELY( ((ulong)ctx->data)+sizeof(ulong)>(ulong)ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
     138           0 :   fd_bincode_uint64_decode_unsafe( &root, &root_ctx );
     139           0 :   root = root != ULONG_MAX ? root : 0UL;
     140             :   /* Done with first modification */
     141             : 
     142           0 :   if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err;
     143           0 :   ushort lockout_offsets_len;
     144           0 :   if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
     145           0 :   err = fd_bincode_compact_u16_decode( &lockout_offsets_len, ctx );
     146             : 
     147           0 :   if( FD_UNLIKELY( err ) ) return err;
     148           0 :   ulong lockout_offsets_max = fd_ulong_max( lockout_offsets_len, 32 );
     149           0 :   *total_sz += deq_fd_lockout_offset_t_align() + deq_fd_lockout_offset_t_footprint( lockout_offsets_max );
     150             : 
     151           0 :   for( ulong i = 0; i < lockout_offsets_len; ++i ) {
     152             : 
     153           0 :     uchar const * start_data = ctx->data;
     154           0 :     if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
     155           0 :     err = fd_lockout_offset_decode_footprint_inner( ctx, total_sz );
     156           0 :     if( FD_UNLIKELY( err ) ) {
     157           0 :       return err;
     158           0 :     }
     159             : 
     160             :     /* The second modification is that we want to grab the lockout offset from
     161             :     the deque to make sure that we can do a checked add successfully. */
     162           0 :     fd_lockout_offset_t lockout_offset = {0};
     163           0 :     fd_bincode_decode_ctx_t lockout_ctx = { .data = start_data, .dataend = start_data+sizeof(fd_lockout_offset_t) };
     164           0 :     if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
     165           0 :     fd_lockout_offset_decode_inner( &lockout_offset, NULL, &lockout_ctx );
     166           0 :     err = __builtin_uaddl_overflow( root, lockout_offset.offset, &root );
     167           0 :     if( FD_UNLIKELY( err ) ) {
     168           0 :       return err;
     169           0 :     }
     170             :     /* Done with second modification. */
     171           0 :   }
     172             : 
     173           0 :   if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
     174           0 :   err = fd_hash_decode_footprint_inner( ctx, total_sz );
     175           0 :   if( FD_UNLIKELY( err ) ) return err;
     176           0 :   {
     177           0 :     uchar o;
     178           0 :     if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
     179           0 :     err = fd_bincode_bool_decode( &o, ctx );
     180           0 :     if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err;
     181           0 :     if( o ) {
     182           0 :       if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
     183           0 :       err = fd_bincode_int64_decode_footprint( ctx );
     184           0 :       if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) return err;
     185           0 :     }
     186           0 :   }
     187           0 :   if( FD_UNLIKELY( ctx->data>=ctx->dataend ) ) { return FD_BINCODE_ERR_OVERFLOW; }
     188           0 :   err = fd_hash_decode_footprint_inner( ctx, total_sz );
     189           0 :   if( FD_UNLIKELY( err ) ) return err;
     190           0 :   return 0;
     191           0 : }
     192             : 
     193           0 : void * fd_tower_sync_decode( void * mem, fd_bincode_decode_ctx_t * ctx ) {
     194           0 :   fd_tower_sync_t * self = (fd_tower_sync_t *)mem;
     195           0 :   fd_tower_sync_new( self );
     196           0 :   void * alloc_region = (uchar *)mem + sizeof(fd_tower_sync_t);
     197           0 :   void * * alloc_mem = &alloc_region;
     198           0 :   fd_tower_sync_decode_inner( mem, alloc_mem, ctx );
     199           0 :   return self;
     200           0 : }
     201             : 
     202           0 : void fd_tower_sync_decode_inner( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) {
     203           0 :   fd_tower_sync_t * self = (fd_tower_sync_t *)struct_mem;
     204           0 :   self->has_root = 1;
     205           0 :   fd_bincode_uint64_decode_unsafe( &self->root, ctx );
     206           0 :   self->has_root = self->root != ULONG_MAX;
     207             : 
     208           0 :   ushort lockout_offsets_len;
     209           0 :   fd_bincode_compact_u16_decode_unsafe( &lockout_offsets_len, ctx );
     210           0 :   ulong lockout_offsets_max = fd_ulong_max( lockout_offsets_len, 32 );
     211           0 :   self->lockouts = deq_fd_vote_lockout_t_join_new( alloc_mem, lockout_offsets_max );
     212             : 
     213             :   /* NOTE: Agave does a a checked add on the sum of the root with all of the
     214             :      lockout offsets in their custom deserializer for tower sync votes. If the
     215             :      checked add is violated (this should never happen), the deocder will
     216             :      return NULL.  */
     217             : 
     218             :   // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L1062-L1077
     219           0 :   ulong last_slot = ((self->root == ULONG_MAX) ? 0 : self->root);
     220           0 :   for( ulong i=0; i < lockout_offsets_len; i++ ) {
     221           0 :     fd_vote_lockout_t * elem = deq_fd_vote_lockout_t_push_tail_nocopy( self->lockouts );
     222             : 
     223           0 :     fd_lockout_offset_t o;
     224           0 :     fd_lockout_offset_decode_inner( &o, alloc_mem, ctx );
     225             : 
     226           0 :     elem->slot = last_slot + o.offset;
     227           0 :     elem->confirmation_count = o.confirmation_count;
     228           0 :     last_slot = elem->slot;
     229           0 :   }
     230             : 
     231           0 :   fd_hash_decode_inner( &self->hash, alloc_mem, ctx );
     232           0 :   {
     233           0 :     uchar o;
     234           0 :     fd_bincode_bool_decode_unsafe( &o, ctx );
     235           0 :     self->has_timestamp = !!o;
     236           0 :     if( o ) {
     237           0 :       fd_bincode_int64_decode_unsafe( &self->timestamp, ctx );
     238           0 :     }
     239           0 :   }
     240           0 :   fd_hash_decode_inner( &self->block_id, alloc_mem, ctx );
     241           0 : }
     242             : 
     243           0 : void fd_tower_sync_decode_inner_global( void * struct_mem, void * * alloc_mem, fd_bincode_decode_ctx_t * ctx ) {
     244           0 :   FD_LOG_ERR(("TODO: Implement"));
     245           0 : }
     246             : 
     247           0 : #define REDBLK_T fd_vote_reward_t_mapnode_t
     248             : #define REDBLK_NAME fd_vote_reward_t_map
     249             : #define REDBLK_IMPL_STYLE 2
     250             : #include "../../util/tmpl/fd_redblack.c"
     251             : 
     252           0 : long fd_vote_reward_t_map_compare( fd_vote_reward_t_mapnode_t * left, fd_vote_reward_t_mapnode_t * right ) {
     253           0 :   return memcmp( left->elem.pubkey.uc, right->elem.pubkey.uc, sizeof(right->elem.pubkey) );
     254           0 : }

Generated by: LCOV version 1.14