LCOV - code coverage report
Current view: top level - flamenco/runtime/tests - fd_gossip_harness.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 342 0.0 %
Date: 2026-05-31 08:07:40 Functions: 0 12 0.0 %

          Line data    Source code
       1             : #undef FD_SPAD_USE_HANDHOLDING
       2             : #define FD_SPAD_USE_HANDHOLDING 1
       3             : 
       4             : #include "fd_solfuzz_private.h"
       5             : #include "fd_gossip_harness.h"
       6             : #include "../../gossip/fd_gossip_message.h"
       7             : #include "../../../ballet/txn/fd_compact_u16.h"
       8             : #include "generated/gossip.pb.h"
       9             : 
      10             : /* alloc_bytes allocates a pb_bytes_array_t on the spad and copies
      11             :    src[0..len) into it. */
      12             : 
      13             : static pb_bytes_array_t *
      14             : alloc_bytes( fd_spad_t *   spad,
      15             :              uchar const * src,
      16           0 :              ulong         len ) {
      17           0 :   pb_bytes_array_t * arr = fd_spad_alloc( spad, alignof(pb_bytes_array_t), PB_BYTES_ARRAY_T_ALLOCSIZE( len ) );
      18           0 :   arr->size = (pb_size_t)len;
      19           0 :   if( FD_LIKELY( len ) ) memcpy( arr->bytes, src, len );
      20           0 :   return arr;
      21           0 : }
      22             : 
      23             : /* Re-parse helpers that walk raw wire bytes to extract fields the
      24             :    main deserializer does not retain (addrs, sockets, extensions,
      25             :    compressed slots). */
      26             : 
      27           0 : #define FD_VARINT_U64_MAX_BYTES (10UL) /* ceil(64/7) */
      28             : 
      29             : static inline int
      30             : skip_varint_u16( uchar const ** p,
      31           0 :                  ulong *        sz ) {
      32           0 :   ulong n = fd_cu16_dec_sz( *p, *sz );
      33           0 :   if( FD_UNLIKELY( !n ) ) return 0;
      34           0 :   *p  += n;
      35           0 :   *sz -= n;
      36           0 :   return 1;
      37           0 : }
      38             : 
      39             : static inline int
      40             : read_varint_u16( ushort *        dst,
      41             :                  uchar const **  p,
      42           0 :                  ulong *         sz ) {
      43           0 :   ulong n = fd_cu16_dec_sz( *p, *sz );
      44           0 :   if( FD_UNLIKELY( !n ) ) return 0;
      45           0 :   *dst = fd_cu16_dec_fixed( *p, n );
      46           0 :   *p  += n;
      47           0 :   *sz -= n;
      48           0 :   return 1;
      49           0 : }
      50             : 
      51             : static inline int
      52             : skip_varint_u64( uchar const ** p,
      53           0 :                  ulong *        sz ) {
      54           0 :   for( ulong i=0UL; i<FD_VARINT_U64_MAX_BYTES; i++ ) {
      55           0 :     if( FD_UNLIKELY( !*sz ) ) return 0;
      56           0 :     uchar byte = **p;
      57           0 :     (*p)++; (*sz)--;
      58           0 :     if( FD_LIKELY( !(byte & 0x80) ) ) return 1;
      59           0 :   }
      60           0 :   return 0;
      61           0 : }
      62             : 
      63           0 : #define NEED(n) do { if( FD_UNLIKELY( sz < (n) ) ) return; } while(0)
      64           0 : #define SKIP(n) do { NEED(n); p += (n); sz -= (n); } while(0)
      65             : 
      66             : static void
      67             : reparse_contact_info_extra( fd_spad_t *                          spad,
      68             :                             uchar const *                        value_start,
      69             :                             ulong                                value_len,
      70           0 :                             fd_exec_test_gossip_contact_info_t * ci ) {
      71           0 :   uchar const * p  = value_start;
      72           0 :   ulong         sz = value_len;
      73             : 
      74           0 :   SKIP( 68UL );  /* signature(64) + tag(4) */
      75           0 :   SKIP( 32UL );  /* origin(32) */
      76           0 :   if( FD_UNLIKELY( !skip_varint_u64( &p, &sz ) ) ) return;  /* wallclock */
      77           0 :   SKIP( 10UL );  /* outset(8) + shred_version(2) */
      78             : 
      79           0 :   if( FD_UNLIKELY( !skip_varint_u16( &p, &sz ) ) ) return;  /* major */
      80           0 :   if( FD_UNLIKELY( !skip_varint_u16( &p, &sz ) ) ) return;  /* minor */
      81           0 :   if( FD_UNLIKELY( !skip_varint_u16( &p, &sz ) ) ) return;  /* patch */
      82           0 :   SKIP( 4UL );  /* commit (u32) */
      83           0 :   SKIP( 4UL );  /* feature_set (u32) */
      84           0 :   if( FD_UNLIKELY( !skip_varint_u16( &p, &sz ) ) ) return;  /* client */
      85             : 
      86             :   /* Addrs */
      87           0 :   ushort addrs_len = 0;
      88           0 :   if( FD_UNLIKELY( !read_varint_u16( &addrs_len, &p, &sz ) ) ) return;
      89           0 :   ci->addrs_count = (pb_size_t)addrs_len;
      90           0 :   if( addrs_len ) {
      91           0 :     ci->addrs = fd_spad_alloc( spad, alignof(fd_exec_test_gossip_ip_addr_t),
      92           0 :                                addrs_len * sizeof(fd_exec_test_gossip_ip_addr_t) );
      93           0 :     for( ushort i=0; i<addrs_len; i++ ) {
      94           0 :       NEED( 4UL );
      95           0 :       uint is_ip6 = FD_LOAD( uint, p );
      96           0 :       p += 4UL; sz -= 4UL;
      97           0 :       if( !is_ip6 ) {
      98           0 :         NEED( 4UL );
      99           0 :         ci->addrs[i].which_addr = FD_EXEC_TEST_GOSSIP_IP_ADDR_IPV4_TAG;
     100           0 :         ci->addrs[i].addr.ipv4  = fd_uint_bswap( FD_LOAD( uint, p ) );
     101           0 :         p += 4UL; sz -= 4UL;
     102           0 :       } else {
     103           0 :         NEED( 16UL );
     104           0 :         ci->addrs[i].which_addr    = FD_EXEC_TEST_GOSSIP_IP_ADDR_IPV6_TAG;
     105           0 :         ci->addrs[i].addr.ipv6.hi  = fd_ulong_bswap( FD_LOAD( ulong, p ) );
     106           0 :         ci->addrs[i].addr.ipv6.lo  = fd_ulong_bswap( FD_LOAD( ulong, p+8UL ) );
     107           0 :         p += 16UL; sz -= 16UL;
     108           0 :       }
     109           0 :     }
     110           0 :   }
     111             : 
     112             :   /* Sockets */
     113           0 :   ushort sockets_len = 0;
     114           0 :   if( FD_UNLIKELY( !read_varint_u16( &sockets_len, &p, &sz ) ) ) return;
     115           0 :   ci->sockets_count = (pb_size_t)sockets_len;
     116           0 :   if( sockets_len ) {
     117           0 :     ci->sockets = fd_spad_alloc( spad, alignof(fd_exec_test_gossip_socket_entry_t),
     118           0 :                                  sockets_len * sizeof(fd_exec_test_gossip_socket_entry_t) );
     119           0 :     for( ushort i=0; i<sockets_len; i++ ) {
     120           0 :       NEED( 2UL );
     121           0 :       ci->sockets[i].key   = *p; p++; sz--;
     122           0 :       ci->sockets[i].index = *p; p++; sz--;
     123           0 :       ushort offset = 0;
     124           0 :       if( FD_UNLIKELY( !read_varint_u16( &offset, &p, &sz ) ) ) return;
     125           0 :       ci->sockets[i].offset = offset;
     126           0 :     }
     127           0 :   }
     128             : 
     129             :   /* Extensions (Agave always sends empty) */
     130           0 :   ci->extensions = NULL;
     131           0 : }
     132             : 
     133             : static void
     134             : reparse_epoch_slots_extra( fd_spad_t *                         spad,
     135             :                            uchar const *                       value_start,
     136             :                            ulong                               value_len,
     137           0 :                            fd_exec_test_gossip_epoch_slots_t * es ) {
     138           0 :   uchar const * p  = value_start;
     139           0 :   ulong         sz = value_len;
     140             : 
     141           0 :   SKIP( 68UL );  /* signature(64) + tag(4) */
     142           0 :   SKIP( 33UL );  /* index(1) + origin(32) */
     143             : 
     144             :   /* slots_len (u64) */
     145           0 :   NEED( 8UL );
     146           0 :   ulong slots_len = FD_LOAD( ulong, p );
     147           0 :   p += 8UL; sz -= 8UL;
     148             : 
     149           0 :   es->slots_count = (pb_size_t)slots_len;
     150           0 :   if( !slots_len ) {
     151           0 :     es->slots = NULL;
     152           0 :     return;
     153           0 :   }
     154             : 
     155           0 :   es->slots = fd_spad_alloc( spad, alignof(fd_exec_test_gossip_compressed_slots_t),
     156           0 :                              slots_len * sizeof(fd_exec_test_gossip_compressed_slots_t) );
     157             : 
     158           0 :   for( ulong i=0UL; i<slots_len; i++ ) {
     159           0 :     fd_exec_test_gossip_compressed_slots_t * slot = &es->slots[i];
     160             : 
     161           0 :     NEED( 4UL );
     162           0 :     uint is_uncompressed = FD_LOAD( uint, p );
     163           0 :     p += 4UL; sz -= 4UL;
     164             : 
     165           0 :     NEED( 8UL );
     166           0 :     slot->first_slot = FD_LOAD( ulong, p );
     167           0 :     p += 8UL; sz -= 8UL;
     168             : 
     169           0 :     NEED( 8UL );
     170           0 :     slot->num = FD_LOAD( ulong, p );
     171           0 :     p += 8UL; sz -= 8UL;
     172             : 
     173           0 :     if( is_uncompressed ) {
     174           0 :       slot->which_data = FD_EXEC_TEST_GOSSIP_COMPRESSED_SLOTS_UNCOMPRESSED_TAG;
     175           0 :       NEED( 1UL );
     176           0 :       uchar has_bits = *p; p++; sz--;
     177             : 
     178           0 :       if( has_bits ) {
     179           0 :         NEED( 8UL );
     180           0 :         ulong bits_cap = FD_LOAD( ulong, p );
     181           0 :         p += 8UL; sz -= 8UL;
     182           0 :         NEED( bits_cap );
     183           0 :         slot->data.uncompressed = alloc_bytes( spad, p, bits_cap );
     184           0 :         p += bits_cap; sz -= bits_cap;
     185           0 :         SKIP( 8UL );  /* bits_cnt */
     186           0 :       } else {
     187           0 :         slot->data.uncompressed = alloc_bytes( spad, NULL, 0UL );
     188           0 :         SKIP( 8UL );  /* bits_cnt */
     189           0 :       }
     190           0 :     } else {
     191           0 :       slot->which_data = FD_EXEC_TEST_GOSSIP_COMPRESSED_SLOTS_FLATE2_TAG;
     192           0 :       NEED( 8UL );
     193           0 :       ulong compressed_len = FD_LOAD( ulong, p );
     194           0 :       p += 8UL; sz -= 8UL;
     195           0 :       NEED( compressed_len );
     196           0 :       slot->data.flate2 = alloc_bytes( spad, p, compressed_len );
     197           0 :       p += compressed_len; sz -= compressed_len;
     198           0 :     }
     199           0 :   }
     200           0 : }
     201             : 
     202             : #undef SKIP
     203             : #undef NEED
     204             : 
     205             : static void
     206             : convert_crds_data( fd_spad_t *                          spad,
     207             :                    fd_gossip_value_t const *            val,
     208             :                    uchar const *                        raw_in,
     209           0 :                    fd_exec_test_gossip_crds_data_t *    out ) {
     210           0 :   switch( val->tag ) {
     211           0 :   case FD_GOSSIP_VALUE_CONTACT_INFO: {
     212           0 :     out->which_data = FD_EXEC_TEST_GOSSIP_CRDS_DATA_CONTACT_INFO_TAG;
     213           0 :     fd_exec_test_gossip_contact_info_t * ci = &out->data.contact_info;
     214           0 :     ci->pubkey              = alloc_bytes( spad, val->origin, sizeof(val->origin) );
     215           0 :     ci->wallclock           = val->wallclock;
     216           0 :     ci->outset              = val->contact_info->outset;
     217           0 :     ci->shred_version       = val->contact_info->shred_version;
     218           0 :     ci->version_major       = val->contact_info->version.major;
     219           0 :     ushort packed_minor     = val->contact_info->version.minor;
     220           0 :     ushort prerelease_bits  = (ushort)((packed_minor >> 14U) & 0x3U);
     221           0 :     ci->version_minor       = (uint)(packed_minor & 0x3FFFU);
     222           0 :     ci->version_patch       = prerelease_bits ? 0U : (uint)val->contact_info->version.patch;
     223           0 :     ci->version_commit      = val->contact_info->version.commit;
     224           0 :     ci->version_feature_set = val->contact_info->version.feature_set;
     225           0 :     ci->version_client      = val->contact_info->version.client;
     226           0 :     reparse_contact_info_extra( spad, raw_in + val->offset, val->length, ci );
     227           0 :     break;
     228           0 :   }
     229           0 :   case FD_GOSSIP_VALUE_VOTE:
     230           0 :     out->which_data = FD_EXEC_TEST_GOSSIP_CRDS_DATA_VOTE_TAG;
     231           0 :     out->data.vote.index       = val->vote->index;
     232           0 :     out->data.vote.from        = alloc_bytes( spad, val->origin, sizeof(val->origin) );
     233           0 :     out->data.vote.wallclock   = val->wallclock;
     234           0 :     out->data.vote.transaction = alloc_bytes( spad, val->vote->transaction, val->vote->transaction_len );
     235           0 :     break;
     236           0 :   case FD_GOSSIP_VALUE_LOWEST_SLOT:
     237           0 :     out->which_data = FD_EXEC_TEST_GOSSIP_CRDS_DATA_LOWEST_SLOT_TAG;
     238           0 :     out->data.lowest_slot.index     = 0;
     239           0 :     out->data.lowest_slot.from      = alloc_bytes( spad, val->origin, sizeof(val->origin) );
     240           0 :     out->data.lowest_slot.lowest    = val->lowest_slot->lowest;
     241           0 :     out->data.lowest_slot.wallclock = val->wallclock;
     242           0 :     break;
     243           0 :   case FD_GOSSIP_VALUE_EPOCH_SLOTS: {
     244           0 :     out->which_data = FD_EXEC_TEST_GOSSIP_CRDS_DATA_EPOCH_SLOTS_TAG;
     245           0 :     fd_exec_test_gossip_epoch_slots_t * es = &out->data.epoch_slots;
     246           0 :     es->index     = val->epoch_slots->index;
     247           0 :     es->from      = alloc_bytes( spad, val->origin, sizeof(val->origin) );
     248           0 :     es->wallclock = val->wallclock;
     249           0 :     reparse_epoch_slots_extra( spad, raw_in + val->offset, val->length, es );
     250           0 :     break;
     251           0 :   }
     252           0 :   case FD_GOSSIP_VALUE_SNAPSHOT_HASHES: {
     253           0 :     out->which_data = FD_EXEC_TEST_GOSSIP_CRDS_DATA_SNAPSHOT_HASHES_TAG;
     254           0 :     fd_exec_test_gossip_snapshot_hashes_t * sh = &out->data.snapshot_hashes;
     255           0 :     sh->from      = alloc_bytes( spad, val->origin, sizeof(val->origin) );
     256           0 :     sh->full_slot = val->snapshot_hashes->full_slot;
     257           0 :     sh->full_hash = alloc_bytes( spad, val->snapshot_hashes->full_hash, sizeof(val->snapshot_hashes->full_hash) );
     258           0 :     sh->wallclock = val->wallclock;
     259           0 :     sh->incremental_count = (pb_size_t)val->snapshot_hashes->incremental_len;
     260           0 :     if( sh->incremental_count ) {
     261           0 :       sh->incremental = fd_spad_alloc( spad, alignof(fd_exec_test_gossip_incremental_hash_t),
     262           0 :                                        sh->incremental_count * sizeof(fd_exec_test_gossip_incremental_hash_t) );
     263           0 :       for( ulong i=0UL; i<sh->incremental_count; i++ ) {
     264           0 :         sh->incremental[i].slot = val->snapshot_hashes->incremental[i].slot;
     265           0 :         sh->incremental[i].hash = alloc_bytes( spad, val->snapshot_hashes->incremental[i].hash,
     266           0 :                                                sizeof(val->snapshot_hashes->incremental[i].hash) );
     267           0 :       }
     268           0 :     }
     269           0 :     break;
     270           0 :   }
     271           0 :   case FD_GOSSIP_VALUE_DUPLICATE_SHRED:
     272           0 :     out->which_data = FD_EXEC_TEST_GOSSIP_CRDS_DATA_DUPLICATE_SHRED_TAG;
     273           0 :     out->data.duplicate_shred.index       = val->duplicate_shred->index;
     274           0 :     out->data.duplicate_shred.from        = alloc_bytes( spad, val->origin, sizeof(val->origin) );
     275           0 :     out->data.duplicate_shred.wallclock   = val->wallclock;
     276           0 :     out->data.duplicate_shred.slot        = val->duplicate_shred->slot;
     277           0 :     out->data.duplicate_shred.shred_index = 0;
     278           0 :     out->data.duplicate_shred.shred_type  = 0;
     279           0 :     out->data.duplicate_shred.num_chunks  = val->duplicate_shred->num_chunks;
     280           0 :     out->data.duplicate_shred.chunk_index = val->duplicate_shred->chunk_index;
     281           0 :     out->data.duplicate_shred.chunk       = val->duplicate_shred->chunk_len
     282           0 :                                               ? alloc_bytes( spad, val->duplicate_shred->chunk,
     283           0 :                                                              val->duplicate_shred->chunk_len )
     284           0 :                                               : NULL;
     285           0 :     break;
     286           0 :   default:
     287           0 :     out->which_data = 0;
     288           0 :     break;
     289           0 :   }
     290           0 : }
     291             : 
     292             : static void
     293             : convert_crds_value( fd_spad_t *                          spad,
     294             :                     fd_gossip_value_t const *            val,
     295             :                     uchar const *                        raw_in,
     296           0 :                     fd_exec_test_gossip_crds_value_t *   out ) {
     297           0 :   out->signature = alloc_bytes( spad, val->signature, sizeof(val->signature) );
     298           0 :   out->has_data  = true;
     299           0 :   convert_crds_data( spad, val, raw_in, &out->data );
     300           0 : }
     301             : 
     302             : static void
     303             : convert_crds_values( fd_spad_t *                           spad,
     304             :                      fd_gossip_value_t const *             vals,
     305             :                      ulong                                 vals_len,
     306             :                      uchar const *                         raw_in,
     307             :                      fd_exec_test_gossip_crds_value_t **   out_vals,
     308           0 :                      pb_size_t *                           out_count ) {
     309           0 :   *out_count = (pb_size_t)vals_len;
     310           0 :   if( !vals_len ) {
     311           0 :     *out_vals = NULL;
     312           0 :     return;
     313           0 :   }
     314           0 :   *out_vals = fd_spad_alloc( spad, alignof(fd_exec_test_gossip_crds_value_t),
     315           0 :                              vals_len * sizeof(fd_exec_test_gossip_crds_value_t) );
     316           0 :   for( ulong i=0UL; i<vals_len; i++ ) {
     317           0 :     convert_crds_value( spad, &vals[i], raw_in, &(*out_vals)[i] );
     318           0 :   }
     319           0 : }
     320             : 
     321             : static void
     322             : convert_bloom( fd_spad_t *                   spad,
     323             :                fd_gossip_bloom_t const *     bloom,
     324           0 :                fd_exec_test_gossip_bloom_t * out ) {
     325           0 :   out->keys_count = (pb_size_t)bloom->keys_len;
     326           0 :   if( bloom->keys_len ) {
     327           0 :     out->keys = fd_spad_alloc( spad, alignof(uint64_t), bloom->keys_len * sizeof(uint64_t) );
     328           0 :     memcpy( out->keys, bloom->keys, bloom->keys_len * sizeof(uint64_t) );
     329           0 :   }
     330             :   /* Copy only block_len() worth of u64 blocks, not bits_cap.
     331             :      https://github.com/tov/bv-rs/blob/0.11.1/src/bit_vec/mod.rs#L243-L245 */
     332           0 :   ulong bits_blocks   = (bloom->bits_len + 63UL) / 64UL;
     333           0 :   ulong bits_byte_len = bits_blocks * sizeof(bloom->bits[0]);
     334           0 :   out->bits = alloc_bytes( spad, (uchar const *)bloom->bits, bits_byte_len );
     335             :   /* Mask trailing bits beyond bits_len in the last block of the
     336             :      protobuf copy.  bv::BitVec::get_block() returns get_masked_block()
     337             :      which zeros bits past bit_len() in the last block.
     338             :      https://github.com/tov/bv-rs/blob/0.11.1/src/bit_vec/impls.rs#L30-L32
     339             :      https://github.com/tov/bv-rs/blob/0.11.1/src/traits/bits.rs#L134-L137 */
     340           0 :   if( bloom->bits_len & 63UL ) {
     341           0 :     ulong last = bits_blocks - 1UL;
     342           0 :     ulong mask = ( 2UL << ((bloom->bits_len - 1UL) & 63UL) ) - 1UL;
     343           0 :     ((ulong *)out->bits->bytes)[ last ] &= mask;
     344           0 :   }
     345           0 :   out->num_bits_set = bloom->num_bits_set;
     346           0 : }
     347             : 
     348             : static void
     349             : convert_gossip_msg( fd_spad_t *                 spad,
     350             :                     fd_gossip_message_t const * msg,
     351             :                     uchar const *               raw_in,
     352           0 :                     fd_exec_test_gossip_msg_t * out ) {
     353           0 :   switch( msg->tag ) {
     354           0 :   case FD_GOSSIP_MESSAGE_PING:
     355           0 :     out->which_msg = FD_EXEC_TEST_GOSSIP_MSG_PING_TAG;
     356           0 :     out->msg.ping.from      = alloc_bytes( spad, msg->ping->from,      sizeof(msg->ping->from) );
     357           0 :     out->msg.ping.token     = alloc_bytes( spad, msg->ping->token,     sizeof(msg->ping->token) );
     358           0 :     out->msg.ping.signature = alloc_bytes( spad, msg->ping->signature, sizeof(msg->ping->signature) );
     359           0 :     break;
     360           0 :   case FD_GOSSIP_MESSAGE_PONG:
     361           0 :     out->which_msg = FD_EXEC_TEST_GOSSIP_MSG_PONG_TAG;
     362           0 :     out->msg.pong.from      = alloc_bytes( spad, msg->pong->from,      sizeof(msg->pong->from) );
     363           0 :     out->msg.pong.hash      = alloc_bytes( spad, msg->pong->hash,      sizeof(msg->pong->hash) );
     364           0 :     out->msg.pong.signature = alloc_bytes( spad, msg->pong->signature, sizeof(msg->pong->signature) );
     365           0 :     break;
     366           0 :   case FD_GOSSIP_MESSAGE_PULL_REQUEST: {
     367           0 :     out->which_msg = FD_EXEC_TEST_GOSSIP_MSG_PULL_REQUEST_TAG;
     368           0 :     fd_exec_test_gossip_pull_request_t * pr = &out->msg.pull_request;
     369           0 :     pr->has_filter = true;
     370           0 :     pr->filter.has_filter = true;
     371           0 :     convert_bloom( spad, msg->pull_request->crds_filter->filter, &pr->filter.filter );
     372           0 :     pr->filter.mask_bits = msg->pull_request->crds_filter->mask_bits;
     373             :     /* Agave canonicalizes the mask by setting all (64-mask_bits) low bits to 1.
     374             :        https://github.com/anza-xyz/agave/blob/v4.0.0-beta.6/gossip/src/crds_gossip_pull.rs#L152-L155 */
     375           0 :     ulong lsb_mask = (pr->filter.mask_bits>=64U) ? 0UL : (ULONG_MAX >> pr->filter.mask_bits);
     376           0 :     pr->filter.mask = msg->pull_request->crds_filter->mask | lsb_mask;
     377           0 :     pr->has_value = true;
     378           0 :     convert_crds_value( spad, msg->pull_request->contact_info, raw_in, &pr->value );
     379           0 :     break;
     380           0 :   }
     381           0 :   case FD_GOSSIP_MESSAGE_PULL_RESPONSE: {
     382           0 :     out->which_msg = FD_EXEC_TEST_GOSSIP_MSG_PULL_RESPONSE_TAG;
     383           0 :     fd_exec_test_gossip_pull_response_t * pr = &out->msg.pull_response;
     384           0 :     pr->pubkey = alloc_bytes( spad, msg->pull_response->from, sizeof(msg->pull_response->from) );
     385           0 :     convert_crds_values( spad, msg->pull_response->values,
     386           0 :                          msg->pull_response->values_len,
     387           0 :                          raw_in,
     388           0 :                          &pr->values, &pr->values_count );
     389           0 :     break;
     390           0 :   }
     391           0 :   case FD_GOSSIP_MESSAGE_PUSH: {
     392           0 :     out->which_msg = FD_EXEC_TEST_GOSSIP_MSG_PUSH_MESSAGE_TAG;
     393           0 :     fd_exec_test_gossip_push_message_t * pm = &out->msg.push_message;
     394           0 :     pm->pubkey = alloc_bytes( spad, msg->push->from, sizeof(msg->push->from) );
     395           0 :     convert_crds_values( spad, msg->push->values,
     396           0 :                          msg->push->values_len,
     397           0 :                          raw_in,
     398           0 :                          &pm->values, &pm->values_count );
     399           0 :     break;
     400           0 :   }
     401           0 :   case FD_GOSSIP_MESSAGE_PRUNE: {
     402           0 :     out->which_msg = FD_EXEC_TEST_GOSSIP_MSG_PRUNE_MESSAGE_TAG;
     403           0 :     fd_exec_test_gossip_prune_message_t * pm = &out->msg.prune_message;
     404           0 :     pm->pubkey   = alloc_bytes( spad, msg->prune->sender,      sizeof(msg->prune->sender) );
     405           0 :     pm->has_data = true;
     406           0 :     pm->data.pubkey      = alloc_bytes( spad, msg->prune->pubkey,      sizeof(msg->prune->pubkey) );
     407           0 :     pm->data.signature   = alloc_bytes( spad, msg->prune->signature,   sizeof(msg->prune->signature) );
     408           0 :     pm->data.destination = alloc_bytes( spad, msg->prune->destination, sizeof(msg->prune->destination) );
     409           0 :     pm->data.wallclock   = msg->prune->wallclock;
     410           0 :     pm->data.prunes_count = (pb_size_t)msg->prune->prunes_len;
     411           0 :     if( msg->prune->prunes_len ) {
     412           0 :       pm->data.prunes = fd_spad_alloc( spad, alignof(pb_bytes_array_t *),
     413           0 :                                        msg->prune->prunes_len * sizeof(pb_bytes_array_t *) );
     414           0 :       for( ulong i=0UL; i<msg->prune->prunes_len; i++ ) {
     415           0 :         pm->data.prunes[i] = alloc_bytes( spad, msg->prune->prunes[i], sizeof(msg->prune->prunes[i]) );
     416           0 :       }
     417           0 :     }
     418           0 :     break;
     419           0 :   }
     420           0 :   default:
     421           0 :     out->which_msg = 0;
     422           0 :     break;
     423           0 :   }
     424           0 : }
     425             : 
     426             : int
     427             : fd_solfuzz_gossip_decode( fd_solfuzz_runner_t * runner,
     428             :                           uchar *               out,
     429             :                           ulong *               out_sz,
     430             :                           uchar const *         in,
     431           0 :                           ulong                 in_sz ) {
     432           0 :   if( FD_UNLIKELY( in_sz>FD_TPU_MTU ) ) FD_LOG_CRIT(( "invariant violation: gossip input %lu bytes exceeds MTU %lu, check fuzzer configuration", in_sz, FD_TPU_MTU ));
     433             : 
     434           0 :   fd_gossip_message_t * msg = fd_spad_alloc( runner->spad, alignof(fd_gossip_message_t), sizeof(fd_gossip_message_t) );
     435           0 :   fd_memset( msg, 0, sizeof(fd_gossip_message_t) );
     436           0 :   fd_exec_test_gossip_effects_t effects = FD_EXEC_TEST_GOSSIP_EFFECTS_INIT_ZERO;
     437             : 
     438           0 :   int ok = fd_gossip_message_deserialize( msg, in, in_sz );
     439           0 :   if( ok ) {
     440           0 :     effects.valid   = true;
     441           0 :     effects.has_msg = true;
     442           0 :     convert_gossip_msg( runner->spad, msg, in, &effects.msg );
     443           0 :   } else {
     444           0 :     effects.valid   = false;
     445           0 :     effects.has_msg = false;
     446           0 :   }
     447             : 
     448           0 :   return !!sol_compat_encode( out, out_sz, &effects, &fd_exec_test_gossip_effects_t_msg );
     449           0 : }

Generated by: LCOV version 1.14