Line data Source code
1 : #include "fd_accdb_svm.h"
2 : #include "fd_hashes.h"
3 : #include "fd_bank.h"
4 : #include "../capture/fd_capture_ctx.h"
5 :
6 : static void
7 : log_account_change( fd_bank_t const * bank,
8 : fd_acc_t * ro,
9 6066 : fd_capture_ctx_t * capture_ctx ) {
10 6066 : if( FD_UNLIKELY( capture_ctx &&
11 6066 : capture_ctx->capture_solcap &&
12 6066 : bank->f.slot>=capture_ctx->solcap_start_slot ) ) {
13 0 : fd_solana_account_meta_t solana_meta[1];
14 0 : fd_solana_account_meta_init( solana_meta, ro->lamports, ro->owner, ro->executable );
15 0 : fd_capture_link_write_account_update(
16 0 : capture_ctx,
17 0 : capture_ctx->current_txn_idx,
18 0 : (fd_pubkey_t const *)ro->pubkey,
19 0 : solana_meta,
20 0 : bank->f.slot,
21 0 : ro->data,
22 0 : ro->data_len );
23 0 : }
24 6066 : }
25 :
26 : fd_acc_t
27 : fd_accdb_svm_open_rw( fd_bank_t * bank,
28 : fd_accdb_t * accdb,
29 : fd_accdb_svm_update_t * update,
30 : fd_pubkey_t const * pubkey,
31 6075 : int create ) {
32 6075 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
33 6075 : if( FD_UNLIKELY( !acc.lamports && !create ) ) {
34 9 : fd_accdb_unwrite_one( accdb, &acc );
35 9 : return acc;
36 9 : }
37 :
38 6066 : update->lamports_before = acc.lamports;
39 :
40 6066 : fd_lthash_value_t hash[1];
41 6066 : fd_hashes_account_lthash_simple( acc.pubkey, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, hash );
42 :
43 6066 : fd_lthash_value_t * bank_lthash = fd_bank_lthash_locking_modify( bank );
44 6066 : fd_lthash_sub( bank_lthash, hash );
45 6066 : fd_bank_lthash_end_locking_modify( bank );
46 :
47 6066 : return acc;
48 6075 : }
49 :
50 : void
51 : fd_accdb_svm_close_rw( fd_bank_t * bank,
52 : fd_accdb_t * accdb,
53 : fd_capture_ctx_t * capture_ctx,
54 : fd_acc_t * acc,
55 6066 : fd_accdb_svm_update_t * update ) {
56 6066 : if( FD_UNLIKELY( acc->lamports>update->lamports_before ) ) {
57 15 : ulong delta = acc->lamports-update->lamports_before;
58 15 : FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
59 6051 : } else if( FD_UNLIKELY( acc->lamports<update->lamports_before ) ) {
60 0 : ulong delta = update->lamports_before-acc->lamports;
61 0 : FD_TEST( !__builtin_usubl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
62 0 : }
63 :
64 6066 : fd_lthash_value_t hash[1];
65 6066 : fd_hashes_account_lthash_simple( acc->pubkey, acc->owner, acc->lamports, acc->executable, acc->data, acc->data_len, hash );
66 :
67 6066 : fd_lthash_value_t * bank_lthash = fd_bank_lthash_locking_modify( bank );
68 6066 : fd_lthash_add( bank_lthash, hash );
69 6066 : fd_bank_lthash_end_locking_modify( bank );
70 :
71 6066 : log_account_change( bank, acc, capture_ctx );
72 6066 : acc->commit = 1;
73 6066 : fd_accdb_unwrite_one( accdb, acc );
74 6066 : }
75 :
76 : void
77 : fd_accdb_svm_credit( fd_bank_t * bank,
78 : fd_accdb_t * accdb,
79 : fd_capture_ctx_t * capture_ctx,
80 : fd_pubkey_t const * pubkey,
81 6 : ulong lamports_add ) {
82 6 : if( FD_UNLIKELY( !lamports_add ) ) return;
83 :
84 6 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
85 :
86 6 : fd_lthash_value_t hash[1];
87 6 : fd_hashes_account_lthash_simple( acc.pubkey, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, hash );
88 6 : FD_TEST( !__builtin_uaddl_overflow( acc.lamports, lamports_add, &acc.lamports ) );
89 6 : FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, lamports_add, &bank->f.capitalization ) );
90 :
91 6 : fd_lthash_value_t post[1];
92 6 : fd_hashes_update_simple( post, hash, pubkey->uc, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, bank, capture_ctx );
93 6 : acc.commit = 1;
94 6 : fd_accdb_unwrite_one( accdb, &acc );
95 6 : }
96 :
97 : void
98 : fd_accdb_svm_write( fd_bank_t * bank,
99 : fd_accdb_t * accdb,
100 : fd_capture_ctx_t * capture_ctx,
101 : fd_pubkey_t const * pubkey,
102 : fd_pubkey_t const * owner,
103 : void const * data,
104 : ulong sz,
105 : ulong lamports_min,
106 5202 : int exec_bit ) {
107 5202 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
108 :
109 5202 : fd_lthash_value_t hash[1];
110 5202 : fd_hashes_account_lthash_simple( acc.pubkey, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, hash );
111 :
112 5202 : if( FD_UNLIKELY( acc.lamports<lamports_min ) ) {
113 270 : ulong delta = lamports_min - acc.lamports;
114 270 : acc.lamports = lamports_min;
115 270 : FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
116 270 : }
117 :
118 5202 : fd_memcpy( acc.owner, owner, 32UL );
119 5202 : acc.executable = !!exec_bit;
120 :
121 5202 : fd_memcpy( acc.data, data, sz );
122 5202 : acc.data_len = sz;
123 :
124 5202 : fd_lthash_value_t post[1];
125 5202 : fd_hashes_update_simple( post, hash, pubkey->uc, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, bank, capture_ctx );
126 5202 : acc.commit = 1;
127 5202 : fd_accdb_unwrite_one( accdb, &acc );
128 5202 : }
129 :
130 : ulong
131 : fd_accdb_svm_remove( fd_bank_t * bank,
132 : fd_accdb_t * accdb,
133 : fd_capture_ctx_t * capture_ctx,
134 81 : fd_pubkey_t const * pubkey ) {
135 81 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
136 81 : if( FD_UNLIKELY( !acc.lamports ) ) {
137 81 : fd_accdb_unwrite_one( accdb, &acc );
138 81 : return 0UL;
139 81 : }
140 :
141 0 : ulong burned = acc.lamports;
142 :
143 0 : fd_lthash_value_t hash[1];
144 0 : fd_hashes_account_lthash_simple( acc.pubkey, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, hash );
145 :
146 0 : bank->f.capitalization -= burned;
147 0 : acc.lamports = 0UL;
148 :
149 0 : fd_lthash_value_t post[1];
150 0 : fd_hashes_update_simple( post, hash, pubkey->uc, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, bank, capture_ctx );
151 0 : acc.commit = 1;
152 0 : fd_accdb_unwrite_one( accdb, &acc );
153 0 : return burned;
154 81 : }
|