Line data Source code
1 : #include "fd_sysvar_instructions.h" 2 : #include "../fd_account.h" 3 : #include "../fd_system_ids.h" 4 : 5 : static ulong 6 : instructions_serialized_size( fd_instr_info_t const * instrs, 7 0 : ushort instrs_cnt ) { 8 0 : ulong serialized_size = 0; 9 : 10 0 : serialized_size += sizeof(ushort) // num_instructions 11 0 : + (sizeof(ushort) * instrs_cnt); // instruction offsets 12 : 13 0 : for ( ushort i = 0; i < instrs_cnt; ++i ) { 14 0 : fd_instr_info_t const * instr = &instrs[i]; 15 : 16 0 : serialized_size += sizeof(ushort); // num_accounts; 17 : 18 0 : serialized_size += instr->acct_cnt * ( 19 0 : sizeof(uchar) // flags (is_signer, is_writeable) 20 0 : + sizeof(fd_pubkey_t) // pubkey 21 0 : ); 22 : 23 0 : serialized_size += sizeof(fd_pubkey_t) // program_id pubkey 24 0 : + sizeof(ushort) // instr_data_len; 25 0 : + instr->data_sz; // instr_data; 26 : 27 0 : } 28 : 29 0 : serialized_size += sizeof(ushort); // current_instr_idx 30 : 31 0 : return serialized_size; 32 0 : } 33 : 34 : int 35 : fd_sysvar_instructions_serialize_account( fd_exec_txn_ctx_t * txn_ctx, 36 : fd_instr_info_t const * instrs, 37 0 : ushort instrs_cnt ) { 38 0 : ulong serialized_sz = instructions_serialized_size( instrs, instrs_cnt ); 39 : 40 0 : fd_borrowed_account_t * rec = NULL; 41 0 : int err = fd_txn_borrowed_account_view( txn_ctx, &fd_sysvar_instructions_id, &rec ); 42 0 : if( FD_UNLIKELY( err != FD_ACC_MGR_SUCCESS && rec == NULL ) ) 43 0 : return FD_ACC_MGR_ERR_READ_FAILED; 44 : 45 0 : fd_account_meta_t * meta = fd_valloc_malloc( txn_ctx->valloc, FD_ACCOUNT_META_ALIGN, sizeof(fd_account_meta_t) + serialized_sz ); 46 0 : void * data = (uchar *)meta + sizeof(fd_account_meta_t); 47 : 48 0 : rec->const_meta = rec->meta = meta; 49 0 : rec->const_data = rec->data = data; 50 : 51 0 : memcpy( rec->meta->info.owner, fd_sysvar_owner_id.key, sizeof(fd_pubkey_t) ); 52 0 : rec->meta->info.lamports = 0; // TODO: This cannot be right... well, it gets destroyed almost instantly... 53 0 : rec->meta->info.executable = 0; 54 0 : rec->meta->info.rent_epoch = 0; 55 0 : rec->meta->dlen = serialized_sz; 56 : 57 0 : uchar * serialized_instructions = rec->data; 58 0 : ulong offset = 0; 59 : 60 : // TODO: do we needs bounds checking? 61 : // num_instructions 62 0 : FD_STORE( ushort, serialized_instructions + offset, instrs_cnt); 63 0 : offset += sizeof(ushort); 64 : 65 : // instruction offsets 66 0 : uchar * serialized_instruction_offsets = serialized_instructions + offset; 67 0 : offset += (ushort)(sizeof(ushort) * instrs_cnt); 68 : 69 : // serialize instructions 70 0 : for( ushort i = 0; i < instrs_cnt; ++i ) { 71 : // set the instruction offset 72 0 : FD_STORE( ushort, serialized_instruction_offsets, (ushort) offset ); 73 0 : serialized_instruction_offsets += sizeof(ushort); 74 : 75 0 : fd_instr_info_t const * instr = &instrs[i]; 76 : 77 : // num_accounts 78 0 : FD_STORE( ushort, serialized_instructions + offset, instr->acct_cnt ); 79 0 : offset += sizeof(ushort); 80 : 81 0 : for ( ushort j = 0; j < instr->acct_cnt; j++ ) { 82 : // flags 83 0 : FD_STORE( uchar, serialized_instructions + offset, instr->acct_flags[j] ); 84 0 : offset += sizeof(uchar); 85 : 86 : // pubkey 87 0 : FD_STORE( fd_pubkey_t, serialized_instructions + offset, instr->acct_pubkeys[j] ); 88 0 : offset += sizeof(fd_pubkey_t); 89 0 : } 90 : 91 : // program_id_pubkey 92 0 : FD_STORE( fd_pubkey_t, serialized_instructions + offset, instr->program_id_pubkey ); 93 0 : offset += sizeof(fd_pubkey_t); 94 : 95 : // instr_data_len 96 0 : FD_STORE( ushort, serialized_instructions + offset, instr->data_sz ); 97 0 : offset += sizeof(ushort); 98 : 99 : // instr_data 100 0 : fd_memcpy( serialized_instructions + offset, instr->data, instr->data_sz ); 101 0 : offset += instr->data_sz; 102 0 : } 103 : 104 : // 105 0 : FD_STORE( ushort, serialized_instructions + offset, 0 ); 106 0 : offset += sizeof(ushort); 107 : 108 0 : return FD_ACC_MGR_SUCCESS; 109 0 : } 110 : 111 : int 112 0 : fd_sysvar_instructions_cleanup_account( fd_exec_txn_ctx_t * txn_ctx ) { 113 0 : fd_borrowed_account_t * rec = NULL; 114 0 : int err = fd_txn_borrowed_account_modify( txn_ctx, &fd_sysvar_instructions_id, 0, &rec ); 115 0 : if( FD_UNLIKELY( err != FD_ACC_MGR_SUCCESS ) ) 116 0 : return FD_ACC_MGR_ERR_READ_FAILED; 117 : 118 0 : fd_valloc_free( txn_ctx->valloc, rec->meta ); 119 0 : rec->const_meta = rec->meta = NULL; 120 0 : rec->const_data = rec->data = NULL; 121 : 122 0 : return FD_ACC_MGR_SUCCESS; 123 0 : } 124 : 125 : int 126 : fd_sysvar_instructions_update_current_instr_idx( fd_exec_txn_ctx_t * txn_ctx, 127 0 : ushort current_instr_idx ) { 128 0 : fd_borrowed_account_t * rec = NULL; 129 0 : int err = fd_txn_borrowed_account_modify( txn_ctx, &fd_sysvar_instructions_id, 0, &rec ); 130 0 : if( FD_UNLIKELY( err != FD_ACC_MGR_SUCCESS ) ) 131 0 : return FD_ACC_MGR_ERR_READ_FAILED; 132 : 133 0 : uchar * serialized_current_instr_idx = rec->data + (rec->meta->dlen - sizeof(ushort)); 134 0 : FD_STORE( ushort, serialized_current_instr_idx, current_instr_idx ); 135 : 136 0 : return FD_ACC_MGR_SUCCESS; 137 0 : }