Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_vm_syscall_fd_vm_cpi_h 2 : #define HEADER_fd_src_flamenco_vm_syscall_fd_vm_cpi_h 3 : 4 : #ifndef HEADER_fd_src_flamenco_vm_syscall_fd_vm_syscall_h 5 : #error "Do not include this directly; use fd_vm_syscall.h" 6 : #endif 7 : 8 : /* fd_vm_cpi contains type definitions for the cross-program-invocation 9 : (CPI) API. These types are passed from the virtual machine to the 10 : CPI syscall handlers and are thus untrusted. Addresses are in VM 11 : address space. Struct parameter offsets and sizes match exactly. 12 : Structs also have alignment requirements in VM address space. These 13 : alignments are provided as const macros. Alignment is not checked 14 : for deprecated loader programs, so host addresses may be unaligned. 15 : Thus, all structs support unaligned access (i.e. alignof(type)==1UL). 16 : 17 : Unfortunately, the Solana protocol provides this API twice: 18 : In a C-style ABI and in Rust ABI. */ 19 : 20 : 21 : /* Structs fd_vm_c_{...}_t are part of the C ABI for the cross-program 22 : invocation syscall API. */ 23 : 24 : #define FD_VM_C_INSTRUCTION_ALIGN (8UL) 25 : #define FD_VM_C_INSTRUCTION_SIZE (40UL) 26 : 27 : struct __attribute__((packed)) fd_vm_c_instruction { 28 : ulong program_id_addr; 29 : ulong accounts_addr; 30 : ulong accounts_len; 31 : ulong data_addr; 32 : ulong data_len; 33 : }; 34 : 35 : typedef struct fd_vm_c_instruction fd_vm_c_instruction_t; 36 : 37 : #define FD_VM_C_ACCOUNT_META_ALIGN (8UL) 38 : #define FD_VM_C_ACCOUNT_META_SIZE (16UL) 39 : struct __attribute__((packed)) fd_vm_c_account_meta { 40 : ulong pubkey_addr; 41 : uchar is_writable; 42 : uchar is_signer; 43 : uchar _padding_0[6]; 44 : }; 45 : 46 : typedef struct fd_vm_c_account_meta fd_vm_c_account_meta_t; 47 : 48 : #define FD_VM_C_ACCOUNT_INFO_ALIGN (8UL) 49 1039 : #define FD_VM_C_ACCOUNT_INFO_SIZE (56UL) 50 : 51 : struct __attribute__((packed)) fd_vm_c_account_info { 52 : ulong pubkey_addr; 53 : ulong lamports_addr; 54 : ulong data_sz; 55 : ulong data_addr; 56 : ulong owner_addr; 57 : ulong rent_epoch; 58 : uchar is_signer; 59 : uchar is_writable; 60 : uchar executable; 61 : uchar _padding_0[5]; 62 : }; 63 : 64 : typedef struct fd_vm_c_account_info fd_vm_c_account_info_t; 65 : 66 : /* Structs fd_vm_rust_{...}_t are part of the Rust ABI for the 67 : cross-program-invocation syscall API. */ 68 : 69 : /* fd_vm_rust_vec_t is Rust type Vec<_> using the default allocator. */ 70 : 71 : #define FD_VM_RUST_VEC_ALIGN (8UL) 72 : #define FD_VM_RUST_VEC_SIZE (24UL) 73 : 74 : struct __attribute__((packed)) fd_vm_rust_vec { 75 : ulong addr; 76 : ulong cap; 77 : ulong len; 78 : }; 79 : 80 : typedef struct fd_vm_rust_vec fd_vm_rust_vec_t; 81 : 82 : #define FD_VM_RUST_RC_ALIGN (8UL) 83 : 84 : #define FD_VM_RUST_INSTRUCTION_ALIGN (8UL) 85 : #define FD_VM_RUST_INSTRUCTION_SIZE (80UL) 86 : 87 : struct __attribute__((packed)) fd_vm_rust_instruction { 88 : fd_vm_rust_vec_t accounts; /* points to fd_vm_rust_account_meta_t */ 89 : fd_vm_rust_vec_t data; /* points to bytes */ 90 : uchar pubkey[32]; 91 : }; 92 : 93 : typedef struct fd_vm_rust_instruction fd_vm_rust_instruction_t; 94 : 95 1989 : #define FD_VM_RUST_ACCOUNT_META_SIZE (34UL) 96 2 : #define FD_VM_RUST_ACCOUNT_META_ALIGN (1UL) 97 : 98 : struct __attribute__((packed)) fd_vm_rust_account_meta { 99 : uchar pubkey[32]; 100 : uchar is_signer; 101 : uchar is_writable; 102 : }; 103 : 104 : typedef struct fd_vm_rust_account_meta fd_vm_rust_account_meta_t; 105 : 106 : #define FD_VM_RUST_ACCOUNT_INFO_ALIGN (8UL) 107 498 : #define FD_VM_RUST_ACCOUNT_INFO_SIZE (48UL) 108 : 109 : struct __attribute__((packed)) fd_vm_rust_account_info { 110 : ulong pubkey_addr; /* points to uchar[32] */ 111 : ulong lamports_box_addr; /* points to Rc with embedded RefCell which points to u64 */ 112 : ulong data_box_addr; /* points to Rc with embedded RefCell which contains slice which points to bytes */ 113 : ulong owner_addr; /* points to uchar[32] */ 114 : ulong rent_epoch; 115 : uchar is_signer; 116 : uchar is_writable; 117 : uchar executable; 118 : uchar _padding_0[5]; 119 : }; 120 : 121 : typedef struct fd_vm_rust_account_info fd_vm_rust_account_info_t; 122 : 123 : /* These define the in-memory layout of Rc<Refcell<T>> types to 124 : facilitate checks on Rust AccountInfo fields. 125 : */ 126 : 127 : #define FD_VM_RC_REFCELL_ALIGN (8UL) 128 : 129 : struct __attribute__((packed)) fd_vm_rc_refcell { 130 : ulong strong; /* Rc */ 131 : ulong weak; /* Rc */ 132 : ulong borrow; /* RefCell */ 133 : ulong payload[]; /* Underlying data */ 134 : }; 135 : typedef struct fd_vm_rc_refcell fd_vm_rc_refcell_t; 136 : 137 : struct __attribute__((packed)) fd_vm_rc_refcell_vec { 138 : ulong strong; /* Rc */ 139 : ulong weak; /* Rc */ 140 : ulong borrow; /* RefCell */ 141 : ulong addr; /* Slice */ 142 : ulong len; /* Slice */ 143 : }; 144 : typedef struct fd_vm_rc_refcell_vec fd_vm_rc_refcell_vec_t; 145 : 146 : FD_STATIC_ASSERT( sizeof(fd_vm_rc_refcell_t)+sizeof(fd_vm_vec_t)==sizeof(fd_vm_rc_refcell_vec_t), sizeof_fd_vm_rc_refcell_vec_t ); 147 : 148 : struct __attribute__((packed)) fd_vm_rc_refcell_ref { 149 : ulong strong; /* Rc */ 150 : ulong weak; /* Rc */ 151 : ulong borrow; /* RefCell */ 152 : ulong addr; /* Ref */ 153 : }; 154 : typedef struct fd_vm_rc_refcell_ref fd_vm_rc_refcell_ref_t; 155 : 156 : /* https://github.com/anza-xyz/agave/blob/v4.0.0-beta.7/program-runtime/src/cpi.rs#L224-L247 157 : 158 : This struct caches the result of a translated CallerAccount, 159 : which could be translated from either the Rust or C ABI. 160 : It serves the same purpose as the corresponding struct in Agave. 161 : Essentially, it caches the results of translations that have been 162 : performed leading up to the CPI. 163 : Or, in the case of direct mapping, it sometimes stores the vm 164 : virtual addresses for translation later on. 165 : In direct mapping, translation is sometimes delayed because 166 : "permissions on the realloc region can change during CPI". 167 : */ 168 : struct fd_vm_cpi_caller_account { 169 : void * lamports; /* ulong, possibly unaligned */ 170 : fd_pubkey_t * owner; 171 : ulong orig_data_len; 172 : uchar * serialized_data; /* NULL if direct mapping */ 173 : ulong serialized_data_len; 174 : ulong vm_data_vaddr; 175 : void * ref_to_len_in_vm; /* ulong, possibly unaligned */ 176 : }; 177 : typedef struct fd_vm_cpi_caller_account fd_vm_cpi_caller_account_t; 178 : 179 : /* TranslatedAccount is responsible for storing the result of Agave's 180 : solana_program_runtime::cpi::SyscallInvokeSigned::translate_accounts. 181 : 182 : The control and data flow matches Agave 1-1 for ease of auditability. 183 : 184 : https://github.com/anza-xyz/agave/blob/v4.0.0-beta.7/program-runtime/src/cpi.rs#L979-L985 */ 185 : struct fd_vm_cpi_translated_account { 186 : ushort index_in_caller; 187 : fd_vm_cpi_caller_account_t caller_account; 188 : uchar update_caller_account_region; 189 : uchar update_caller_account_info; 190 : }; 191 : typedef struct fd_vm_cpi_translated_account fd_vm_cpi_translated_account_t; 192 : 193 : #endif /* HEADER_fd_src_flamenco_vm_syscall_fd_vm_cpi_h */