LCOV - code coverage report
Current view: top level - flamenco/vm - fd_vm_base.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 93 145 64.1 %
Date: 2026-11-11 12:40:43 Functions: 1 1055 0.1 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_vm_fd_vm_base_h
       2             : #define HEADER_fd_src_flamenco_vm_fd_vm_base_h
       3             : 
       4             : /* FIXME: Headers included from other modules need cleanup.  As it
       5             :    stands, flamenco_base brings in types/custom, types/meta,
       6             :    types/bincode, ballet/base58, ballet/sha256, ballet/sha512,
       7             :    ballet/ed25519, ballet/txnthis also brings in util, flamenco_base,
       8             :    ballet/base58, util and the optional util/net/ipv4 ballet/sha256,
       9             :    most of which is probably not necessary to use this module in a
      10             :    somewhat haphazard fashion (include no-no things that are only
      11             :    available in hosted environments like stdio and stdlib) */
      12             : 
      13             : #include "../fd_flamenco_base.h"
      14             : #include "../../ballet/sbpf/fd_sbpf_loader.h" /* FIXME: functionality needed from here probably should be moved here */
      15             : #include "../features/fd_features.h"
      16             : 
      17             : /* Defines the different VM access types */
      18         431 : #define FD_VM_ACCESS_TYPE_LD (1)
      19         345 : #define FD_VM_ACCESS_TYPE_ST (2)
      20             : 
      21             : /* FD_VM_SUCCESS is zero and returned to indicate that an operation
      22             :    completed successfully.  FD_VM_ERR_* are negative integers and
      23             :    returned to indicate an operation that failed and why. */
      24             : 
      25             : /* "Standard" Firedancer error codes (FIXME: harmonize and consolidate) */
      26             : 
      27      849216 : #define FD_VM_SUCCESS   ( 0) /* success */
      28          77 : #define FD_VM_ERR_INVAL (-1) /* invalid request */
      29           0 : #define FD_VM_ERR_UNSUP (-3) /* unsupported request */
      30           0 : #define FD_VM_ERR_FULL  (-5) /* storage full */
      31           0 : #define FD_VM_ERR_EMPTY (-6) /* nothing to do */
      32           0 : #define FD_VM_ERR_IO    (-7) /* input-output error */
      33             : 
      34             : /* VM exec error codes:  These are only produced by the VM itself. */
      35             : 
      36           0 : #define FD_VM_ERR_SIGFPE      (-18) /* divide by zero */
      37             : 
      38             : /* sBPF validation error codes.  These are only produced by
      39             :    fd_vm_validate.  FIXME: Consider having fd_vm_validate return
      40             :    standard error codes and then provide detail like this through an
      41             :    info arg.  FIXME: Are these exact matches to Solana?  If so, provide
      42             :    link, if not, document and refine name / consolidate further. */
      43             : 
      44          16 : #define FD_VM_ERR_INVALID_OPCODE    (-25) /* detected an invalid opcode */
      45           0 : #define FD_VM_ERR_INVALID_SRC_REG   (-26) /* detected an invalid source register */
      46           0 : #define FD_VM_ERR_INVALID_DST_REG   (-27) /* detected an invalid destination register */
      47           0 : #define FD_VM_ERR_JMP_OUT_OF_BOUNDS (-29) /* detected an out of bounds jump */
      48           6 : #define FD_VM_ERR_JMP_TO_ADDL_IMM   (-30) /* detected a jump to an addl imm */
      49           0 : #define FD_VM_ERR_INVALID_END_IMM   (-31) /* detected an invalid immediate for an endianness conversion instruction */
      50           0 : #define FD_VM_ERR_INCOMPLETE_LDQ    (-32) /* detected an incomplete ldq at program end */
      51           0 : #define FD_VM_ERR_LDQ_NO_ADDL_IMM   (-33) /* detected a ldq without an addl imm following it */
      52           0 : #define FD_VM_ERR_INVALID_REG       (-35) /* detected an invalid register */
      53           0 : #define FD_VM_ERR_BAD_TEXT          (-36) /* detected a bad text section (overflow, outside rodata boundary, etc.,)*/
      54           0 : #define FD_VM_SH_OVERFLOW           (-37) /* detected a shift overflow, equivalent to VeriferError::ShiftWithOverflow */
      55           1 : #define FD_VM_TEXT_SZ_UNALIGNED     (-38) /* detected a text section that is not a multiple of 8 */
      56             : 
      57             : /* Syscall Errors
      58             :    https://github.com/anza-xyz/agave/blob/v2.0.7/programs/bpf_loader/src/syscalls/mod.rs#L81 */
      59             : 
      60           3 : #define FD_VM_SYSCALL_ERR_INVALID_STRING                          (-1)
      61          33 : #define FD_VM_SYSCALL_ERR_ABORT                                   (-2)
      62          18 : #define FD_VM_SYSCALL_ERR_PANIC                                   (-3)
      63           0 : #define FD_VM_SYSCALL_ERR_INVOKE_CONTEXT_BORROW_FAILED            (-4)
      64           0 : #define FD_VM_SYSCALL_ERR_MALFORMED_SIGNER_SEED                   (-5)
      65          80 : #define FD_VM_SYSCALL_ERR_BAD_SEEDS                               (-6)
      66          57 : #define FD_VM_SYSCALL_ERR_PROGRAM_NOT_SUPPORTED                   (-7)
      67         286 : #define FD_VM_SYSCALL_ERR_UNALIGNED_POINTER                       (-8)
      68           8 : #define FD_VM_SYSCALL_ERR_TOO_MANY_SIGNERS                        (-9)
      69           0 : #define FD_VM_SYSCALL_ERR_INSTRUCTION_TOO_LARGE                   (-10)
      70           0 : #define FD_VM_SYSCALL_ERR_TOO_MANY_ACCOUNTS                       (-11)
      71           9 : #define FD_VM_SYSCALL_ERR_COPY_OVERLAPPING                        (-12)
      72           0 : #define FD_VM_SYSCALL_ERR_RETURN_DATA_TOO_LARGE                   (-13)
      73           2 : #define FD_VM_SYSCALL_ERR_TOO_MANY_SLICES                         (-14)
      74          19 : #define FD_VM_SYSCALL_ERR_INVALID_LENGTH                          (-15)
      75           0 : #define FD_VM_SYSCALL_ERR_MAX_INSTRUCTION_DATA_LEN_EXCEEDED       (-16)
      76           0 : #define FD_VM_SYSCALL_ERR_MAX_INSTRUCTION_ACCOUNTS_EXCEEDED       (-17)
      77           0 : #define FD_VM_SYSCALL_ERR_MAX_INSTRUCTION_ACCOUNT_INFOS_EXCEEDED  (-18)
      78          23 : #define FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE                       (-19)
      79         125 : #define FD_VM_SYSCALL_ERR_INVALID_POINTER                         (-20)
      80           0 : #define FD_VM_SYSCALL_ERR_ARITHMETIC_OVERFLOW                     (-21)
      81             : 
      82             : /* These syscall errors are unique to Firedancer and do not have an Agave equivalent. */
      83           0 : #define FD_VM_SYSCALL_ERR_INSTR_ERR                               (-22)
      84        1409 : #define FD_VM_SYSCALL_ERR_INVALID_PDA                             (-23) /* the computed pda was not a valid ed25519 point */
      85        1050 : #define FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED                 (-24) /* compute unit limit exceeded in syscall */
      86         597 : #define FD_VM_SYSCALL_ERR_SEGFAULT                                (-25) /* illegal memory address (e.g. read/write to an address not backed by any memory) in syscall */
      87           0 : #define FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME                         (-26) /* syscall called with vm not running in solana runtime */
      88             : 
      89             : /* Poseidon returns custom errors for some reason */
      90           2 : #define FD_VM_SYSCALL_ERR_POSEIDON_INVALID_PARAMS                 (1)
      91           3 : #define FD_VM_SYSCALL_ERR_POSEIDON_INVALID_ENDIANNESS             (2)
      92             : 
      93             : /* EbpfError
      94             :    https://github.com/anza-xyz/sbpf/blob/main/src/error.rs#L20-L78 */
      95             : 
      96           0 : #define FD_VM_ERR_EBPF_ELF_ERROR                                  (-1)
      97           0 : #define FD_VM_ERR_EBPF_FUNCTION_ALREADY_REGISTERED                (-2)
      98           1 : #define FD_VM_ERR_EBPF_CALL_DEPTH_EXCEEDED                        (-3)
      99           0 : #define FD_VM_ERR_EBPF_EXIT_ROOT_CALL_FRAME                       (-4)
     100        1245 : #define FD_VM_ERR_EBPF_DIVIDE_BY_ZERO                             (-5)
     101           0 : #define FD_VM_ERR_EBPF_DIVIDE_OVERFLOW                            (-6)
     102           1 : #define FD_VM_ERR_EBPF_EXECUTION_OVERRUN                          (-7)
     103          56 : #define FD_VM_ERR_EBPF_CALL_OUTSIDE_TEXT_SEGMENT                  (-8)
     104          32 : #define FD_VM_ERR_EBPF_EXCEEDED_MAX_INSTRUCTIONS                  (-9)
     105           0 : #define FD_VM_ERR_EBPF_JIT_NOT_COMPILED                           (-10)
     106           0 : #define FD_VM_ERR_EBPF_INVALID_MEMORY_REGION                      (-11)
     107         730 : #define FD_VM_ERR_EBPF_ACCESS_VIOLATION                           (-12)
     108          39 : #define FD_VM_ERR_EBPF_STACK_ACCESS_VIOLATION                     (-13)
     109           0 : #define FD_VM_ERR_EBPF_INVALID_INSTRUCTION                        (-14)
     110         124 : #define FD_VM_ERR_EBPF_UNSUPPORTED_INSTRUCTION                    (-15)
     111           0 : #define FD_VM_ERR_EBPF_EXHAUSTED_TEXT_SEGMENT                     (-16)
     112           0 : #define FD_VM_ERR_EBPF_LIBC_INVOCATION_FAILED                     (-17)
     113           0 : #define FD_VM_ERR_EBPF_VERIFIER_ERROR                             (-18)
     114        2651 : #define FD_VM_ERR_EBPF_SYSCALL_ERROR                              (-19)
     115             : 
     116             : 
     117             : FD_PROTOTYPES_BEGIN
     118             : 
     119             : /* fd_vm_strerror converts an FD_VM_SUCCESS / FD_VM_ERR_* code into
     120             :    a human readable cstr.  The lifetime of the returned pointer is
     121             :    infinite.  The returned pointer is always to a non-NULL cstr. */
     122             : 
     123             : FD_FN_CONST char const * fd_vm_strerror( int err );
     124             : 
     125             : FD_PROTOTYPES_END
     126             : 
     127             : /* fd_vm_limits API ***************************************************/
     128             : 
     129             : /* FIXME: pretty good case these actually belong in ballet/sbpf */
     130             : /* FIXME: DOCUMENT THESE / LINK TO SOLANA CODE / ETC */
     131             : 
     132             : /* VM register constants */
     133             : 
     134           0 : #define FD_VM_REG_CNT (11UL)
     135       16098 : #define FD_VM_REG_MAX (16UL) /* Actual number of SBPF instruction src/dst register indices */
     136             : 
     137             : #define FD_VM_SHADOW_REG_CNT (4UL)
     138             : 
     139             : /* VM stack constants */
     140             : 
     141       44850 : #define FD_VM_STACK_FRAME_MAX (64UL)
     142       51453 : #define FD_VM_STACK_FRAME_SZ  FD_VM_STACK_FRAME_SIZE
     143             : #define FD_VM_STACK_GUARD_SZ  (0x1000UL)
     144       40619 : #define FD_VM_STACK_MAX       (FD_VM_STACK_FRAME_MAX*(FD_VM_STACK_FRAME_SZ))
     145             : 
     146             : /* VM heap constants */
     147             : 
     148       64663 : #define FD_VM_HEAP_DEFAULT ( 32UL*1024UL) /* FIXME: SHOULD THIS MATCH FD_VM_HEAP_SIZE LIMIT BELOW? */
     149        7530 : #define FD_VM_HEAP_MAX     (256UL*1024UL)
     150             : 
     151             : /* VM log constants */
     152             : 
     153             : #define FD_VM_LOG_MAX  (10000UL)
     154             : #define FD_VM_LOG_TAIL (128UL)   /* Large enough to cover the worst case syscall log tail clobbering in string parsing */
     155             : 
     156             : /* VM memory map constants
     157             : 
     158             :    The sBPF virtual address space is divided into 4 GiB regions:
     159             : 
     160             :    SBPF V0-V2:
     161             :      region 0  0x000000000  (unmapped)
     162             :      region 1  0x100000000  program (full ELF: rodata + text)
     163             :      region 2  0x200000000  stack
     164             :      region 3  0x300000000  heap
     165             :      region 4  0x400000000  input
     166             : 
     167             :    SBPF V3:
     168             :      region 0  0x000000000  rodata segment (read-only)
     169             :      region 1  0x100000000  (unmapped, bytecode execute-only)
     170             :      region 2  0x200000000  stack
     171             :      region 3  0x300000000  heap
     172             :      region 4  0x400000000  input
     173             : 
     174             :    https://github.com/anza-xyz/sbpf/blob/v0.14.4/src/ebpf.rs#L42-L51 */
     175             : 
     176             : #define FD_VM_LO_REGION    (0UL)
     177       48309 : #define FD_VM_PROG_REGION  (1UL)
     178       70455 : #define FD_VM_STACK_REGION (2UL)
     179       58735 : #define FD_VM_HEAP_REGION  (3UL)
     180     1183549 : #define FD_VM_INPUT_REGION (4UL)
     181     1183598 : #define FD_VM_HIGH_REGION  (5UL)
     182             : 
     183           0 : #define FD_VM_MEM_MAP_RODATA_REGION_START   (0x000000000UL) /* SBPF V3+ only */
     184             : #define FD_VM_MEM_MAP_PROGRAM_REGION_START  (0x100000000UL)
     185       16867 : #define FD_VM_MEM_MAP_STACK_REGION_START    (0x200000000UL)
     186         456 : #define FD_VM_MEM_MAP_HEAP_REGION_START     (0x300000000UL)
     187      813631 : #define FD_VM_MEM_MAP_INPUT_REGION_START    (0x400000000UL)
     188             : #define FD_VM_MEM_MAP_REGION_SZ             (0x0FFFFFFFFUL)
     189             : #define FD_VM_MEM_MAP_REGION_MASK           (~FD_VM_MEM_MAP_REGION_SZ)
     190     1183598 : #define FD_VM_MEM_MAP_REGION_VIRT_ADDR_BITS (32)
     191             : 
     192             : /* VM compute budget.  Note: these names should match exactly the names
     193             :    used in existing Solana validator.  See:
     194             :    https://github.com/anza-xyz/agave/blob/v1.18.5/program-runtime/src/compute_budget.rs#L19
     195             :    https://github.com/anza-xyz/agave/blob/v1.18.5/program-runtime/src/compute_budget.rs#L133 */
     196             : /* FIXME: DOUBLE CHECK THESE */
     197             : 
     198             : /* FD_VM_COMPUTE_UNIT_LIMIT is the number of compute units that a
     199             :    transaction or individual instruction is allowed to consume.  Compute
     200             :    units are consumed by program execution, resources they use, etc ... */
     201             : 
     202           0 : #define FD_VM_COMPUTE_UNIT_LIMIT                        (         1400000UL)
     203             : 
     204             : /* FD_VM_LOG_64_UNITS is the number of compute units consumed by a
     205             :    log_64 call */
     206             : 
     207             : #define FD_VM_LOG_64_UNITS                              (             100UL)
     208             : 
     209             : /* FD_VM_CREATE_PROGRAM_ADDRESS_UNITS is the number of compute units
     210             :    consumed by a create_program_address call and a try_find_program_address_call */
     211             : 
     212             : #define FD_VM_CREATE_PROGRAM_ADDRESS_UNITS              (            1500UL)
     213             : 
     214             : /* FD_VM_INVOKE_UNITS is the number of compute units consumed by an
     215             :    invoke call (not including the cost incurred by the called program)
     216             :    https://github.com/anza-xyz/agave/blob/v3.1.2/program-runtime/src/execution_budget.rs#L22-L23 */
     217        2149 : #define FD_VM_INVOKE_UNITS                              (             946UL)
     218             : 
     219             : /* SIMD-0339 uses a fixed size (80 bytes) to bill each account info:
     220             :    - 32 bytes for account address
     221             :    - 32 bytes for owner address
     222             :    - 8 bytes for lamports
     223             :    - 8 bytes for data length
     224             :    https://github.com/anza-xyz/agave/blob/v3.1.2/program-runtime/src/cpi.rs#L63-L68
     225             :  */
     226        1332 : #define FD_VM_ACCOUNT_INFO_BYTE_SIZE                     (             80UL)
     227             : 
     228             : /* FD_VM_MAX_INVOKE_STACK_HEIGHT is the maximum program instruction
     229             :    invocation stack height. Invocation stack height starts at 1 for
     230             :    transaction instructions and the stack height is incremented each
     231             :    time a program invokes an instruction and decremented when a program
     232             :    returns */
     233             : 
     234             : #define FD_VM_MAX_INVOKE_STACK_HEIGHT                   (               5UL)
     235             : 
     236             : /* FD_VM_MAX_INSTRUCTION_TRACE_LENGTH is the maximum cross-program
     237             :    invocation and instructions per transaction */
     238             : 
     239             : #define FD_VM_MAX_INSTRUCTION_TRACE_LENGTH              (              64UL)
     240             : 
     241             : /* FD_VM_SHA256_BASE_COST is the base number of compute units consumed
     242             :    to call SHA256 */
     243             : 
     244         558 : #define FD_VM_SHA256_BASE_COST                          (              85UL)
     245             : 
     246             : /* FD_VM_SHA256_BYTE_COST is the incremental number of units consumed by
     247             :    SHA256 (based on bytes) */
     248             : 
     249        6654 : #define FD_VM_SHA256_BYTE_COST                          (               1UL)
     250             : 
     251             : /* FD_VM_SHA256_MAX_SLICES is the maximum number of slices hashed per
     252             :    syscall */
     253             : 
     254           2 : #define FD_VM_SHA256_MAX_SLICES                         (           20000UL)
     255             : 
     256             : /* FD_VM_MAX_CALL_DEPTH is the maximum SBF to BPF call depth */
     257             : 
     258         347 : #define FD_VM_MAX_CALL_DEPTH                            (              64UL)
     259             : 
     260             : /* FD_VM_STACK_FRAME_SIZE is the size of a stack frame in bytes, must
     261             :    match the size specified in the LLVM SBF backend */
     262             : 
     263       51453 : #define FD_VM_STACK_FRAME_SIZE                          (            4096UL)
     264             : 
     265             : /* FD_VM_LOG_PUBKEY_UNITS is the number of compute units consumed by
     266             :    logging a `Pubkey` */
     267             : 
     268             : #define FD_VM_LOG_PUBKEY_UNITS                          (             100UL)
     269             : 
     270             : /* FD_VM_MAX_CPI_INSTRUCTION_SIZE is the maximum cross-program
     271             :    invocation instruction size */
     272             : 
     273             : #define FD_VM_MAX_CPI_INSTRUCTION_SIZE                  (            1280UL) /* IPv6 Min MTU size */
     274             : 
     275             : /* FD_VM_CPI_BYTES_PER_UNIT is the number of account data bytes per
     276             :    compute unit charged during a cross-program invocation */
     277             : 
     278        4364 : #define FD_VM_CPI_BYTES_PER_UNIT                        (             250UL) /* ~50MB at 200,000 units */
     279             : 
     280             : /* FD_VM_SYSVAR_BASE_COST is the base number of compute units consumed
     281             :    to get a sysvar */
     282             : 
     283             : #define FD_VM_SYSVAR_BASE_COST                          (             100UL)
     284             : 
     285             : /* FD_VM_SECP256K1_RECOVER_COST is the number of compute units consumed
     286             :    to call secp256k1_recover */
     287             : 
     288             : #define FD_VM_SECP256K1_RECOVER_COST                    (           25000UL)
     289             : 
     290             : /* FD_VM_SYSCALL_BASE_COST is the number of compute units consumed to do
     291             :    a syscall without any work */
     292             : 
     293        1212 : #define FD_VM_SYSCALL_BASE_COST                         (             100UL)
     294             : 
     295             : /* FD_VM_CURVE_EDWARDS_VALIDATE_POINT_COST is the number of compute
     296             :    units consumed to validate a curve25519 edwards point */
     297             : 
     298             : #define FD_VM_CURVE_EDWARDS_VALIDATE_POINT_COST    (             159UL)
     299             : 
     300             : /* FD_VM_CURVE_EDWARDS_ADD_COST is the number of compute units
     301             :    consumed to add two curve25519 edwards points */
     302             : 
     303          61 : #define FD_VM_CURVE_EDWARDS_ADD_COST               (             473UL)
     304             : 
     305             : /* FD_VM_CURVE_EDWARDS_SUBTRACT_COST is the number of compute units
     306             :    consumed to subtract two curve25519 edwards points */
     307             : 
     308          53 : #define FD_VM_CURVE_EDWARDS_SUBTRACT_COST          (             475UL)
     309             : 
     310             : /* FD_VM_CURVE_EDWARDS_MULTIPLY_COST is the number of compute units
     311             :    consumed to multiply a curve25519 edwards point */
     312             : 
     313          87 : #define FD_VM_CURVE_EDWARDS_MULTIPLY_COST          (            2177UL)
     314             : 
     315             : /* FD_VM_CURVE_EDWARDS_MSM_BASE_COST is the number of compute units
     316             :    consumed for a multiscalar multiplication (msm) of edwards points.
     317             :    The total cost is calculated as
     318             :      `msm_base_cost + (length - 1) * msm_incremental_cost` */
     319             : 
     320         224 : #define FD_VM_CURVE_EDWARDS_MSM_BASE_COST          (            2273UL)
     321             : 
     322             : /* FD_VM_CURVE_EDWARDS_MSM_INCREMENTAL_COST is the number of
     323             :    compute units consumed for a multiscalar multiplication (msm) of
     324             :    edwards points.  The total cost is calculated as
     325             :      `msm_base_cost + (length - 1) * msm_incremental_cost` */
     326             : 
     327         224 : #define FD_VM_CURVE_EDWARDS_MSM_INCREMENTAL_COST   (             758UL)
     328             : 
     329             : /* FD_VM_CURVE_RISTRETTO_VALIDATE_POINT_COST is the number of
     330             :    compute units consumed to validate a curve25519 ristretto point */
     331             : 
     332             : #define FD_VM_CURVE_RISTRETTO_VALIDATE_POINT_COST  (             169UL)
     333             : 
     334             : /* FD_VM_CURVE_RISTRETTO_ADD_COST is the number of compute units
     335             :    consumed to add two curve25519 ristretto points */
     336             : 
     337          48 : #define FD_VM_CURVE_RISTRETTO_ADD_COST             (             521UL)
     338             : 
     339             : /* FD_VM_CURVE_RISTRETTO_SUBTRACT_COST is the number of compute
     340             :    units consumed to subtract two curve25519 ristretto points */
     341             : 
     342          54 : #define FD_VM_CURVE_RISTRETTO_SUBTRACT_COST        (             519UL)
     343             : 
     344             : /* FD_VM_CURVE_RISTRETTO_MULTIPLY_COST is the number of compute
     345             :    units consumed to multiply a curve25519 ristretto point */
     346             : 
     347          66 : #define FD_VM_CURVE_RISTRETTO_MULTIPLY_COST        (            2208UL)
     348             : 
     349             : /* FD_VM_CURVE_RISTRETTO_MSM_BASE_COST is the number of compute
     350             :    units consumed for a multiscalar multiplication (msm) of ristretto
     351             :    points.  The total cost is calculated as
     352             :      `msm_base_cost + (length - 1) * msm_incremental_cost` */
     353             : 
     354         235 : #define FD_VM_CURVE_RISTRETTO_MSM_BASE_COST        (            2303UL)
     355             : 
     356             : /* FD_VM_CURVE_RISTRETTO_MSM_INCREMENTAL_COST is the number of
     357             :    compute units consumed for a multiscalar multiplication (msm) of
     358             :    ristretto points.  The total cost is calculated as
     359             :      `msm_base_cost + (length - 1) * msm_incremental_cost` */
     360             : 
     361         235 : #define FD_VM_CURVE_RISTRETTO_MSM_INCREMENTAL_COST (             788UL)
     362             : 
     363             : /* FD_VM_CURVE_BLS12_381_G1_ADD_COST is the number of compute
     364             :    units consumed for addition in BLS12-381 G1. */
     365             : 
     366          41 : #define FD_VM_CURVE_BLS12_381_G1_ADD_COST          (             128UL)
     367             : 
     368             : /* FD_VM_CURVE_BLS12_381_G2_ADD_COST is the number of compute
     369             :    units consumed for addition in BLS12-381 G2. */
     370             : 
     371          44 : #define FD_VM_CURVE_BLS12_381_G2_ADD_COST          (             203UL)
     372             : 
     373             : /* FD_VM_CURVE_BLS12_381_G1_SUB_COST is the number of compute
     374             :    units consumed for subtraction in BLS12-381 G1. */
     375             : 
     376          49 : #define FD_VM_CURVE_BLS12_381_G1_SUB_COST          (             129UL)
     377             : 
     378             : /* FD_VM_CURVE_BLS12_381_G2_SUB_COST is the number of compute
     379             :    units consumed for subtraction in BLS12-381 G2. */
     380             : 
     381          41 : #define FD_VM_CURVE_BLS12_381_G2_SUB_COST          (             204UL)
     382             : 
     383             : /* FD_VM_CURVE_BLS12_381_G1_MUL_COST is the number of compute
     384             :    units consumed for multiplication in BLS12-381 G1. */
     385             : 
     386          47 : #define FD_VM_CURVE_BLS12_381_G1_MUL_COST          (            4627UL)
     387             : 
     388             : /* FD_VM_CURVE_BLS12_381_G2_MUL_COST is the number of compute
     389             :    units consumed for multiplication in BLS12-381 G2. */
     390             : 
     391          48 : #define FD_VM_CURVE_BLS12_381_G2_MUL_COST          (            8255UL)
     392             : 
     393             : /* FD_VM_CURVE_BLS12_381_G1_DECOMPRESS_COST is the number of compute
     394             :    units consumed for point decompression in BLS12-381 G1. */
     395             : #define FD_VM_CURVE_BLS12_381_G1_DECOMPRESS_COST   (            2100UL)
     396             : 
     397             : /* FD_VM_CURVE_BLS12_381_G2_DECOMPRESS_COST is the number of compute
     398             :    units consumed for point decompression in BLS12-381 G2. */
     399             : 
     400             : #define FD_VM_CURVE_BLS12_381_G2_DECOMPRESS_COST   (            3050UL)
     401             : 
     402             : /* FD_VM_CURVE_BLS12_381_G1_VALIDATE_COST is the number of compute
     403             :    units consumed for point validation in BLS12-381 G1. */
     404             : 
     405             : #define FD_VM_CURVE_BLS12_381_G1_VALIDATE_COST     (            1565UL)
     406             : 
     407             : /* FD_VM_CURVE_BLS12_381_G2_VALIDATE_COST is the number of compute
     408             :    units consumed for point validation in BLS12-381 G2. */
     409             : 
     410             : #define FD_VM_CURVE_BLS12_381_G2_VALIDATE_COST     (            1968UL)
     411             : 
     412             : /* FD_VM_CURVE_BLS12_381_PAIRING_*_COST are the number of compute
     413             :    units consumed for calculating a pairing map in BLS12-381.
     414             :    The total cost is calculated as
     415             :      `pairing_base_cost + (length-1) * pairing_incr_cost` */
     416             : 
     417         138 : #define FD_VM_CURVE_BLS12_381_PAIRING_BASE_COST    (           25445UL)
     418         138 : #define FD_VM_CURVE_BLS12_381_PAIRING_INCR_COST    (           13023UL)
     419             : 
     420             : /* FD_VM_CURVE_SECP256R1_ADD_COST is the number of compute units
     421             :    consumed for addition in secp256r1. */
     422             : 
     423           0 : #define FD_VM_CURVE_SECP256R1_ADD_COST             (             520UL)
     424             : 
     425             : /* FD_VM_CURVE_SECP256R1_SUB_COST is the number of compute units
     426             :    consumed for subtraction in secp256r1. */
     427             : 
     428           0 : #define FD_VM_CURVE_SECP256R1_SUB_COST             (             520UL)
     429             : 
     430             : /* FD_VM_CURVE_SECP256R1_MUL_COST is the number of compute units
     431             :    consumed for scalar multiplication in secp256r1. */
     432             : 
     433           0 : #define FD_VM_CURVE_SECP256R1_MUL_COST             (            9000UL)
     434             : 
     435             : /* FD_VM_CURVE_SECP256R1_MSM_*_COST are the number of compute units
     436             :    consumed for multiscalar multiplication in secp256r1.
     437             :    The total cost is calculated as
     438             :      `msm_base_cost + (length-1) * msm_incremental_cost` */
     439             : 
     440           0 : #define FD_VM_CURVE_SECP256R1_MSM_BASE_COST        (            9000UL)
     441           0 : #define FD_VM_CURVE_SECP256R1_MSM_INCREMENTAL_COST (            3800UL)
     442             : 
     443             : /* FD_VM_CURVE_SECP256R1_VALIDATE_COST is the number of compute units
     444             :    consumed for point validation in secp256r1. */
     445             : 
     446             : #define FD_VM_CURVE_SECP256R1_VALIDATE_COST        (              20UL)
     447             : 
     448             : /* FD_VM_CURVE_SECP256R1_DECOMPRESS_COST is the number of compute
     449             :    units consumed for point decompression in secp256r1. */
     450             : 
     451             : #define FD_VM_CURVE_SECP256R1_DECOMPRESS_COST      (             610UL)
     452             : 
     453             : /* FD_VM_HEAP_SIZE is the program heap region size, default:
     454             :    solana_sdk::entrypoint::HEAP_LENGTH */
     455             : 
     456             : #define FD_VM_HEAP_SIZE                                 (           32768UL)
     457             : 
     458             : /* FD_VM_HEAP_COST is the number of compute units per additional 32k
     459             :    heap above the default (~.5 us per 32k at 15 units/us rounded up) */
     460             : 
     461       11366 : #define FD_VM_HEAP_COST                                 (               8UL) /* DEFAULT_HEAP_COST */
     462             : 
     463             : /* FD_VM_MEM_OP_BASE_COST is the memory operation syscall base cost */
     464             : 
     465        6654 : #define FD_VM_MEM_OP_BASE_COST                          (              10UL)
     466             : 
     467             : /* FD_VM_ALT_BN128_ADDITION_COST is the number of compute units consumed
     468             :    to call alt_bn128_addition */
     469             : 
     470          95 : #define FD_VM_ALT_BN128_G1_ADDITION_COST                (             334UL)
     471          64 : #define FD_VM_ALT_BN128_G2_ADDITION_COST                (             535UL)
     472             : 
     473             : /* FD_VM_ALT_BN128_MULTIPLICATION_COST is the number of compute units
     474             :    consumed to call alt_bn128_multiplication */
     475             : 
     476        1853 : #define FD_VM_ALT_BN128_G1_MULTIPLICATION_COST          (            3840UL)
     477          54 : #define FD_VM_ALT_BN128_G2_MULTIPLICATION_COST          (           15670UL)
     478             : 
     479             : /* FD_VM_ALT_BN128_PAIRING_ONE_PAIR_COST_FIRST
     480             :    FD_VM_ALT_BN128_PAIRING_ONE_PAIR_COST_OTHER give the total cost as
     481             :      alt_bn128_pairing_one_pair_cost_first + alt_bn128_pairing_one_pair_cost_other * (num_elems - 1) */
     482             : 
     483         558 : #define FD_VM_ALT_BN128_PAIRING_ONE_PAIR_COST_FIRST     (           36364UL)
     484         558 : #define FD_VM_ALT_BN128_PAIRING_ONE_PAIR_COST_OTHER     (           12121UL)
     485             : 
     486             : /* FD_VM_BIG_MODULAR_EXPONENTIATION_COST is the big integer modular
     487             :    exponentiation cost */
     488             : 
     489             : #define FD_VM_BIG_MODULAR_EXPONENTIATION_COST           (              33UL)
     490             : 
     491             : /* FD_VM_POSEIDON_COST_COEFFICIENT_A is the coefficient `a` of the
     492             :    quadratic function which determines the number of compute units
     493             :    consumed to call poseidon syscall for a given number of inputs */
     494             : 
     495         282 : #define FD_VM_POSEIDON_COST_COEFFICIENT_A               (              61UL)
     496             : 
     497             : /* FD_VM_POSEIDON_COST_COEFFICIENT_C is the coefficient `c` of the
     498             :    quadratic function which determines the number of compute units
     499             :    consumed to call poseidon syscall for a given number of inputs */
     500             : 
     501         282 : #define FD_VM_POSEIDON_COST_COEFFICIENT_C               (             542UL)
     502             : 
     503             : /* FD_VM_GET_REMAINING_COMPUTE_UNITS_COST is the number of compute units
     504             :    consumed for reading the remaining compute units */
     505             : 
     506             : #define FD_VM_GET_REMAINING_COMPUTE_UNITS_COST          (             100UL)
     507             : 
     508             : /* FD_VM_ALT_BN128_G1_COMPRESS is the number of compute units consumed
     509             :    to call alt_bn128_g1_compress */
     510             : 
     511         274 : #define FD_VM_ALT_BN128_G1_COMPRESS                     (              30UL)
     512             : 
     513             : /* FD_VM_ALT_BN128_G1_DECOMPRESS is the number of compute units consumed
     514             :    to call alt_bn128_g1_decompress */
     515             : 
     516         269 : #define FD_VM_ALT_BN128_G1_DECOMPRESS                   (             398UL)
     517             : 
     518             : /* FD_VM_ALT_BN128_G2_COMPRESS is the number of compute units consumed
     519             :    to call alt_bn128_g2_compress */
     520             : 
     521         331 : #define FD_VM_ALT_BN128_G2_COMPRESS                     (              86UL)
     522             : 
     523             : /* FD_VM_ALT_BN128_G2_DECOMPRESS is the number of compute units consumed
     524             :    to call alt_bn128_g2_decompress */
     525             : 
     526         340 : #define FD_VM_ALT_BN128_G2_DECOMPRESS                   (           13610UL)
     527             : 
     528             : /* FD_VM_LOADED_ACCOUNTS_DATA_SIZE_LIMIT is the maximum accounts data
     529             :    size, in bytes, that a transaction is allowed to load */
     530             : 
     531       64940 : #define FD_VM_LOADED_ACCOUNTS_DATA_SIZE_LIMIT           (64UL*1024UL*1024UL) /* 64MiB */
     532             : 
     533             : /* fd_vm_trace API ****************************************************/
     534             : 
     535             : /* FIXME: pretty good case this actually belongs in ballet/sbpf */
     536             : 
     537             : struct fd_vm_trace_event_exe {
     538             :   /* This point is aligned 8 */
     539             :   ulong multiword;            /* 1 if multiword, 0 otherwise */
     540             :   ulong pc;                   /* pc */
     541             :   ulong ic;                   /* ic */
     542             :   ulong cu;                   /* cu */
     543             :   ulong ic_correction;        /* ic_correction */
     544             :   ulong frame_cnt;            /* frame_cnt */
     545             :   ulong reg[ FD_VM_REG_CNT ]; /* registers */
     546             :   ulong text[ 2 ];            /* If !multiword, text[1] is omitted */
     547             :   /* This point is aligned 8 */
     548             : };
     549             : 
     550             : typedef struct fd_vm_trace_event_exe fd_vm_trace_event_exe_t;
     551             : 
     552           0 : #define FD_VM_TRACE_MAGIC (0xfdc377ace3a61c01UL) /* FD VM TRACE MAGIC version 1 */
     553             : 
     554             : struct fd_vm_trace {
     555             :   /* This point is aligned 8 */
     556             :   ulong magic;          /* ==FD_VM_TRACE_MAGIC */
     557             :   ulong event_max;      /* Number bytes of event storage */
     558             :   ulong event_sz;       /* Used bytes of event storage */
     559             :   /* This point is aligned 8
     560             :      event_max bytes storage
     561             :      padding to aligned 8 */
     562             : };
     563             : 
     564             : typedef struct fd_vm_trace fd_vm_trace_t;
     565             : 
     566             : FD_PROTOTYPES_BEGIN
     567             : 
     568             : /* trace object structors */
     569             : /* FIXME: DOCUMENT (USUAL CONVENTIONS) */
     570             : 
     571             : FD_FN_CONST ulong
     572             : fd_vm_trace_align( void );
     573             : 
     574             : FD_FN_CONST ulong
     575             : fd_vm_trace_footprint( ulong event_max ); /* Maximum amount of event storage (<=1 EiB) */
     576             : 
     577             : void *
     578             : fd_vm_trace_new( void * shmem,
     579             :                  ulong  event_max );
     580             : 
     581             : fd_vm_trace_t *
     582             : fd_vm_trace_join( void * _trace );
     583             : 
     584             : void *
     585             : fd_vm_trace_leave( fd_vm_trace_t * trace );
     586             : 
     587             : void *
     588             : fd_vm_trace_delete( void * _trace );
     589             : 
     590             : /* Given a current local join, fd_vm_trace_event returns the location in
     591             :    the caller's address space where trace events are stored and
     592             :    fd_vm_trace_event_sz returns number of bytes of trace events stored
     593             :    at that location.  event_max is the number of bytes of event storage
     594             :    (value used to construct the trace).  event will be aligned 8 and
     595             :    event_sz will be a multiple of 8 in [0,event_max].  The lifetime of
     596             :    the returned pointer is the lifetime of the current join.  Events are
     597             :    fd_vm_trace_event_exe_t, with text[1] omitted if !multiword. */
     598             : 
     599           0 : FD_FN_CONST static inline void const * fd_vm_trace_event    ( fd_vm_trace_t const * trace ) { return (void *)(trace+1); }
     600           0 : FD_FN_CONST static inline ulong        fd_vm_trace_event_sz ( fd_vm_trace_t const * trace ) { return trace->event_sz;   }
     601           0 : FD_FN_CONST static inline ulong        fd_vm_trace_event_max( fd_vm_trace_t const * trace ) { return trace->event_max;  }
     602             : 
     603             : /* fd_vm_trace_reset frees all events in the trace.  Returns
     604             :    FD_VM_SUCCESS (0) on success or FD_VM_ERR code (negative) on failure.
     605             :    Reasons for failure include NULL trace. */
     606             : 
     607             : static inline int
     608           0 : fd_vm_trace_reset( fd_vm_trace_t * trace ) {
     609           0 :   if( FD_UNLIKELY( !trace ) ) return FD_VM_ERR_INVAL;
     610           0 :   trace->event_sz = 0UL;
     611           0 :   return FD_VM_SUCCESS;
     612           0 : }
     613             : 
     614             : /* fd_vm_trace_event_exe records the current pc, ic, cu and
     615             :    register file of the VM and the instruction about to execute.  Text
     616             :    points to the first word of the instruction about to execute and
     617             :    text_cnt points to the number of words available at that point.
     618             :    Returns FD_VM_SUCCESS (0) on success and a FD_VM_ERR code (negative)
     619             :    on failure.  Reasons for failure include INVAL (trace NULL, reg NULL,
     620             :    text NULL, and/or text_cnt 0) and FULL (insufficient trace event
     621             :    storage available). */
     622             : 
     623             : int
     624             : fd_vm_trace_event_exe( fd_vm_trace_t * trace,
     625             :                        ulong           pc,
     626             :                        ulong           ic,
     627             :                        ulong           cu,
     628             :                        ulong           reg[ FD_VM_REG_CNT ],
     629             :                        ulong const *   text,       /* Indexed [0,text_cnt) */
     630             :                        ulong           text_cnt,
     631             :                        ulong           ic_correction,
     632             :                        ulong           frame_cnt );
     633             : 
     634             : /* fd_vm_trace_printf pretty prints the current trace to stdout.
     635             :    Returns FD_VM_SUCCESS (0) on success and a FD_VM_ERR code (negative) on failure.  Reasons for
     636             :    failure include INVAL (NULL trace) and IO (corruption detected while
     637             :    parsing the trace events).  FIXME: REVAMP THIS API FOR MORE GENERAL
     638             :    USE CASES. */
     639             : 
     640             : int
     641             : fd_vm_trace_printf( fd_vm_trace_t const * trace );
     642             : 
     643             : /* fd_vm_syscall API **************************************************/
     644             : 
     645             : /* FIXME: fd_sbpf_syscalls_t and fd_sbpf_syscall_func_t probably should
     646             :    be moved from ballet/sbpf to here. */
     647             : 
     648             : /* Note: the syscall map is kept separate from the fd_vm_t itself to
     649             :    support, for example, multiple fd_vm_t executing transactions
     650             :    concurrently for a slot.  They could use the same syscalls for setup,
     651             :    memory and cache efficiency. */
     652             : 
     653             : /* fd_vm_syscall_register inserts the syscall with the given cstr name
     654             :    into the given syscalls.  The VM syscall implementation to use is
     655             :    given by func (NULL is fine though a VM itself may not accept such as
     656             :    valid).  The caller promises there is room in the syscall map.
     657             :    Returns FD_VM_SUCCESS (0) on success or a FD_VM_ERR code (negative)
     658             :    on failure.  Reasons for failure include INVAL (NULL syscalls, NULL
     659             :    name, name or the hash of name already in the map).  On success,
     660             :    syscalls retains a read-only interest in name (e.g. use an infinite
     661             :    lifetime cstr here).  (This function is exposed to allow VM users to
     662             :    add custom syscalls but most use cases probably should just call
     663             :    fd_vm_syscall_register_slot below.)
     664             : 
     665             :    IMPORTANT SAFETY TIP!  See notes in syscall/fd_vm_syscall.h on what a
     666             :    syscall should expect to see and what to return. */
     667             : 
     668             : int
     669             : fd_vm_syscall_register( fd_sbpf_syscalls_t *   syscalls,
     670             :                         char const *           name,
     671             :                         fd_sbpf_syscall_func_t func );
     672             : 
     673             : /* fd_vm_syscall_register_slot unmaps all syscalls in the current map
     674             :    (also ending any interest in the corresponding name cstr) and
     675             :    registers all syscalls appropriate for the slot.  Returns
     676             :    FD_VM_SUCCESS (0) on success and FD_VM_ERR code (negative) on
     677             :    failure.  Reasons for failure include INVAL (NULL syscalls) and FULL
     678             :    (tried to register too many system calls ... compile time map size
     679             :    needs to be adjusted).
     680             : 
     681             :    If features is NULL, slot is ignored and all feature-gated syscalls
     682             :    are registered.
     683             : 
     684             :    is_deploy should be 1 if the set of syscalls registered should be that
     685             :    used to verify programs before they are deployed, and 0 if it
     686             :    should be the set used to execute programs. */
     687             : 
     688             : int
     689             : fd_vm_syscall_register_slot( fd_sbpf_syscalls_t *  syscalls,
     690             :                              ulong                 slot,
     691             :                              fd_features_t const * features,
     692             :                              uchar                 is_deploy );
     693             : 
     694             : /* fd_vm_syscall_register_all is a shorthand for registering all
     695             :    syscalls (see register slot). */
     696             : 
     697             : static inline int
     698        7467 : fd_vm_syscall_register_all( fd_sbpf_syscalls_t * syscalls, uchar is_deploy ) {
     699        7467 :   return fd_vm_syscall_register_slot( syscalls, 0UL, NULL, is_deploy );
     700        7467 : }
     701             : 
     702             : FD_PROTOTYPES_END
     703             : 
     704             : #endif /* HEADER_fd_src_flamenco_vm_fd_vm_base_h */

Generated by: LCOV version 1.14