Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_accdb_fd_accdb_ref_h 2 : #define HEADER_fd_src_flamenco_accdb_fd_accdb_ref_h 3 : 4 : /* fd_accdb_ref.h provides account database handle classes. 5 : 6 : - accdb_ref is an opaque handle to an account database cache entry. 7 : - accdb_ro (extends accdb_ref) represents a read-only handle. 8 : - accdb_rw (extends accdb_ro) represents a read-write handle. 9 : - accdb_spec is an account speculative read guard 10 : 11 : These APIs sit between the database layer (abstracts away backing 12 : stores and DB specifics) and the runtime layer (offer no runtime 13 : protections). */ 14 : 15 : #include "fd_accdb_base.h" 16 : #include "../fd_flamenco_base.h" 17 : 18 : /* fd_accdb_ref_t is an opaque account database handle. */ 19 : 20 : struct fd_accdb_ref { 21 : ulong meta_laddr; 22 : ulong user_data; 23 : ulong user_data2; 24 : uchar address[32]; 25 : uint accdb_type; /* FD_ACCDB_TYPE_* */ 26 : uchar ref_type; /* FD_ACCDB_REF_* */ 27 : }; 28 : typedef struct fd_accdb_ref fd_accdb_ref_t; 29 : 30 : /* fd_accdb_ro_t is a readonly account database handle. */ 31 : 32 : union fd_accdb_ro { 33 : fd_accdb_ref_t ref[1]; 34 : struct { 35 : fd_account_meta_t const * meta; 36 : }; 37 : }; 38 : typedef union fd_accdb_ro fd_accdb_ro_t; 39 : 40 : FD_PROTOTYPES_BEGIN 41 : 42 : /* fd_accdb_ro_init_nodb creates a read-only account reference to an 43 : account that is not managed by an account database. This is useful 44 : for local caching (e.g. cross-program invocations). */ 45 : 46 : static inline fd_accdb_ro_t * 47 : fd_accdb_ro_init_nodb( fd_accdb_ro_t * ro, 48 : void const * address, 49 6 : fd_account_meta_t const * meta ) { 50 6 : ro->meta = meta; 51 6 : ro->ref->user_data = 0UL; 52 6 : ro->ref->user_data2 = 0UL; 53 6 : memcpy( ro->ref->address, address, 32UL ); 54 6 : ro->ref->accdb_type = FD_ACCDB_TYPE_NONE; 55 6 : ro->ref->ref_type = FD_ACCDB_REF_RO; 56 6 : return ro; 57 6 : } 58 : 59 : /* fd_accdb_ro_init_empty creates a read-only account reference to a 60 : non-existent account. */ 61 : 62 : extern fd_account_meta_t const fd_accdb_meta_empty; 63 : 64 : static inline fd_accdb_ro_t * 65 : fd_accdb_ro_init_empty( fd_accdb_ro_t * ro, 66 9729 : void const * address ) { 67 9729 : ro->meta = &fd_accdb_meta_empty; 68 9729 : ro->ref->user_data = 0UL; 69 9729 : ro->ref->user_data2 = 0UL; 70 9729 : memcpy( ro->ref->address, address, 32UL ); 71 9729 : ro->ref->accdb_type = FD_ACCDB_TYPE_NONE; 72 9729 : ro->ref->ref_type = FD_ACCDB_REF_RO; 73 9729 : return ro; 74 9729 : } 75 : 76 : static inline void const * 77 597 : fd_accdb_ref_address( fd_accdb_ro_t const * ro ) { 78 597 : return ro->ref->address; 79 597 : } 80 : 81 : static inline void const * 82 1539 : fd_accdb_ref_data_const( fd_accdb_ro_t const * ro ) { 83 1539 : return (void *)( ro->meta+1 ); 84 1539 : } 85 : 86 : static inline ulong 87 7716 : fd_accdb_ref_data_sz( fd_accdb_ro_t const * ro ) { 88 7716 : return ro->meta->dlen; 89 7716 : } 90 : 91 : static inline ulong 92 21438 : fd_accdb_ref_lamports( fd_accdb_ro_t const * ro ) { 93 21438 : return ro->meta->lamports; 94 21438 : } 95 : 96 : static inline void const * 97 114 : fd_accdb_ref_owner( fd_accdb_ro_t const * ro ) { 98 114 : return ro->meta->owner; 99 114 : } 100 : 101 : static inline uint 102 0 : fd_accdb_ref_exec_bit( fd_accdb_ro_t const * ro ) { 103 0 : return !!ro->meta->executable; 104 0 : } 105 : 106 : static inline ulong 107 0 : fd_accdb_ref_slot( fd_accdb_ro_t const * ro ) { 108 0 : return ro->meta->slot; 109 0 : } 110 : 111 : // void 112 : // fd_accdb_ref_lthash( fd_accdb_ro_t const * ro, 113 : // void * lthash ); 114 : 115 : FD_PROTOTYPES_END 116 : 117 : /* fd_accdb_rw_t is a writable database handle. Typically, writable 118 : handles are only available for invisible/in-prepartion records. 119 : In rare cases (e.g. when booting up), components may directly write 120 : to globally visible writable records. */ 121 : 122 : union fd_accdb_rw { 123 : fd_accdb_ref_t ref[1]; 124 : fd_accdb_ro_t ro [1]; 125 : struct { 126 : fd_account_meta_t * meta; 127 : }; 128 : }; 129 : typedef union fd_accdb_rw fd_accdb_rw_t; 130 : 131 : FD_PROTOTYPES_BEGIN 132 : 133 : /* fd_accdb_rw_init_nodb creates a writable account reference to an 134 : account that is not managed by an account database. This is useful 135 : for local caching (e.g. cross-program invocations). */ 136 : 137 : static inline fd_accdb_rw_t * 138 : fd_accdb_rw_init_nodb( fd_accdb_rw_t * rw, 139 : void const * address, 140 : fd_account_meta_t const * meta, 141 768 : ulong data_max ) { 142 768 : rw->meta = (fd_account_meta_t *)meta; 143 768 : rw->ref->user_data = data_max; 144 768 : memcpy( rw->ref->address, address, 32UL ); 145 768 : rw->ref->accdb_type = FD_ACCDB_TYPE_NONE; 146 768 : return rw; 147 768 : } 148 : 149 : // void 150 : // fd_accdb_ref_clear( fd_accdb_rw_t * rw ); 151 : 152 : static inline void * 153 744 : fd_accdb_ref_data( fd_accdb_rw_t * rw ) { 154 744 : return (void *)( rw->meta+1 ); 155 744 : } 156 : 157 : static inline void 158 : fd_accdb_ref_lamports_set( fd_accdb_rw_t * rw, 159 6900 : ulong lamports ) { 160 6900 : rw->meta->lamports = lamports; 161 6900 : } 162 : 163 : static inline void 164 : fd_accdb_ref_owner_set( fd_accdb_rw_t * rw, 165 729 : void const * owner ) { 166 729 : memcpy( rw->meta->owner, owner, 32UL ); 167 729 : } 168 : 169 : static inline void 170 : fd_accdb_ref_exec_bit_set( fd_accdb_rw_t * rw, 171 132 : uint exec_bit ) { 172 132 : rw->meta->executable = !!exec_bit; 173 132 : } 174 : 175 : static inline void 176 : fd_accdb_ref_slot_set( fd_accdb_rw_t * rw, 177 24 : ulong slot ) { 178 24 : rw->meta->slot = slot; 179 24 : } 180 : 181 : FD_PROTOTYPES_END 182 : 183 : FD_STATIC_ASSERT( sizeof(fd_accdb_ref_t)==sizeof(fd_accdb_ro_t), layout ); 184 : FD_STATIC_ASSERT( sizeof(fd_accdb_ref_t)==sizeof(fd_accdb_rw_t), layout ); 185 : 186 : #endif /* HEADER_fd_src_flamenco_accdb_fd_accdb_ref_h */