LCOV - code coverage report
Current view: top level - flamenco/capture - fd_solcap_reader.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 119 0.0 %
Date: 2024-11-13 11:58:15 Functions: 0 6 0.0 %

          Line data    Source code
       1             : #include "fd_solcap_reader.h"
       2             : #include "fd_solcap_proto.h"
       3             : #include "../nanopb/pb_decode.h"
       4             : 
       5             : #if !FD_HAS_HOSTED
       6             : #error "fd_solcap_reader requires FD_HAS_HOSTED"
       7             : #endif
       8             : 
       9             : #include <errno.h>
      10             : #include <stdio.h>
      11             : 
      12             : fd_solcap_chunk_iter_t *
      13             : fd_solcap_chunk_iter_new( fd_solcap_chunk_iter_t * iter,
      14           0 :                           void *                   _stream ) {
      15             : 
      16           0 :   FILE * stream = (FILE *)_stream;
      17             : 
      18           0 :   long pos = ftell( stream );
      19           0 :   if( FD_UNLIKELY( pos<0L ) ) {
      20           0 :     iter->err = errno;
      21           0 :     return iter;
      22           0 :   }
      23             : 
      24           0 :   *iter = (fd_solcap_chunk_iter_t) {
      25           0 :     .stream    = stream,
      26           0 :     .chunk     = {0},
      27           0 :     .chunk_off = 0UL,
      28           0 :     .chunk_end = (ulong)pos,
      29           0 :   };
      30           0 :   return iter;
      31           0 : }
      32             : 
      33             : long
      34           0 : fd_solcap_chunk_iter_next( fd_solcap_chunk_iter_t * iter ) {
      35             : 
      36           0 :   FILE * stream = (FILE *)iter->stream;
      37             : 
      38           0 :   long chunk_gaddr = (long)iter->chunk_end;
      39           0 :   if( FD_UNLIKELY( 0!=fseek( iter->stream, chunk_gaddr, SEEK_SET ) ) ) {
      40           0 :     FD_LOG_WARNING(( "fseek failed (%d-%s)", errno, strerror( errno ) ));
      41           0 :     iter->err = errno;
      42           0 :     return -1L;
      43           0 :   }
      44           0 :   iter->chunk_off = (ulong)chunk_gaddr;
      45             : 
      46           0 :   ulong n = fread( &iter->chunk, sizeof(fd_solcap_chunk_t), 1UL, stream );
      47           0 :   if( FD_UNLIKELY( n!=1UL ) ) {
      48           0 :     int err = ferror( stream );
      49           0 :     if( FD_UNLIKELY( err ) ) {
      50           0 :       FD_LOG_WARNING(( "fread failed (%d-%s)", errno, strerror( errno ) ));
      51           0 :       iter->err = err;
      52           0 :     }
      53           0 :     iter->err = 0;
      54           0 :     return -1L;
      55           0 :   }
      56             : 
      57           0 :   if( FD_UNLIKELY( ( !fd_solcap_is_chunk_magic( iter->chunk.magic )   )
      58           0 :                  | ( iter->chunk.total_sz < sizeof(fd_solcap_chunk_t) ) ) ) {
      59           0 :     FD_LOG_WARNING(( "invalid chunk (offset=%#lx magic=0x%016lx total_sz=%lu)",
      60           0 :                      (ulong)chunk_gaddr, iter->chunk.magic, iter->chunk.total_sz ));
      61           0 :     iter->err = EPROTO;
      62           0 :     return -1L;
      63           0 :   }
      64             : 
      65           0 :   iter->chunk_end = (ulong)chunk_gaddr + iter->chunk.total_sz;
      66             : 
      67           0 :   return chunk_gaddr;
      68           0 : }
      69             : 
      70             : int
      71           0 : fd_solcap_chunk_iter_done( fd_solcap_chunk_iter_t const * iter ) {
      72           0 :   return feof( (FILE *)iter->stream ) || fd_solcap_chunk_iter_err( iter );
      73           0 : }
      74             : 
      75             : 
      76             : int
      77             : fd_solcap_read_bank_preimage( void *                    _file,
      78             :                               ulong                     chunk_goff,
      79             :                               fd_solcap_BankPreimage *  preimage,
      80           0 :                               fd_solcap_chunk_t const * hdr ) {
      81             : 
      82           0 :   if( FD_UNLIKELY( hdr->magic != FD_SOLCAP_V1_BANK_MAGIC ) )
      83           0 :     return EPROTO;
      84             : 
      85             :   /* Seek to Protobuf */
      86           0 :   FILE * file = (FILE *)_file;
      87           0 :   if( FD_UNLIKELY( 0!=fseek( file, (long)chunk_goff + hdr->meta_coff, SEEK_SET ) ) )
      88           0 :     return errno;
      89             : 
      90             :   /* Read into stack buffer */
      91           0 :   uchar buf[ FD_SOLCAP_BANK_PREIMAGE_FOOTPRINT ];
      92           0 :   if( FD_UNLIKELY( hdr->meta_sz > FD_SOLCAP_BANK_PREIMAGE_FOOTPRINT ) )
      93           0 :     return ENOMEM;
      94           0 :   if( FD_UNLIKELY( hdr->meta_sz != fread( buf, 1UL, hdr->meta_sz, file ) ) )
      95           0 :     return ferror( file );
      96             : 
      97             :   /* Decode */
      98           0 :   pb_istream_t stream = pb_istream_from_buffer( buf, hdr->meta_sz );
      99           0 :   if( FD_UNLIKELY( !pb_decode( &stream, fd_solcap_BankPreimage_fields, preimage ) ) ) {
     100           0 :     FD_LOG_WARNING(( "pb_decode failed (%s)", PB_GET_ERROR(&stream) ));
     101           0 :     return EPROTO;
     102           0 :   }
     103             : 
     104           0 :   return 0;
     105           0 : }
     106             : 
     107             : int
     108             : fd_solcap_find_account_table( void *                       _file,
     109             :                               fd_solcap_AccountTableMeta * meta,
     110           0 :                               ulong                        _chunk_goff ) {
     111             : 
     112             :   /* Read account table chunk header */
     113           0 :   long chunk_goff = (long)_chunk_goff;
     114           0 :   fd_solcap_chunk_t hdr[1];
     115           0 :   FILE * file = (FILE *)_file;
     116           0 :   if( FD_UNLIKELY( 0!=fseek( file, chunk_goff, SEEK_SET ) ) )
     117           0 :     return errno;
     118           0 :   if( FD_UNLIKELY( 1UL != fread( hdr, sizeof(fd_solcap_chunk_t), 1UL, file ) ) )
     119           0 :     return ferror( file );
     120           0 :   if( FD_UNLIKELY( hdr->magic != FD_SOLCAP_V1_ACTB_MAGIC ) )
     121           0 :     return EPROTO;
     122             : 
     123             :   /* Seek to Protobuf */
     124           0 :   if( FD_UNLIKELY( 0!=fseek( file, chunk_goff + hdr->meta_coff, SEEK_SET ) ) )
     125           0 :     return errno;
     126             : 
     127             :   /* Read into stack buffer */
     128           0 :   uchar buf[ FD_SOLCAP_ACTB_META_FOOTPRINT ];
     129           0 :   if( FD_UNLIKELY( hdr->meta_sz > FD_SOLCAP_ACTB_META_FOOTPRINT ) )
     130           0 :     return ENOMEM;
     131           0 :   if( FD_UNLIKELY( hdr->meta_sz != fread( buf, 1UL, hdr->meta_sz, file ) ) )
     132           0 :     return ferror( file );
     133             : 
     134             :   /* Decode */
     135           0 :   pb_istream_t stream = pb_istream_from_buffer( buf, hdr->meta_sz );
     136           0 :   if( FD_UNLIKELY( !pb_decode( &stream, fd_solcap_AccountTableMeta_fields, meta ) ) ) {
     137           0 :     FD_LOG_WARNING(( "pb_decode failed (%s)", PB_GET_ERROR(&stream) ));
     138           0 :     return EPROTO;
     139           0 :   }
     140             : 
     141             :   /* Seek to table */
     142           0 :   if( meta->account_table_coff ) {
     143           0 :     if( FD_UNLIKELY( 0!=fseek( file, chunk_goff + (long)meta->account_table_coff, SEEK_SET ) ) )
     144           0 :       return errno;
     145           0 :   }
     146             : 
     147           0 :   return 0;
     148           0 : }
     149             : 
     150             : int
     151             : fd_solcap_find_account( void *                          _file,
     152             :                         fd_solcap_AccountMeta *         meta,
     153             :                         ulong *                         opt_data_off,
     154             :                         fd_solcap_account_tbl_t const * rec,
     155           0 :                         ulong                           acc_tbl_goff ) {
     156             : 
     157             :   /* Read account chunk header */
     158           0 :   long chunk_goff = (long)acc_tbl_goff + rec->acc_coff;
     159           0 :   fd_solcap_chunk_t hdr[1];
     160           0 :   FILE * file = (FILE *)_file;
     161           0 :   if( FD_UNLIKELY( 0!=fseek( file, chunk_goff, SEEK_SET ) ) )
     162           0 :     return errno;
     163           0 :   if( FD_UNLIKELY( 1UL != fread( hdr, sizeof(fd_solcap_chunk_t), 1UL, file ) ) )
     164           0 :     return ferror( file );
     165           0 :   if( FD_UNLIKELY( hdr->magic != FD_SOLCAP_V1_ACCT_MAGIC ) )
     166           0 :     return EPROTO;
     167             : 
     168             :   /* Seek to Protobuf */
     169           0 :   if( FD_UNLIKELY( 0!=fseek( file, chunk_goff + hdr->meta_coff, SEEK_SET ) ) )
     170           0 :     return errno;
     171             : 
     172             :   /* Read into stack buffer */
     173           0 :   uchar buf[ FD_SOLCAP_ACCOUNT_META_FOOTPRINT ];
     174           0 :   if( FD_UNLIKELY( hdr->meta_sz > FD_SOLCAP_ACCOUNT_META_FOOTPRINT ) )
     175           0 :     return ENOMEM;
     176           0 :   if( FD_UNLIKELY( hdr->meta_sz != fread( buf, 1UL, hdr->meta_sz, file ) ) )
     177           0 :     return ferror( file );
     178             : 
     179             :   /* Decode */
     180           0 :   pb_istream_t stream = pb_istream_from_buffer( buf, hdr->meta_sz );
     181           0 :   if( FD_UNLIKELY( !pb_decode( &stream, fd_solcap_AccountMeta_fields, meta ) ) ) {
     182           0 :     FD_LOG_WARNING(( "pb_decode failed (%s)", PB_GET_ERROR(&stream) ));
     183           0 :     return EPROTO;
     184           0 :   }
     185             : 
     186             :   /* Seek to account data */
     187           0 :   if( fd_solcap_includes_account_data( meta ) && opt_data_off )
     188           0 :     *opt_data_off = (ulong)( chunk_goff + (long)meta->data_coff );
     189             : 
     190           0 :   return 0;
     191           0 : }

Generated by: LCOV version 1.14