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 86 0.0 %
Date: 2025-12-04 04:56:06 Functions: 0 3 0.0 %

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

Generated by: LCOV version 1.14