Line data Source code
1 : #include "fd_hashes.h"
2 : #include "fd_bank.h"
3 : #include "../../ballet/sha256/fd_sha256.h"
4 : #include "../capture/fd_capture_ctx.h"
5 :
6 : static fd_blake3_t *
7 : account_lthash_init( fd_blake3_t * b3,
8 : uchar const pubkey[ static FD_HASH_FOOTPRINT ],
9 : uchar const owner[ static FD_HASH_FOOTPRINT ],
10 : ulong lamports,
11 : int executable,
12 : uchar const * data,
13 131241 : ulong data_len ) {
14 131241 : uchar executable_flag = !!executable;
15 :
16 131241 : fd_blake3_init( b3 );
17 131241 : fd_blake3_append( b3, &lamports, sizeof( ulong ) );
18 131241 : fd_blake3_append( b3, data, data_len );
19 131241 : fd_blake3_append( b3, &executable_flag, sizeof( uchar ) );
20 131241 : fd_blake3_append( b3, owner, FD_HASH_FOOTPRINT );
21 131241 : fd_blake3_append( b3, pubkey, FD_HASH_FOOTPRINT );
22 131241 : return b3;
23 131241 : }
24 :
25 : void
26 : fd_hashes_account_lthash_simple( uchar const pubkey[ static FD_HASH_FOOTPRINT ],
27 : uchar const owner[ static FD_HASH_FOOTPRINT ],
28 : ulong lamports,
29 : int executable,
30 : uchar const * data,
31 : ulong data_len,
32 38583 : fd_lthash_value_t * lthash_out ) {
33 38583 : if( FD_UNLIKELY( !lamports ) ) {
34 2394 : fd_lthash_zero( lthash_out );
35 2394 : return;
36 2394 : }
37 :
38 36189 : fd_blake3_t b3[1];
39 36189 : fd_blake3_fini_2048( account_lthash_init( b3, pubkey, owner, lamports, executable, data, data_len ), lthash_out->bytes );
40 36189 : }
41 :
42 : void
43 : fd_hashes_account_lthash_xn( ulong n,
44 : uchar const * const * pubkey,
45 : uchar const * const * owner,
46 : ulong const * lamports,
47 : int const * executable,
48 : uchar const * const * data,
49 : ulong const * data_len,
50 46182 : fd_lthash_value_t ** lthash_out ) {
51 46182 : fd_blake3_t b3 [ FD_BLAKE3_XN_MAX ];
52 46182 : fd_blake3_t * sha [ FD_BLAKE3_XN_MAX ];
53 46182 : void * hash[ FD_BLAKE3_XN_MAX ];
54 46182 : ulong m = 0UL;
55 :
56 144933 : for( ulong i=0UL; i<n; i++ ) {
57 98751 : if( FD_UNLIKELY( !lamports[ i ] ) ) {
58 3699 : fd_lthash_zero( lthash_out[ i ] );
59 3699 : continue;
60 3699 : }
61 :
62 95052 : sha [ m ] = account_lthash_init( b3+m, pubkey[ i ], owner[ i ], lamports[ i ], executable[ i ], data[ i ], data_len[ i ] );
63 95052 : hash[ m ] = lthash_out[ i ]->bytes;
64 95052 : m++;
65 95052 : }
66 :
67 46182 : if( FD_LIKELY( m ) ) fd_blake3_fini_2048_xn( m, sha, hash );
68 46182 : }
69 :
70 : void
71 : fd_hashes_hash_bank( fd_lthash_value_t const * lthash,
72 : fd_hash_t const * prev_bank_hash,
73 : fd_hash_t const * last_blockhash,
74 : ulong signature_count,
75 411 : fd_hash_t * hash_out ) {
76 :
77 : /* The bank hash for a slot is a sha256 of two sub-hashes:
78 : sha256(
79 : sha256( previous bank hash, signature count, last PoH blockhash ),
80 : lthash of the accounts modified in this slot
81 : )
82 : */
83 411 : fd_sha256_t sha;
84 411 : fd_sha256_init( &sha );
85 411 : fd_sha256_append( &sha, prev_bank_hash, sizeof( fd_hash_t ) );
86 411 : fd_sha256_append( &sha, (uchar const *) &signature_count, sizeof( ulong ) );
87 411 : fd_sha256_append( &sha, (uchar const *) last_blockhash, sizeof( fd_hash_t ) );
88 411 : fd_sha256_fini( &sha, hash_out->hash );
89 :
90 411 : fd_sha256_init( &sha );
91 411 : fd_sha256_append( &sha, (uchar const *) hash_out->hash, sizeof(fd_hash_t) );
92 411 : fd_sha256_append( &sha, (uchar const *) lthash->bytes, sizeof(fd_lthash_value_t) );
93 411 : fd_sha256_fini( &sha, hash_out->hash );
94 411 : }
95 :
96 : static void
97 : update_bank_lthash( fd_bank_t * bank,
98 : fd_lthash_value_t const * lthash_prev,
99 10428 : fd_lthash_value_t const * lthash_post ) {
100 10428 : fd_lthash_value_t delta[1];
101 10428 : fd_memcpy( delta, lthash_post, sizeof(fd_lthash_value_t) );
102 10428 : fd_lthash_sub( delta, lthash_prev );
103 :
104 10428 : fd_lthash_value_t * bank_lthash = fd_bank_lthash_locking_modify( bank );
105 10428 : fd_lthash_add( bank_lthash, delta );
106 10428 : fd_bank_lthash_end_locking_modify( bank );
107 10428 : }
108 :
109 : void
110 : fd_hashes_update_simple( fd_lthash_value_t * lthash_post, /* out */
111 : fd_lthash_value_t const * lthash_prev, /* in */
112 : uchar const pubkey[ static FD_HASH_FOOTPRINT ],
113 : uchar const owner[ static FD_HASH_FOOTPRINT ],
114 : ulong lamports,
115 : int executable,
116 : uchar const * data,
117 : ulong data_len,
118 : fd_bank_t * bank,
119 138 : fd_capture_ctx_t * capture_ctx ) {
120 138 : if( bank->lthash_mode==FD_BANK_LTHASH_MODE_INBAND ) {
121 138 : fd_hashes_account_lthash_simple( pubkey, owner, lamports, executable, data, data_len, lthash_post );
122 138 : update_bank_lthash( bank, lthash_prev, lthash_post );
123 138 : } else if( bank->lthash_mode==FD_BANK_LTHASH_MODE_OOB_RECORD ) {
124 0 : fd_bank_lthash_record( bank, pubkey );
125 0 : }
126 :
127 138 : fd_hashes_capture_account( pubkey, owner, lamports, executable, data, data_len, bank, capture_ctx );
128 138 : }
129 :
130 : void
131 : fd_hashes_update_pair( uchar const pubkey[ static FD_HASH_FOOTPRINT ],
132 : uchar const prev_owner[ static FD_HASH_FOOTPRINT ],
133 : ulong prev_lamports,
134 : int prev_executable,
135 : uchar const * prev_data,
136 : ulong prev_data_len,
137 : uchar const owner[ static FD_HASH_FOOTPRINT ],
138 : ulong lamports,
139 : int executable,
140 : uchar const * data,
141 : ulong data_len,
142 : fd_bank_t * bank,
143 10290 : fd_capture_ctx_t * capture_ctx ) {
144 10290 : if( bank->lthash_mode==FD_BANK_LTHASH_MODE_INBAND ) {
145 10290 : fd_lthash_value_t lthash_prev[1];
146 10290 : fd_lthash_value_t lthash_post[1];
147 10290 : uchar const * pk [2] = { pubkey, pubkey };
148 10290 : uchar const * ow [2] = { prev_owner, owner };
149 10290 : ulong la [2] = { prev_lamports, lamports };
150 10290 : int ex [2] = { prev_executable, executable };
151 10290 : uchar const * da [2] = { prev_data, data };
152 10290 : ulong dl [2] = { prev_data_len, data_len };
153 10290 : fd_lthash_value_t * out[2] = { lthash_prev, lthash_post };
154 10290 : fd_hashes_account_lthash_xn( 2UL, pk, ow, la, ex, da, dl, out );
155 10290 : update_bank_lthash( bank, lthash_prev, lthash_post );
156 10290 : } else if( bank->lthash_mode==FD_BANK_LTHASH_MODE_OOB_RECORD ) {
157 0 : fd_bank_lthash_record( bank, pubkey );
158 0 : }
159 :
160 10290 : fd_hashes_capture_account( pubkey, owner, lamports, executable, data, data_len, bank, capture_ctx );
161 10290 : }
162 :
163 : void
164 : fd_hashes_capture_account( uchar const pubkey[ static FD_HASH_FOOTPRINT ],
165 : uchar const owner[ static FD_HASH_FOOTPRINT ],
166 : ulong lamports,
167 : int executable,
168 : uchar const * data,
169 : ulong data_len,
170 : fd_bank_t * bank,
171 38058 : fd_capture_ctx_t * capture_ctx ) {
172 38058 : if( FD_LIKELY( !capture_ctx ||
173 38058 : !capture_ctx->capture_solcap ||
174 38058 : bank->f.slot<capture_ctx->solcap_start_slot ) ) return;
175 :
176 0 : fd_solana_account_meta_t solana_meta[1];
177 0 : fd_solana_account_meta_init( solana_meta, lamports, owner, executable );
178 0 : fd_capture_link_write_account_update(
179 0 : capture_ctx,
180 0 : capture_ctx->current_txn_idx,
181 0 : (fd_pubkey_t const *)pubkey,
182 0 : solana_meta,
183 0 : bank->f.slot,
184 0 : data,
185 0 : data_len );
186 0 : }
187 :
188 : void
189 : fd_hashes_apply_hard_forks( fd_hash_t * hash,
190 : ulong slot,
191 : ulong parent_slot,
192 : fd_hard_fork_t const * hard_forks,
193 420 : ulong hard_fork_cnt ) {
194 420 : ulong sum = 0UL;
195 444 : for( ulong i=0UL; i<hard_fork_cnt; i++ ) {
196 24 : if( FD_UNLIKELY( parent_slot<hard_forks[ i ].slot && hard_forks[ i ].slot<=slot ) ) sum += hard_forks[ i ].cnt;
197 24 : }
198 :
199 420 : if( FD_UNLIKELY( !sum ) ) return;
200 :
201 9 : ulong sum_le[ 1 ];
202 9 : FD_STORE( ulong, sum_le, sum );
203 :
204 9 : fd_sha256_t sha;
205 9 : fd_sha256_init( &sha );
206 9 : fd_sha256_append( &sha, hash->hash, sizeof(fd_hash_t) );
207 9 : fd_sha256_append( &sha, sum_le, sizeof(ulong) );
208 9 : fd_sha256_fini( &sha, hash->hash );
209 9 : }
|