diff --git a/src/flamenco/vm/fd_vm_cpi.h b/src/flamenco/vm/fd_vm_cpi.h index b3c1627a3d..858a4c802e 100644 --- a/src/flamenco/vm/fd_vm_cpi.h +++ b/src/flamenco/vm/fd_vm_cpi.h @@ -3,6 +3,23 @@ #include "../fd_flamenco_base.h" +/* fd_vm_cpi contains type definitions for the cross-program-invocation + (CPI) API. These types are passed from the virtual machine to the + CPI syscall handlers and are thus untrusted. Addresses are in VM + address space. Struct parameter offsets and sizes match exactly. + Structs also have alignment requirements in VM address space. These + alignments are provided as const macros. Since we cannot guarantee + that a type is aligned in host address space even when aligned in + VM address space, all structs support unaligned access + (i.e. alignof(type)==1UL). + + Unfortunately, the Solana protocol provides this API twice: + In a C-style ABI and in Rust ABI. */ + +/* fd_vm_vec_t is the in-memory representation of a vector descriptor. + Equal in layout to the Rust slice header &[_] and various vector + types in the C version of the syscall API. */ + #define FD_VM_VEC_ALIGN (8UL) struct __attribute__((packed)) fd_vm_vec { @@ -12,4 +29,134 @@ struct __attribute__((packed)) fd_vm_vec { typedef struct fd_vm_vec fd_vm_vec_t; +#define FD_VM_RC_REFCELL_ALIGN (8UL) + +struct __attribute__((packed)) fd_vm_rc_refcell_vec { + ulong strong; + ulong weak; + ulong borrow; + ulong addr; + ulong len; +}; +typedef struct fd_vm_rc_refcell_vec fd_vm_rc_refcell_vec_t; + +struct __attribute__((packed)) fd_vm_rc_refcell { + ulong strong; + ulong weak; + ulong borrow; + ulong addr; +}; +typedef struct fd_vm_rc_refcell fd_vm_rc_refcell_t; + +/* Structs fd_vm_c_{...}_t are part of the C ABI for the cross-program + invocation syscall API. */ + +#define FD_VM_C_INSTRUCTION_ALIGN (8UL) + +struct __attribute__((packed)) fd_vm_c_instruction { + ulong program_id_addr; + ulong accounts_addr; + ulong accounts_len; + ulong data_addr; + ulong data_len; +}; + +typedef struct fd_vm_c_instruction fd_vm_c_instruction_t; + +#define FD_VM_C_ACCOUNT_META_ALIGN (8UL) + +struct fd_vm_c_account_meta { + ulong pubkey_addr; + uchar is_writable; + uchar is_signer; +}; + +typedef struct fd_vm_c_account_meta fd_vm_c_account_meta_t; + +#define FD_VM_C_ACCOUNT_INFO_ALIGN (8UL) + +struct fd_vm_c_account_info { + ulong key_addr; + ulong lamports_addr; + ulong data_sz; + ulong data_addr; + ulong owner_addr; + ulong rent_epoch; + uchar is_signer; + uchar is_writable; + uchar executable; +}; + +typedef struct fd_vm_c_account_info fd_vm_c_account_info_t; + +/* Structs fd_vm_rust_{...}_t are part of the Rust ABI for the + cross-program-invocation syscall API. */ + +/* fd_vm_rust_vec_t is Rust type Vec<_> using the default allocator. */ + +#define FD_VM_RUST_VEC_ALIGN (8UL) + +struct __attribute__((packed)) fd_vm_rust_vec { + ulong addr; + ulong cap; + ulong len; +}; + +typedef struct fd_vm_rust_vec fd_vm_rust_vec_t; + +#define FD_VM_RUST_RC_ALIGN (8UL) + +#define FD_VM_RUST_INSTRUCTION_ALIGN (8UL) + +struct __attribute__((packed)) fd_vm_rust_instruction { + fd_vm_rust_vec_t accounts; /* points to fd_vm_rust_account_meta_t */ + fd_vm_rust_vec_t data; /* points to bytes */ + uchar pubkey[32]; +}; + +typedef struct fd_vm_rust_instruction fd_vm_rust_instruction_t; + +#define FD_VM_RUST_ACCOUNT_META_ALIGN (1UL) + +struct __attribute__((packed)) fd_vm_rust_account_meta { + uchar pubkey[32]; + uchar is_signer; + uchar is_writable; +}; + +typedef struct fd_vm_rust_account_meta fd_vm_rust_account_meta_t; + +#define FD_VM_RUST_ACCOUNT_INFO_ALIGN (8UL) + +struct __attribute__((packed)) fd_vm_rust_account_info { + ulong pubkey_addr; /* points to uchar[32] */ + ulong lamports_box_addr; /* points to Rc with embedded RefCell which points to u64 */ + ulong data_box_addr; /* points to Rc with embedded RefCell which contains slice which points to bytes */ + ulong owner_addr; /* points to uchar[32] */ + ulong rent_epoch; + uchar is_signer; + uchar is_writable; + uchar executable; + uchar _padding_0[5]; +}; + +typedef struct fd_vm_rust_account_info fd_vm_rust_account_info_t; + +union fd_vm_account_info_inner { + fd_vm_rust_account_info_t const * rust_acct_infos; + fd_vm_c_account_info_t const * c_acct_infos; +}; + +typedef union fd_vm_account_info_inner fd_vm_account_info_inner_t; + +struct __attribute__((packed)) fd_vm_account_info { + uint discriminant; +# define FD_VM_ACCOUNT_INFO_RUST (0U) +# define FD_VM_ACCOUNT_INFO_C (1U) + + fd_vm_account_info_inner_t inner; +}; + +typedef struct fd_vm_account_info fd_vm_account_info_t; + #endif /* HEADER_fd_src_flamenco_vm_fd_vm_cpi_h */