LCOV - code coverage report
Current view: top level - flamenco/txn - fd_txn_generate.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 86 0.0 %
Date: 2026-10-22 18:10:43 Functions: 0 3 0.0 %

          Line data    Source code
       1             : #include "fd_txn_generate.h"
       2             : 
       3             : /* Message header type */
       4             : struct __attribute__((packed)) fd_txn_message_hdr {
       5             :   uchar num_signatures;
       6             :   uchar num_readonly_signatures;
       7             :   uchar num_readonly_unsigned;
       8             : };
       9             : 
      10             : typedef struct fd_txn_message_hdr fd_txn_message_hdr_t;
      11             : 
      12             : static fd_txn_instr_t *
      13             : fd_txn_instr_meta_generate( uchar * out_buf,
      14             :                             uchar program_id,
      15             :                             ushort acct_cnt,
      16             :                             ushort data_sz,
      17             :                             ushort acct_off,
      18           0 :                             ushort data_off ) {
      19           0 :     fd_txn_instr_t * out_instr = (fd_txn_instr_t *) out_buf;
      20           0 :     out_instr->program_id = program_id;
      21           0 :     out_instr->acct_cnt   = acct_cnt;
      22           0 :     out_instr->data_sz    = data_sz;
      23           0 :     out_instr->acct_off   = acct_off;
      24           0 :     out_instr->data_off   = data_off;
      25           0 :     return out_instr;
      26           0 : }
      27             : 
      28             : ulong
      29             : fd_txn_base_generate( uchar out_txn_meta[ static FD_TXN_MAX_SZ ],
      30             :                       uchar out_txn_payload[ static FD_TXN_MTU ],
      31             :                       ulong num_signatures,
      32             :                       fd_txn_accounts_t * accounts,
      33           0 :                       uchar const * opt_recent_blockhash ) {
      34             : 
      35             :   /* Number of signatures cannot exceed 127. */
      36           0 :   FD_TEST(num_signatures <= FD_TXN_SIG_MAX);
      37           0 :   *out_txn_payload = (uchar)num_signatures;
      38             : 
      39             :   /* Fill out txn metadata */
      40           0 :   fd_txn_t * txn_meta             = (fd_txn_t *) out_txn_meta;
      41           0 :   txn_meta->transaction_version   = FD_TXN_VLEGACY;
      42           0 :   txn_meta->signature_cnt         = (uchar)num_signatures;
      43           0 :   txn_meta->acct_addr_cnt         = accounts->acct_cnt;
      44           0 :   txn_meta->readonly_signed_cnt   = accounts->readonly_signed_cnt;
      45           0 :   txn_meta->readonly_unsigned_cnt = accounts->readonly_unsigned_cnt;
      46             :   /* Number of signatures is encoded as a compact u16 but
      47             :      can always be encoded using 1 byte here. */
      48           0 :   txn_meta->message_off           = (ushort)(num_signatures * FD_TXN_SIGNATURE_SZ  + 1);
      49           0 :   txn_meta->signature_off         = (ushort)1UL;
      50           0 :   txn_meta->instr_cnt             = 0;
      51             : 
      52           0 :   FD_TEST(txn_meta->acct_addr_cnt < FD_TXN_ACCT_ADDR_MAX);
      53           0 :   txn_meta->acct_addr_off        = (ushort)(txn_meta->message_off + (sizeof(fd_txn_message_hdr_t)) + 1);
      54           0 :   txn_meta->recent_blockhash_off = (ushort)(txn_meta->acct_addr_off + (txn_meta->acct_addr_cnt * FD_TXN_ACCT_ADDR_SZ));
      55             : 
      56             :   /* Fill message header in txn payload */
      57           0 :   uchar * write_ptr = out_txn_payload + txn_meta->message_off;
      58           0 :   fd_txn_message_hdr_t msg_header = { .num_signatures = accounts->signature_cnt,
      59           0 :                                       .num_readonly_signatures = accounts->readonly_signed_cnt,
      60           0 :                                       .num_readonly_unsigned   = accounts->readonly_unsigned_cnt };
      61           0 :   memcpy( write_ptr, &msg_header, sizeof(fd_txn_message_hdr_t) ) ;
      62           0 :   write_ptr += sizeof(fd_txn_message_hdr_t);
      63             : 
      64             :   /* Write number of accounts */
      65           0 :   *write_ptr = (uchar)txn_meta->acct_addr_cnt;
      66           0 :   write_ptr += 1;
      67             : 
      68             :   /* Write accounts list to txn payload */
      69           0 :   ulong signers_write_sz     = FD_TXN_ACCT_ADDR_SZ * (ulong)(accounts->signature_cnt - accounts->readonly_signed_cnt);
      70           0 :   ulong signers_read_sz      = FD_TXN_ACCT_ADDR_SZ * (ulong)accounts->readonly_signed_cnt;
      71           0 :   ulong non_signers_write_sz = FD_TXN_ACCT_ADDR_SZ * (ulong)(accounts->acct_cnt - accounts->readonly_unsigned_cnt - accounts->signature_cnt);
      72           0 :   ulong non_signers_read_sz  = FD_TXN_ACCT_ADDR_SZ * (ulong)accounts->readonly_unsigned_cnt;
      73             : 
      74           0 :   if( signers_write_sz ) memcpy( write_ptr, accounts->signers_w, signers_write_sz );
      75           0 :   write_ptr += signers_write_sz;
      76             : 
      77           0 :   if( signers_read_sz ) memcpy( write_ptr, accounts->signers_r, signers_read_sz );
      78           0 :   write_ptr += signers_read_sz;
      79             : 
      80           0 :   if( non_signers_write_sz ) memcpy( write_ptr, accounts->non_signers_w, non_signers_write_sz );
      81           0 :   write_ptr += non_signers_write_sz;
      82             : 
      83           0 :   if( non_signers_read_sz ) memcpy( write_ptr, accounts->non_signers_r, non_signers_read_sz );
      84           0 :   write_ptr += non_signers_read_sz;
      85           0 :   FD_TEST( (ushort)((ulong)write_ptr - (ulong)out_txn_payload) == txn_meta->recent_blockhash_off );
      86             : 
      87             :   /* Write recent blockhash */
      88           0 :   if( FD_LIKELY( opt_recent_blockhash ) ) {
      89           0 :     memcpy( write_ptr, opt_recent_blockhash, FD_TXN_BLOCKHASH_SZ );
      90           0 :   } else {
      91           0 :     memset( write_ptr, 0UL, FD_TXN_BLOCKHASH_SZ );
      92           0 :   }
      93           0 :   write_ptr += FD_TXN_BLOCKHASH_SZ;
      94             : 
      95           0 :   return (ulong)(write_ptr - out_txn_payload);
      96           0 : }
      97             : 
      98             : ulong
      99             : fd_txn_add_instr( uchar * txn_meta_ptr,
     100             :                   uchar out_txn_payload[ static FD_TXN_MTU ],
     101             :                   uchar program_id,
     102             :                   uchar const * accounts,
     103             :                   ulong accounts_sz,
     104             :                   uchar const * instr_buf,
     105           0 :                   ulong instr_buf_sz ) {
     106             : 
     107           0 :   fd_txn_t * txn_meta = (fd_txn_t *) txn_meta_ptr;
     108           0 :   FD_TEST( txn_meta->instr_cnt < FD_TXN_INSTR_MAX );
     109           0 :   FD_TEST( txn_meta->recent_blockhash_off != 0 );
     110             : 
     111           0 :   uchar * instr_start = out_txn_payload + txn_meta->recent_blockhash_off + FD_TXN_BLOCKHASH_SZ;
     112           0 :   txn_meta->instr_cnt++;
     113           0 :   uchar * write_ptr       = instr_start;
     114             : 
     115           0 :   uint compact_instr_cnt_sz = fd_cu16_enc( (ushort)txn_meta->instr_cnt, write_ptr );
     116           0 :   FD_TEST( compact_instr_cnt_sz == 1 );
     117             : 
     118           0 :   write_ptr += compact_instr_cnt_sz;
     119             : 
     120             :   /* Calculate offset of next instruction. */
     121           0 :   if ( FD_UNLIKELY( txn_meta->instr_cnt > 1 ) ) {
     122           0 :     write_ptr = out_txn_payload + txn_meta->instr[txn_meta->instr_cnt-2].data_off + txn_meta->instr[txn_meta->instr_cnt-2].data_sz;
     123           0 :   }
     124             : 
     125           0 :   instr_start = write_ptr;
     126             : 
     127           0 :   *write_ptr = program_id;
     128           0 :   write_ptr += sizeof(uchar);
     129             : 
     130           0 :   uint compact_accts_len_sz = fd_cu16_enc( (ushort)accounts_sz, write_ptr );
     131           0 :   write_ptr += compact_accts_len_sz;
     132             : 
     133           0 :   ushort acct_off = (ushort) (write_ptr - out_txn_payload);
     134           0 :   fd_memcpy( write_ptr, accounts, accounts_sz );
     135           0 :   write_ptr += accounts_sz;
     136             : 
     137           0 :   ushort data_sz = (ushort)instr_buf_sz;
     138           0 :   uint compact_data_len_sz = fd_cu16_enc( data_sz, write_ptr );
     139           0 :   write_ptr += compact_data_len_sz;
     140             : 
     141             :   /* Copy data buffer over */
     142           0 :   ushort data_off = (ushort) (write_ptr - out_txn_payload);
     143           0 :   fd_memcpy( write_ptr, instr_buf, data_sz );
     144           0 :   write_ptr += data_sz;
     145             : 
     146           0 :   (void) fd_txn_instr_meta_generate( (uchar*)&txn_meta->instr[txn_meta->instr_cnt-1],
     147           0 :                                       program_id,
     148           0 :                                       (ushort)accounts_sz,
     149           0 :                                       data_sz, acct_off, data_off );
     150           0 :   return (ulong)(write_ptr - out_txn_payload);
     151           0 : }

Generated by: LCOV version 1.14