Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_runtime_fd_txn_account_h 2 : #define HEADER_fd_src_flamenco_runtime_fd_txn_account_h 3 : 4 : #include "../accdb/fd_accdb_sync.h" 5 : #include "../types/fd_types.h" 6 : #include "../../funk/fd_funk_rec.h" 7 : 8 : struct fd_acc_mgr; 9 : typedef struct fd_acc_mgr fd_acc_mgr_t; 10 : 11 : /* fd_txn_account_t is a wrapper around a database record. It is used to 12 : provide an interface for an account during transaction execution 13 : along with reference counting semantics. The fd_txn_account_t object 14 : is initialized with a pointer to the account's metadata and data, the 15 : wksp that the data belongs to, its pubkey, and if the transaction 16 : account is mutable. 17 : 18 : fd_txn_account_t is NOT thread-safe and only supports a single join 19 : at a given time. 20 : 21 : TODO: Consider changing the meta/data boundary to make it more 22 : explicit that the caller passes in a contigious region of memory 23 : which has to correspond to the meta/data layout. 24 : 25 : TODO: Consider making the fd_txn_account struct private */ 26 : 27 : struct __attribute__((aligned(8UL))) fd_txn_account { 28 : ulong magic; 29 : 30 : fd_pubkey_t pubkey[1]; 31 : 32 : fd_account_meta_t * meta; 33 : uchar * data; 34 : 35 : int is_mutable; 36 : long meta_soff; 37 : 38 : ulong starting_dlen; 39 : ulong starting_lamports; 40 : 41 : /* Provide borrowing semantics. Used for single-threaded logic only, 42 : thus not comparable to a data synchronization lock. */ 43 : ushort refcnt_excl; 44 : 45 : }; 46 : typedef struct fd_txn_account fd_txn_account_t; 47 3 : #define FD_TXN_ACCOUNT_FOOTPRINT (sizeof(fd_txn_account_t)) 48 3 : #define FD_TXN_ACCOUNT_ALIGN (8UL) 49 1032 : #define FD_TXN_ACCOUNT_MAGIC (0xF15EDF1C51F51AA1UL) 50 : 51 : FD_PROTOTYPES_BEGIN 52 : 53 : /* fd_txn_account_new lays out the memory required for a 54 : fd_txn_account object. The caller should only use the struct 55 : after it has been joined. fd_txn_account_t makes the assumption 56 : that the account data is laid out directly after the account meta. 57 : After a successful call to fd_txn_account_new, the object will now 58 : own the account's metadata and data. */ 59 : 60 : void * 61 : fd_txn_account_new( void * mem, 62 : fd_pubkey_t const * pubkey, 63 : fd_account_meta_t * meta, 64 : int is_mutable ); 65 : 66 : /* fd_txn_account_join joins a thread with an indepedent address space 67 : to the memory region allocated by fd_txn_account_new. There can be 68 : only ONE valid join per fd_txn_account_t object. If a _join is called 69 : from one thread, it is implied that the object is no longer valid 70 : on other threads. 71 : 72 : TODO: When the new db is introduced, the wksp argument should be 73 : removed in favor of using offsets into other data structures. */ 74 : 75 : fd_txn_account_t * 76 : fd_txn_account_join( void * mem, fd_wksp_t * data_wksp ); 77 : 78 : /* fd_txn_account_leave leaves a current local join and returns a 79 : pointer to the underlying shared memory region. The fd_txn_account_t 80 : will still own the account's metadata and data. */ 81 : 82 : void * 83 : fd_txn_account_leave( fd_txn_account_t * acct ); 84 : 85 : /* fd_txn_account_delete removes the memory layout for the 86 : fd_txn_account_t object. It returns a pointer to the underlying 87 : shared struct. Any attempts to join after a call to 88 : fd_txn_account_delete will fail. The account's metadata and data 89 : will be owned by the caller after the delete is called. */ 90 : 91 : void * 92 : fd_txn_account_delete( void * mem ); 93 : 94 : /* Factory constructors from funk. 95 : TODO: These need to be removed when a new db is introduced and either 96 : replaced with a new factory constructor or removed entirely in favor 97 : of the generic constructors defined above. */ 98 : 99 : /* fd_txn_account_init_from_funk_readonly initializes a fd_txn_account_t 100 : object with a readonly handle into its funk record. 101 : 102 : IMPORTANT: When we access the account metadata and data pointer later 103 : on in the execution pipeline, we assume that nothing else will change 104 : these. 105 : 106 : This is safe because we assume that we hold a read lock on the 107 : account, since we are inside a Solana transaction. */ 108 : 109 : int 110 : fd_txn_account_init_from_funk_readonly( fd_txn_account_t * acct, 111 : fd_pubkey_t const * pubkey, 112 : fd_funk_t const * funk, 113 : fd_funk_txn_xid_t const * xid ); 114 : 115 : /* fd_txn_account_init_from_funk_mutable initializes a fd_txn_account_t 116 : object with a mutable handle into its funk record. 117 : 118 : IMPORTANT: Cannot be called in the executor tile. */ 119 : 120 : fd_account_meta_t * 121 : fd_txn_account_init_from_funk_mutable( fd_txn_account_t * acct, 122 : fd_pubkey_t const * pubkey, 123 : fd_accdb_user_t * accdb, 124 : fd_funk_txn_xid_t const * xid, 125 : int do_create, 126 : ulong min_data_sz, 127 : fd_funk_rec_prepare_t * prepare_out ); 128 : 129 : /* Publishes the record contents of a mutable fd_txn_account_t object 130 : obtained from fd_txn_account_init_from_funk_mutable into funk 131 : if the record does not yet exist in the current funk txn. 132 : ie. the record was created / cloned from an ancestor funk txn 133 : by fd_txn_account_init_from_funk_mutable. */ 134 : 135 : void 136 : fd_txn_account_mutable_fini( fd_txn_account_t * acct, 137 : fd_accdb_user_t * funk, 138 : fd_funk_rec_prepare_t * prepare ); 139 : 140 : /* Simple accesssors and mutators. */ 141 : 142 : fd_pubkey_t const * 143 : fd_txn_account_get_owner( fd_txn_account_t const * acct ); 144 : 145 : fd_account_meta_t const * 146 : fd_txn_account_get_meta( fd_txn_account_t const * acct ); 147 : 148 : uchar const * 149 : fd_txn_account_get_data( fd_txn_account_t const * acct ); 150 : 151 : uchar * 152 : fd_txn_account_get_data_mut( fd_txn_account_t const * acct ); 153 : 154 : ulong 155 : fd_txn_account_get_data_len( fd_txn_account_t const * acct ); 156 : 157 : int 158 : fd_txn_account_is_executable( fd_txn_account_t const * acct ); 159 : 160 : ulong 161 : fd_txn_account_get_lamports( fd_txn_account_t const * acct ); 162 : 163 : ulong 164 : fd_txn_account_get_rent_epoch( fd_txn_account_t const * acct ); 165 : 166 : void 167 : fd_txn_account_set_meta( fd_txn_account_t * acct, fd_account_meta_t * meta ); 168 : 169 : void 170 : fd_txn_account_set_executable( fd_txn_account_t * acct, int is_executable ); 171 : 172 : void 173 : fd_txn_account_set_owner( fd_txn_account_t * acct, fd_pubkey_t const * owner ); 174 : 175 : void 176 : fd_txn_account_set_lamports( fd_txn_account_t * acct, ulong lamports ); 177 : 178 : int 179 : fd_txn_account_checked_add_lamports( fd_txn_account_t * acct, ulong lamports ); 180 : 181 : int 182 : fd_txn_account_checked_sub_lamports( fd_txn_account_t * acct, ulong lamports ); 183 : 184 : void 185 : fd_txn_account_set_data( fd_txn_account_t * acct, 186 : void const * data, 187 : ulong data_sz ); 188 : 189 : void 190 : fd_txn_account_set_data_len( fd_txn_account_t * acct, ulong data_len ); 191 : 192 : void 193 : fd_txn_account_set_slot( fd_txn_account_t * acct, 194 : ulong slot ); 195 : 196 : void 197 : fd_txn_account_clear_owner( fd_txn_account_t * acct ); 198 : 199 : void 200 : fd_txn_account_resize( fd_txn_account_t * acct, ulong dlen ); 201 : 202 : ushort 203 : fd_txn_account_is_borrowed( fd_txn_account_t const * acct ); 204 : 205 : int 206 : fd_txn_account_is_mutable( fd_txn_account_t const * acct ); 207 : 208 : int 209 : fd_txn_account_is_readonly( fd_txn_account_t const * acct ); 210 : 211 : int 212 : fd_txn_account_try_borrow_mut( fd_txn_account_t * acct ); 213 : 214 : void 215 : fd_txn_account_drop( fd_txn_account_t * acct ); 216 : 217 : void 218 : fd_txn_account_set_readonly( fd_txn_account_t * acct ); 219 : 220 : void 221 : fd_txn_account_set_mutable( fd_txn_account_t * acct ); 222 : 223 : fd_solana_account_meta_t 224 : fd_txn_account_get_solana_meta( fd_txn_account_t const * acct ); 225 : 226 : FD_PROTOTYPES_END 227 : 228 : #endif /* HEADER_fd_src_flamenco_runtime_fd_txn_account_h */