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 84 : void const * src_data ) {
9 84 : memset( out_meta, 0, sizeof(fd_account_meta_t) );
10 84 : out_meta->lamports = src_meta->lamports;
11 84 : if( FD_LIKELY( out_meta->lamports ) ) {
12 78 : memcpy( out_meta->owner, src_meta->owner, 32UL );
13 78 : out_meta->executable = !!src_meta->executable;
14 78 : out_meta->dlen = (uint)src_meta->dlen;
15 78 : fd_memcpy( out_data, src_data, out_meta->dlen );
16 78 : }
17 84 : }
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 285 : ulong val_max ) {
42 285 : FD_CRIT( val_sz >=sizeof(fd_account_meta_t), "invalid val_sz" );
43 285 : FD_CRIT( val_max>=sizeof(fd_account_meta_t), "invalid val_max" );
44 285 : FD_CRIT( val_sz<=val_max, "invalid val_max" );
45 :
46 285 : fd_funk_rec_t * rec = fd_funk_rec_pool_acquire( funk->rec_pool, NULL, 1, NULL );
47 285 : if( FD_UNLIKELY( !rec ) ) FD_LOG_CRIT(( "Failed to modify account: DB record pool is out of memory" ));
48 :
49 285 : fd_funk_txn_xid_copy( rec->pair.xid, &txn->xid );
50 285 : memcpy( rec->pair.key->uc, address, 32UL );
51 285 : rec->map_next = 0U;
52 285 : 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 285 : rec->next_idx = FD_FUNK_REC_IDX_NULL;
54 285 : rec->prev_idx = FD_FUNK_REC_IDX_NULL;
55 285 : rec->val_sz = (uint)( fd_ulong_min( val_sz, FD_FUNK_REC_VAL_MAX ) & FD_FUNK_REC_VAL_MAX );
56 285 : rec->val_max = (uint)( fd_ulong_min( val_max, FD_FUNK_REC_VAL_MAX ) & FD_FUNK_REC_VAL_MAX );
57 285 : rec->tag = 0;
58 285 : rec->val_gaddr = fd_wksp_gaddr_fast( funk->wksp, val );
59 :
60 285 : fd_account_meta_t * meta = val;
61 285 : meta->slot = txn->xid.ul[0];
62 :
63 285 : *rw = (fd_accdb_rw_t){0};
64 285 : memcpy( rw->ref->address, address, 32UL );
65 285 : rw->ref->accdb_type = FD_ACCDB_TYPE_V1;
66 285 : rw->ref->user_data = (ulong)rec;
67 285 : rw->ref->user_data2 = (ulong)txn;
68 285 : rw->ref->ref_type = FD_ACCDB_REF_RW;
69 285 : rw->meta = meta;
70 285 : return rw;
71 285 : }
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 195 : ulong data_max ) {
102 195 : ulong val_sz_min = sizeof(fd_account_meta_t)+data_max;
103 195 : ulong val_max = 0UL;
104 195 : void * val = fd_alloc_malloc_at_least( funk->alloc, 16UL, val_sz_min, &val_max );
105 195 : if( FD_UNLIKELY( !val ) ) {
106 0 : FD_LOG_CRIT(( "Failed to modify account: out of memory allocating %lu bytes", data_max ));
107 0 : }
108 195 : memset( val, 0, sizeof(fd_account_meta_t) );
109 195 : return fd_accdb_funk_prep_create( rw, funk, txn, address, val, sizeof(fd_account_meta_t), val_max );
110 195 : }
|