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