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 33 : fd_acc_t const * ro ) { 10 33 : 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 30 : fd_bpf_state_t state; 15 30 : 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 27 : 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 24 : *out = (fd_prog_info_t) { 25 24 : .elf_off = PROGRAMDATA_METADATA_SIZE, 26 24 : .elf_sz = ro->data_len - PROGRAMDATA_METADATA_SIZE, 27 24 : .deploy_slot = state.inner.program_data.slot 28 24 : }; 29 24 : return out; 30 27 : } 31 : 32 : static fd_prog_info_t * 33 : fd_prog_info_v1( fd_prog_info_t * out, 34 2544 : fd_acc_t const * acc ) { 35 2544 : *out = (fd_prog_info_t) { 36 2544 : .elf_off = 0UL, 37 2544 : .elf_sz = acc->data_len, 38 2544 : .deploy_slot = 0UL 39 2544 : }; 40 2544 : return out; 41 2544 : } 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 2580 : fd_acc_t const * acc ){ 47 2580 : fd_pubkey_t const * program_owner = (fd_pubkey_t const*)acc->owner; 48 2580 : if( fd_pubkey_eq( program_owner, &fd_solana_bpf_loader_upgradeable_program_id ) ) { 49 33 : return fd_prog_info_v3( out, acc ); 50 2547 : } else if( fd_pubkey_eq( program_owner, &fd_solana_bpf_loader_program_id ) || 51 2547 : fd_pubkey_eq( program_owner, &fd_solana_bpf_loader_deprecated_program_id ) ) { 52 2544 : return fd_prog_info_v1( out, acc ); 53 2544 : } 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 2580 : } 60 : 61 : FD_FN_PURE fd_prog_versions_t 62 : fd_prog_versions( fd_features_t const * features, 63 2574 : ulong slot ) { 64 2574 : int disable_v0 = FD_FEATURE_ACTIVE( slot, features, disable_sbpf_v0_execution ); 65 2574 : int reenable_v0 = FD_FEATURE_ACTIVE( slot, features, reenable_sbpf_v0_execution ); 66 2574 : int enable_v0 = !disable_v0 || reenable_v0; 67 2574 : int enable_v1 = FD_FEATURE_ACTIVE( slot, features, enable_sbpf_v1_deployment_and_execution ); 68 2574 : int enable_v2 = FD_FEATURE_ACTIVE( slot, features, enable_sbpf_v2_deployment_and_execution ); 69 2574 : int enable_v3 = FD_FEATURE_ACTIVE( slot, features, enable_sbpf_v3_deployment_and_execution ); 70 : 71 2574 : fd_prog_versions_t v = {0}; 72 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.4/syscalls/src/lib.rs#L314-L319 */ 73 2574 : v.min_sbpf_version = enable_v0 ? FD_SBPF_V0 : FD_SBPF_V3; 74 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.4/syscalls/src/lib.rs#L320-L328 */ 75 2574 : if( enable_v3 ) { v.max_sbpf_version = FD_SBPF_V3; } 76 2454 : else if( enable_v2 ) { v.max_sbpf_version = FD_SBPF_V2; } 77 2454 : else if( enable_v1 ) { v.max_sbpf_version = FD_SBPF_V1; } 78 2454 : else { v.max_sbpf_version = FD_SBPF_V0; } 79 2574 : return v; 80 2574 : } 81 : 82 : fd_prog_load_env_t * 83 : fd_prog_load_env_from_bank( fd_prog_load_env_t * env, 84 2472 : fd_bank_t const * bank ) { 85 2472 : fd_features_t const * features = &bank->f.features; 86 2472 : ulong bank_slot = bank->f.slot; 87 2472 : ulong feature_slot = 0UL; 88 : 89 : /* compute the max feature_slot that's active and <= bank_slot */ 90 687216 : for( ulong i=0UL; i<FD_FEATURE_ID_CNT; i++ ) { 91 684744 : ulong s = features->f[ i ]; 92 684744 : if( (s!=FD_FEATURE_DISABLED) && (s<=bank_slot) && (s>feature_slot) ) { 93 21 : feature_slot = s; 94 21 : } 95 684744 : } 96 : 97 2472 : *env = (fd_prog_load_env_t) { 98 2472 : .features = features, 99 2472 : .feature_slot = feature_slot 100 2472 : }; 101 2472 : return env; 102 2472 : }