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 150 : void const * src_data ) {
9 150 : memset( out_meta, 0, sizeof(fd_account_meta_t) );
10 150 : out_meta->lamports = src_meta->lamports;
11 150 : if( FD_LIKELY( out_meta->lamports ) ) {
12 144 : memcpy( out_meta->owner, src_meta->owner, 32UL );
13 144 : out_meta->executable = !!src_meta->executable;
14 144 : out_meta->dlen = (uint)src_meta->dlen;
15 144 : fd_memcpy( out_data, src_data, out_meta->dlen );
16 144 : }
17 150 : }
18 :
19 : void
20 : fd_accdb_funk_copy_truncated( fd_account_meta_t * out_meta,
21 6 : fd_account_meta_t const * src_meta ) {
22 6 : memset( out_meta, 0, sizeof(fd_account_meta_t) );
23 6 : out_meta->lamports = src_meta->lamports;
24 6 : if( FD_LIKELY( out_meta->lamports ) ) {
25 6 : memcpy( out_meta->owner, src_meta->owner, 32UL );
26 6 : out_meta->executable = !!src_meta->executable;
27 6 : out_meta->dlen = 0;
28 6 : }
29 6 : }
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 1224 : ulong val_max ) {
42 1224 : FD_CRIT( val_sz >=sizeof(fd_account_meta_t), "invalid val_sz" );
43 1224 : FD_CRIT( val_max>=sizeof(fd_account_meta_t), "invalid val_max" );
44 1224 : FD_CRIT( val_sz<=val_max, "invalid val_max" );
45 :
46 1224 : fd_funk_rec_t * rec = fd_funk_rec_pool_acquire( funk->rec_pool, NULL, 1, NULL );
47 1224 : if( FD_UNLIKELY( !rec ) ) FD_LOG_CRIT(( "Failed to modify account: DB record pool is out of memory" ));
48 :
49 1224 : fd_funk_txn_xid_copy( rec->pair.xid, &txn->xid );
50 1224 : memcpy( rec->pair.key->uc, address, 32UL );
51 1224 : rec->map_next = 0U;
52 1224 : rec->ver_lock = fd_funk_rec_ver_lock( fd_funk_rec_ver_inc( fd_funk_rec_ver_bits( rec->ver_lock ) ), FD_FUNK_REC_LOCK_MASK );
53 1224 : rec->next_idx = FD_FUNK_REC_IDX_NULL;
54 1224 : rec->prev_idx = FD_FUNK_REC_IDX_NULL;
55 1224 : rec->val_sz = (uint)( fd_ulong_min( val_sz, FD_FUNK_REC_VAL_MAX ) & FD_FUNK_REC_VAL_MAX );
56 1224 : rec->val_max = (uint)( fd_ulong_min( val_max, FD_FUNK_REC_VAL_MAX ) & FD_FUNK_REC_VAL_MAX );
57 1224 : rec->tag = 0;
58 1224 : rec->val_gaddr = fd_wksp_gaddr_fast( funk->wksp, val );
59 :
60 1224 : fd_account_meta_t * meta = val;
61 1224 : meta->slot = txn->xid.ul[0];
62 :
63 1224 : *rw = (fd_accdb_rw_t){0};
64 1224 : memcpy( rw->ref->address, address, 32UL );
65 1224 : rw->ref->accdb_type = FD_ACCDB_TYPE_V1;
66 1224 : rw->ref->user_data = (ulong)rec;
67 1224 : rw->ref->user_data2 = (ulong)txn;
68 1224 : rw->ref->ref_type = FD_ACCDB_REF_RW;
69 1224 : rw->meta = meta;
70 1224 : return rw;
71 1224 : }
72 :
73 : /* fd_accdb_prep_inplace preps a writable handle for a mutable record. */
74 :
75 : fd_accdb_rw_t *
76 : fd_accdb_funk_prep_inplace( fd_accdb_rw_t * rw,
77 : fd_funk_t * funk,
78 6633 : fd_funk_rec_t * rec ) {
79 : /* Take the opportunity to run some validation checks */
80 6633 : if( FD_UNLIKELY( !rec->val_gaddr ) ) {
81 0 : FD_LOG_CRIT(( "Failed to prepare in-place account write: rec %p is not allocated", (void *)rec ));
82 0 : }
83 :
84 6633 : *rw = (fd_accdb_rw_t) {0};
85 6633 : memcpy( rw->ref->address, rec->pair.key->uc, 32UL );
86 6633 : rw->ref->accdb_type = FD_ACCDB_TYPE_V1;
87 6633 : rw->ref->user_data = (ulong)rec;
88 6633 : rw->ref->ref_type = FD_ACCDB_REF_RW;
89 6633 : rw->meta = fd_funk_val( rec, funk->wksp );
90 6633 : if( FD_UNLIKELY( !rw->meta->lamports ) ) {
91 3072 : memset( rw->meta, 0, sizeof(fd_account_meta_t) );
92 3072 : }
93 6633 : return rw;
94 6633 : }
95 :
96 : fd_accdb_rw_t *
97 : fd_accdb_funk_create( fd_funk_t * funk,
98 : fd_accdb_rw_t * rw,
99 : fd_funk_txn_t const * txn,
100 : void const * address,
101 1068 : ulong data_max ) {
102 1068 : ulong val_sz_min = sizeof(fd_account_meta_t)+data_max;
103 1068 : ulong val_max = 0UL;
104 1068 : void * val = fd_alloc_malloc_at_least( funk->alloc, 16UL, val_sz_min, &val_max );
105 1068 : if( FD_UNLIKELY( !val ) ) {
106 0 : FD_LOG_CRIT(( "Failed to modify account: out of memory allocating %lu bytes", data_max ));
107 0 : }
108 1068 : memset( val, 0, sizeof(fd_account_meta_t) );
109 1068 : return fd_accdb_funk_prep_create( rw, funk, txn, address, val, sizeof(fd_account_meta_t), val_max );
110 1068 : }
|