Line data Source code
1 : #include "fd_prog_load.h" 2 : #include "../runtime/program/fd_bpf_loader_program.h" 3 : #include "../runtime/sysvar/fd_sysvar_epoch_schedule.h" 4 : #include "../runtime/fd_system_ids.h" 5 : #include "../../ballet/sbpf/fd_sbpf_loader.h" 6 : 7 : static fd_prog_info_t * 8 : fd_prog_info_v3( fd_prog_info_t * out, 9 965 : fd_acc_t const * ro ) { 10 965 : if( FD_UNLIKELY( ro->data_len<PROGRAMDATA_METADATA_SIZE ) ) { 11 0 : FD_LOG_WARNING(( "program data account is too small" )); 12 0 : return NULL; 13 0 : } 14 965 : fd_bpf_state_t state; 15 965 : if( FD_UNLIKELY( fd_bpf_state_decode( &state, ro->data, ro->data_len ) ) ) { 16 0 : FD_LOG_WARNING(( "program data account is invalid" )); 17 0 : return NULL; 18 0 : } 19 965 : if( FD_UNLIKELY( state.discriminant!=FD_BPF_STATE_PROGRAM_DATA ) ) { 20 0 : FD_LOG_WARNING(( "loader v3 account is not a program data account" )); 21 0 : return NULL; 22 0 : } 23 : 24 965 : *out = (fd_prog_info_t) { 25 965 : .elf_off = PROGRAMDATA_METADATA_SIZE, 26 965 : .elf_sz = ro->data_len - PROGRAMDATA_METADATA_SIZE, 27 965 : .deploy_slot = state.inner.program_data.slot 28 965 : }; 29 965 : return out; 30 965 : } 31 : 32 : static fd_prog_info_t * 33 : fd_prog_info_v1( fd_prog_info_t * out, 34 3835 : fd_acc_t const * acc ) { 35 3835 : *out = (fd_prog_info_t) { 36 3835 : .elf_off = 0UL, 37 3835 : .elf_sz = acc->data_len, 38 3835 : .deploy_slot = 0UL 39 3835 : }; 40 3835 : return out; 41 3835 : } 42 : 43 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.5/svm/src/program_loader.rs#L29 */ 44 : fd_prog_info_t * 45 : fd_prog_info( fd_prog_info_t * out, 46 4800 : fd_acc_t const * acc ){ 47 4800 : fd_pubkey_t const * program_owner = (fd_pubkey_t const*)acc->owner; 48 4800 : if( fd_pubkey_eq( program_owner, &fd_solana_bpf_loader_upgradeable_program_id ) ) { 49 965 : return fd_prog_info_v3( out, acc ); 50 3835 : } else if( fd_pubkey_eq( program_owner, &fd_solana_bpf_loader_program_id ) || 51 3835 : fd_pubkey_eq( program_owner, &fd_solana_bpf_loader_deprecated_program_id ) ) { 52 3835 : return fd_prog_info_v1( out, acc ); 53 3835 : } else { 54 0 : FD_BASE58_ENCODE_32_BYTES( acc->pubkey, addr_b58 ); 55 0 : FD_BASE58_ENCODE_32_BYTES( program_owner->key, owner_b58 ); 56 0 : FD_LOG_WARNING(( "unsupported program data account (address=%s program_owner=%s)", addr_b58, owner_b58 )); 57 0 : return NULL; 58 0 : } 59 4800 : } 60 : 61 : FD_FN_PURE fd_prog_versions_t 62 : fd_prog_versions( fd_features_t const * features, 63 6889 : ulong slot ) { 64 6889 : int disable_v0 = FD_FEATURE_ACTIVE( slot, features, disable_sbpf_v0_execution ); 65 6889 : int reenable_v0 = FD_FEATURE_ACTIVE( slot, features, reenable_sbpf_v0_execution ); 66 6889 : int enable_v0 = !disable_v0 || reenable_v0; 67 6889 : fd_prog_versions_t v = {0}; 68 : /* https://github.com/anza-xyz/agave/blob/v4.3.0-beta.0/syscalls/src/lib.rs#L333-L340 */ 69 6889 : v.min_sbpf_version = enable_v0 ? FD_SBPF_V0 : FD_SBPF_V3; 70 6889 : v.max_sbpf_version = FD_SBPF_V3; 71 6889 : return v; 72 6889 : } 73 : 74 : fd_prog_load_env_t * 75 : fd_prog_load_env_from_bank( fd_prog_load_env_t * env, 76 4800 : fd_bank_t const * bank ) { 77 4800 : fd_features_t const * features = &bank->f.features; 78 4800 : ulong feature_slot = 0UL; 79 : 80 : #if FD_PROGCACHE_EB_ALWAYS_INVALIDATE 81 : 82 : /* Valid for FD_FEATURE_ACTIVE only because activations land on epoch starts. */ 83 : feature_slot = fd_epoch_slot0( &bank->f.epoch_schedule, bank->f.epoch ); 84 : 85 : #else 86 : 87 : /* Max activation slot <= bank_slot. Signed so DISABLED (ULONG_MAX) compares 88 : as -1 and never wins the max. */ 89 4800 : long const * f = (long const *)features->f; 90 4800 : long limit = (long)bank->f.slot; 91 4800 : long acc = 0L; 92 1447391 : for( ulong i=0UL; i<FD_FEATURE_ID_CNT; i++ ) { 93 1442591 : long s = f[ i ]; 94 1442591 : long v = (s<=limit) ? s : 0L; /* a not-yet-active feature must not win */ 95 1442591 : acc = v>acc ? v : acc; 96 1442591 : } 97 4800 : feature_slot = (ulong)acc; 98 : 99 4800 : #endif 100 : 101 4800 : *env = (fd_prog_load_env_t) { 102 4800 : .features = features, 103 4800 : .feature_slot = feature_slot 104 4800 : }; 105 4800 : return env; 106 4800 : }