LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_borrowed_account.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 125 0.0 %
Date: 2025-12-13 04:39:40 Functions: 0 8 0.0 %

          Line data    Source code
       1             : #include "fd_borrowed_account.h"
       2             : #include "fd_runtime.h"
       3             : int
       4             : fd_borrowed_account_get_data_mut( fd_borrowed_account_t * borrowed_acct,
       5             :                                   uchar * *               data_out,
       6           0 :                                   ulong *                 dlen_out ) {
       7           0 :   fd_txn_account_t * acct = borrowed_acct->acct;
       8             : 
       9             :   /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L824 */
      10           0 :   int err;
      11           0 :   fd_borrowed_account_can_data_be_changed( borrowed_acct, &err );
      12           0 :   if( FD_UNLIKELY( err ) ) {
      13           0 :     return err;
      14           0 :   }
      15             : 
      16           0 :   if ( data_out != NULL )
      17           0 :     *data_out = fd_txn_account_get_data_mut( acct );
      18           0 :   if ( dlen_out != NULL )
      19           0 :     *dlen_out = fd_txn_account_get_data_len( acct );
      20             : 
      21           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
      22           0 : }
      23             : 
      24             : int
      25             : fd_borrowed_account_set_owner( fd_borrowed_account_t * borrowed_acct,
      26           0 :                                fd_pubkey_t const *     owner ) {
      27           0 :   fd_txn_account_t * acct = borrowed_acct->acct;
      28             : 
      29             :   /* Only the owner can assign a new owner
      30             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L741 */
      31           0 :   if( FD_UNLIKELY( !fd_borrowed_account_is_owned_by_current_program( borrowed_acct ) ) ) {
      32           0 :     return FD_EXECUTOR_INSTR_ERR_MODIFIED_PROGRAM_ID;
      33           0 :   }
      34             : 
      35             :   /* And only if the account is writable
      36             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L745 */
      37           0 :   if( FD_UNLIKELY( !fd_borrowed_account_is_writable( borrowed_acct ) ) ) {
      38           0 :     return FD_EXECUTOR_INSTR_ERR_MODIFIED_PROGRAM_ID;
      39           0 :   }
      40             : 
      41             :   /* And only if the data is zero-initialized or empty
      42             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L753 */
      43           0 :   if( FD_UNLIKELY( !fd_borrowed_account_is_zeroed( borrowed_acct ) ) ) {
      44           0 :     return FD_EXECUTOR_INSTR_ERR_MODIFIED_PROGRAM_ID;
      45           0 :   }
      46             : 
      47             :   /* Don't copy the account if the owner does not change
      48             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L757 */
      49           0 :   if( !memcmp( fd_txn_account_get_owner( acct ), owner, sizeof( fd_pubkey_t ) ) ) {
      50           0 :     return FD_EXECUTOR_INSTR_SUCCESS;
      51           0 :   }
      52             : 
      53             :   /* Agave self.touch() is a no-op */
      54             : 
      55             :   /* Copy into owner
      56             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L761 */
      57           0 :   fd_txn_account_set_owner( acct, owner );
      58           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
      59           0 : }
      60             : 
      61             : /* Overwrites the number of lamports of this account (transaction wide)
      62             :    https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L773 */
      63             : int
      64             : fd_borrowed_account_set_lamports( fd_borrowed_account_t * borrowed_acct,
      65           0 :                                   ulong                   lamports ) {
      66           0 :   fd_txn_account_t * acct = borrowed_acct->acct;
      67             : 
      68             :   /* An account not owned by the program cannot have its blanace decrease
      69             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L775 */
      70           0 :   if( FD_UNLIKELY( (!fd_borrowed_account_is_owned_by_current_program( borrowed_acct )) &&
      71           0 :                    (lamports<fd_txn_account_get_lamports( acct )) ) ) {
      72           0 :     return FD_EXECUTOR_INSTR_ERR_EXTERNAL_ACCOUNT_LAMPORT_SPEND;
      73           0 :   }
      74             : 
      75             :   /* The balance of read-only may not change
      76             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L779 */
      77           0 :   if( FD_UNLIKELY( !fd_borrowed_account_is_writable( borrowed_acct ) ) ) {
      78           0 :     return FD_EXECUTOR_INSTR_ERR_READONLY_LAMPORT_CHANGE;
      79           0 :   }
      80             : 
      81             :   /* Don't copy the account if the lamports do not change
      82             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L787 */
      83           0 :   if( fd_txn_account_get_lamports( acct )==lamports ) {
      84           0 :     return FD_EXECUTOR_INSTR_SUCCESS;
      85           0 :   }
      86             : 
      87             :   /* Agave self.touch() is a no-op */
      88             : 
      89           0 :   fd_txn_account_set_lamports( acct, lamports );
      90           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
      91           0 : }
      92             : 
      93             : int
      94             : fd_borrowed_account_set_data_from_slice( fd_borrowed_account_t * borrowed_acct,
      95             :                                          uchar const *           data,
      96           0 :                                          ulong                   data_sz ) {
      97           0 :   fd_txn_account_t * acct = borrowed_acct->acct;
      98             : 
      99             :   /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L865 */
     100           0 :   int err;
     101           0 :   if ( FD_UNLIKELY( !fd_borrowed_account_can_data_be_resized( borrowed_acct, data_sz, &err ) ) ) {
     102           0 :     return err;
     103           0 :   }
     104             : 
     105             :   /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L866 */
     106           0 :   if( FD_UNLIKELY( !fd_borrowed_account_can_data_be_changed( borrowed_acct, &err ) ) ) {
     107           0 :     return err;
     108           0 :   }
     109             : 
     110             :   /* Agave self.touch() is a no-op */
     111             : 
     112             :   /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L868 */
     113           0 :   if( FD_UNLIKELY( !fd_borrowed_account_update_accounts_resize_delta( borrowed_acct, data_sz, &err ) ) ) {
     114           0 :     return err;
     115           0 :   }
     116             : 
     117             :   /* AccountSharedData::set_data_from_slice() */
     118           0 :   fd_txn_account_set_data( acct, data, data_sz );
     119             : 
     120           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
     121           0 : }
     122             : 
     123             : int
     124             : fd_borrowed_account_set_data_length( fd_borrowed_account_t * borrowed_acct,
     125           0 :                                      ulong                   new_len ) {
     126           0 :   fd_txn_account_t * acct = borrowed_acct->acct;
     127           0 :   int                err  = FD_EXECUTOR_INSTR_SUCCESS;
     128             : 
     129             :   /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L883 */
     130           0 :   if( FD_UNLIKELY( !fd_borrowed_account_can_data_be_resized( borrowed_acct, new_len, &err ) ) ) {
     131           0 :     return err;
     132           0 :   }
     133             : 
     134             :   /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L884 */
     135           0 :   if( FD_UNLIKELY( !fd_borrowed_account_can_data_be_changed( borrowed_acct, &err ) ) ) {
     136           0 :     return err;
     137           0 :   }
     138             : 
     139           0 :   ulong old_len = fd_txn_account_get_data_len( acct );
     140             : 
     141             :   /* Don't copy the account if the length does not change
     142             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L886 */
     143           0 :   if( old_len==new_len ) {
     144           0 :     return FD_EXECUTOR_INSTR_SUCCESS;
     145           0 :   }
     146             : 
     147             :   /* Agave self.touch() is a no-op */
     148             : 
     149             :   /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L890 */
     150           0 :   if( FD_UNLIKELY( !fd_borrowed_account_update_accounts_resize_delta( borrowed_acct, new_len, &err ) ) ) {
     151           0 :     return err;
     152           0 :   }
     153             : 
     154             :   /* Resize the account
     155             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L891 */
     156           0 :   fd_txn_account_resize( acct, new_len );
     157           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
     158           0 : }
     159             : 
     160             : int
     161             : fd_borrowed_account_set_executable( fd_borrowed_account_t * borrowed_acct,
     162           0 :                                     int                     is_executable ) {
     163           0 :   fd_txn_account_t * acct = borrowed_acct->acct;
     164             : 
     165             :   /* To become executable an account must be rent exempt
     166             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1003-L1006 */
     167           0 :   fd_rent_t const * rent = fd_bank_rent_query( borrowed_acct->instr_ctx->bank );
     168           0 :   if( FD_UNLIKELY( fd_txn_account_get_lamports( acct )<fd_rent_exempt_minimum_balance( rent, fd_txn_account_get_data_len( acct ) ) ) ) {
     169           0 :     return FD_EXECUTOR_INSTR_ERR_EXECUTABLE_ACCOUNT_NOT_RENT_EXEMPT;
     170           0 :   }
     171             : 
     172             :   /* Only the owner can set the exectuable flag
     173             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1011 */
     174           0 :   if( FD_UNLIKELY( !fd_borrowed_account_is_owned_by_current_program( borrowed_acct ) ) ) {
     175           0 :     return FD_EXECUTOR_INSTR_ERR_EXECUTABLE_MODIFIED;
     176           0 :   }
     177             : 
     178             :   /* And only if the account is writable
     179             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1015 */
     180           0 :   if( FD_UNLIKELY( !fd_borrowed_account_is_writable( borrowed_acct ) ) ) {
     181           0 :     return FD_EXECUTOR_INSTR_ERR_EXECUTABLE_MODIFIED;
     182           0 :   }
     183             : 
     184             :   /* Don't copy the account if the exectuable flag does not change
     185             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1023 */
     186           0 :   if( fd_borrowed_account_is_executable( borrowed_acct ) == is_executable ) {
     187           0 :     return FD_EXECUTOR_INSTR_SUCCESS;
     188           0 :   }
     189             : 
     190             :   /* Agave self.touch() is a no-op */
     191             : 
     192             :   /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1027 */
     193           0 :   fd_txn_account_set_executable( acct, is_executable );
     194             : 
     195           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
     196           0 : }
     197             : 
     198             : int
     199             : fd_borrowed_account_update_accounts_resize_delta( fd_borrowed_account_t * borrowed_acct,
     200             :                                                   ulong                   new_len,
     201           0 :                                                   int *                   err ) {
     202           0 :   fd_exec_instr_ctx_t const * instr_ctx  = borrowed_acct->instr_ctx;
     203           0 :   fd_txn_account_t *          acct       = borrowed_acct->acct;
     204           0 :   ulong                       size_delta = fd_ulong_sat_sub( new_len, fd_txn_account_get_data_len( acct ) );
     205             : 
     206             :   /* TODO: The size delta should never exceed the value of ULONG_MAX so this
     207             :      could be replaced with a normal addition. However to match execution with
     208             :      the agave client, this is being left as a sat add */
     209           0 :   instr_ctx->txn_out->details.accounts_resize_delta = fd_ulong_sat_add( instr_ctx->txn_out->details.accounts_resize_delta, size_delta );
     210           0 :   *err = FD_EXECUTOR_INSTR_SUCCESS;
     211           0 :   return 1;
     212           0 : }
     213             : 
     214             : int
     215             : fd_borrowed_account_can_data_be_resized( fd_borrowed_account_t const * borrowed_acct,
     216             :                                          ulong                         new_length,
     217           0 :                                          int *                         err ) {
     218           0 :   fd_txn_account_t * acct = borrowed_acct->acct;
     219             : 
     220             :   /* Only the owner can change the length of the data
     221             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1095 */
     222           0 :   if( FD_UNLIKELY( (fd_txn_account_get_data_len( acct )!=new_length) &
     223           0 :                    (!fd_borrowed_account_is_owned_by_current_program( borrowed_acct )) ) ) {
     224           0 :     *err = FD_EXECUTOR_INSTR_ERR_ACC_DATA_SIZE_CHANGED;
     225           0 :     return 0;
     226           0 :   }
     227             : 
     228             :   /* The new length can not exceed the maximum permitted length
     229             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1099 */
     230           0 :   if( FD_UNLIKELY( new_length>MAX_PERMITTED_DATA_LENGTH ) ) {
     231           0 :     *err = FD_EXECUTOR_INSTR_ERR_INVALID_REALLOC;
     232           0 :     return 0;
     233           0 :   }
     234             : 
     235             :   /* The resize can not exceed the per-transaction maximum
     236             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1104-L1108 */
     237           0 :   ulong length_delta              = fd_ulong_sat_sub( new_length, fd_txn_account_get_data_len( acct ) );
     238           0 :   ulong new_accounts_resize_delta = fd_ulong_sat_add( borrowed_acct->instr_ctx->txn_out->details.accounts_resize_delta, length_delta );
     239           0 :   if( FD_UNLIKELY( new_accounts_resize_delta > MAX_PERMITTED_ACCOUNT_DATA_ALLOCS_PER_TXN ) ) {
     240           0 :     *err = FD_EXECUTOR_INSTR_ERR_MAX_ACCS_DATA_ALLOCS_EXCEEDED;
     241           0 :     return 0;
     242           0 :   }
     243             : 
     244           0 :   *err = FD_EXECUTOR_INSTR_SUCCESS;
     245           0 :   return 1;
     246           0 : }

Generated by: LCOV version 1.14