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 "../../ballet/txn/fd_txn.h" 5 : #include "../types/fd_types.h" 6 : #include "../../funk/fd_funk_rec.h" 7 : #include "program/fd_program_util.h" 8 : 9 : struct fd_acc_mgr; 10 : typedef struct fd_acc_mgr fd_acc_mgr_t; 11 : 12 : struct __attribute__((aligned(8UL))) fd_txn_account { 13 : ulong magic; 14 : 15 : fd_pubkey_t pubkey[1]; 16 : 17 : fd_account_meta_t const * const_meta; 18 : uchar const * const_data; 19 : fd_funk_rec_t const * const_rec; 20 : 21 : fd_account_meta_t * meta; 22 : uchar * data; 23 : fd_funk_rec_t * rec; 24 : 25 : fd_account_meta_t const * orig_meta; 26 : uchar const * orig_data; 27 : fd_funk_rec_t const * orig_rec; 28 : 29 : /* consider making this a struct or removing entirely if not needed */ 30 : ulong starting_dlen; 31 : ulong starting_lamports; 32 : ulong starting_owner_dlen; 33 : 34 : /* Provide read/write mutual exclusion semantics. 35 : Used for single-threaded logic only, thus not comparable to a 36 : data synchronization lock. */ 37 : 38 : ushort refcnt_excl; 39 : ushort refcnt_shared; 40 : 41 : uchar account_found; 42 : }; 43 : typedef struct fd_txn_account fd_txn_account_t; 44 24 : #define FD_TXN_ACCOUNT_FOOTPRINT (sizeof(fd_txn_account_t)) 45 : #define FD_TXN_ACCOUNT_ALIGN (8UL) 46 24 : #define FD_TXN_ACCOUNT_MAGIC (0xF15EDF1C51F51AA1UL) 47 : 48 24 : #define FD_TXN_ACCOUNT_DECL(_x) fd_txn_account_t _x[1]; fd_txn_account_init(_x); 49 : 50 : FD_PROTOTYPES_BEGIN 51 : 52 : /* TODO: Initializes an fd_txn_account from a pointer to a region of memory */ 53 : fd_txn_account_t * 54 : fd_txn_account_init( void * ptr ); 55 : 56 : /* Accessors */ 57 : 58 : /* Returns the total size of the account shared data */ 59 : FD_FN_PURE static inline ulong 60 0 : fd_txn_account_raw_size( fd_txn_account_t const * acct ) { 61 0 : ulong dlen = ( acct->const_meta != NULL ) ? acct->const_meta->dlen : 0; 62 0 : return sizeof(fd_account_meta_t) + dlen; 63 0 : } 64 : 65 : static inline int 66 0 : fd_txn_account_is_executable( fd_txn_account_t const * acct ) { 67 0 : return !!acct->const_meta->info.executable; 68 0 : } 69 : 70 : /* Setters */ 71 : 72 : static inline void 73 0 : fd_txn_account_set_lamports( fd_txn_account_t * acct, ulong lamports ) { 74 0 : acct->meta->info.lamports = lamports; 75 0 : } 76 : 77 : static inline void 78 0 : fd_txn_account_set_executable( fd_txn_account_t * acct, int is_executable ) { 79 0 : acct->meta->info.executable = !!is_executable; 80 0 : } 81 : 82 : /* Resizes the account data */ 83 : void 84 : fd_txn_account_resize( fd_txn_account_t * acct, 85 : ulong dlen ); 86 : 87 : /* Operators */ 88 : 89 : /* buf is a handle to the account shared data. 90 : Sets the account shared data as mutable. */ 91 : fd_txn_account_t * 92 : fd_txn_account_make_mutable( fd_txn_account_t * acct, 93 : void * buf ); 94 : 95 : /* In Agave, dummy accounts are sometimes created that contain metadata 96 : that differs from what's in the accounts DB. For example, see 97 : handling of the executable bit in 98 : fd_executor_load_transaction_accounts(). 99 : This allows us to emulate that by modifying metadata of read-only 100 : borrowed accounts without those modification writing through to 101 : funk. */ 102 : 103 : /* buf is a handle to the account shared data. 104 : Sets the account shared data as read only. */ 105 : fd_txn_account_t * 106 : fd_txn_account_make_readonly( fd_txn_account_t * acct, 107 : void * buf ); 108 : 109 : /* Restores the original contents of the account shared data into 110 : its read-only fields (const_meta, const_data, const_rec). 111 : If the account metadata was modified, returns a pointer to metadata, 112 : otherwise returns null. */ 113 : void * 114 : fd_txn_account_restore( fd_txn_account_t * acct ); 115 : 116 : static inline int 117 0 : fd_txn_account_checked_add_lamports( fd_txn_account_t * acct, ulong lamports ) { 118 0 : ulong balance_post = 0UL; 119 0 : int err = fd_ulong_checked_add( acct->const_meta->info.lamports, lamports, &balance_post ); 120 0 : if( FD_UNLIKELY( err ) ) { 121 0 : return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW; 122 0 : } 123 : 124 0 : fd_txn_account_set_lamports( acct, balance_post ); 125 0 : return FD_EXECUTOR_INSTR_SUCCESS; 126 0 : } 127 : 128 : static inline ulong 129 0 : fd_txn_account_get_lamports( fd_txn_account_t const * acct ) { 130 : /* (!meta) considered an internal error */ 131 0 : if( FD_UNLIKELY( !acct->const_meta ) ) return 0UL; 132 0 : return acct->const_meta->info.lamports; 133 0 : } 134 : 135 : /* read/write mutual exclusion */ 136 : 137 : FD_FN_PURE static inline int 138 0 : fd_txn_account_acquire_write_is_safe( fd_txn_account_t const * acct ) { 139 0 : return (!acct->refcnt_excl) & (!acct->refcnt_shared); 140 0 : } 141 : 142 : FD_FN_PURE static inline int 143 0 : fd_txn_account_acquire_read_is_safe( fd_txn_account_t const * acct ) { 144 0 : return (!acct->refcnt_excl); 145 0 : } 146 : 147 : /* fd_txn_account_acquire_write acquires write/exclusive access. 148 : Causes all other write or read acquire attempts will fail. Returns 1 149 : on success, 0 on failure. */ 150 : static inline int 151 0 : fd_txn_account_acquire_write( fd_txn_account_t * acct ) { 152 0 : if( FD_UNLIKELY( !fd_txn_account_acquire_write_is_safe( acct ) ) ) { 153 0 : return 0; 154 0 : } 155 0 : acct->refcnt_excl = (ushort)1; 156 0 : return 1; 157 0 : } 158 : 159 : /* fd_txn_account_release_write{_private} releases a write/exclusive 160 : access handle. The private version should only be used by fd_borrowed_account_drop 161 : and fd_borrowed_account_destroy. */ 162 : static inline void 163 0 : fd_txn_account_release_write( fd_txn_account_t * acct ) { 164 0 : FD_TEST( acct->refcnt_excl==1U ); 165 0 : acct->refcnt_excl = (ushort)0; 166 0 : } 167 : 168 : static inline void 169 0 : fd_txn_account_release_write_private(fd_txn_account_t * acct ) { 170 : /* Only release if it is not yet released */ 171 0 : if( !fd_txn_account_acquire_write_is_safe( acct ) ) { 172 0 : fd_txn_account_release_write( acct ); 173 0 : } 174 0 : } 175 : 176 : /* Factory constructor */ 177 : int 178 : fd_txn_account_create_from_funk( fd_txn_account_t * acct_ptr, 179 : fd_pubkey_t const * acc_pubkey, 180 : fd_acc_mgr_t * acc_mgr, 181 : fd_funk_txn_t * funk_txn ); 182 : 183 : FD_PROTOTYPES_END 184 : 185 : #endif /* HEADER_fd_src_flamenco_runtime_fd_txn_account_h */