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 48 : fd_acc_t const * ro ) { 10 48 : if( FD_UNLIKELY( ro->data_len<PROGRAMDATA_METADATA_SIZE ) ) { 11 3 : FD_LOG_WARNING(( "program data account is too small" )); 12 3 : return NULL; 13 3 : } 14 45 : fd_bpf_state_t state; 15 45 : if( FD_UNLIKELY( fd_bpf_state_decode( &state, ro->data, ro->data_len ) ) ) { 16 3 : FD_LOG_WARNING(( "program data account is invalid" )); 17 3 : return NULL; 18 3 : } 19 42 : if( FD_UNLIKELY( state.discriminant!=FD_BPF_STATE_PROGRAM_DATA ) ) { 20 3 : FD_LOG_WARNING(( "loader v3 account is not a program data account" )); 21 3 : return NULL; 22 3 : } 23 : 24 39 : *out = (fd_prog_info_t) { 25 39 : .elf_off = PROGRAMDATA_METADATA_SIZE, 26 39 : .elf_sz = ro->data_len - PROGRAMDATA_METADATA_SIZE, 27 39 : .deploy_slot = state.inner.program_data.slot 28 39 : }; 29 39 : return out; 30 42 : } 31 : 32 : static fd_prog_info_t * 33 : fd_prog_info_v1( fd_prog_info_t * out, 34 919931 : fd_acc_t const * acc ) { 35 919931 : *out = (fd_prog_info_t) { 36 919931 : .elf_off = 0UL, 37 919931 : .elf_sz = acc->data_len, 38 919931 : .deploy_slot = 0UL 39 919931 : }; 40 919931 : return out; 41 919931 : } 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 919982 : fd_acc_t const * acc ){ 47 919982 : fd_pubkey_t const * program_owner = (fd_pubkey_t const*)acc->owner; 48 919982 : if( fd_pubkey_eq( program_owner, &fd_solana_bpf_loader_upgradeable_program_id ) ) { 49 48 : return fd_prog_info_v3( out, acc ); 50 919934 : } else if( fd_pubkey_eq( program_owner, &fd_solana_bpf_loader_program_id ) || 51 919934 : fd_pubkey_eq( program_owner, &fd_solana_bpf_loader_deprecated_program_id ) ) { 52 919931 : return fd_prog_info_v1( out, acc ); 53 919931 : } else { 54 3 : FD_BASE58_ENCODE_32_BYTES( acc->pubkey, addr_b58 ); 55 3 : FD_BASE58_ENCODE_32_BYTES( program_owner->key, owner_b58 ); 56 3 : FD_LOG_WARNING(( "unsupported program data account (address=%s program_owner=%s)", addr_b58, owner_b58 )); 57 3 : return NULL; 58 3 : } 59 919982 : } 60 : 61 : FD_FN_PURE fd_prog_versions_t 62 : fd_prog_versions( fd_features_t const * features, 63 919979 : ulong slot ) { 64 919979 : int disable_v0 = FD_FEATURE_ACTIVE( slot, features, disable_sbpf_v0_execution ); 65 919979 : int reenable_v0 = FD_FEATURE_ACTIVE( slot, features, reenable_sbpf_v0_execution ); 66 919979 : int enable_v0 = !disable_v0 || reenable_v0; 67 919979 : 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 919979 : v.min_sbpf_version = enable_v0 ? FD_SBPF_V0 : FD_SBPF_V3; 70 919979 : v.max_sbpf_version = FD_SBPF_V3; 71 919979 : return v; 72 919979 : } 73 : 74 : fd_prog_load_env_t * 75 : fd_prog_load_env_from_bank( fd_prog_load_env_t * env, 76 2487 : fd_bank_t const * bank ) { 77 2487 : fd_features_t const * features = &bank->f.features; 78 2487 : 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 2487 : long const * f = (long const *)features->f; 90 2487 : long limit = (long)bank->f.slot; 91 2487 : long acc = 0L; 92 738639 : for( ulong i=0UL; i<FD_FEATURE_ID_CNT; i++ ) { 93 736152 : long s = f[ i ]; 94 736152 : long v = (s<=limit) ? s : 0L; /* a not-yet-active feature must not win */ 95 736152 : acc = v>acc ? v : acc; 96 736152 : } 97 2487 : feature_slot = (ulong)acc; 98 : 99 2487 : #endif 100 : 101 2487 : *env = (fd_prog_load_env_t) { 102 2487 : .features = features, 103 2487 : .feature_slot = feature_slot 104 2487 : }; 105 2487 : return env; 106 2487 : }