Line data Source code
1 : #include "fd_accdb_funk.h"
2 : #include "../../funk/fd_funk.h"
3 :
4 : void
5 : fd_accdb_funk_copy_account( fd_account_meta_t * out_meta,
6 : void * out_data,
7 : fd_account_meta_t const * src_meta,
8 228 : void const * src_data ) {
9 228 : memset( out_meta, 0, sizeof(fd_account_meta_t) );
10 228 : out_meta->lamports = src_meta->lamports;
11 228 : if( FD_LIKELY( out_meta->lamports ) ) {
12 222 : memcpy( out_meta->owner, src_meta->owner, 32UL );
13 222 : out_meta->executable = !!src_meta->executable;
14 222 : out_meta->dlen = (uint)src_meta->dlen;
15 222 : fd_memcpy( out_data, src_data, out_meta->dlen );
16 222 : }
17 228 : }
18 :
19 : void
20 : fd_accdb_funk_copy_truncated( fd_account_meta_t * out_meta,
21 3 : fd_account_meta_t const * src_meta ) {
22 3 : memset( out_meta, 0, sizeof(fd_account_meta_t) );
23 3 : out_meta->lamports = src_meta->lamports;
24 3 : if( FD_LIKELY( out_meta->lamports ) ) {
25 3 : memcpy( out_meta->owner, src_meta->owner, 32UL );
26 3 : out_meta->executable = !!src_meta->executable;
27 3 : out_meta->dlen = 0;
28 3 : }
29 3 : }
30 :
31 : /* fd_accdb_v1_prep_create preps a writable handle for a newly created
32 : account. */
33 :
34 : fd_accdb_rw_t *
35 : fd_accdb_funk_prep_create( fd_accdb_rw_t * rw,
36 : fd_funk_t * funk,
37 : fd_funk_txn_t const * txn,
38 : void const * address,
39 : void * val,
40 : ulong val_sz,
41 2496 : ulong val_max ) {
42 2496 : FD_CRIT( val_sz >=sizeof(fd_account_meta_t), "invalid val_sz" );
43 2496 : FD_CRIT( val_max>=sizeof(fd_account_meta_t), "invalid val_max" );
44 2496 : FD_CRIT( val_sz<=val_max, "invalid val_max" );
45 2496 : fd_account_meta_t * meta = val;
46 :
47 2496 : fd_funk_rec_t * rec = fd_funk_rec_pool_acquire( funk->rec_pool, NULL, 1, NULL );
48 2496 : if( FD_UNLIKELY( !rec ) ) FD_LOG_CRIT(( "Failed to modify account: DB record pool is out of memory" ));
49 2496 : ulong rec_idx = (ulong)( rec - funk->rec_pool->ele );
50 2496 : funk->rec_lock[ rec_idx ] = fd_funk_rec_ver_lock( fd_funk_rec_ver_inc( fd_funk_rec_ver_bits( funk->rec_lock[ rec_idx ] ) ), FD_FUNK_REC_LOCK_MASK );
51 :
52 2496 : if( FD_LIKELY( txn ) ) {
53 1650 : fd_funk_txn_xid_copy( rec->pair.xid, &txn->xid );
54 1650 : meta->slot = txn->xid.ul[0];
55 1650 : } else {
56 846 : fd_funk_txn_xid_set_root( rec->pair.xid );
57 846 : meta->slot = fd_funk_last_publish( funk )->ul[0];
58 846 : }
59 2496 : memcpy( rec->pair.key->uc, address, 32UL );
60 2496 : rec->map_next = 0U;
61 2496 : rec->next_idx = FD_FUNK_REC_IDX_NULL;
62 2496 : rec->prev_idx = FD_FUNK_REC_IDX_NULL;
63 2496 : rec->val_sz = (uint)( fd_ulong_min( val_sz, FD_FUNK_REC_VAL_MAX ) & FD_FUNK_REC_VAL_MAX );
64 2496 : rec->val_max = (uint)( fd_ulong_min( val_max, FD_FUNK_REC_VAL_MAX ) & FD_FUNK_REC_VAL_MAX );
65 2496 : rec->tag = 0;
66 2496 : rec->val_gaddr = fd_wksp_gaddr_fast( funk->wksp, val );
67 :
68 2496 : *rw = (fd_accdb_rw_t){0};
69 2496 : memcpy( rw->ref->address, address, 32UL );
70 2496 : rw->ref->accdb_type = FD_ACCDB_TYPE_V1;
71 2496 : rw->ref->user_data = (ulong)rec;
72 2496 : rw->ref->user_data2 = (ulong)txn;
73 2496 : rw->ref->ref_type = FD_ACCDB_REF_RW;
74 2496 : rw->meta = meta;
75 2496 : return rw;
76 2496 : }
77 :
78 : /* fd_accdb_prep_inplace preps a writable handle for a mutable record. */
79 :
80 : fd_accdb_rw_t *
81 : fd_accdb_funk_prep_inplace( fd_accdb_rw_t * rw,
82 : fd_funk_t * funk,
83 6663 : fd_funk_rec_t * rec ) {
84 : /* Take the opportunity to run some validation checks */
85 6663 : if( FD_UNLIKELY( !rec->val_gaddr ) ) {
86 0 : FD_LOG_CRIT(( "Failed to prepare in-place account write: rec %p is not allocated", (void *)rec ));
87 0 : }
88 :
89 6663 : *rw = (fd_accdb_rw_t) {0};
90 6663 : memcpy( rw->ref->address, rec->pair.key->uc, 32UL );
91 6663 : rw->ref->accdb_type = FD_ACCDB_TYPE_V1;
92 6663 : rw->ref->user_data = (ulong)rec;
93 6663 : rw->ref->ref_type = FD_ACCDB_REF_RW;
94 6663 : rw->meta = fd_funk_val( rec, funk->wksp );
95 6663 : if( FD_UNLIKELY( !rw->meta->lamports ) ) {
96 3075 : memset( rw->meta, 0, sizeof(fd_account_meta_t) );
97 3075 : }
98 6663 : return rw;
99 6663 : }
100 :
101 : fd_accdb_rw_t *
102 : fd_accdb_funk_create( fd_funk_t * funk,
103 : fd_accdb_rw_t * rw,
104 : fd_funk_txn_t const * txn,
105 : void const * address,
106 2265 : ulong data_max ) {
107 2265 : ulong val_sz_min = sizeof(fd_account_meta_t)+data_max;
108 2265 : ulong val_max = 0UL;
109 2265 : void * val = fd_alloc_malloc_at_least( funk->alloc, 16UL, val_sz_min, &val_max );
110 2265 : if( FD_UNLIKELY( !val ) ) {
111 0 : FD_LOG_CRIT(( "Failed to modify account: out of memory allocating %lu bytes", data_max ));
112 0 : }
113 2265 : memset( val, 0, sizeof(fd_account_meta_t) );
114 2265 : return fd_accdb_funk_prep_create( rw, funk, txn, address, val, sizeof(fd_account_meta_t), val_max );
115 2265 : }
|