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 : #include "../events/fd_event_runtime.h"
6 :
7 : static void
8 : log_account_change( fd_bank_t const * bank,
9 : fd_acc_t * ro,
10 1832 : fd_capture_ctx_t * capture_ctx ) {
11 1832 : if( FD_UNLIKELY( capture_ctx &&
12 1832 : capture_ctx->capture_solcap &&
13 1832 : bank->f.slot>=capture_ctx->solcap_start_slot ) ) {
14 0 : fd_solana_account_meta_t solana_meta[1];
15 0 : fd_solana_account_meta_init( solana_meta, ro->lamports, ro->owner, ro->executable );
16 0 : fd_capture_link_write_account_update(
17 0 : capture_ctx,
18 0 : capture_ctx->current_txn_idx,
19 0 : (fd_pubkey_t const *)ro->pubkey,
20 0 : solana_meta,
21 0 : bank->f.slot,
22 0 : ro->data,
23 0 : ro->data_len );
24 0 : }
25 1832 : }
26 :
27 : fd_acc_t
28 : fd_accdb_svm_open_rw( fd_bank_t * bank,
29 : fd_accdb_t * accdb,
30 : fd_accdb_svm_update_t * update,
31 : fd_pubkey_t const * pubkey,
32 1832 : int create ) {
33 1832 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
34 1832 : if( FD_UNLIKELY( !acc.lamports && !create ) ) {
35 0 : fd_accdb_unwrite_one( accdb, &acc );
36 0 : return acc;
37 0 : }
38 :
39 1832 : update->lamports_before = acc.lamports;
40 1832 : update->data_len_before = acc.data_len;
41 1832 : update->skip_event_diff = 0;
42 1832 : fd_memcpy( update->owner_before, acc.owner, 32UL );
43 :
44 1832 : if( bank->lthash_mode==FD_BANK_LTHASH_MODE_INBAND ) {
45 1832 : fd_lthash_value_t hash[1];
46 1832 : fd_hashes_account_lthash_simple( acc.pubkey, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, hash );
47 :
48 1832 : fd_lthash_value_t * bank_lthash = fd_bank_lthash_locking_modify( bank );
49 1832 : fd_lthash_sub( bank_lthash, hash );
50 1832 : fd_bank_lthash_end_locking_modify( bank );
51 1832 : }
52 :
53 1832 : return acc;
54 1832 : }
55 :
56 : void
57 : fd_accdb_svm_close_rw( fd_bank_t * bank,
58 : fd_accdb_t * accdb,
59 : fd_capture_ctx_t * capture_ctx,
60 : fd_acc_t * acc,
61 1832 : fd_accdb_svm_update_t * update ) {
62 1832 : if( FD_UNLIKELY( acc->lamports>update->lamports_before ) ) {
63 337 : ulong delta = acc->lamports-update->lamports_before;
64 337 : FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
65 1495 : } else if( FD_UNLIKELY( acc->lamports<update->lamports_before ) ) {
66 101 : ulong delta = update->lamports_before-acc->lamports;
67 101 : FD_TEST( !__builtin_usubl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
68 101 : }
69 :
70 1832 : if( bank->lthash_mode==FD_BANK_LTHASH_MODE_INBAND ) {
71 1832 : fd_lthash_value_t hash[1];
72 1832 : fd_hashes_account_lthash_simple( acc->pubkey, acc->owner, acc->lamports, acc->executable, acc->data, acc->data_len, hash );
73 :
74 1832 : fd_lthash_value_t * bank_lthash = fd_bank_lthash_locking_modify( bank );
75 1832 : fd_lthash_add( bank_lthash, hash );
76 1832 : fd_bank_lthash_end_locking_modify( bank );
77 1832 : } else if( bank->lthash_mode==FD_BANK_LTHASH_MODE_OOB_RECORD ) {
78 0 : fd_bank_lthash_record( bank, acc->pubkey );
79 0 : }
80 :
81 1832 : log_account_change( bank, acc, capture_ctx );
82 1832 : if( FD_UNLIKELY( fd_bank_report_runtime_diffs( bank ) && !update->skip_event_diff ) ) fd_event_runtime_block_account( bank, acc->pubkey, update->owner_before, acc->owner, update->lamports_before, acc->lamports, update->data_len_before, acc->data_len, acc->executable );
83 1832 : acc->commit = 1;
84 1832 : fd_accdb_unwrite_one( accdb, acc );
85 1832 : }
86 :
87 : void
88 : fd_accdb_svm_credit( fd_bank_t * bank,
89 : fd_accdb_t * accdb,
90 : fd_capture_ctx_t * capture_ctx,
91 : fd_pubkey_t const * pubkey,
92 : ulong lamports_add,
93 50 : int is_vote_reward ) {
94 50 : if( FD_UNLIKELY( !lamports_add ) ) return;
95 :
96 48 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
97 :
98 48 : ulong lamports_pre = acc.lamports;
99 48 : FD_TEST( !__builtin_uaddl_overflow( acc.lamports, lamports_add, &acc.lamports ) );
100 48 : FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, lamports_add, &bank->f.capitalization ) );
101 :
102 48 : fd_hashes_update_pair( pubkey->uc, acc.owner, lamports_pre, acc.executable, acc.data, acc.data_len,
103 48 : acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len,
104 48 : bank, capture_ctx );
105 48 : if( FD_UNLIKELY( fd_bank_report_runtime_diffs( bank ) ) ) {
106 0 : if( FD_UNLIKELY( is_vote_reward ) ) fd_event_runtime_reward_emit( bank, FD_EVENT_RUNTIME_REWARD_KIND_VOTE, acc.pubkey, acc.owner, lamports_pre, acc.lamports, 0UL, 0UL, 0UL );
107 0 : else fd_event_runtime_block_account( bank, acc.pubkey, acc.owner, acc.owner, lamports_pre, acc.lamports, acc.data_len, acc.data_len, acc.executable );
108 0 : }
109 48 : acc.commit = 1;
110 48 : fd_accdb_unwrite_one( accdb, &acc );
111 48 : }
112 :
113 : void
114 : fd_accdb_svm_write( fd_bank_t * bank,
115 : fd_accdb_t * accdb,
116 : fd_capture_ctx_t * capture_ctx,
117 : fd_pubkey_t const * pubkey,
118 : fd_pubkey_t const * owner,
119 : void const * data,
120 : ulong sz,
121 : ulong lamports_min,
122 : int exec_bit,
123 1650 : int skip_event_diff ) {
124 1650 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
125 1650 : ulong lamports_pre = acc.lamports;
126 1650 : ulong data_len_pre = acc.data_len;
127 1650 : uchar owner_pre[ 32 ]; fd_memcpy( owner_pre, acc.owner, 32UL );
128 :
129 1650 : if( FD_UNLIKELY( acc.lamports<lamports_min ) ) {
130 3 : ulong delta = lamports_min - acc.lamports;
131 3 : acc.lamports = lamports_min;
132 3 : FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
133 3 : }
134 :
135 1650 : fd_memcpy( acc.owner, owner, 32UL );
136 1650 : acc.executable = !!exec_bit;
137 :
138 1650 : fd_memcpy( acc.data, data, sz );
139 1650 : acc.data_len = sz;
140 :
141 1650 : fd_hashes_update_pair( pubkey->uc, acc.prior_owner, acc.prior_lamports, acc.prior_executable, acc.prior_data, acc.prior_data_len,
142 1650 : acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len,
143 1650 : bank, capture_ctx );
144 1650 : if( FD_UNLIKELY( fd_bank_report_runtime_diffs( bank ) && !skip_event_diff ) ) fd_event_runtime_block_account( bank, acc.pubkey, owner_pre, acc.owner, lamports_pre, acc.lamports, data_len_pre, acc.data_len, acc.executable );
145 1650 : acc.commit = 1;
146 1650 : fd_accdb_unwrite_one( accdb, &acc );
147 1650 : }
148 :
149 : ulong
150 : fd_accdb_svm_remove( fd_bank_t * bank,
151 : fd_accdb_t * accdb,
152 : fd_capture_ctx_t * capture_ctx,
153 611 : fd_pubkey_t const * pubkey ) {
154 611 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
155 611 : if( FD_UNLIKELY( !acc.lamports ) ) {
156 585 : fd_accdb_unwrite_one( accdb, &acc );
157 585 : return 0UL;
158 585 : }
159 :
160 26 : ulong burned = acc.lamports;
161 :
162 26 : fd_lthash_value_t hash[1]; /* read by fd_hashes_update_simple only in INBAND mode */
163 26 : if( bank->lthash_mode==FD_BANK_LTHASH_MODE_INBAND ) {
164 26 : fd_hashes_account_lthash_simple( acc.pubkey, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, hash );
165 26 : }
166 :
167 26 : bank->f.capitalization -= burned;
168 26 : acc.lamports = 0UL;
169 :
170 26 : fd_lthash_value_t post[1];
171 26 : fd_hashes_update_simple( post, hash, pubkey->uc, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, bank, capture_ctx );
172 26 : if( FD_UNLIKELY( fd_bank_report_runtime_diffs( bank ) ) ) fd_event_runtime_block_account( bank, acc.pubkey, acc.owner, acc.owner, burned, 0UL, acc.data_len, 0UL, 0 );
173 26 : acc.commit = 1;
174 26 : fd_accdb_unwrite_one( accdb, &acc );
175 26 : return burned;
176 611 : }
|