LCOV - code coverage report
Current view: top level - flamenco/vm/syscall - fd_vm_syscall.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 7 20 35.0 %
Date: 2025-09-18 04:41:32 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_vm_syscall_fd_vm_syscall_h
       2             : #define HEADER_fd_src_flamenco_vm_syscall_fd_vm_syscall_h
       3             : 
       4             : #include "../fd_vm_private.h"
       5             : #include "fd_vm_syscall_macros.h"
       6             : #include "fd_vm_cpi.h"                /* FIXME: REFINE THIS MORE */
       7             : #include "../../runtime/fd_runtime.h" /* FIXME: REFINE THIS MORE */
       8             : #include "../../runtime/context/fd_exec_instr_ctx.h"
       9             : #include "../../log_collector/fd_log_collector.h"
      10             : 
      11             : #define FD_VM_RETURN_DATA_MAX  (1024UL) /* FIXME: DOCUMENT AND DOES THIS BELONG HERE? */
      12             : 
      13             : /* The maximum number of seeds a PDA can have
      14             :    https://github.com/solana-labs/solana/blob/2afde1b028ed4593da5b6c735729d8994c4bfac6/sdk/program/src/pubkey.rs#L21 */
      15             : #define FD_VM_PDA_SEEDS_MAX    (16UL)
      16             : /* The maximum length of a PDA seed
      17             :    https://github.com/solana-labs/solana/blob/2afde1b028ed4593da5b6c735729d8994c4bfac6/sdk/program/src/pubkey.rs#L19 */
      18             : #define FD_VM_PDA_SEED_MEM_MAX (32UL)
      19             : 
      20             : /* PYTHON3 CODE FOR COMPUTING THE SYSCALL MURMUR3 HASH (e.g. sol_get_epoch_stake):
      21             :   ```
      22             :   import mmh3
      23             :   import ctypes
      24             : 
      25             :   def compute_murmur3_hash(input_string):
      26             :       # Compute the Murmur3 hash of the input string
      27             :       hash_value = mmh3.hash(input_string)
      28             :       # Convert the hash value to a 32-bit unsigned integer
      29             :       u32_hash_value = ctypes.c_uint32(hash_value).value
      30             :       return u32_hash_value
      31             : 
      32             :   input_string = b"sol_get_epoch_stake"
      33             :   hash_value = compute_murmur3_hash(input_string)
      34             :   print(f"The Murmur3 hash of '{input_string}' as u32 is: {hex(hash_value)}")
      35             : 
      36             :   Output:
      37             :   The Murmur3 hash of 'b'sol_get_epoch_stake'' as u32 is: 0x5be92f4a
      38             :   ```
      39             : */
      40             : 
      41             : /* https://github.com/solana-labs/solana/blob/2afde1b028ed4593da5b6c735729d8994c4bfac6/sdk/program/src/pubkey.rs#L22 */
      42             : 
      43             : /* FIXME: CONSIDER NOT PREFIXING SYSCALLS WITH SOL_? (OR MAYBE THIS
      44             :    IS NECESSARY TO DISAMBIGUATE SOLANA SYSCALLS FROM NON-SOLANA?
      45             :    SYSCALLS? */
      46             : 
      47             : /* FD_VM_SYSCALL_DECL declares a prototype of a syscall.  When a
      48             :    syscall implementation is called, the syscall will see a precise
      49             :    reporting VM's state at time of the syscall.  Notably:
      50             : 
      51             :    - vm->pc will be at the syscall instruction
      52             :    - vm->ic will include the syscall instruction
      53             :    - vm->cu will include the 1 cu cost of the syscall instruction.
      54             :      Further, it will be positive.
      55             : 
      56             :    r1,r2,r3,r4,r5 are the values in r1,r2,r3,r4,r5 at time of the
      57             :    syscall.
      58             : 
      59             :    When a syscall implementation returns FD_VM_SUCCESS, *_r0 should hold
      60             :    the application return error value it wants to place in r0.
      61             : 
      62             :    When an syscall implementation returns FD_VM_SYSCALL_ERR*, the
      63             :    syscall is considered to have faulted the VM.  It ideally should not
      64             :    have set *_r0 (or changed any vm state, except vm->cu, though that
      65             :    often isn't practical, and not critical to consensus).
      66             : 
      67             :    It is the syscall's responsibility to deduct from vm->cu its specific
      68             :    cost model (not including the syscall instruction itself).  As such,
      69             :    when a syscall returns COMPUTE_BUDGET_EXCEEDED, it should have set
      70             :    vm->cu to zero. When it returns anything else, it should have set cu
      71             :    to something in [0,cu_at_function_entry] (upper bound inclusive,
      72             :    despite most syscalls deducing base CUs first thing, some don't,
      73             :    e.g., sol_sha256).
      74             : 
      75             :    To mitigate risks of from syscall implementations that do not
      76             :    strictly enforce this and other similar risks that can affect
      77             :    bookkeeping, on return from a syscall, the VM will:
      78             : 
      79             :    - Ignore updates to pc, ic and frame_cnt.
      80             :    - Ignore updates to cu that increase it.
      81             :    - Treat updates to cu that zero it as SIGCOST.
      82             :    - Treat SIGCOST returns that didn't update cu to zero as zeroing it.
      83             : 
      84             :    FIXME: ADD NO SETTING OF R0 ON VM_ERR IN VM_INTERP. */
      85             : 
      86             : #define FD_VM_SYSCALL_DECL(name)   \
      87             : int                                \
      88             : fd_vm_syscall_##name( void *  _vm, \
      89             :                       ulong   r1,  \
      90             :                       ulong   r2,  \
      91             :                       ulong   r3,  \
      92             :                       ulong   r4,  \
      93             :                       ulong   r5,  \
      94             :                       ulong * _ret )
      95             : 
      96             : FD_PROTOTYPES_BEGIN
      97             : 
      98             : /* fd_vm_syscall_util *************************************************/
      99             : 
     100             : /* syscall(b6fc1a11) "abort"
     101             :    Abort program execution and fail transaction.
     102             : 
     103             :    Inputs:
     104             : 
     105             :      r1 - ignored
     106             :      r2 - ignored
     107             :      r3 - ignored
     108             :      r4 - ignored
     109             :      r5 - ignored
     110             : 
     111             :    Return:
     112             : 
     113             :      FD_VM_SYSCALL_ERR_ABORT: *_ret unchanged.  vm->cu unchanged.
     114             : 
     115             :    FIXME: SHOULD THIS BE NAMED "SOL_ABORT"? */
     116             : 
     117             : FD_VM_SYSCALL_DECL( abort );
     118             : 
     119             : /* syscall(686093bb) "sol_panic_"
     120             :    Log panic message, abort program execution, and fail transaction.
     121             : 
     122             :    Inputs:
     123             : 
     124             :      r1 - msg, byte VM pointer, indexed [0,msg_sz), msg doesn't have to
     125             :      be \0 terminated and can contain \0 within,
     126             :      r2 - msg_sz, may be 0,
     127             :      r3 - ignored
     128             :      r4 - ignored
     129             :      r5 - ignored
     130             : 
     131             :    Return:
     132             : 
     133             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     134             :      budget.  *_ret unchanged.  vm->cu==0.
     135             : 
     136             :      FD_VM_SYSCALL_ERR_INVALID_STRING: Bad filepath string, msg is not
     137             :      a valid sequence of utf8 bytes.  *_ret unchanged and vm->cu>=0.
     138             : 
     139             :      FD_VM_SYSCALL_ERR_PANIC: *_ret unchanged.  *_ret unchanged.  vm->cu
     140             :      decremented and vm->cu>=0. */
     141             : 
     142             : FD_VM_SYSCALL_DECL( sol_panic );
     143             : 
     144             : /* syscall(207559bd) "sol_log_"
     145             :    Write message encoded as (msg, msg_sz) to log, prefixed with
     146             :    "Program log: ".
     147             : 
     148             :    Inputs:
     149             : 
     150             :      r1 - msg, byte VM pointer, indexed [0,msg_sz),
     151             :      r2 - msg_sz, may be 0,
     152             :      r3 - ignored
     153             :      r4 - ignored
     154             :      r5 - ignored
     155             : 
     156             :    Return:
     157             : 
     158             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     159             :      budget.  *_ret unchanged.  vm->cu==0.
     160             : 
     161             :      FD_VM_SYSCALL_ERR_INVALID_STRING: bad message string.  *_ret
     162             :      unchanged. vm->cu decremented and vm->cu>=0.
     163             : 
     164             :      FD_VM_SUCCESS: success.  *_ret==0.  vm->cu decremented and
     165             :      vm->cu>=0.
     166             : 
     167             :      IMPORTANT SAFETY TIP!  The log message will be silently truncated
     168             :      if there was not enough room for the message in the syscall log
     169             :      when called. */
     170             : 
     171             : FD_VM_SYSCALL_DECL( sol_log );
     172             : 
     173             : /* syscall(5c2a3178) "sol_log_64_"
     174             :    Write r1:5 to the log as a hexadecimal
     175             : 
     176             :    Inputs:
     177             : 
     178             :      r1 - ulong
     179             :      r2 - ulong
     180             :      r3 - ulong
     181             :      r4 - ulong
     182             :      r5 - ulong
     183             : 
     184             :    Return:
     185             : 
     186             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     187             :      budget.  *_ret unchanged.  vm->cu==0.
     188             : 
     189             :      FD_VM_SUCCESS: success.  *_ret=0.  vm->cu decremented and
     190             :      vm->cu>=0.
     191             : 
     192             :      IMPORTANT SAFETY TIP!  The log message will be silently truncated
     193             :      if there was not enough room for the message in the syscall log
     194             :      when called. */
     195             : 
     196             : FD_VM_SYSCALL_DECL( sol_log_64 );
     197             : 
     198             : /* syscall(7ef088ca) "sol_log_pubkey"
     199             :    Write the base58 encoding of 32 byte array to the log.
     200             : 
     201             :    Inputs:
     202             : 
     203             :      r1 - pubkey, byte VM pointer, indexed [0,32)
     204             :      r2 - ignored
     205             :      r3 - ignored
     206             :      r4 - ignored
     207             :      r5 - ignored
     208             : 
     209             :    Return:
     210             : 
     211             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     212             :      budget.  *_ret unchanged.  vm->cu==0.
     213             : 
     214             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  *_ret unchanged.
     215             :      vm->cu decremented and vm->cu>=0.
     216             : 
     217             :      FD_VM_SUCCESS: success.  *_ret==0.  vm->cu decremented and
     218             :      vm->cu>=0.
     219             : 
     220             :      IMPORTANT SAFETY TIP!  The log message will be silently truncated
     221             :      if there was not enough room for the message in the syscall log
     222             :      when called. */
     223             : 
     224             : FD_VM_SYSCALL_DECL( sol_log_pubkey );
     225             : 
     226             : /* syscall(52ba5096) "sol_log_compute_units_"
     227             :    Write remaining compute unit count to log.
     228             : 
     229             :    Inputs:
     230             : 
     231             :      r1 - ignored
     232             :      r2 - ignored
     233             :      r3 - ignored
     234             :      r4 - ignored
     235             :      r5 - ignored
     236             : 
     237             :    Return:
     238             : 
     239             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     240             :      budget.  *_ret unchanged.  vm->cu==0.
     241             : 
     242             :      FD_VM_SUCCESS: success.  *_ret=0.  vm->cu decremented
     243             :      and vm->cu>=0.  The value logged will be the value of cu when
     244             :      between when the syscall completed and the next interation starts
     245             :      and will be >=0.
     246             : 
     247             :      IMPORTANT SAFETY TIP!  The log message will be silently truncated
     248             :      if there was not enough room for the message in the syscall log
     249             :      when called. */
     250             : 
     251             : FD_VM_SYSCALL_DECL( sol_log_compute_units );
     252             : 
     253             : /* syscall(7317b434) "sol_log_data"
     254             :    Write the base64 encoded cnt data slices to the log.
     255             : 
     256             :    Inputs:
     257             : 
     258             :      r1 - slice, ulong pair VM pointer, indexed [0,cnt),
     259             :      r2 - cnt, may be 0,
     260             :      r3 - ignored
     261             :      r4 - ignored
     262             :      r5 - ignored
     263             : 
     264             :      slice[i] holds the ulong pair:
     265             :        mem, byte VM pointer, indexed [0,sz),
     266             :        sz, may be 0
     267             : 
     268             :    Return:
     269             : 
     270             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
     271             :      *_ret unchanged. vm->cu==0.
     272             : 
     273             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  *_ret unchanged.  vm->cu
     274             :      decremented and vm->cu>0.
     275             : 
     276             :      FD_VM_SUCCESS: success.  *_ret=0.  vm->cu decremented and vm->cu>0.
     277             : 
     278             :      IMPORTANT SAFETY TIP!  The log message will be silently truncated
     279             :      if there was not enough room for the message in the syscall log
     280             :      when called. */
     281             : 
     282             : FD_VM_SYSCALL_DECL( sol_log_data );
     283             : 
     284             : /* syscall(83f00e8f) "sol_alloc_free_"
     285             :    DEPRECATED ... dynamic heap allocation support
     286             : 
     287             :    Inputs:
     288             : 
     289             :      r1 - sz, ignored if vaddr is not 0
     290             :      r2 - free_vaddr, byte VM pointer
     291             :      r3 - ignored
     292             :      r4 - ignored
     293             :      r5 - ignored
     294             : 
     295             :    Return:
     296             : 
     297             :      All cases return FD_VM_SUCCESS and leave vm->cu unchanged.
     298             : 
     299             :      If free_vaddr is 0, this is "malloc"-like:
     300             : 
     301             :        Let the VM heap region cover bytes [heap_start,heap_end) with
     302             :        heap_start<=heap_end.  If the request was satisfied, on return,
     303             :        *_ret will point to a range of heap bytes [*_ret,*_ret+sz) that
     304             :        does not overlap with any other current allocation such that
     305             :        heap_start<=*_ret<=*_ret+sz<=heap_end.  This includes the zero sz
     306             :        case (note that the zero sz case might return the same value as a
     307             :        previous zero sz case and/or return the exact value of heap_end).
     308             : 
     309             :        If the request cannot be satisfied, *_ret=0 on return and the
     310             :        heap unchanged.
     311             : 
     312             :        IMPORTANT SAFETY TIP!  If the VM has check_align set, this
     313             :        location will have at least 8 byte alignment.  Otherwise, this
     314             :        location will have no particular alignment.  Note that this
     315             :        implies allocations done by this syscall do not conform to the
     316             :        usual alignment requirements of a standard malloc call for older
     317             :        VM code.
     318             : 
     319             :      If vaddr is not-zero, this is "free"-like.  Since the underlying
     320             :      implementation is necessarily a bump allocator (see implementation
     321             :      for more details), the specific value is ignored and *_ret=0 on
     322             :      return. */
     323             : 
     324             : FD_VM_SYSCALL_DECL( sol_alloc_free );
     325             : 
     326             : /* syscall(717cc4a3) "sol_memcpy_"
     327             :    Copy sz bytes from src to dst.  src and dst should not overlap.
     328             : 
     329             :    Inputs:
     330             : 
     331             :      r1 - dst, byte VM pointer, indexed [0,sz),
     332             :      r2 - src, byte VM pointer, indexed [0,sz),
     333             :      r3 - sz,
     334             :      r4 - ignored
     335             :      r5 - ignored
     336             : 
     337             :   Return:
     338             : 
     339             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     340             :      budget.  *_ret unchanged.  vm->cu==0.
     341             : 
     342             :      FD_VM_SYSCALL_ERR_COPY_OVERLAPPING: address ranges for src and dst
     343             :      overlap (either partially or fully).  Empty address ranges are
     344             :      considered to **never** overlap.  *_ret==0.  vm->cu decremented and
     345             :      vm->cu>=0.
     346             : 
     347             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  *_ret==0.  vm->cu
     348             :      decremented and vm->cu>=0.
     349             : 
     350             :      FD_VM_SUCCESS: success.  *_ret==0.  vm->cu decremented and
     351             :      vm->cu>=0. On return, dst[i]==src[i] for i in [0,sz). */
     352             : 
     353             : FD_VM_SYSCALL_DECL( sol_memcpy );
     354             : 
     355             : /* syscall(5fdcde31) "sol_memcmp_"
     356             :    Compare sz bytes at m0 to m1
     357             : 
     358             :    Inputs:
     359             : 
     360             :      r1 - m0, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
     361             :      r2 - m1, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
     362             :      r3 - sz, FIXME: IS SZ 0 OKAY?
     363             :      r4 - out, int VM pointer
     364             :      r5 - ignored
     365             : 
     366             :   Return:
     367             : 
     368             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
     369             :      *_ret unchanged. vm->cu==0.
     370             : 
     371             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range (including out not 4 byte
     372             :      aligned).  *_ret unchanged.  vm->cu decremented and vm->cu>0.
     373             :      Strict alignment is only required when the VM has check_align set.
     374             : 
     375             :      FD_VM_SUCCESS: success.  *_ret=0.  vm->cu decremented and vm->cu>0.
     376             :      On return, *_out will hold a positive / zero / negative number if
     377             :      the region at m0 lexicographically compares strictly greater than /
     378             :      equal to / strictly less than the region at m1 when treated as
     379             :      uchars.  Specifically, if the regions are different, *_out will be
     380             :      (int)m0[i] - (int)m1[i] where i is the first differing byte.
     381             : 
     382             :      IMPORANT SAFETY TIP!  Note that, strangely, this returns the result
     383             :      in memory instead via *_ret like a libc-style memcmp would. */
     384             : 
     385             : FD_VM_SYSCALL_DECL( sol_memcmp );
     386             : 
     387             : /* syscall(3770fb22) "sol_memset_"
     388             :    Set sz bytes at dst to the byte value c.
     389             : 
     390             :    Inputs:
     391             : 
     392             :      r1 - dst, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
     393             :      r2 - c, bits [8,64) ignored (FIXME: CHECK SOLANA DOES THIS)
     394             :      r3 - sz, may be 0,
     395             :      r4 - ignored
     396             :      r5 - ignored
     397             : 
     398             :   Return:
     399             : 
     400             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
     401             :      *_ret unchanged. vm->cu==0.
     402             : 
     403             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  *_ret unchanged.  vm->cu
     404             :      decremented and vm->cu>0.
     405             : 
     406             :      FD_VM_SUCCESS: success.  *_ret=0.  vm->cu decremented and vm->cu>0.
     407             :      On return, dst[i]==(uchar)(c & 255UL) for i in [0,sz). */
     408             : 
     409             : FD_VM_SYSCALL_DECL( sol_memset );
     410             : 
     411             : /* syscall(434371f8) "sol_memmove_"
     412             :    Copy sz bytes from src to dst.  src and dst can overlap.
     413             : 
     414             :    Inputs:
     415             : 
     416             :      r1 - dst, byte VM pointer, indexed [0,sz),
     417             :      r2 - src, byte VM pointer, indexed [0,sz),
     418             :      r3 - sz, may be 0,
     419             :      r4 - ignored
     420             :      r5 - ignored
     421             : 
     422             :   Return:
     423             : 
     424             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
     425             :      *_ret unchanged. vm->cu==0.
     426             : 
     427             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  *_ret unchanged.  vm->cu
     428             :      decremented and vm->cu>0.
     429             : 
     430             :      FD_VM_SUCCESS: success.  *_ret=0.  vm->cu decremented and vm->cu>0.
     431             :      On return, dst[i]==src_as_it_was_before_the_call[i] for i in
     432             :      [0,sz). */
     433             : 
     434             : FD_VM_SYSCALL_DECL( sol_memmove );
     435             : 
     436             : /* fd_vm_syscall_runtime **********************************************/
     437             : 
     438             : /* syscall(d56b5fe9) "sol_get_clock_sysvar"
     439             :    syscall(23a29a61) "sol_get_epoch_schedule_sysvar"
     440             :    syscall(bf7188f6) "sol_get_rent_sysvar"
     441             :    syscall(77f9b9d0) "sol_get_last_restart_slot_sysvar"
     442             :    Get various sysvar values
     443             : 
     444             :    Inputs:
     445             : 
     446             :      r1 - out, {clock,schedule,fees,rent,last_restart_slot} VM pointer
     447             :      r2 - ignored
     448             :      r3 - ignored
     449             :      r4 - ignored
     450             :      r5 - ignored
     451             : 
     452             :    Return:
     453             : 
     454             :      FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME: the VM is not running within the
     455             :      Solana runtime.  *_ret unchanged.  vm->cu unchanged.
     456             : 
     457             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     458             :      budget.  *_ret unchanged.  vm->cu==0.
     459             : 
     460             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  *_ret unchanged.
     461             :      vm->cu decremented and vm->cu>=0.  out should have:
     462             :                           | align | sz
     463             :        clock              |     8 | 40
     464             :        schedule           |     8 | 40
     465             :        rent               |     8 | 24
     466             :        last restart slot  |     8 | 8
     467             :      Strict alignment is only required when the VM has check_align set.
     468             : 
     469             :      FD_VM_SUCCESS: success.  *_ret=0.  vm->cu decremented and vm->cu>0.
     470             :      On return, *out will hold the value of the appropriate sysvar. */
     471             : 
     472             : FD_VM_SYSCALL_DECL( sol_get_clock_sysvar             );
     473             : FD_VM_SYSCALL_DECL( sol_get_epoch_schedule_sysvar    );
     474             : FD_VM_SYSCALL_DECL( sol_get_rent_sysvar              );
     475             : FD_VM_SYSCALL_DECL( sol_get_last_restart_slot_sysvar );
     476             : FD_VM_SYSCALL_DECL( sol_get_epoch_rewards_sysvar     );
     477             : 
     478             : /* syscall(13c1b505) "sol_get_sysvar"
     479             : 
     480             :    Get a slice of a sysvar account's data.
     481             : 
     482             :    Inputs:
     483             : 
     484             :      r1 - sysvar_id_vaddr, sysvar pubkey VM pointer
     485             :      r2 - out_vaddr, byte VM pointer
     486             :      r3 - offset, ulong
     487             :      r4 - sz, num bytes to store
     488             :      r5 - ignored
     489             : 
     490             :    Return:
     491             : 
     492             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     493             :      budget.  *_ret unchanged.  vm->cu==0.
     494             : 
     495             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad sysvar_id_vaddr, bad out_vaddr,
     496             :      requested slice outside of sysvar data buffer.  _ret unchanged.
     497             :      vm->cu decremented and vm->cu>=0.
     498             : 
     499             :      FD_VM_SYSCALL_ERR_ABORT: offset+sz overflow.  *_ret unchanged.
     500             :      vm->cu decremented and vm->cu>=0.
     501             : 
     502             :      FD_VM_SUCCESS: success. vm->cu decremented and vm->cu>=0.
     503             :       - *_ret = 2 if sysvar id is not in {clock,schedule,rewards,rent,
     504             :                   slot hashes,stake history, last restart slot}
     505             :                   OR sysvar account does not exist.
     506             :       - *_ret = 1 if [offset,offset+sz) is outside of sysvar data
     507             :                   buffer.
     508             :       - *_ret = 0 if success.
     509             : 
     510             :      On return, sz bytes of appropriate offset sysvar data will be
     511             :      copied into haddr belonging to out_vaddr. */
     512             : FD_VM_SYSCALL_DECL( sol_get_sysvar );
     513             : 
     514             : /* syscall(5be92f4a) "sol_get_epoch_stake"
     515             : 
     516             :    This syscall is meant to return the latest frozen stakes at an epoch
     517             :    boundary.  So for instance, when we are executing in epoch 7, this
     518             :    should return the stakes at the end of epoch 6.  Note that this is
     519             :    also the stakes that determined the leader schedule for the upcoming
     520             :    epoch, namely epoch 8.
     521             : 
     522             :    Inputs:
     523             : 
     524             :      r1 - var_addr, vote pubkey VM pointer, or zero to get the total
     525             :           active stake on the cluster.
     526             :      r2 - ignored
     527             :      r3 - ignored
     528             :      r4 - ignored
     529             :      r5 - ignored
     530             : 
     531             :    Return:
     532             : 
     533             :      FD_VM_ERR_SIGCOST: insufficient compute budget.  *_ret unchanged.
     534             :      vm->cu==0.
     535             : 
     536             :      FD_VM_ERR_SIGSEGV: bad var_addr.  _ret unchanged.  vm->cu
     537             :      decremented and vm->cu>=0.
     538             : 
     539             :      FD_VM_ERR_ABORT: offset+sz overflow.  *_ret unchanged.
     540             : 
     541             :      FD_VM_SUCCESS: success. vm->cu decremented and vm->cu>=0.
     542             :       If var_addr == 0, *_ret is the total active stake on the
     543             :       cluster.  Else, it is the vote account's delegated stake if
     544             :       var_addr is an existing vote account, and 0 otherwise. */
     545             : 
     546             : FD_VM_SYSCALL_DECL( sol_get_epoch_stake );
     547             : 
     548             : /* syscall(85532d94) "sol_get_stack_height"
     549             : 
     550             :    Inputs:
     551             : 
     552             :      r1 - ignored
     553             :      r2 - ignored
     554             :      r3 - ignored
     555             :      r4 - ignored
     556             :      r5 - ignored
     557             : 
     558             :    Return:
     559             : 
     560             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     561             :      budget.  *_ret unchanged.  vm->cu==0.
     562             : 
     563             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  *_ret unchanged.
     564             :      vm->cu decremented and vm->cu>=0.
     565             : 
     566             :      FD_VM_SUCCESS: success.  *_ret==stack_height.  vm->cu decremented
     567             :      and vm->cu>=0. */
     568             : 
     569             : FD_VM_SYSCALL_DECL( sol_get_stack_height );
     570             : 
     571             : /* syscall(5d2245e4) "sol_get_return_data"
     572             :    Get the return data and program id associated with it.
     573             : 
     574             :    Inputs:
     575             : 
     576             :      r1 - dst, byte VM pointer, indexed [0,dst_max),
     577             :      r2 - dst_max, may be 0,
     578             :      r3 - program_id, byte VM pointer, indexed [0,32)
     579             :      r4 - ignored
     580             :      r5 - ignored
     581             : 
     582             :    Return:
     583             : 
     584             :      FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME: the VM is not running within
     585             :      the Solana runtime.  *_ret unchanged.  vm->cu unchanged.
     586             : 
     587             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     588             :      budget.  *_ret unchanged. vm->cu==0.
     589             : 
     590             :      FD_VM_SYSCALL_ERR_COPY_OVERLAPPING: dst and program_id address
     591             :      ranges overlap.  *_ret unchanged.   vm->cu decremented and
     592             :      vm->cu>=0.
     593             : 
     594             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for dst and/or
     595             :      program_id. *_ret unchanged.  Compute budget decremented.
     596             : 
     597             :      FD_VM_SUCCESS: success.  *_ret=return_data_sz.  vm->cu decremented
     598             :      and vm->cu>=0.  On return, if dst_max was non-zero, dst holds the
     599             :      leading min(return_data_sz,dst_max) bytes of return data (as such,
     600             :      if return_data_sz>dst_max, the value returned in the buffer was
     601             :      truncated).  Any trailing bytes of dst are unchanged.  program_id
     602             :      holds the program_id associated with the return data.
     603             : 
     604             :      If dst_max was zero, dst and program_id are untouched. */
     605             : 
     606             : FD_VM_SYSCALL_DECL( sol_get_return_data );
     607             : 
     608             : /* syscall(a226d3eb) "sol_set_return_data"
     609             :    Set the return data.  The return data will be associated with the
     610             :    caller's program ID.
     611             : 
     612             :    Inputs:
     613             : 
     614             :      r1 - src, byte VM pointer, indexed [0,src_sz),
     615             :      r2 - src_sz, may be 0,
     616             :      r3 - ignored
     617             :      r4 - ignored
     618             :      r5 - ignored
     619             : 
     620             :    Return:
     621             :      FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME: the VM is not running within the
     622             :      Solana runtime.  *_ret unchanged.  vm->cu unchanged.
     623             : 
     624             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     625             :      budget.  *_ret unchanged.  vm->cu==0.
     626             : 
     627             :      FD_VM_SYSCALL_ERR_RETURN_DATA_TOO_LARGE: src_sz too large.  *_ret
     628             :      unchanged.  vm->cu decremented and vm->cu>0.
     629             : 
     630             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for src.  *_ret unchanged.
     631             :      vm->cu decremented and vm->cu>=0.
     632             : 
     633             :      FD_VM_SUCCESS: success.  *_ret=0.  vm->cu decremented and vm->cu>0. */
     634             : 
     635             : FD_VM_SYSCALL_DECL( sol_set_return_data );
     636             : 
     637             : /* syscall(adb8efc8) "sol_get_processed_sibling_instruction"
     638             :    Returns the last element from a reverse-ordered list of successfully
     639             :    processed sibling instructions: the "processed sibling instruction
     640             :    list".
     641             : 
     642             :    For example, given the call flow:
     643             :    A
     644             :    B -> C -> D
     645             :    B -> E
     646             :    B -> F      (current execution point)
     647             : 
     648             :    B's processed sibling instruction list is [A]
     649             :    F's processed sibling instruction list is [E, C]
     650             : 
     651             :    This allows the current instruction to know what the last processed
     652             :    sibling instruction was.  This is useful to check that critical
     653             :    preceding instructions have actually executed: for example, ensuring
     654             :    that an assert instruction has successfully executed.
     655             : 
     656             :    Inputs:
     657             : 
     658             :      r1 - index
     659             :      r2 - result_meta_vaddr, byte VM pointer of the object where
     660             :           metadata about the last processed sibling instruction will be
     661             :           stored upon successful execution (the length of the arrays in
     662             :           the result). Has the type
     663             :           solana_program::instruction::ProcessedSiblingInstruction
     664             :           https://github.com/anza-xyz/agave/blob/70089cce5119c9afaeb2986e2ecaa6d4505ec15d/sdk/program/src/instruction.rs#L672-L681
     665             :      r3 - result_program_id_vaddr, byte VM pointer where the pubkey of
     666             :           the program ID of the last processed sibling instruction will
     667             :           be stored upon successful execution
     668             :      r4 - result_data_vaddr, byte VM pointer where the instruction
     669             :           data of the last processed sibling instruction will be stored
     670             :           upon successful execution. The length of the data will be
     671             :           stored in ProcessedSiblingInstruction.data_len
     672             :      r5 - result_accounts_vaddr, byte VM pointer where an array of
     673             :           account meta structures will be stored into upon successful
     674             :           execution.  The length of the data will be stored in
     675             :           ProcessedSiblingInstruction.accounts_len.  Each account meta
     676             :           has the type solana_program::instruction::AccountMeta
     677             :           https://github.com/anza-xyz/agave/blob/70089cce5119c9afaeb2986e2ecaa6d4505ec15d/sdk/program/src/instruction.rs#L525-L548
     678             : 
     679             :     Return:
     680             : 
     681             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     682             :      budget.  *_ret unchanged.  vm->cu==0.
     683             : 
     684             :      FD_VM_SUCCESS: *_ret==1 if the instruction was found and, *_ret==0
     685             :      otherwise.  vm->cu decremented and vm->cu>=0. */
     686             : 
     687             : 
     688             : FD_VM_SYSCALL_DECL( sol_get_processed_sibling_instruction );
     689             : 
     690             : /* fd_vm_syscall_pda **************************************************/
     691             : 
     692             : /* syscall(9377323c) "sol_create_program_address"
     693             : 
     694             :    Compute SHA-256 hash of <program ID> .. &[&[u8]] .. <PDA Marker>
     695             :    and check whether result is an Ed25519 curve point.
     696             : 
     697             :    Inputs:
     698             : 
     699             :      r1 - seeds, bytes VM pointer, indexed [0,seed_cnt),
     700             :      r2 - seed_cnt, may be 0,
     701             :      r3 - program_id, byte VM pointer, indexed [0,32), FD_PUBKEY_ALIGN
     702             :           aligned
     703             :      r4 - out, byte VM pointer, indexed [0,32), FD_PUBKEY_ALIGN aligned
     704             :      r5 - ignored
     705             : 
     706             :      seed[i] holds the ulong pair
     707             :        mem, byte VM pointer, indexed [0,sz),
     708             :        sz, may be 0
     709             : 
     710             :    Return:
     711             : 
     712             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     713             :      budget.  *_ret unchanged.  vm->cu==0.
     714             : 
     715             :      FD_VM_SYSCALL_ERR_BAD_SEEDS: seed_cnt and/or seed[i].sz too large,
     716             :      bad address range for program_id, seed,
     717             :      seed[i].mem and/or out (including 8-byte alignment for seed if the
     718             :      VM has check_align set). *_ret unchanged.  Compute budget
     719             :      decremented.
     720             : 
     721             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  *_ret unchanged.
     722             :      vm->cu decremented and vm->cu>=0.
     723             : 
     724             :      FD_VM_SUCCESS: success.  If *_ret==0, a PDA was created and
     725             :      stored at out.  If *_ret==1, create failed and out was unchanged.
     726             :      Compute budget decremented. */
     727             : 
     728             : FD_VM_SYSCALL_DECL( sol_create_program_address );
     729             : 
     730             : /* syscall(48504a38) "sol_try_find_program_address"
     731             : 
     732             :    Repeatedly derive program address while incrementing nonce in seed
     733             :    list until a point is found that is not a valid Ed25519 curve point.
     734             : 
     735             :    Inputs:
     736             : 
     737             :      r1 - seed, ulong pair VM pointer, indexed [0,seed_cnt),
     738             :      r2 - seed_cnt, may be 0,
     739             :      r3 - program_id, byte VM pointer, indexed [0,32), FD_PUBKEY_ALIGN
     740             :           aligned
     741             :      r4 - out, byte VM pointer, indexed [0,32), FD_PUBKEY_ALIGN aligned
     742             :      r5 - bump_seed, byte VM pointer, indexed [0,1)
     743             : 
     744             :      seed[i] holds the ulong pair
     745             :        mem, byte VM pointer, indexed [0,sz),
     746             :        sz, may be 0
     747             : 
     748             :    Return:
     749             : 
     750             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     751             :      budget.  *_ret unchanged.  vm->cu==0.
     752             : 
     753             :      FD_VM_SYSCALL_ERR_BAD_SEEDS: seed_cnt and/or seed[i].sz too large,
     754             :      bad address range for program_id, seed,
     755             :      seed[i].mem, out and/or bump_seed (including 8-byte alignment for
     756             :      seed if the VM has check_align set). *_ret unchanged.  Compute
     757             :      budget decremented.
     758             : 
     759             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  *_ret unchanged.
     760             :      vm->cu decremented and vm->cu>=0.
     761             : 
     762             :      FD_VM_SUCCESS: success.  If *_ret==0, a PDA was found and stored at
     763             :      out and the suffix stored at bump_seed.  If *_ret==1, no PDA was
     764             :      found and out and bump_seed were unchanged.  Compute budget
     765             :      decremented. */
     766             : 
     767             : FD_VM_SYSCALL_DECL( sol_try_find_program_address );
     768             : 
     769             : /* fd_vm_syscall_cpi **************************************************/
     770             : 
     771             : /* Prepare instruction method */
     772             : /* FIXME: DOES THIS GO HERE?  MAYBE GROUP WITH ADMIN OR OUTSIDE SYSCALL? */
     773             : 
     774             : int
     775             : fd_vm_prepare_instruction( fd_instr_info_t *        callee_instr,
     776             :                            fd_exec_instr_ctx_t *    instr_ctx,
     777             :                            fd_pubkey_t const *      callee_program_id_pubkey,
     778             :                            fd_pubkey_t const        instr_acct_keys[ FD_INSTR_ACCT_MAX ],
     779             :                            fd_instruction_account_t instruction_accounts[ FD_INSTR_ACCT_MAX ],
     780             :                            ulong *                  instruction_accounts_cnt,
     781             :                            fd_pubkey_t const *      signers,
     782             :                            ulong                    signers_cnt );
     783             : 
     784             : /* syscall(a22b9c85) "sol_invoke_signed_c"
     785             :    Dispatch a cross program invocation.  Inputs are in C ABI.
     786             : 
     787             :    FIXME: BELT SAND AND DOCUMENT */
     788             : 
     789             : FD_VM_SYSCALL_DECL( cpi_c );
     790             : 
     791             : /* syscall(d7449092) "sol_invoke_signed_rust"
     792             :    Dispatch a cross program invocation.  Inputs are in Rust ABI.
     793             : 
     794             :    FIXME: BELT SAND AND DOCUMENT */
     795             : 
     796             : FD_VM_SYSCALL_DECL( cpi_rust );
     797             : 
     798             : /* fd_vm_syscall_crypto ***********************************************/
     799             : 
     800             : /* FD_VM_SYSCALL_SOL_ALT_BN128_{ADD,SUB,MUL,PAIRING} specifies the curve operation. */
     801             : 
     802           0 : #define FD_VM_SYSCALL_SOL_ALT_BN128_ADD                 (  0UL) /* add */
     803             : #define FD_VM_SYSCALL_SOL_ALT_BN128_SUB                 (  1UL) /* add inverse */
     804           0 : #define FD_VM_SYSCALL_SOL_ALT_BN128_MUL                 (  2UL) /* scalar mult */
     805           0 : #define FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING             (  3UL) /* pairing */
     806             : 
     807             : /* FD_VM_SYSCALL_SOL_ALT_BN128_{...}COMPRESS specifies the (de)compress operation. */
     808             : 
     809           0 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESS         (  0UL) /* compress point in G1 */
     810           0 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_DECOMPRESS       (  1UL) /* decompress point in G1 */
     811           0 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESS         (  2UL) /* compress point in G2 */
     812           0 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_DECOMPRESS       (  3UL) /* decompress point in G2 */
     813             : 
     814             : /* FD_VM_SYSCALL_SOL_ALT_BN128_{...}_SZ specifies the size of inputs/outputs for the Alt_BN128 curve. */
     815             : 
     816           0 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_SZ               ( 64UL) /* size of a point in G1 */
     817           0 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESSED_SZ    ( 32UL) /* size of a compressed point in G2 */
     818           0 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_SZ               (128UL) /* size of a point in G2 */
     819           0 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESSED_SZ    ( 64UL) /* size of a compressed point in G2 */
     820             : #define FD_VM_SYSCALL_SOL_ALT_BN128_SCALAR_SZ           ( 32UL) /* size of a scalar */
     821           0 : #define FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_INPUT_EL_SZ (192UL) /* size of G1 + G2 */
     822           0 : #define FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_OUTPUT_SZ   ( 32UL) /* size of pairing syscall result, i.e. 0 or 1 as 256-bit int ¯\_(ツ)_/¯ */
     823             : 
     824             : /* syscall(ae0c318b) sol_alt_bn128_group_op computes operations on the Alt_BN128 curve,
     825             :    including point addition in G1, scalar multiplication in G1, and pairing.
     826             :    See SIMD-0129.
     827             : 
     828             :    FIXME: DOCUMENT */
     829             : 
     830             : FD_VM_SYSCALL_DECL( sol_alt_bn128_group_op    );
     831             : 
     832             : /* syscall(334fd5ed) sol_alt_bn128_compression allows to compress or decompress points
     833             :    in G1 or G2 groups over the Alt_BN128 curve.
     834             :    See SIMD-0129.
     835             : 
     836             :    FIXME: DOCUMENT */
     837             : 
     838             : FD_VM_SYSCALL_DECL( sol_alt_bn128_compression );
     839             : 
     840             : /* syscall(174c5122) "sol_blake3"
     841             :    syscall(d7793abb) "sol_keccak256"
     842             :    syscall(11f49d86) "sol_sha256"
     843             : 
     844             :    Inputs:
     845             : 
     846             :      arg0 - slice, ulong pair VM pointer, indexed [0,cnt), FIXME: WHEN IS NULL OKAY?
     847             :      arg1 - cnt, FIXME: IS 0 OKAY?
     848             :      arg2 - hash, byte VM pointer, indexed [0,32)
     849             :      arg3 - ignored
     850             :      arg4 - ignored
     851             : 
     852             :      slice[i] holds the ulong pair:
     853             :        mem, byte vector VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
     854             :        sz, FIXME: IS 0 OKAY?
     855             : 
     856             :    Return:
     857             : 
     858             :      FD_VM_ERR_INVAL: cnt too large.  *_ret unchanged.
     859             : 
     860             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
     861             :      *_ret unchanged. Compute budget decremented.
     862             : 
     863             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for slice, hash and/or
     864             :      slice[i].addr (including slice not 8 byte aligned if the VM has
     865             :      check_align set).  *_ret unchanged.  Compute budget decremented.
     866             : 
     867             :      FD_VM_SUCCESS: success.  *_ret=0 and hash[i] holds the hash of the
     868             :      concatentation of the slices.  Compute budget decremented. */
     869             : 
     870             : FD_VM_SYSCALL_DECL( sol_blake3    );
     871             : FD_VM_SYSCALL_DECL( sol_keccak256 );
     872             : FD_VM_SYSCALL_DECL( sol_sha256    );
     873             : 
     874             : /* syscall(c4947c21) sol_poseidon computes the Poseidon hash on an array of input values.
     875             :    See SIMD-0129.
     876             : 
     877             :    FIXME: DOCUMENT */
     878             : 
     879             : #define FD_VM_SYSCALL_SOL_POSEIDON_MAX_VALS 12UL
     880             : 
     881             : FD_VM_SYSCALL_DECL( sol_poseidon ); /* Light protocol flavor */
     882             : 
     883             : /* syscall(17e40350) "sol_secp256k1_recover"
     884             : 
     885             :    FIXME: BELT SAND AND DOCUMENT */
     886             : 
     887             : FD_VM_SYSCALL_DECL( sol_secp256k1_recover );
     888             : 
     889             : /* fd_vm_syscall_curve ************************************************/
     890             : 
     891             : /* FD_VM_SYSCALL_SOL_CURVE_CURVE25519_{...} specifies the curve ID */
     892             : 
     893           9 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_EDWARDS   ( 0UL) /* ed25519 */
     894          18 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_RISTRETTO ( 1UL) /* ristretto255 */
     895             : 
     896             : /* FD_VM_SYSCALL_SOL_CURVE_{...} specifies the curve operation */
     897             : 
     898           6 : #define FD_VM_SYSCALL_SOL_CURVE_ADD                  ( 0UL) /* add */
     899           3 : #define FD_VM_SYSCALL_SOL_CURVE_SUB                  ( 1UL) /* add inverse */
     900           3 : #define FD_VM_SYSCALL_SOL_CURVE_MUL                  ( 2UL) /* scalar mul */
     901             : 
     902             : /* FD_VM_SYSCALL_SOL_CURVE_CURVE25519_{...}_SZ specifies the size of inputs/outputs. */
     903             : 
     904          24 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ  (32UL) /* point (compressed) */
     905           6 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_SCALAR_SZ (32UL) /* scalar */
     906             : 
     907             : /* syscall(aa2607ca) sol_curve_validate_point
     908             : 
     909             :    FIXME: BELT SAND AND DOCUMENT */
     910             : 
     911             : FD_VM_SYSCALL_DECL( sol_curve_validate_point  );
     912             : 
     913             : /* syscall(dd1c41a6) sol_curve_validate_point
     914             : 
     915             :    FIXME: BELT SAND AND DOCUMENT */
     916             : 
     917             : FD_VM_SYSCALL_DECL( sol_curve_group_op );
     918             : 
     919             : /* syscall(60a40880) sol_curve_validate_point
     920             : 
     921             :    FIXME: BELT SAND AND DOCUMENT */
     922             : 
     923             : FD_VM_SYSCALL_DECL( sol_curve_multiscalar_mul );
     924             : 
     925             : int
     926             : fd_vm_derive_pda( fd_vm_t *           vm,
     927             :                   fd_pubkey_t const * program_id,
     928             :                   void const * *      seed_haddrs,
     929             :                   ulong *             seed_szs,
     930             :                   ulong               seeds_cnt,
     931             :                   uchar *             bump_seed,
     932             :                   fd_pubkey_t *       out );
     933             : 
     934             : int
     935             : fd_vm_translate_and_check_program_address_inputs( fd_vm_t *             vm,
     936             :                                                   ulong                 seeds_vaddr,
     937             :                                                   ulong                 seeds_cnt,
     938             :                                                   ulong                 program_id_vaddr,
     939             :                                                   void const * *        out_seed_haddrs,
     940             :                                                   ulong *               out_seed_szs,
     941             :                                                   fd_pubkey_t const * * out_program_id,
     942             :                                                   uchar                 is_syscall );
     943             : FD_PROTOTYPES_END
     944             : 
     945             : #endif /* HEADER_src_flamenco_vm_syscall_fd_vm_syscall_h */

Generated by: LCOV version 1.14