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