LCOV - code coverage report
Current view: top level - flamenco/runtime/program - fd_builtin_programs.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 72 81 88.9 %
Date: 2026-03-08 05:35:00 Functions: 9 9 100.0 %

          Line data    Source code
       1             : #include "fd_builtin_programs.h"
       2             : #include "fd_precompiles.h"
       3             : #include "../fd_system_ids.h"
       4             : #include "../fd_system_ids_pp.h"
       5             : #include "../../accdb/fd_accdb_sync.h"
       6             : 
       7             : #define BUILTIN_PROGRAM(program_id, name, feature_offset, migration_config) \
       8             :     {                                                                       \
       9             :         program_id,                                                         \
      10             :         name,                                                               \
      11             :         feature_offset,                                                     \
      12             :         migration_config                                                    \
      13             :     }
      14             : 
      15             : #define STATELESS_BUILTIN(program_id, migration_config) \
      16             :     {                                                   \
      17             :         program_id,                                     \
      18             :         migration_config                                \
      19             :     }
      20             : 
      21             : #define CORE_BPF_MIGRATION_CONFIG(source_buffer_address, upgrade_authority_address, enable_feature_offset, builtin_program_id) \
      22             :     {                                                                                                                          \
      23             :         source_buffer_address,                                                                                                 \
      24             :         upgrade_authority_address,                                                                                             \
      25             :         enable_feature_offset,                                                                                                 \
      26             :         builtin_program_id                                                                                                     \
      27             :     }
      28             : 
      29             : /* Core BPF migration configs */
      30             : static const fd_core_bpf_migration_config_t BUILTIN_TO_CORE_BPF_STAKE_PROGRAM_CONFIG = {
      31             :     &fd_solana_stake_program_buffer_address,
      32             :     NULL,
      33             :     offsetof(fd_features_t, migrate_stake_program_to_core_bpf),
      34             :     FD_CORE_BPF_MIGRATION_TARGET_BUILTIN,
      35             :     &fd_solana_stake_program_id,
      36             :     NULL
      37             : };
      38             : static const fd_core_bpf_migration_config_t * const MIGRATE_BUILTIN_TO_CORE_BPF_STAKE_PROGRAM_CONFIG = &BUILTIN_TO_CORE_BPF_STAKE_PROGRAM_CONFIG;
      39             : 
      40             : static const fd_core_bpf_migration_config_t BUILTIN_TO_CORE_BPF_CONFIG_PROGRAM_CONFIG = {
      41             :     &fd_solana_config_program_buffer_address,
      42             :     NULL,
      43             :     offsetof(fd_features_t, migrate_config_program_to_core_bpf),
      44             :     FD_CORE_BPF_MIGRATION_TARGET_BUILTIN,
      45             :     &fd_solana_config_program_id,
      46             :     NULL
      47             : };
      48             : static const fd_core_bpf_migration_config_t * const MIGRATE_BUILTIN_TO_CORE_BPF_CONFIG_PROGRAM_CONFIG = &BUILTIN_TO_CORE_BPF_CONFIG_PROGRAM_CONFIG;
      49             : 
      50             : static const fd_core_bpf_migration_config_t BUILTIN_TO_CORE_BPF_ADDRESS_LOOKUP_TABLE_PROGRAM_CONFIG = {
      51             :     &fd_solana_address_lookup_table_program_buffer_address,
      52             :     NULL,
      53             :     offsetof(fd_features_t, migrate_address_lookup_table_program_to_core_bpf),
      54             :     FD_CORE_BPF_MIGRATION_TARGET_BUILTIN,
      55             :     &fd_solana_address_lookup_table_program_id,
      56             :     NULL
      57             : };
      58             : static const fd_core_bpf_migration_config_t * const MIGRATE_BUILTIN_TO_CORE_BPF_ADDRESS_LOOKUP_TABLE_PROGRAM_CONFIG = &BUILTIN_TO_CORE_BPF_ADDRESS_LOOKUP_TABLE_PROGRAM_CONFIG;
      59             : 
      60             : static const fd_core_bpf_migration_config_t STATELESS_TO_CORE_BPF_FEATURE_GATE_PROGRAM_CONFIG = {
      61             :     &fd_solana_feature_program_buffer_address,
      62             :     NULL,
      63             :     offsetof(fd_features_t, migrate_feature_gate_program_to_core_bpf),
      64             :     FD_CORE_BPF_MIGRATION_TARGET_STATELESS,
      65             :     &fd_solana_feature_program_id,
      66             :     NULL
      67             : };
      68             : static const fd_core_bpf_migration_config_t * const MIGRATE_STATELESS_TO_CORE_BPF_FEATURE_GATE_PROGRAM_CONFIG = &STATELESS_TO_CORE_BPF_FEATURE_GATE_PROGRAM_CONFIG;
      69             : 
      70             : /* 192ed727334abe822d5accba8b886e25f88b03c76973c2e7290cfb55b9e1115f */
      71             : #define SLASHING_PROG_HASH_SIMD_204 0x19U,0x2eU,0xd7U,0x27U,0x33U,0x4aU,0xbeU,0x82U,0x2dU,0x5aU,0xccU,0xbaU,0x8bU,0x88U,0x6eU,0x25U, \
      72             :                                     0xf8U,0x8bU,0x03U,0xc7U,0x69U,0x73U,0xc2U,0xe7U,0x29U,0x0cU,0xfbU,0x55U,0xb9U,0xe1U,0x11U,0x5fU
      73             : const fd_hash_t fd_solana_slashing_program_verified_build_hash_simd_204 = { .uc = { SLASHING_PROG_HASH_SIMD_204 } };
      74             : static const fd_core_bpf_migration_config_t STATELESS_TO_CORE_BPF_SLASHING_PROGRAM_CONFIG = {
      75             :     &fd_solana_slashing_program_buffer_address,
      76             :     NULL,
      77             :     offsetof(fd_features_t, enshrine_slashing_program),
      78             :     FD_CORE_BPF_MIGRATION_TARGET_STATELESS,
      79             :     &fd_solana_slashing_program_id,
      80             :     &fd_solana_slashing_program_verified_build_hash_simd_204
      81             : };
      82             : static const fd_core_bpf_migration_config_t * const MIGRATE_STATELESS_TO_CORE_BPF_SLASHING_PROGRAM_CONFIG = &STATELESS_TO_CORE_BPF_SLASHING_PROGRAM_CONFIG;
      83             : 
      84             : #define SYSTEM_PROGRAM_BUILTIN                BUILTIN_PROGRAM(&fd_solana_system_program_id,                 "system_program",                        NO_ENABLE_FEATURE_ID,                                      NULL)
      85             : #define VOTE_PROGRAM_BUILTIN                  BUILTIN_PROGRAM(&fd_solana_vote_program_id,                   "vote_program",                          NO_ENABLE_FEATURE_ID,                                      NULL)
      86             : #define STAKE_PROGRAM_BUILTIN                 BUILTIN_PROGRAM(&fd_solana_stake_program_id,                  "stake_program",                         NO_ENABLE_FEATURE_ID,                                      MIGRATE_BUILTIN_TO_CORE_BPF_STAKE_PROGRAM_CONFIG)
      87             : #define CONFIG_PROGRAM_BUILTIN                BUILTIN_PROGRAM(&fd_solana_config_program_id,                 "config_program",                        NO_ENABLE_FEATURE_ID,                                      MIGRATE_BUILTIN_TO_CORE_BPF_CONFIG_PROGRAM_CONFIG)
      88             : #define LOADER_V4_BUILTIN                     BUILTIN_PROGRAM(&fd_solana_bpf_loader_v4_program_id,          "loader_v4",                             offsetof(fd_features_t, enable_loader_v4),                 NULL)
      89             : #define ADDRESS_LOOKUP_TABLE_PROGRAM_BUILTIN  BUILTIN_PROGRAM(&fd_solana_address_lookup_table_program_id,   "address_lookup_table_program",          NO_ENABLE_FEATURE_ID,                                      MIGRATE_BUILTIN_TO_CORE_BPF_ADDRESS_LOOKUP_TABLE_PROGRAM_CONFIG)
      90             : #define BPF_LOADER_DEPRECATED_BUILTIN         BUILTIN_PROGRAM(&fd_solana_bpf_loader_deprecated_program_id,  "solana_bpf_loader_deprecated_program",  NO_ENABLE_FEATURE_ID,                                      NULL)
      91             : #define BPF_LOADER_BUILTIN                    BUILTIN_PROGRAM(&fd_solana_bpf_loader_program_id,             "solana_bpf_loader_program",             NO_ENABLE_FEATURE_ID,                                      NULL)
      92             : #define BPF_LOADER_UPGRADEABLE_BUILTIN        BUILTIN_PROGRAM(&fd_solana_bpf_loader_upgradeable_program_id, "solana_bpf_loader_upgradeable_program", NO_ENABLE_FEATURE_ID,                                      NULL)
      93             : #define COMPUTE_BUDGET_PROGRAM_BUILTIN        BUILTIN_PROGRAM(&fd_solana_compute_budget_program_id,         "compute_budget_program",                NO_ENABLE_FEATURE_ID,                                      NULL)
      94             : #define ZK_TOKEN_PROOF_PROGRAM_BUILTIN        BUILTIN_PROGRAM(&fd_solana_zk_token_proof_program_id,         "zk_token_proof_program",                offsetof(fd_features_t, zk_token_sdk_enabled),             NULL)
      95             : #define ZK_ELGAMAL_PROOF_PROGRAM_BUILTIN      BUILTIN_PROGRAM(&fd_solana_zk_elgamal_proof_program_id,       "zk_elgamal_proof_program",              offsetof(fd_features_t, zk_elgamal_proof_program_enabled), NULL)
      96             : 
      97             : #define FEATURE_PROGRAM_BUILTIN               STATELESS_BUILTIN(&fd_solana_feature_program_id,  MIGRATE_STATELESS_TO_CORE_BPF_FEATURE_GATE_PROGRAM_CONFIG)
      98             : #define SLASHING_PROGRAM_BUILTIN              STATELESS_BUILTIN(&fd_solana_slashing_program_id, MIGRATE_STATELESS_TO_CORE_BPF_SLASHING_PROGRAM_CONFIG)
      99             : 
     100             : /* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/mod.rs#L133-L143 */
     101             : static const fd_stateless_builtin_program_t stateless_programs_builtins[] = {
     102             :     FEATURE_PROGRAM_BUILTIN,
     103             :     SLASHING_PROGRAM_BUILTIN
     104             : };
     105         126 : #define STATELESS_BUILTINS_COUNT (sizeof(stateless_programs_builtins) / sizeof(fd_stateless_builtin_program_t))
     106             : 
     107             : /* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/mod.rs#L34-L131 */
     108             : static fd_builtin_program_t const builtin_programs[] = {
     109             :     SYSTEM_PROGRAM_BUILTIN,
     110             :     VOTE_PROGRAM_BUILTIN,
     111             :     STAKE_PROGRAM_BUILTIN,
     112             :     CONFIG_PROGRAM_BUILTIN,
     113             :     LOADER_V4_BUILTIN,
     114             :     ADDRESS_LOOKUP_TABLE_PROGRAM_BUILTIN,
     115             :     BPF_LOADER_DEPRECATED_BUILTIN,
     116             :     BPF_LOADER_BUILTIN,
     117             :     BPF_LOADER_UPGRADEABLE_BUILTIN,
     118             :     COMPUTE_BUDGET_PROGRAM_BUILTIN,
     119             :     ZK_TOKEN_PROOF_PROGRAM_BUILTIN,
     120             :     ZK_ELGAMAL_PROOF_PROGRAM_BUILTIN
     121             : };
     122        1170 : #define BUILTIN_PROGRAMS_COUNT (sizeof(builtin_programs) / sizeof(fd_builtin_program_t))
     123             : 
     124             : /* Used by the compute budget program to determine how many CUs to deduct by default
     125             :    https://github.com/anza-xyz/agave/blob/v2.1.13/builtins-default-costs/src/lib.rs#L113-L139 */
     126             : static fd_core_bpf_migration_config_t const * migrating_builtins[] = {
     127             :     MIGRATE_BUILTIN_TO_CORE_BPF_STAKE_PROGRAM_CONFIG,
     128             :     MIGRATE_BUILTIN_TO_CORE_BPF_CONFIG_PROGRAM_CONFIG,
     129             :     MIGRATE_BUILTIN_TO_CORE_BPF_ADDRESS_LOOKUP_TABLE_PROGRAM_CONFIG,
     130             : };
     131         348 : #define MIGRATING_BUILTINS_COUNT (sizeof(migrating_builtins) / sizeof(fd_core_bpf_migration_config_t const *))
     132             : 
     133             : /* https://github.com/anza-xyz/agave/blob/v2.1.13/builtins-default-costs/src/lib.rs#L141-L193 */
     134             : #define MAP_PERFECT_NAME fd_non_migrating_builtins_tbl
     135             : #define MAP_PERFECT_LG_TBL_SZ 4
     136             : #define MAP_PERFECT_T fd_pubkey_t
     137          60 : #define MAP_PERFECT_HASH_C 146U
     138             : #define MAP_PERFECT_KEY uc
     139             : #define MAP_PERFECT_KEY_T fd_pubkey_t const *
     140             : #define MAP_PERFECT_ZERO_KEY  (0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0)
     141             : #define MAP_PERFECT_COMPLEX_KEY 1
     142          60 : #define MAP_PERFECT_KEYS_EQUAL(k1,k2) (!memcmp( (k1), (k2), 32UL ))
     143             : 
     144          60 : #define PERFECT_HASH( u ) (((MAP_PERFECT_HASH_C*(u))>>28)&0x0FU)
     145             : 
     146             : #define MAP_PERFECT_HASH_PP( a00,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11,a12,a13,a14,a15, \
     147             :                              a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31) \
     148             :                                           PERFECT_HASH( (a08 | (a09<<8) | (a10<<16) | (a11<<24)) )
     149          60 : #define MAP_PERFECT_HASH_R( ptr ) PERFECT_HASH( fd_uint_load_4( (uchar const *)ptr->uc + 8UL ) )
     150             : 
     151             : #define MAP_PERFECT_0      ( VOTE_PROG_ID            ),
     152             : #define MAP_PERFECT_1      ( SYS_PROG_ID             ),
     153             : #define MAP_PERFECT_2      ( COMPUTE_BUDGET_PROG_ID  ),
     154             : #define MAP_PERFECT_3      ( BPF_UPGRADEABLE_PROG_ID ),
     155             : #define MAP_PERFECT_4      ( BPF_LOADER_1_PROG_ID    ),
     156             : #define MAP_PERFECT_5      ( BPF_LOADER_2_PROG_ID    ),
     157             : #define MAP_PERFECT_6      ( LOADER_V4_PROG_ID       ),
     158             : #define MAP_PERFECT_7      ( KECCAK_SECP_PROG_ID     ),
     159             : #define MAP_PERFECT_8      ( ED25519_SV_PROG_ID      ),
     160             : 
     161             : #include "../../../util/tmpl/fd_map_perfect.c"
     162             : #undef PERFECT_HASH
     163             : 
     164             : // https://github.com/anza-xyz/agave/blob/v2.3.7/runtime/src/bank.rs#L4944
     165             : static int
     166             : fd_builtin_is_bpf( fd_accdb_user_t *         accdb,
     167             :                    fd_funk_txn_xid_t const * xid,
     168         270 :                    fd_pubkey_t const  *      pubkey ) {
     169         270 :   fd_accdb_ro_t ro[1];
     170         270 :   if( !fd_accdb_open_ro( accdb, ro, xid, pubkey ) ) {
     171         270 :     return 0;
     172         270 :   }
     173           0 :   int is_bpf = memcmp( fd_accdb_ref_owner( ro ), &fd_solana_bpf_loader_upgradeable_program_id, sizeof(fd_solana_bpf_loader_upgradeable_program_id) )==0;
     174           0 :   fd_accdb_close_ro( accdb, ro );
     175           0 :   return is_bpf;
     176         270 : }
     177             : 
     178             : 
     179             : /* BuiltIn programs need "bogus" executable accounts to exist.
     180             :    These are loaded and ignored during execution.
     181             : 
     182             :    Bogus accounts are marked as "executable", but their data is a
     183             :    hardcoded ASCII string. */
     184             : 
     185             : /* https://github.com/solana-labs/solana/blob/8f2c8b8388a495d2728909e30460aa40dcc5d733/sdk/src/native_loader.rs#L19 */
     186             : void
     187             : fd_write_builtin_account( fd_bank_t  *              bank,
     188             :                           fd_accdb_user_t *         accdb,
     189             :                           fd_funk_txn_xid_t const * xid,
     190             :                           fd_capture_ctx_t *        capture_ctx,
     191             :                           fd_pubkey_t const         pubkey,
     192             :                           void const *              data,
     193         642 :                           ulong                     sz ) {
     194             : 
     195         642 :   fd_accdb_rw_t rw[1];
     196         642 :   fd_accdb_open_rw( accdb, rw, xid, &pubkey, sz, FD_ACCDB_FLAG_CREATE );
     197             : 
     198         642 :   fd_lthash_value_t prev_hash[1];
     199         642 :   fd_hashes_account_lthash(
     200         642 :     &pubkey,
     201         642 :     rw->meta,
     202         642 :     fd_accdb_ref_data_const( rw->ro ),
     203         642 :     prev_hash );
     204             : 
     205         642 :   fd_accdb_ref_data_set( accdb, rw, data, sz );
     206         642 :   fd_accdb_ref_lamports_set( rw, 1UL );
     207         642 :   fd_accdb_ref_exec_bit_set( rw, 1 );
     208         642 :   fd_accdb_ref_owner_set( rw, &fd_solana_native_loader_id );
     209             : 
     210         642 :   fd_hashes_update_lthash( &pubkey, rw->meta, prev_hash, bank, capture_ctx );
     211         642 :   fd_bank_capitalization_set( bank, fd_bank_capitalization_get( bank ) + 1UL );
     212         642 :   fd_accdb_close_rw( accdb, rw );
     213         642 : }
     214             : 
     215             : void
     216             : fd_builtin_programs_init( fd_bank_t *               bank,
     217             :                           fd_accdb_user_t *         accdb,
     218             :                           fd_funk_txn_xid_t const * xid,
     219          48 :                           fd_capture_ctx_t *        capture_ctx ) {
     220             :   /* https://github.com/anza-xyz/agave/blob/v2.3.7/builtins/src/lib.rs#L52 */
     221          48 :   fd_builtin_program_t const * builtins = fd_builtins();
     222             : 
     223         624 :   for( ulong i=0UL; i<fd_num_builtins(); i++ ) {
     224             :     /** https://github.com/anza-xyz/agave/blob/v2.3.7/runtime/src/bank.rs#L4949 */
     225         576 :     if( fd_bank_slot_get( bank )==0UL && builtins[i].enable_feature_offset==NO_ENABLE_FEATURE_ID && !fd_builtin_is_bpf( accdb, xid, builtins[i].pubkey ) ) {
     226         270 :       fd_write_builtin_account( bank, accdb, xid, capture_ctx, *builtins[i].pubkey, builtins[i].data, strlen( builtins[i].data ) );
     227         306 :     } else if( builtins[i].core_bpf_migration_config && FD_FEATURE_ACTIVE_OFFSET( fd_bank_slot_get( bank ), fd_bank_features_query( bank ), builtins[i].core_bpf_migration_config->enable_feature_offset ) ) {
     228          36 :       continue;
     229         270 :     } else if( builtins[i].enable_feature_offset!=NO_ENABLE_FEATURE_ID && !FD_FEATURE_ACTIVE_OFFSET( fd_bank_slot_get( bank ), fd_bank_features_query( bank ), builtins[i].enable_feature_offset ) ) {
     230          30 :       continue;
     231         240 :     } else {
     232         240 :       fd_write_builtin_account( bank, accdb, xid, capture_ctx, *builtins[i].pubkey, builtins[i].data, strlen(builtins[i].data) );
     233         240 :     }
     234         576 :   }
     235             : 
     236             :   /* Precompiles have empty account data */
     237          48 :   fd_write_builtin_account( bank, accdb, xid, capture_ctx, fd_solana_keccak_secp_256k_program_id, "", 0 );
     238          48 :   fd_write_builtin_account( bank, accdb, xid, capture_ctx, fd_solana_ed25519_sig_verify_program_id, "", 0 );
     239          48 :   if( FD_FEATURE_ACTIVE_BANK( bank, enable_secp256r1_precompile ) ) {
     240          36 :     fd_write_builtin_account( bank, accdb, xid, capture_ctx, fd_solana_secp256r1_program_id, "", 0 );
     241          36 :   }
     242          48 : }
     243             : 
     244             : fd_builtin_program_t const *
     245          90 : fd_builtins( void ) {
     246          90 :   return builtin_programs;
     247          90 : }
     248             : 
     249             : ulong
     250        1170 : fd_num_builtins( void ) {
     251        1170 :   return BUILTIN_PROGRAMS_COUNT;
     252        1170 : }
     253             : 
     254             : fd_stateless_builtin_program_t const *
     255          42 : fd_stateless_builtins( void ) {
     256          42 :   return stateless_programs_builtins;
     257          42 : }
     258             : 
     259             : ulong
     260         126 : fd_num_stateless_builtins( void ) {
     261         126 :   return STATELESS_BUILTINS_COUNT;
     262         126 : }
     263             : 
     264             : uchar
     265             : fd_is_migrating_builtin_program( fd_bank_t const *   bank,
     266             :                                  fd_pubkey_t const * pubkey,
     267          87 :                                  uchar *             migrated_yet ) {
     268          87 :   *migrated_yet = 0;
     269             : 
     270         348 :   for( ulong i=0; i<MIGRATING_BUILTINS_COUNT; i++ ) {
     271         261 :     fd_core_bpf_migration_config_t const * config = migrating_builtins[i];
     272         261 :     if( !memcmp( pubkey->uc, config->builtin_program_id->key, sizeof(fd_pubkey_t) ) ) {
     273           0 :       if( config->enable_feature_offset!=NO_ENABLE_FEATURE_ID &&
     274           0 :         FD_FEATURE_ACTIVE_OFFSET( fd_bank_slot_get( bank ), fd_bank_features_query( bank ), config->enable_feature_offset ) ) {
     275             :         /* The program has been migrated to BPF. */
     276           0 :         *migrated_yet = 1;
     277           0 :       }
     278             : 
     279           0 :       return 1;
     280           0 :     }
     281         261 :   }
     282             : 
     283             :   /* No migration config exists for this program */
     284          87 :   return 0;
     285          87 : }
     286             : 
     287             : FD_FN_PURE uchar
     288          60 : fd_is_non_migrating_builtin_program( fd_pubkey_t const * pubkey ) {
     289          60 :   return !!( fd_non_migrating_builtins_tbl_contains( pubkey ) );
     290          60 : }

Generated by: LCOV version 1.14