LCOV - code coverage report
Current view: top level - flamenco/runtime/sysvar - fd_sysvar_instructions.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 73 0.0 %
Date: 2025-07-01 05:00:49 Functions: 0 3 0.0 %

          Line data    Source code
       1             : #include "fd_sysvar_instructions.h"
       2             : #include "../fd_borrowed_account.h"
       3             : #include "../fd_system_ids.h"
       4             : 
       5             : static ulong
       6             : instructions_serialized_size( fd_instr_info_t const *   instrs,
       7           0 :                               ushort                    instrs_cnt ) {
       8           0 :   ulong serialized_size = 0;
       9             : 
      10           0 :   serialized_size += sizeof(ushort)       // num_instructions
      11           0 :     + (sizeof(ushort) * instrs_cnt);      // instruction offsets
      12             : 
      13           0 :   for ( ushort i = 0; i < instrs_cnt; ++i ) {
      14           0 :     fd_instr_info_t const * instr = &instrs[i];
      15             : 
      16           0 :     serialized_size += sizeof(ushort); // num_accounts;
      17             : 
      18           0 :     serialized_size += instr->acct_cnt * (
      19           0 :       sizeof(uchar)               // flags (is_signer, is_writeable)
      20           0 :       + sizeof(fd_pubkey_t)         // pubkey
      21           0 :     );
      22             : 
      23           0 :     serialized_size += sizeof(fd_pubkey_t)  // program_id pubkey
      24           0 :         + sizeof(ushort)                    // instr_data_len;
      25           0 :         + instr->data_sz;                   // instr_data;
      26             : 
      27           0 :   }
      28             : 
      29           0 :   serialized_size += sizeof(ushort); // current_instr_idx
      30             : 
      31           0 :   return serialized_size;
      32           0 : }
      33             : 
      34             : /* https://github.com/anza-xyz/agave/blob/v2.1.1/svm/src/account_loader.rs#L547-L576 */
      35             : void
      36             : fd_sysvar_instructions_serialize_account( fd_exec_txn_ctx_t *      txn_ctx,
      37             :                                           fd_instr_info_t const *  instrs,
      38           0 :                                           ushort                   instrs_cnt ) {
      39           0 :   ulong serialized_sz = instructions_serialized_size( instrs, instrs_cnt );
      40             : 
      41           0 :   fd_txn_account_t * rec = NULL;
      42           0 :   int err = fd_exec_txn_ctx_get_account_with_key( txn_ctx,
      43           0 :                                                   &fd_sysvar_instructions_id,
      44           0 :                                                   &rec,
      45           0 :                                                   fd_txn_account_check_exists );
      46           0 :   if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS && rec==NULL ) ) {
      47             :     /* The way we use this, this should NEVER hit since the borrowed accounts should be set up
      48             :        before this is called, and this is only called if the sysvar instructions account is in
      49             :        the borrowed accounts list. */
      50           0 :     FD_LOG_ERR(( "Failed to view sysvar instructions borrowed account. It may not be included in the txn account keys." ));
      51           0 :   }
      52             : 
      53             :   /* This stays within the FD spad allocation bounds because...
      54             :      1. Case 1: rec->meta!=NULL
      55             :         - rec->meta was set up in `fd_executor_setup_accounts_for_txn()` and data was allocated from the spad
      56             :         - No need to allocate meta and data here
      57             :      2. Case 2: rec->meta==NULL
      58             :         - `fd_executor_setup_accounts_for_txn()` did not make an spad allocation for this account
      59             :         - spad memory is sized out for allocations for 128 (max number) accounts
      60             :         - sizeof(fd_account_meta_t) + serialized_sz will always be less than FD_ACC_TOT_SZ_MAX
      61             :         - at most 127 accounts could be using spad memory right now, so this allocation is safe */
      62           0 :   if( !rec->vt->is_mutable( rec ) ) {
      63           0 :     fd_txn_account_setup_meta_mutable( rec, txn_ctx->spad, serialized_sz );
      64           0 :   }
      65             : 
      66             :   /* Agave sets up the borrowed account for the instructions sysvar to contain
      67             :      default values except for the data which is serialized into the account. */
      68             : 
      69           0 :   rec->vt->set_owner( rec, &fd_sysvar_owner_id );
      70           0 :   rec->vt->set_lamports( rec, 0UL );
      71           0 :   rec->vt->set_executable( rec, 0 );
      72           0 :   rec->vt->set_rent_epoch( rec, 0UL );
      73           0 :   rec->vt->set_data_len( rec, serialized_sz );
      74           0 :   rec->starting_lamports = 0UL;
      75             : 
      76           0 :   uchar * serialized_instructions = rec->vt->get_data_mut( rec );
      77           0 :   ulong offset = 0;
      78             : 
      79             :   // TODO: do we needs bounds checking?
      80             :   // num_instructions
      81           0 :   FD_STORE( ushort, serialized_instructions + offset, instrs_cnt);
      82           0 :   offset += sizeof(ushort);
      83             : 
      84             :   // instruction offsets
      85           0 :   uchar * serialized_instruction_offsets = serialized_instructions + offset;
      86           0 :   offset += (ushort)(sizeof(ushort) * instrs_cnt);
      87             : 
      88             :   // serialize instructions
      89           0 :   for( ushort i = 0; i < instrs_cnt; ++i ) {
      90             :     // set the instruction offset
      91           0 :     FD_STORE( ushort, serialized_instruction_offsets, (ushort) offset );
      92           0 :     serialized_instruction_offsets += sizeof(ushort);
      93             : 
      94           0 :     fd_instr_info_t const * instr = &instrs[i];
      95             : 
      96             :     // num_accounts
      97           0 :     FD_STORE( ushort, serialized_instructions + offset, instr->acct_cnt );
      98           0 :     offset += sizeof(ushort);
      99             : 
     100           0 :     for ( ushort j = 0; j < instr->acct_cnt; j++ ) {
     101             :       // flags
     102           0 :       FD_STORE( uchar, serialized_instructions + offset, fd_instr_get_acc_flags( instr, j ) );
     103           0 :       offset += sizeof(uchar);
     104             : 
     105             :       // pubkey
     106           0 :       ushort idx_in_txn = instr->accounts[j].index_in_transaction;
     107           0 :       FD_STORE( fd_pubkey_t, serialized_instructions + offset, txn_ctx->account_keys[ idx_in_txn ] );
     108           0 :       offset += sizeof(fd_pubkey_t);
     109           0 :     }
     110             : 
     111             :     // program_id_pubkey
     112           0 :     FD_STORE( fd_pubkey_t, serialized_instructions + offset, txn_ctx->account_keys[ instr->program_id ] );
     113           0 :     offset += sizeof(fd_pubkey_t);
     114             : 
     115             :     // instr_data_len
     116           0 :     FD_STORE( ushort, serialized_instructions + offset, instr->data_sz );
     117           0 :     offset += sizeof(ushort);
     118             : 
     119             :     // instr_data
     120           0 :     fd_memcpy( serialized_instructions + offset, instr->data, instr->data_sz );
     121           0 :     offset += instr->data_sz;
     122           0 :   }
     123             : 
     124             :   //
     125           0 :   FD_STORE( ushort, serialized_instructions + offset, 0 );
     126           0 :   offset += sizeof(ushort);
     127           0 : }
     128             : 
     129             : /* Stores the current instruction index in the instructions sysvar account.
     130             :    https://github.com/anza-xyz/solana-sdk/blob/instructions-sysvar%40v2.2.1/instructions-sysvar/src/lib.rs#L164-L167 */
     131             : void
     132             : fd_sysvar_instructions_update_current_instr_idx( fd_txn_account_t * rec,
     133           0 :                                                  ushort             current_instr_idx ) {
     134             :   /* Extra safety checks */
     135           0 :   if( FD_UNLIKELY( rec->vt->get_data_len( rec )<sizeof(ushort) ) ) {
     136           0 :     return;
     137           0 :   }
     138             : 
     139           0 :   uchar * serialized_current_instr_idx = rec->vt->get_data_mut( rec ) + (rec->vt->get_data_len( rec ) - sizeof(ushort));
     140           0 :   FD_STORE( ushort, serialized_current_instr_idx, current_instr_idx );
     141           0 : }

Generated by: LCOV version 1.14