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 1757 : fd_capture_ctx_t * capture_ctx ) {
11 1757 : if( FD_UNLIKELY( capture_ctx &&
12 1757 : capture_ctx->capture_solcap &&
13 1757 : 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 1757 : }
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 1751 : int create ) {
33 1751 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
34 1751 : if( FD_UNLIKELY( !acc.lamports && !create ) ) {
35 0 : fd_accdb_unwrite_one( accdb, &acc );
36 0 : return acc;
37 0 : }
38 :
39 1751 : update->lamports_before = acc.lamports;
40 1751 : update->data_len_before = acc.data_len;
41 1751 : update->skip_event_diff = 0;
42 1751 : fd_memcpy( update->owner_before, acc.owner, 32UL );
43 :
44 1751 : fd_lthash_value_t hash[1];
45 1751 : fd_hashes_account_lthash_simple( acc.pubkey, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, hash );
46 :
47 1751 : fd_lthash_value_t * bank_lthash = fd_bank_lthash_locking_modify( bank );
48 1751 : fd_lthash_sub( bank_lthash, hash );
49 1751 : fd_bank_lthash_end_locking_modify( bank );
50 :
51 1751 : return acc;
52 1751 : }
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 1757 : fd_accdb_svm_update_t * update ) {
60 1757 : if( FD_UNLIKELY( acc->lamports>update->lamports_before ) ) {
61 311 : ulong delta = acc->lamports-update->lamports_before;
62 311 : FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
63 1446 : } else if( FD_UNLIKELY( acc->lamports<update->lamports_before ) ) {
64 5 : ulong delta = update->lamports_before-acc->lamports;
65 5 : FD_TEST( !__builtin_usubl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
66 5 : }
67 :
68 1757 : fd_lthash_value_t hash[1];
69 1757 : fd_hashes_account_lthash_simple( acc->pubkey, acc->owner, acc->lamports, acc->executable, acc->data, acc->data_len, hash );
70 :
71 1757 : fd_lthash_value_t * bank_lthash = fd_bank_lthash_locking_modify( bank );
72 1757 : fd_lthash_add( bank_lthash, hash );
73 1757 : fd_bank_lthash_end_locking_modify( bank );
74 :
75 1757 : log_account_change( bank, acc, capture_ctx );
76 1757 : 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 1757 : acc->commit = 1;
78 1757 : fd_accdb_unwrite_one( accdb, acc );
79 1757 : }
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 91 : int is_vote_reward ) {
88 91 : if( FD_UNLIKELY( !lamports_add ) ) return;
89 :
90 88 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
91 :
92 88 : ulong lamports_pre = acc.lamports;
93 88 : FD_TEST( !__builtin_uaddl_overflow( acc.lamports, lamports_add, &acc.lamports ) );
94 88 : FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, lamports_add, &bank->f.capitalization ) );
95 :
96 88 : fd_hashes_update_pair( pubkey->uc, acc.owner, lamports_pre, acc.executable, acc.data, acc.data_len,
97 88 : acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len,
98 88 : bank, capture_ctx );
99 88 : 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 88 : acc.commit = 1;
104 88 : fd_accdb_unwrite_one( accdb, &acc );
105 88 : }
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 1667 : int skip_event_diff ) {
118 1667 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
119 1667 : ulong lamports_pre = acc.lamports;
120 1667 : ulong data_len_pre = acc.data_len;
121 1667 : uchar owner_pre[ 32 ]; fd_memcpy( owner_pre, acc.owner, 32UL );
122 :
123 1667 : if( FD_UNLIKELY( acc.lamports<lamports_min ) ) {
124 3 : ulong delta = lamports_min - acc.lamports;
125 3 : acc.lamports = lamports_min;
126 3 : FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
127 3 : }
128 :
129 1667 : fd_memcpy( acc.owner, owner, 32UL );
130 1667 : acc.executable = !!exec_bit;
131 :
132 1667 : fd_memcpy( acc.data, data, sz );
133 1667 : acc.data_len = sz;
134 :
135 1667 : fd_hashes_update_pair( pubkey->uc, acc.prior_owner, acc.prior_lamports, acc.prior_executable, acc.prior_data, acc.prior_data_len,
136 1667 : acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len,
137 1667 : bank, capture_ctx );
138 1667 : 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 1667 : acc.commit = 1;
140 1667 : fd_accdb_unwrite_one( accdb, &acc );
141 1667 : }
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 615 : fd_pubkey_t const * pubkey ) {
148 615 : fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
149 615 : if( FD_UNLIKELY( !acc.lamports ) ) {
150 611 : fd_accdb_unwrite_one( accdb, &acc );
151 611 : return 0UL;
152 611 : }
153 :
154 4 : ulong burned = acc.lamports;
155 :
156 4 : fd_lthash_value_t hash[1];
157 4 : fd_hashes_account_lthash_simple( acc.pubkey, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, hash );
158 :
159 4 : bank->f.capitalization -= burned;
160 4 : acc.lamports = 0UL;
161 :
162 4 : fd_lthash_value_t post[1];
163 4 : fd_hashes_update_simple( post, hash, pubkey->uc, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, bank, capture_ctx );
164 4 : 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 4 : acc.commit = 1;
166 4 : fd_accdb_unwrite_one( accdb, &acc );
167 4 : return burned;
168 615 : }
|