LCOV - code coverage report
Current view: top level - flamenco/vm/syscall - fd_vm_syscall_runtime.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 384 0.0 %
Date: 2026-06-08 09:27:03 Functions: 0 11 0.0 %

          Line data    Source code
       1             : #include "fd_vm_syscall.h"
       2             : #include "../../runtime/program/fd_vote_program.h"
       3             : #include "../../runtime/context/fd_exec_instr_ctx.h"
       4             : #include "../../runtime/fd_system_ids.h"
       5             : #include "fd_vm_syscall_macros.h"
       6             : 
       7             : /* The VM structs for sysvars that are exposed by the VM are represented
       8             :    differently from the representations of the accounts in the accounts
       9             :    database. These structs usually have padding which must be zeroed
      10             :    out. */
      11             : struct fd_vm_epoch_schedule {
      12             :   ulong slots_per_epoch;
      13             :   ulong leader_schedule_slot_offset;
      14             :   uchar warmup; /* 0 or 1 */
      15             :   uchar padding_[7];
      16             :   ulong first_normal_epoch;
      17             :   ulong first_normal_slot;
      18             : };
      19             : typedef struct fd_vm_epoch_schedule fd_vm_epoch_schedule_t;
      20             : FD_STATIC_ASSERT( sizeof(fd_vm_epoch_schedule_t) == 40UL, "vm epoch schedule size mismatch" );
      21             : FD_STATIC_ASSERT( alignof(fd_vm_epoch_schedule_t) == FD_VM_ALIGN_RUST_SYSVAR_EPOCH_SCHEDULE, "vm epoch schedule alignment mismatch" );
      22             : FD_STATIC_ASSERT( offsetof(fd_vm_epoch_schedule_t, slots_per_epoch            ) == 0UL,      "vm epoch schedule layout mismatch"    );
      23             : FD_STATIC_ASSERT( offsetof(fd_vm_epoch_schedule_t, leader_schedule_slot_offset) == 8UL,      "vm epoch schedule layout mismatch"    );
      24             : FD_STATIC_ASSERT( offsetof(fd_vm_epoch_schedule_t, warmup                     ) == 16UL,     "vm epoch schedule layout mismatch"    );
      25             : FD_STATIC_ASSERT( offsetof(fd_vm_epoch_schedule_t, first_normal_epoch         ) == 24UL,     "vm epoch schedule layout mismatch"    );
      26             : FD_STATIC_ASSERT( offsetof(fd_vm_epoch_schedule_t, first_normal_slot          ) == 32UL,     "vm epoch schedule layout mismatch"    );
      27             : 
      28             : struct fd_vm_rent {
      29             :   ulong  lamports_per_uint8_year;
      30             :   double exemption_threshold;
      31             :   uchar  burn_percent;
      32             :   uchar  padding_[7];
      33             : };
      34             : typedef struct fd_vm_rent fd_vm_rent_t;
      35             : FD_STATIC_ASSERT( sizeof(fd_vm_rent_t) == 24UL, "vm rent size mismatch" );
      36             : FD_STATIC_ASSERT( alignof(fd_vm_rent_t) == FD_VM_ALIGN_RUST_SYSVAR_RENT,   "vm rent alignment mismatch" );
      37             : FD_STATIC_ASSERT( offsetof(fd_vm_rent_t, lamports_per_uint8_year) == 0UL,  "vm rent layout mismatch"    );
      38             : FD_STATIC_ASSERT( offsetof(fd_vm_rent_t, exemption_threshold    ) == 8UL,  "vm rent layout mismatch"    );
      39             : FD_STATIC_ASSERT( offsetof(fd_vm_rent_t, burn_percent           ) == 16UL, "vm rent layout mismatch"    );
      40             : 
      41             : typedef fd_sol_sysvar_clock_t fd_vm_clock_t;
      42             : FD_STATIC_ASSERT( sizeof(fd_vm_clock_t) == 40UL, "vm clock size mismatch" );
      43             : FD_STATIC_ASSERT( alignof(fd_vm_clock_t) == FD_VM_ALIGN_RUST_SYSVAR_CLOCK, "vm clock alignment mismatch" );
      44             : FD_STATIC_ASSERT( offsetof(fd_vm_clock_t, slot                 ) == 0UL,   "vm clock layout mismatch"    );
      45             : FD_STATIC_ASSERT( offsetof(fd_vm_clock_t, epoch_start_timestamp) == 8UL,   "vm clock layout mismatch"    );
      46             : FD_STATIC_ASSERT( offsetof(fd_vm_clock_t, epoch                ) == 16UL,  "vm clock layout mismatch"    );
      47             : FD_STATIC_ASSERT( offsetof(fd_vm_clock_t, leader_schedule_epoch) == 24UL,  "vm clock layout mismatch"    );
      48             : FD_STATIC_ASSERT( offsetof(fd_vm_clock_t, unix_timestamp       ) == 32UL,  "vm clock layout mismatch"    );
      49             : 
      50             : struct __attribute__((aligned(16))) fd_vm_epoch_rewards {
      51             :   ulong       distribution_starting_block_height;
      52             :   ulong       num_partitions;
      53             :   fd_hash_t   parent_blockhash;
      54             :   fd_w_u128_t total_points;
      55             :   ulong       total_rewards;
      56             :   ulong       distributed_rewards;
      57             :   uchar       active; /* 0 or 1 */
      58             :   uchar       padding_[15];
      59             : };
      60             : typedef struct fd_vm_epoch_rewards fd_vm_epoch_rewards_t;
      61             : FD_STATIC_ASSERT( sizeof(fd_vm_epoch_rewards_t) == 96UL, "vm epoch rewards size mismatch" );
      62             : FD_STATIC_ASSERT( alignof(fd_vm_epoch_rewards_t) == FD_VM_ALIGN_RUST_SYSVAR_EPOCH_REWARDS,     "vm epoch rewards alignment mismatch" );
      63             : FD_STATIC_ASSERT( offsetof(fd_vm_epoch_rewards_t, distribution_starting_block_height) == 0UL,  "vm epoch rewards layout mismatch"    );
      64             : FD_STATIC_ASSERT( offsetof(fd_vm_epoch_rewards_t, num_partitions                    ) == 8UL,  "vm epoch rewards layout mismatch"    );
      65             : FD_STATIC_ASSERT( offsetof(fd_vm_epoch_rewards_t, parent_blockhash                  ) == 16UL, "vm epoch rewards layout mismatch"    );
      66             : FD_STATIC_ASSERT( offsetof(fd_vm_epoch_rewards_t, total_points                      ) == 48UL, "vm epoch rewards layout mismatch"    );
      67             : FD_STATIC_ASSERT( offsetof(fd_vm_epoch_rewards_t, total_rewards                     ) == 64UL, "vm epoch rewards layout mismatch"    );
      68             : FD_STATIC_ASSERT( offsetof(fd_vm_epoch_rewards_t, distributed_rewards               ) == 72UL, "vm epoch rewards layout mismatch"    );
      69             : FD_STATIC_ASSERT( offsetof(fd_vm_epoch_rewards_t, active                            ) == 80UL, "vm epoch rewards layout mismatch"    );
      70             : 
      71             : /* FIXME: In the original version of this code, there was an FD_TEST
      72             :    to check if the VM was attached to an instruction context (that
      73             :    would have crashed anyway because of pointer chasing).  If the VM
      74             :    is being run outside the Solana runtime, it should never invoke
      75             :    this syscall in the first place.  So we treat this as a SIGCALL in
      76             :    a non-crashing way for the time being. */
      77             : 
      78             : int
      79             : fd_vm_syscall_sol_get_clock_sysvar( /**/            void *  _vm,
      80             :                                     /**/            ulong   out_vaddr,
      81             :                                     FD_PARAM_UNUSED ulong   r2,
      82             :                                     FD_PARAM_UNUSED ulong   r3,
      83             :                                     FD_PARAM_UNUSED ulong   r4,
      84             :                                     FD_PARAM_UNUSED ulong   r5,
      85           0 :                                     /**/            ulong * _ret ) {
      86           0 :   fd_vm_t * vm = _vm;
      87           0 :   fd_exec_instr_ctx_t const * instr_ctx = vm->instr_ctx;
      88           0 :   if( FD_UNLIKELY( !instr_ctx ) ) return FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME;
      89             : 
      90           0 :   FD_VM_CU_UPDATE( vm, fd_ulong_sat_add( FD_VM_SYSVAR_BASE_COST, sizeof(fd_vm_clock_t) ) );
      91             : 
      92             :   /* See https://github.com/anza-xyz/agave/pull/12130 */
      93           0 :   if( FD_UNLIKELY( vm->is_deprecated ) ) {
      94           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_UNALIGNED_POINTER );
      95           0 :     return FD_VM_SYSCALL_ERR_UNALIGNED_POINTER;
      96           0 :   }
      97             : 
      98           0 :   if( FD_UNLIKELY( vm->syscall_parameter_address_restrictions && out_vaddr>=FD_VM_MEM_MAP_INPUT_REGION_START ) ) {
      99           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_POINTER );
     100           0 :     return FD_VM_ERR_INVAL;
     101           0 :   }
     102             : 
     103           0 :   fd_vm_haddr_query_t var_query = {
     104           0 :     .vaddr    = out_vaddr,
     105           0 :     .align    = FD_VM_ALIGN_RUST_SYSVAR_CLOCK,
     106           0 :     .sz       = sizeof(fd_vm_clock_t),
     107           0 :     .is_slice = 0,
     108           0 :   };
     109             : 
     110           0 :   fd_vm_haddr_query_t * queries[] = { &var_query };
     111           0 :   FD_VM_TRANSLATE_MUT( vm, queries );
     112             : 
     113           0 :   fd_vm_clock_t clock = fd_sysvar_cache_clock_read_nofail( instr_ctx->sysvar_cache );
     114           0 :   memcpy( var_query.haddr, &clock, sizeof(fd_vm_clock_t) );
     115             : 
     116           0 :   *_ret = 0UL;
     117           0 :   return FD_VM_SUCCESS;
     118           0 : }
     119             : 
     120             : int
     121             : fd_vm_syscall_sol_get_epoch_schedule_sysvar( /**/            void *  _vm,
     122             :                                              /**/            ulong   out_vaddr,
     123             :                                              FD_PARAM_UNUSED ulong   r2,
     124             :                                              FD_PARAM_UNUSED ulong   r3,
     125             :                                              FD_PARAM_UNUSED ulong   r4,
     126             :                                              FD_PARAM_UNUSED ulong   r5,
     127           0 :                                              /**/            ulong * _ret ) {
     128           0 :   fd_vm_t * vm = _vm;
     129           0 :   fd_exec_instr_ctx_t const * instr_ctx = vm->instr_ctx;
     130           0 :   if( FD_UNLIKELY( !instr_ctx ) ) return FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME;
     131             : 
     132           0 :   FD_VM_CU_UPDATE( vm, fd_ulong_sat_add( FD_VM_SYSVAR_BASE_COST, sizeof(fd_vm_epoch_schedule_t) ) );
     133             : 
     134             :   /* See https://github.com/anza-xyz/agave/pull/12130 */
     135           0 :   if( FD_UNLIKELY( vm->is_deprecated ) ) {
     136           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_UNALIGNED_POINTER );
     137           0 :     return FD_VM_SYSCALL_ERR_UNALIGNED_POINTER;
     138           0 :   }
     139             : 
     140           0 :   if( FD_UNLIKELY( vm->syscall_parameter_address_restrictions && out_vaddr>=FD_VM_MEM_MAP_INPUT_REGION_START ) ) {
     141           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_POINTER );
     142           0 :     return FD_VM_ERR_INVAL;
     143           0 :   }
     144             : 
     145           0 :   fd_vm_haddr_query_t var_query = {
     146           0 :     .vaddr    = out_vaddr,
     147           0 :     .align    = FD_VM_ALIGN_RUST_SYSVAR_EPOCH_SCHEDULE,
     148           0 :     .sz       = sizeof(fd_vm_epoch_schedule_t),
     149           0 :     .is_slice = 0,
     150           0 :   };
     151             : 
     152           0 :   fd_vm_haddr_query_t * queries[] = { &var_query };
     153           0 :   FD_VM_TRANSLATE_MUT( vm, queries );
     154             : 
     155           0 :   fd_epoch_schedule_t schedule;
     156           0 :   if( FD_UNLIKELY( !fd_sysvar_cache_epoch_schedule_read( instr_ctx->sysvar_cache, &schedule ) ) ) {
     157           0 :     FD_TXN_ERR_FOR_LOG_INSTR( vm->instr_ctx->txn_out, FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR, vm->instr_ctx->txn_out->err.exec_err_idx );
     158           0 :     return FD_VM_ERR_INVAL;
     159           0 :   }
     160             : 
     161             :   /* Returned value has padding which must be zeroed out. */
     162           0 :   uchar * dst = var_query.haddr;
     163           0 :   fd_vm_epoch_schedule_t * vm_schedule = (fd_vm_epoch_schedule_t *)dst;
     164           0 :   *vm_schedule = (fd_vm_epoch_schedule_t){
     165           0 :     .slots_per_epoch             = schedule.slots_per_epoch,
     166           0 :     .leader_schedule_slot_offset = schedule.leader_schedule_slot_offset,
     167           0 :     .warmup                      = schedule.warmup,
     168           0 :     .first_normal_epoch          = schedule.first_normal_epoch,
     169           0 :     .first_normal_slot           = schedule.first_normal_slot,
     170           0 :   };
     171             : 
     172           0 :   *_ret = 0UL;
     173           0 :   return FD_VM_SUCCESS;
     174           0 : }
     175             : 
     176             : int
     177             : fd_vm_syscall_sol_get_rent_sysvar( /**/            void *  _vm,
     178             :                                    /**/            ulong   out_vaddr,
     179             :                                    FD_PARAM_UNUSED ulong   r2,
     180             :                                    FD_PARAM_UNUSED ulong   r3,
     181             :                                    FD_PARAM_UNUSED ulong   r4,
     182             :                                    FD_PARAM_UNUSED ulong   r5,
     183           0 :                                    /**/            ulong * _ret ) {
     184           0 :   fd_vm_t * vm = _vm;
     185             : 
     186             :   /* Unreachable in a real SVM, used for testing */
     187             : 
     188           0 :   fd_exec_instr_ctx_t const * instr_ctx = vm->instr_ctx;
     189           0 :   if( FD_UNLIKELY( !instr_ctx ) ) return FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME;
     190             : 
     191           0 :   FD_VM_CU_UPDATE( vm, fd_ulong_sat_add( FD_VM_SYSVAR_BASE_COST, sizeof(fd_vm_rent_t) ) );
     192             : 
     193             :   /* See https://github.com/anza-xyz/agave/pull/12130 */
     194           0 :   if( FD_UNLIKELY( vm->is_deprecated ) ) {
     195           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_UNALIGNED_POINTER );
     196           0 :     return FD_VM_SYSCALL_ERR_UNALIGNED_POINTER;
     197           0 :   }
     198             : 
     199           0 :   if( FD_UNLIKELY( vm->syscall_parameter_address_restrictions && out_vaddr>=FD_VM_MEM_MAP_INPUT_REGION_START ) ) {
     200           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_POINTER );
     201           0 :     return FD_VM_ERR_INVAL;
     202           0 :   }
     203             : 
     204           0 :   fd_vm_haddr_query_t var_query = {
     205           0 :     .vaddr    = out_vaddr,
     206           0 :     .align    = FD_VM_ALIGN_RUST_SYSVAR_RENT,
     207           0 :     .sz       = sizeof(fd_vm_rent_t),
     208           0 :     .is_slice = 0,
     209           0 :   };
     210             : 
     211           0 :   fd_vm_haddr_query_t * queries[] = { &var_query };
     212           0 :   FD_VM_TRANSLATE_MUT( vm, queries );
     213             : 
     214           0 :   fd_rent_t rent = fd_sysvar_cache_rent_read_nofail( instr_ctx->sysvar_cache );
     215             : 
     216             :   /* The returned value has padding which must be zeroed out. */
     217           0 :   uchar * dst = var_query.haddr;
     218           0 :   fd_vm_rent_t * vm_rent = (fd_vm_rent_t *)dst;
     219           0 :   *vm_rent = (fd_vm_rent_t){
     220           0 :     .lamports_per_uint8_year = rent.lamports_per_uint8_year,
     221           0 :     .exemption_threshold     = rent.exemption_threshold,
     222           0 :     .burn_percent            = rent.burn_percent,
     223           0 :   };
     224             : 
     225           0 :   *_ret = 0UL;
     226           0 :   return FD_VM_SUCCESS;
     227           0 : }
     228             : 
     229             : /* https://github.com/anza-xyz/agave/blob/v2.3.2/programs/bpf_loader/src/syscalls/sysvar.rs#L149 */
     230             : int
     231             : fd_vm_syscall_sol_get_last_restart_slot_sysvar( /**/            void *  _vm,
     232             :                                                 /**/            ulong   out_vaddr,
     233             :                                                 FD_PARAM_UNUSED ulong   r2,
     234             :                                                 FD_PARAM_UNUSED ulong   r3,
     235             :                                                 FD_PARAM_UNUSED ulong   r4,
     236             :                                                 FD_PARAM_UNUSED ulong   r5,
     237           0 :                                                 /**/            ulong * _ret ) {
     238           0 :   fd_vm_t * vm = _vm;
     239           0 :   fd_exec_instr_ctx_t const * instr_ctx = vm->instr_ctx;
     240           0 :   if( FD_UNLIKELY( !instr_ctx ) ) return FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME;
     241             : 
     242           0 :   FD_VM_CU_UPDATE( vm, fd_ulong_sat_add( FD_VM_SYSVAR_BASE_COST, 8UL ) );
     243             : 
     244             :   /* See https://github.com/anza-xyz/agave/pull/12130 */
     245           0 :   if( FD_UNLIKELY( vm->is_deprecated ) ) {
     246           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_UNALIGNED_POINTER );
     247           0 :     return FD_VM_SYSCALL_ERR_UNALIGNED_POINTER;
     248           0 :   }
     249             : 
     250           0 :   if( FD_UNLIKELY( vm->syscall_parameter_address_restrictions && out_vaddr>=FD_VM_MEM_MAP_INPUT_REGION_START ) ) {
     251           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_POINTER );
     252           0 :     return FD_VM_ERR_INVAL;
     253           0 :   }
     254             : 
     255           0 :   fd_vm_haddr_query_t var_query = {
     256           0 :     .vaddr    = out_vaddr,
     257           0 :     .align    = FD_VM_ALIGN_RUST_SYSVAR_LAST_RESTART_SLOT,
     258           0 :     .sz       = sizeof(ulong),
     259           0 :     .is_slice = 0,
     260           0 :   };
     261             : 
     262           0 :   fd_vm_haddr_query_t * queries[] = { &var_query };
     263           0 :   FD_VM_TRANSLATE_MUT( vm, queries );
     264             : 
     265           0 :   ulong const * last_restart_slot = fd_sysvar_cache_last_restart_slot_read( vm->instr_ctx->sysvar_cache );
     266           0 :   if( FD_UNLIKELY( last_restart_slot==NULL ) ) {
     267           0 :     FD_TXN_ERR_FOR_LOG_INSTR( vm->instr_ctx->txn_out, FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR, vm->instr_ctx->txn_out->err.exec_err_idx );
     268           0 :     return FD_VM_ERR_INVAL;
     269           0 :   }
     270             : 
     271           0 :   memcpy( var_query.haddr, last_restart_slot, sizeof(ulong) );
     272             : 
     273           0 :   *_ret = 0UL;
     274           0 :   return FD_VM_SUCCESS;
     275           0 : }
     276             : 
     277             : /* https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/sysvar.rs#L167-L232 */
     278             : int
     279             : fd_vm_syscall_sol_get_sysvar( /**/            void *  _vm,
     280             :                               /**/            ulong   sysvar_id_vaddr,
     281             :                               /**/            ulong   out_vaddr,
     282             :                               /**/            ulong   offset,
     283             :                               /**/            ulong   sz,
     284             :                               FD_PARAM_UNUSED ulong   r5,
     285           0 :                               /**/            ulong * _ret ) {
     286           0 :   fd_vm_t * vm = _vm;
     287           0 :   fd_exec_instr_ctx_t const * instr_ctx = vm->instr_ctx;
     288           0 :   if( FD_UNLIKELY( !instr_ctx ) ) return FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME;
     289             : 
     290             :   /* sysvar_id_cost seems to just always be 32 / 250 = 0...
     291             :      https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/sysvar.rs#L190-L197 */
     292           0 :   ulong sysvar_buf_cost = sz / FD_VM_CPI_BYTES_PER_UNIT;
     293           0 :   FD_VM_CU_UPDATE( vm, fd_ulong_sat_add( FD_VM_SYSVAR_BASE_COST, fd_ulong_max( sysvar_buf_cost, FD_VM_MEM_OP_BASE_COST ) ) );
     294             : 
     295             :   /* See https://github.com/anza-xyz/agave/pull/12130 */
     296           0 :   if( FD_UNLIKELY( vm->is_deprecated ) ) {
     297           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_UNALIGNED_POINTER );
     298           0 :     return FD_VM_SYSCALL_ERR_UNALIGNED_POINTER;
     299           0 :   }
     300             : 
     301           0 :   if( FD_UNLIKELY( vm->syscall_parameter_address_restrictions && out_vaddr>=FD_VM_MEM_MAP_INPUT_REGION_START ) ) {
     302           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_POINTER );
     303           0 :     return FD_VM_ERR_INVAL;
     304           0 :   }
     305             : 
     306             :   /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/sysvar.rs#L207-L211 */
     307           0 :   fd_vm_haddr_query_t var_query = {
     308           0 :     .vaddr    = out_vaddr,
     309           0 :     .align    = FD_VM_ALIGN_RUST_U8,
     310           0 :     .sz       = sz,
     311           0 :     .is_slice = 1,
     312           0 :   };
     313             : 
     314           0 :   fd_vm_haddr_query_t * queries[] = { &var_query };
     315           0 :   FD_VM_TRANSLATE_MUT( vm, queries );
     316             : 
     317             :   /* https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/sysvar.rs#L199-L200 */
     318           0 :   const fd_pubkey_t * sysvar_id = FD_VM_MEM_HADDR_LD( vm, sysvar_id_vaddr, FD_VM_ALIGN_RUST_PUBKEY, FD_PUBKEY_FOOTPRINT );
     319             : 
     320             :   /* https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/sysvar.rs#L205-L208 */
     321           0 :   ulong offset_length;
     322           0 :   int err = fd_int_if( __builtin_uaddl_overflow( offset, sz, &offset_length ), FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW, FD_EXECUTOR_INSTR_SUCCESS );
     323           0 :   if( FD_UNLIKELY( err ) ) {
     324           0 :     FD_VM_ERR_FOR_LOG_INSTR( vm, err );
     325           0 :     return FD_VM_SYSCALL_ERR_ABORT;
     326           0 :   }
     327             : 
     328             :   /* https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/sysvar.rs#L210-L213
     329             :      We don't need this, we already checked we can store in out_vaddr with requested sz. */
     330             : 
     331             :   /* https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/sysvar.rs#L215-L221 */
     332           0 :   if( FD_UNLIKELY( memcmp( sysvar_id->uc, fd_sysvar_clock_id.uc,             FD_PUBKEY_FOOTPRINT ) &&
     333           0 :                    memcmp( sysvar_id->uc, fd_sysvar_epoch_schedule_id.uc,    FD_PUBKEY_FOOTPRINT ) &&
     334           0 :                    memcmp( sysvar_id->uc, fd_sysvar_epoch_rewards_id.uc,     FD_PUBKEY_FOOTPRINT ) &&
     335           0 :                    memcmp( sysvar_id->uc, fd_sysvar_rent_id.uc,              FD_PUBKEY_FOOTPRINT ) &&
     336           0 :                    memcmp( sysvar_id->uc, fd_sysvar_slot_hashes_id.uc,       FD_PUBKEY_FOOTPRINT ) &&
     337           0 :                    memcmp( sysvar_id->uc, fd_sysvar_stake_history_id.uc,     FD_PUBKEY_FOOTPRINT ) &&
     338           0 :                    memcmp( sysvar_id->uc, fd_sysvar_last_restart_slot_id.uc, FD_PUBKEY_FOOTPRINT ) ) ) {
     339           0 :     *_ret = 2UL;
     340           0 :     return FD_VM_SUCCESS;
     341           0 :   }
     342             : 
     343           0 :   ulong         sysvar_buf_len;
     344           0 :   uchar const * sysvar_buf =
     345           0 :     fd_sysvar_cache_data_query( vm->instr_ctx->sysvar_cache, sysvar_id, &sysvar_buf_len );
     346           0 :   if( FD_UNLIKELY( !sysvar_buf ) ) {
     347           0 :     *_ret = 2UL;
     348           0 :     return FD_VM_SUCCESS;
     349           0 :   }
     350             : 
     351             :   /* https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/sysvar.rs#L223-L228
     352             :      Note the length check is at the very end to fail after performing sufficient checks. */
     353             : 
     354           0 :   if( FD_UNLIKELY( offset_length>sysvar_buf_len ) ) {
     355           0 :     *_ret = 1UL;
     356           0 :     return FD_VM_SUCCESS;
     357           0 :   }
     358             : 
     359           0 :   if( FD_UNLIKELY( sz==0UL ) ) {
     360           0 :     *_ret = 0UL;
     361           0 :     return FD_VM_SUCCESS;
     362           0 :   }
     363             : 
     364           0 :   fd_memcpy( var_query.haddr, sysvar_buf + offset, sz );
     365           0 :   *_ret = 0;
     366           0 :   return FD_VM_SUCCESS;
     367           0 : }
     368             : 
     369             : /* https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/mod.rs#L2043-L2118 */
     370             : int
     371             : fd_vm_syscall_sol_get_epoch_stake( /**/            void *  _vm,
     372             :                                    /**/            ulong   var_addr,
     373             :                                    FD_PARAM_UNUSED ulong   r2,
     374             :                                    FD_PARAM_UNUSED ulong   r3,
     375             :                                    FD_PARAM_UNUSED ulong   r4,
     376             :                                    FD_PARAM_UNUSED ulong   r5,
     377           0 :                                    /**/            ulong * _ret ) {
     378           0 :   fd_vm_t * vm = (fd_vm_t *)_vm;
     379             : 
     380             :   /* Var addr of 0 returns the total active stake on the cluster.
     381             : 
     382             :      https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/mod.rs#L2057-L2075 */
     383           0 :   if( FD_UNLIKELY( var_addr==0UL ) ) {
     384             :     /* https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/mod.rs#L2065-L2066 */
     385           0 :     FD_VM_CU_UPDATE( vm, FD_VM_SYSCALL_BASE_COST );
     386             : 
     387             :     /* https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/mod.rs#L2074 */
     388           0 :     *_ret = vm->instr_ctx->bank->f.total_epoch_stake;
     389           0 :     return FD_VM_SUCCESS;
     390           0 :   }
     391             : 
     392             :   /* https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/mod.rs#L2083-L2091
     393             :      FD_PUBKEY_FOOTPRINT/FD_VM_CPI_BYTES_PER_UNIT is always 32/250 = 0,
     394             :      so we can omit it */
     395             : 
     396           0 :   FD_VM_CU_UPDATE( vm, FD_VM_MEM_OP_BASE_COST + FD_VM_SYSCALL_BASE_COST );
     397             : 
     398             :   /* https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/mod.rs#L2103-L2104 */
     399           0 :   fd_pubkey_t const * vote_address = FD_VM_MEM_HADDR_LD( vm, var_addr, FD_VM_ALIGN_RUST_PUBKEY, FD_PUBKEY_FOOTPRINT );
     400             : 
     401             :   /* https://github.com/anza-xyz/agave/blob/v2.2.14/runtime/src/bank.rs#L6954 */
     402             : 
     403           0 :   ulong stake = 0UL;
     404           0 :   if( FD_FEATURE_ACTIVE_BANK( vm->instr_ctx->bank, validator_admission_ticket ) ) {
     405             :     /* It's okay to ignore if an account is invalid since these stakes
     406             :        are calculated from an older snapshot of vote account stakes. */
     407           0 :     fd_top_votes_t const * top_votes = fd_bank_top_votes_t_1_query( vm->instr_ctx->bank );
     408           0 :     fd_top_votes_query( top_votes, vote_address, NULL, &stake, NULL, NULL, NULL, NULL );
     409           0 :   } else {
     410           0 :     fd_vote_stakes_t * vote_stakes = fd_bank_vote_stakes( vm->instr_ctx->bank );
     411           0 :     fd_vote_stakes_query_t_1( vote_stakes, vm->instr_ctx->bank->vote_stakes_fork_id, vote_address, &stake, NULL, NULL );
     412           0 :   }
     413             : 
     414           0 :   *_ret = stake;
     415             : 
     416           0 :   return FD_VM_SUCCESS;
     417           0 : }
     418             : 
     419             : int
     420             : fd_vm_syscall_sol_get_stack_height( /**/            void *  _vm,
     421             :                                     FD_PARAM_UNUSED ulong   r1,
     422             :                                     FD_PARAM_UNUSED ulong   r2,
     423             :                                     FD_PARAM_UNUSED ulong   r3,
     424             :                                     FD_PARAM_UNUSED ulong   r4,
     425             :                                     FD_PARAM_UNUSED ulong   r5,
     426           0 :                                     /**/            ulong * _ret ) {
     427             :   /* https://github.com/anza-xyz/agave/blob/v2.0.8/programs/bpf_loader/src/syscalls/mod.rs#L1547 */
     428           0 :   fd_vm_t * vm = (fd_vm_t *)_vm;
     429             : 
     430           0 :   FD_VM_CU_UPDATE( vm, FD_VM_SYSCALL_BASE_COST );
     431             : 
     432           0 :   *_ret = vm->instr_ctx->runtime->instr.stack_sz;
     433           0 :   return FD_VM_SUCCESS;
     434           0 : }
     435             : 
     436             : int
     437             : fd_vm_syscall_sol_get_return_data( /**/            void *  _vm,
     438             :                                    /**/            ulong   return_data_vaddr,
     439             :                                    /**/            ulong   sz,
     440             :                                    /**/            ulong   program_id_vaddr,
     441             :                                    FD_PARAM_UNUSED ulong   r4,
     442             :                                    FD_PARAM_UNUSED ulong   r5,
     443           0 :                                    /**/            ulong * _ret ) {
     444           0 :   fd_vm_t * vm = (fd_vm_t *)_vm;
     445             : 
     446             :   /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1465 */
     447           0 :   FD_VM_CU_UPDATE( vm, FD_VM_SYSCALL_BASE_COST );
     448             : 
     449             :   /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1467 */
     450           0 :   fd_txn_return_data_t const * return_data = &vm->instr_ctx->txn_out->details.return_data;
     451             : 
     452             :   /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1468 */
     453           0 :   ulong length = fd_ulong_min( return_data->len, sz );
     454             : 
     455             :   /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1469-L1492 */
     456           0 :   if( FD_LIKELY( length ) ) {
     457             : 
     458             :     /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1470-L1474 */
     459           0 :     FD_VM_CU_UPDATE( vm, fd_ulong_sat_add( length, sizeof(fd_pubkey_t) ) / FD_VM_CPI_BYTES_PER_UNIT );
     460             : 
     461             :     /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1476-L1481 */
     462           0 :     fd_vm_haddr_query_t return_data_query = {
     463           0 :       .vaddr    = return_data_vaddr,
     464           0 :       .align    = FD_VM_ALIGN_RUST_U8,
     465           0 :       .sz       = length,
     466           0 :       .is_slice = 1
     467           0 :     };
     468             : 
     469           0 :     fd_vm_haddr_query_t program_id_query = {
     470           0 :       .vaddr    = program_id_vaddr,
     471           0 :       .align    = FD_VM_ALIGN_RUST_PUBKEY,
     472           0 :       .sz       = sizeof(fd_pubkey_t),
     473           0 :       .is_slice = 0
     474           0 :     };
     475             : 
     476           0 :     fd_vm_haddr_query_t * queries[] = { &return_data_query, &program_id_query };
     477           0 :     FD_VM_TRANSLATE_MUT( vm, queries );
     478             : 
     479             :     /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1490-L1491 */
     480           0 :     memcpy( return_data_query.haddr, return_data->data, length );
     481           0 :     memcpy( program_id_query.haddr, &return_data->program_id, sizeof(fd_pubkey_t) );
     482           0 :   }
     483             : 
     484             :   /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1495 */
     485           0 :   *_ret = return_data->len;
     486           0 :   return FD_VM_SUCCESS;
     487           0 : }
     488             : 
     489             : int
     490             : fd_vm_syscall_sol_set_return_data( /**/            void *  _vm,
     491             :                                    /**/            ulong   src_vaddr,
     492             :                                    /**/            ulong   src_sz,
     493             :                                    FD_PARAM_UNUSED ulong   r3,
     494             :                                    FD_PARAM_UNUSED ulong   r4,
     495             :                                    FD_PARAM_UNUSED ulong   r5,
     496           0 :                                    /**/            ulong * _ret ) {
     497             :   /* https://github.com/anza-xyz/agave/blob/v2.0.8/programs/bpf_loader/src/syscalls/mod.rs#L1297 */
     498           0 :   fd_vm_t * vm = (fd_vm_t *)_vm;
     499             : 
     500             :   /* In the original version of this code, there was an FD_TEST
     501             :      to check if the VM was attached to an instruction context (that
     502             :      would have crashed anyway because of pointer chasing).  If the VM
     503             :      is being run outside the Solana runtime, it should never invoke
     504             :      this syscall in the first place.  So we treat this as a SIGCALL in
     505             :      a non-crashing way for the time being. */
     506           0 :   fd_exec_instr_ctx_t const * instr_ctx = vm->instr_ctx;
     507           0 :   if( FD_UNLIKELY( !instr_ctx ) ) return FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME;
     508             : 
     509           0 :   FD_VM_CU_UPDATE( vm, fd_ulong_sat_add( FD_VM_SYSCALL_BASE_COST, src_sz / FD_VM_CPI_BYTES_PER_UNIT ) );
     510             : 
     511             :   /* https://github.com/anza-xyz/agave/blob/v2.0.8/programs/bpf_loader/src/syscalls/mod.rs#L1316 */
     512           0 :   if( FD_UNLIKELY( src_sz>FD_VM_RETURN_DATA_MAX ) ) {
     513             :     /* TODO: this is a bit annoying, we may want to unify return codes...
     514             :        - FD_VM_SYSCALL_ERR_RETURN_DATA_TOO_LARGE is Agave's return code,
     515             :          also used for logging */
     516           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_RETURN_DATA_TOO_LARGE );
     517           0 :     return FD_VM_SYSCALL_ERR_RETURN_DATA_TOO_LARGE;
     518           0 :   }
     519             : 
     520             :   /* src_sz == 0 is ok */
     521           0 :   void const * src = FD_VM_MEM_SLICE_HADDR_LD( vm, src_vaddr, FD_VM_ALIGN_RUST_U8, src_sz );
     522             : 
     523             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/programs/bpf_loader/src/syscalls/mod.rs#L1480-L1484 */
     524           0 :   fd_pubkey_t const * program_id = NULL;
     525           0 :   int err = fd_exec_instr_ctx_get_last_program_key( vm->instr_ctx, &program_id );
     526           0 :   if( FD_UNLIKELY( err ) ) {
     527           0 :     FD_VM_ERR_FOR_LOG_INSTR( vm, err );
     528           0 :     return err;
     529           0 :   }
     530             : 
     531           0 :   fd_txn_return_data_t * return_data = &instr_ctx->txn_out->details.return_data;
     532             : 
     533           0 :   return_data->len = src_sz;
     534           0 :   if( FD_LIKELY( src_sz!=0UL ) ) {
     535           0 :     fd_memcpy( return_data->data, src, src_sz );
     536           0 :   }
     537           0 :   return_data->program_id = *program_id;
     538             : 
     539           0 :   *_ret = 0;
     540           0 :   return FD_VM_SUCCESS;
     541           0 : }
     542             : 
     543             : /* Used to query and convey information about the sibling instruction
     544             :    https://github.com/anza-xyz/agave/blob/70089cce5119c9afaeb2986e2ecaa6d4505ec15d/sdk/program/src/instruction.rs#L676
     545             : 
     546             :     */
     547             : struct fd_vm_syscall_processed_sibling_instruction {
     548             :   /* Length of the instruction data */
     549             :   ulong data_len;
     550             :   /* Number of accounts */
     551             :   ulong accounts_len;
     552             : };
     553             : typedef struct fd_vm_syscall_processed_sibling_instruction fd_vm_syscall_processed_sibling_instruction_t;
     554             : 
     555           0 : #define FD_VM_SYSCALL_PROCESSED_SIBLING_INSTRUCTION_SIZE  (16UL)
     556           0 : #define FD_VM_SYSCALL_PROCESSED_SIBLING_INSTRUCTION_ALIGN (8UL )
     557             : 
     558             : /* https://github.com/anza-xyz/agave/blob/70089cce5119c9afaeb2986e2ecaa6d4505ec15d/programs/bpf_loader/src/syscalls/mod.rs#L1402 */
     559             : int
     560             : fd_vm_syscall_sol_get_processed_sibling_instruction(
     561             :     void * _vm,
     562             :     ulong index,
     563             :     ulong result_meta_vaddr,
     564             :     ulong result_program_id_vaddr,
     565             :     ulong result_data_vaddr,
     566             :     ulong result_accounts_vaddr,
     567             :     ulong * _ret
     568           0 : ) {
     569           0 :   fd_vm_t * vm = (fd_vm_t *)_vm;
     570             : 
     571             :   /* Consume base compute cost
     572             :      https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1513 */
     573           0 :   FD_VM_CU_UPDATE( vm, FD_VM_SYSCALL_BASE_COST );
     574             : 
     575             :   /* Get the current instruction stack height.  This value is 1-indexed
     576             :      (top level instruction has a stack height of 1).
     577             :     https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1517 */
     578           0 :   ulong stack_height = vm->instr_ctx->runtime->instr.stack_sz;
     579             : 
     580             :   /* Reverse iterate through the instruction trace, ignoring anything except instructions on the same level.
     581             :      https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1518-L1522 */
     582           0 :   ulong instruction_trace_length = vm->instr_ctx->runtime->instr.trace_length;
     583           0 :   ulong reverse_index_at_stack_height = 0UL;
     584           0 :   fd_instr_info_t * found_instruction_context = NULL;
     585           0 :   for( ulong index_in_trace=instruction_trace_length; index_in_trace>0UL; index_in_trace-- ) {
     586             : 
     587             :     /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1524-L1526
     588             :        This error can never happen */
     589             : 
     590             :     /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1527-L1529 */
     591           0 :     fd_instr_info_t * instruction_context = &vm->instr_ctx->runtime->instr.trace[ index_in_trace-1UL ];
     592           0 :     if( FD_LIKELY( instruction_context->stack_height<stack_height ) ) {
     593           0 :       break;
     594           0 :     }
     595             : 
     596             :     /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1530-L1536 */
     597           0 :     if( FD_UNLIKELY( instruction_context->stack_height==stack_height ) ) {
     598           0 :       if( FD_UNLIKELY( fd_ulong_sat_add( index, 1UL )==reverse_index_at_stack_height ) ) {
     599           0 :         found_instruction_context = instruction_context;
     600           0 :         break;
     601           0 :       }
     602           0 :       reverse_index_at_stack_height = fd_ulong_sat_add( reverse_index_at_stack_height, 1UL );
     603           0 :     }
     604           0 :   }
     605             : 
     606             :   /* If we have found an entry, then copy the instruction into the
     607             :      result addresses.
     608             :      https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1539-L1588
     609             :    */
     610           0 :   if( FD_LIKELY( found_instruction_context != NULL ) ) {
     611           0 :     fd_vm_haddr_query_t result_header_query = {
     612           0 :       .vaddr    = result_meta_vaddr,
     613           0 :       .align    = FD_VM_SYSCALL_PROCESSED_SIBLING_INSTRUCTION_ALIGN,
     614           0 :       .sz       = FD_VM_SYSCALL_PROCESSED_SIBLING_INSTRUCTION_SIZE,
     615           0 :       .is_slice = 0,
     616           0 :     };
     617             : 
     618           0 :     fd_vm_haddr_query_t * queries[] = { &result_header_query };
     619           0 :     FD_VM_TRANSLATE_MUT( vm, queries );
     620             : 
     621           0 :     fd_vm_syscall_processed_sibling_instruction_t * result_header = result_header_query.haddr;
     622             : 
     623             :     /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1546-L1583 */
     624           0 :     if( result_header->data_len==found_instruction_context->data_sz && result_header->accounts_len==found_instruction_context->acct_cnt ) {
     625           0 :       fd_vm_haddr_query_t program_id_query = {
     626           0 :         .vaddr    = result_program_id_vaddr,
     627           0 :         .align    = FD_VM_ALIGN_RUST_PUBKEY,
     628           0 :         .sz       = sizeof(fd_pubkey_t),
     629           0 :         .is_slice = 0,
     630           0 :       };
     631             : 
     632           0 :       fd_vm_haddr_query_t data_query = {
     633           0 :         .vaddr    = result_data_vaddr,
     634           0 :         .align    = FD_VM_ALIGN_RUST_U8,
     635           0 :         .sz       = result_header->data_len,
     636           0 :         .is_slice = 1,
     637           0 :       };
     638             : 
     639           0 :       fd_vm_haddr_query_t accounts_query = {
     640           0 :         .vaddr    = result_accounts_vaddr,
     641           0 :         .align    = FD_VM_RUST_ACCOUNT_META_ALIGN,
     642           0 :         .sz       = fd_ulong_sat_mul( result_header->accounts_len, FD_VM_RUST_ACCOUNT_META_SIZE ),
     643           0 :         .is_slice = 1,
     644           0 :       };
     645             : 
     646           0 :       fd_vm_haddr_query_t * queries[] = { &program_id_query, &data_query, &accounts_query, &result_header_query };
     647           0 :       FD_VM_TRANSLATE_MUT( vm, queries );
     648             : 
     649           0 :       fd_pubkey_t *               program_id = program_id_query.haddr;
     650           0 :       uchar *                     data       = data_query.haddr;
     651           0 :       fd_vm_rust_account_meta_t * accounts   = accounts_query.haddr;
     652             : 
     653             :       /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1561-L1562 */
     654           0 :       fd_pubkey_t const * instr_ctx_program_id = NULL;
     655           0 :       int err = fd_runtime_get_key_of_account_at_index(
     656           0 :           vm->instr_ctx->txn_out,
     657           0 :           found_instruction_context->program_id,
     658           0 :           &instr_ctx_program_id
     659           0 :       );
     660           0 :       if( FD_UNLIKELY( err ) ) {
     661           0 :         FD_VM_ERR_FOR_LOG_INSTR( vm, err );
     662           0 :         return err;
     663           0 :       }
     664           0 :       fd_memcpy( program_id, instr_ctx_program_id, sizeof(fd_pubkey_t) );
     665             : 
     666             :       /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1563 */
     667           0 :       fd_memcpy( data, found_instruction_context->data, found_instruction_context->data_sz );
     668             : 
     669             :       /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1564-L1581 */
     670           0 :       for( ushort i=0; i<found_instruction_context->acct_cnt; i++ ) {
     671           0 :         fd_pubkey_t const * account_key;
     672           0 :         ushort txn_idx = found_instruction_context->accounts[ i ].index_in_transaction;
     673           0 :         err            = fd_runtime_get_key_of_account_at_index( vm->instr_ctx->txn_out, txn_idx, &account_key );
     674           0 :         if( FD_UNLIKELY( err ) ) {
     675           0 :           FD_VM_ERR_FOR_LOG_INSTR( vm, err );
     676           0 :           return err;
     677           0 :         }
     678             : 
     679           0 :         fd_memcpy( accounts[ i ].pubkey, account_key, sizeof(fd_pubkey_t) );
     680           0 :         accounts[ i ].is_signer   = !!(found_instruction_context->accounts[ i ].is_signer );
     681           0 :         accounts[ i ].is_writable = !!(found_instruction_context->accounts[ i ].is_writable );
     682           0 :       }
     683           0 :     } else {
     684             :       /* Copy the actual metadata into the result meta struct
     685             :          https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1584-L1586 */
     686           0 :       result_header->data_len     = found_instruction_context->data_sz;
     687           0 :       result_header->accounts_len = found_instruction_context->acct_cnt;
     688           0 :     }
     689             : 
     690             :     /* Return true as we found a sibling instruction
     691             :        https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1588 */
     692           0 :     *_ret = 1UL;
     693           0 :     return FD_VM_SUCCESS;
     694           0 :   }
     695             : 
     696             :   /* Return false if we didn't find a sibling instruction
     697             :      https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L1590 */
     698           0 :   *_ret = 0UL;
     699           0 :   return FD_VM_SUCCESS;
     700           0 : }
     701             : 
     702             : /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/sysvar.rs#L80 */
     703             : int
     704             : fd_vm_syscall_sol_get_epoch_rewards_sysvar( /**/            void *  _vm,
     705             :                                             /**/            ulong   out_vaddr,
     706             :                                             FD_PARAM_UNUSED ulong   r2,
     707             :                                             FD_PARAM_UNUSED ulong   r3,
     708             :                                             FD_PARAM_UNUSED ulong   r4,
     709             :                                             FD_PARAM_UNUSED ulong   r5,
     710           0 :                                             /**/            ulong * _ret ) {
     711           0 :   fd_vm_t * vm = _vm;
     712           0 :   fd_exec_instr_ctx_t const * instr_ctx = vm->instr_ctx;
     713           0 :   if( FD_UNLIKELY( !instr_ctx ) ) return FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME;
     714             : 
     715           0 :   FD_VM_CU_UPDATE( vm, fd_ulong_sat_add( FD_VM_SYSVAR_BASE_COST, sizeof(fd_vm_epoch_rewards_t) ) );
     716             : 
     717             :   /* See https://github.com/anza-xyz/agave/pull/12130 */
     718           0 :   if( FD_UNLIKELY( vm->is_deprecated ) ) {
     719           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_UNALIGNED_POINTER );
     720           0 :     return FD_VM_SYSCALL_ERR_UNALIGNED_POINTER;
     721           0 :   }
     722             : 
     723           0 :   if( FD_UNLIKELY( vm->syscall_parameter_address_restrictions && out_vaddr>=FD_VM_MEM_MAP_INPUT_REGION_START ) ) {
     724           0 :     FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_INVALID_POINTER );
     725           0 :     return FD_VM_ERR_INVAL;
     726           0 :   }
     727             : 
     728           0 :   uchar * out = FD_VM_MEM_HADDR_ST( vm, out_vaddr, FD_VM_ALIGN_RUST_SYSVAR_EPOCH_REWARDS, sizeof(fd_vm_epoch_rewards_t) );
     729             : 
     730           0 :   fd_sysvar_epoch_rewards_t epoch_rewards;
     731           0 :   if( FD_UNLIKELY( !fd_sysvar_cache_epoch_rewards_read( instr_ctx->sysvar_cache, &epoch_rewards ) ) ) {
     732           0 :     FD_TXN_ERR_FOR_LOG_INSTR( vm->instr_ctx->txn_out, FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR, vm->instr_ctx->txn_out->err.exec_err_idx );
     733           0 :     return FD_VM_ERR_INVAL;
     734           0 :   }
     735             : 
     736           0 :   fd_vm_epoch_rewards_t * vm_epoch_rewards = (fd_vm_epoch_rewards_t *)out;
     737           0 :   *vm_epoch_rewards = (fd_vm_epoch_rewards_t){
     738           0 :     .distribution_starting_block_height = epoch_rewards.distribution_starting_block_height,
     739           0 :     .num_partitions                     = epoch_rewards.num_partitions,
     740           0 :     .parent_blockhash                   = epoch_rewards.parent_blockhash,
     741           0 :     .total_points                       = epoch_rewards.total_points,
     742           0 :     .total_rewards                      = epoch_rewards.total_rewards,
     743           0 :     .distributed_rewards                = epoch_rewards.distributed_rewards,
     744           0 :     .active                             = epoch_rewards.active,
     745           0 :   };
     746             : 
     747           0 :   *_ret = 0UL;
     748           0 :   return FD_VM_SUCCESS;
     749           0 : }

Generated by: LCOV version 1.14