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 10155 : fd_capture_ctx_t * capture_ctx ) {
11 10155 : if( FD_UNLIKELY( capture_ctx &&
12 10155 : capture_ctx->capture_solcap &&
13 10155 : 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 10155 : }
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 10167 : int create ) {
33 10167 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
34 10167 : if( FD_UNLIKELY( !acc.lamports && !create ) ) {
35 12 : fd_accdb_unwrite_one( accdb, &acc );
36 12 : return acc;
37 12 : }
38 :
39 10155 : update->lamports_before = acc.lamports;
40 10155 : update->data_len_before = acc.data_len;
41 10155 : update->skip_event_diff = 0;
42 10155 : fd_memcpy( update->owner_before, acc.owner, 32UL );
43 :
44 10155 : fd_lthash_value_t hash[1];
45 10155 : fd_hashes_account_lthash_simple( acc.pubkey, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, hash );
46 :
47 10155 : fd_lthash_value_t * bank_lthash = fd_bank_lthash_locking_modify( bank );
48 10155 : fd_lthash_sub( bank_lthash, hash );
49 10155 : fd_bank_lthash_end_locking_modify( bank );
50 :
51 10155 : return acc;
52 10167 : }
53 :
54 : void
55 : fd_accdb_svm_close_rw( fd_bank_t * bank,
56 : fd_accdb_t * accdb,
57 : fd_capture_ctx_t * capture_ctx,
58 : fd_acc_t * acc,
59 10155 : fd_accdb_svm_update_t * update ) {
60 10155 : if( FD_UNLIKELY( acc->lamports>update->lamports_before ) ) {
61 249 : ulong delta = acc->lamports-update->lamports_before;
62 249 : FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
63 9906 : } else if( FD_UNLIKELY( acc->lamports<update->lamports_before ) ) {
64 69 : ulong delta = update->lamports_before-acc->lamports;
65 69 : FD_TEST( !__builtin_usubl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
66 69 : }
67 :
68 10155 : fd_lthash_value_t hash[1];
69 10155 : fd_hashes_account_lthash_simple( acc->pubkey, acc->owner, acc->lamports, acc->executable, acc->data, acc->data_len, hash );
70 :
71 10155 : fd_lthash_value_t * bank_lthash = fd_bank_lthash_locking_modify( bank );
72 10155 : fd_lthash_add( bank_lthash, hash );
73 10155 : fd_bank_lthash_end_locking_modify( bank );
74 :
75 10155 : log_account_change( bank, acc, capture_ctx );
76 10155 : 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 );
77 10155 : acc->commit = 1;
78 10155 : fd_accdb_unwrite_one( accdb, acc );
79 10155 : }
80 :
81 : void
82 : fd_accdb_svm_credit( fd_bank_t * bank,
83 : fd_accdb_t * accdb,
84 : fd_capture_ctx_t * capture_ctx,
85 : fd_pubkey_t const * pubkey,
86 : ulong lamports_add,
87 81 : int is_vote_reward ) {
88 81 : if( FD_UNLIKELY( !lamports_add ) ) return;
89 :
90 78 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
91 :
92 78 : ulong lamports_pre = acc.lamports;
93 78 : FD_TEST( !__builtin_uaddl_overflow( acc.lamports, lamports_add, &acc.lamports ) );
94 78 : FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, lamports_add, &bank->f.capitalization ) );
95 :
96 78 : fd_hashes_update_pair( pubkey->uc, acc.owner, lamports_pre, acc.executable, acc.data, acc.data_len,
97 78 : acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len,
98 78 : bank, capture_ctx );
99 78 : if( FD_UNLIKELY( fd_bank_report_runtime_diffs( bank ) ) ) {
100 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 );
101 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 );
102 0 : }
103 78 : acc.commit = 1;
104 78 : fd_accdb_unwrite_one( accdb, &acc );
105 78 : }
106 :
107 : void
108 : fd_accdb_svm_write( fd_bank_t * bank,
109 : fd_accdb_t * accdb,
110 : fd_capture_ctx_t * capture_ctx,
111 : fd_pubkey_t const * pubkey,
112 : fd_pubkey_t const * owner,
113 : void const * data,
114 : ulong sz,
115 : ulong lamports_min,
116 : int exec_bit,
117 8784 : int skip_event_diff ) {
118 8784 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
119 8784 : ulong lamports_pre = acc.lamports;
120 8784 : ulong data_len_pre = acc.data_len;
121 8784 : uchar owner_pre[ 32 ]; fd_memcpy( owner_pre, acc.owner, 32UL );
122 :
123 8784 : if( FD_UNLIKELY( acc.lamports<lamports_min ) ) {
124 492 : ulong delta = lamports_min - acc.lamports;
125 492 : acc.lamports = lamports_min;
126 492 : FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
127 492 : }
128 :
129 8784 : fd_memcpy( acc.owner, owner, 32UL );
130 8784 : acc.executable = !!exec_bit;
131 :
132 8784 : fd_memcpy( acc.data, data, sz );
133 8784 : acc.data_len = sz;
134 :
135 8784 : fd_hashes_update_pair( pubkey->uc, acc.prior_owner, acc.prior_lamports, acc.prior_executable, acc.prior_data, acc.prior_data_len,
136 8784 : acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len,
137 8784 : bank, capture_ctx );
138 8784 : 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 );
139 8784 : acc.commit = 1;
140 8784 : fd_accdb_unwrite_one( accdb, &acc );
141 8784 : }
142 :
143 : ulong
144 : fd_accdb_svm_remove( fd_bank_t * bank,
145 : fd_accdb_t * accdb,
146 : fd_capture_ctx_t * capture_ctx,
147 414 : fd_pubkey_t const * pubkey ) {
148 414 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
149 414 : if( FD_UNLIKELY( !acc.lamports ) ) {
150 384 : fd_accdb_unwrite_one( accdb, &acc );
151 384 : return 0UL;
152 384 : }
153 :
154 30 : ulong burned = acc.lamports;
155 :
156 30 : fd_lthash_value_t hash[1];
157 30 : fd_hashes_account_lthash_simple( acc.pubkey, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, hash );
158 :
159 30 : bank->f.capitalization -= burned;
160 30 : acc.lamports = 0UL;
161 :
162 30 : fd_lthash_value_t post[1];
163 30 : fd_hashes_update_simple( post, hash, pubkey->uc, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, bank, capture_ctx );
164 30 : 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 );
165 30 : acc.commit = 1;
166 30 : fd_accdb_unwrite_one( accdb, &acc );
167 30 : return burned;
168 414 : }
|