Line data Source code
1 : #include "fd_snapshot.h"
2 : #include "fd_snapshot_loader.h"
3 : #include "fd_snapshot_restore.h"
4 : #include "../runtime/fd_acc_mgr.h"
5 : #include "../runtime/fd_hashes.h"
6 : #include "../runtime/fd_runtime_init.h"
7 : #include "../runtime/fd_system_ids.h"
8 : #include "../runtime/fd_runtime.h"
9 : #include "../runtime/context/fd_exec_slot_ctx.h"
10 : #include "../rewards/fd_rewards.h"
11 :
12 : #include <assert.h>
13 : #include <errno.h>
14 :
15 : /* FIXME: don't hardcode this param */
16 0 : #define ZSTD_WINDOW_SZ (33554432UL)
17 :
18 : struct fd_snapshot_load_ctx {
19 : /* User-defined parameters. */
20 : const char * snapshot_dir;
21 : const char * snapshot_src;
22 : int snapshot_src_type;
23 : fd_exec_slot_ctx_t * slot_ctx;
24 : uint verify_hash;
25 : uint check_hash;
26 : int snapshot_type;
27 :
28 : /* Internal state. */
29 : fd_funk_txn_t * par_txn;
30 : fd_funk_txn_t * child_txn;
31 :
32 : fd_snapshot_loader_t * loader;
33 : fd_snapshot_restore_t * restore;
34 :
35 : fd_spad_t * runtime_spad;
36 :
37 : fd_exec_para_cb_ctx_t * exec_para_ctx;
38 : };
39 : typedef struct fd_snapshot_load_ctx fd_snapshot_load_ctx_t;
40 :
41 : static void
42 0 : fd_hashes_load( fd_exec_slot_ctx_t * slot_ctx ) {
43 0 : FD_TXN_ACCOUNT_DECL( block_hashes_rec );
44 0 : int err = fd_txn_account_init_from_funk_readonly( block_hashes_rec, &fd_sysvar_recent_block_hashes_id, slot_ctx->funk, slot_ctx->funk_txn );
45 :
46 0 : if( err != FD_ACC_MGR_SUCCESS ) {
47 0 : FD_LOG_ERR(( "missing recent block hashes account" ));
48 0 : }
49 :
50 0 : fd_bank_execution_fees_set( slot_ctx->bank, 0UL );
51 0 : }
52 :
53 : static int
54 : restore_manifest( void * ctx,
55 : fd_solana_manifest_global_t const * manifest,
56 0 : fd_spad_t * spad ) {
57 0 : return (!!fd_exec_slot_ctx_recover( ctx, manifest, spad ) ? 0 : EINVAL);
58 0 : }
59 :
60 : static int
61 : restore_status_cache( void * ctx,
62 : fd_bank_slot_deltas_t * slot_deltas,
63 0 : fd_spad_t * spad ) {
64 0 : return (!!fd_exec_slot_ctx_recover_status_cache( ctx, slot_deltas, spad ) ? 0 : EINVAL);
65 0 : }
66 :
67 : ulong
68 0 : fd_snapshot_load_ctx_align( void ) {
69 0 : return alignof(fd_snapshot_load_ctx_t);
70 0 : }
71 :
72 : ulong
73 0 : fd_snapshot_load_ctx_footprint( void ) {
74 0 : return sizeof(fd_snapshot_load_ctx_t);
75 0 : }
76 :
77 : fd_snapshot_load_ctx_t *
78 : fd_snapshot_load_new( uchar * mem,
79 : const char * snapshot_src,
80 : int snapshot_src_type,
81 : const char * snapshot_dir,
82 : fd_exec_slot_ctx_t * slot_ctx,
83 : uint verify_hash,
84 : uint check_hash,
85 : int snapshot_type,
86 : fd_spad_t * * exec_spads,
87 : ulong exec_spad_cnt,
88 : fd_spad_t * runtime_spad,
89 0 : fd_exec_para_cb_ctx_t * exec_para_ctx ) {
90 :
91 0 : (void)exec_spads;
92 0 : (void)exec_spad_cnt;
93 :
94 0 : fd_snapshot_load_ctx_t * ctx = (fd_snapshot_load_ctx_t *)mem;
95 :
96 0 : ctx->snapshot_dir = snapshot_dir;
97 0 : ctx->snapshot_src = snapshot_src;
98 0 : ctx->snapshot_src_type = snapshot_src_type;
99 0 : ctx->slot_ctx = slot_ctx;
100 0 : ctx->verify_hash = verify_hash;
101 0 : ctx->check_hash = check_hash;
102 0 : ctx->snapshot_type = snapshot_type;
103 0 : ctx->runtime_spad = runtime_spad;
104 0 : ctx->exec_para_ctx = exec_para_ctx;
105 :
106 0 : return ctx;
107 0 : }
108 :
109 : void
110 0 : fd_snapshot_load_init( fd_snapshot_load_ctx_t * ctx ) {
111 0 : switch( ctx->snapshot_type ) {
112 0 : case FD_SNAPSHOT_TYPE_UNSPECIFIED:
113 0 : FD_LOG_ERR(("fd_snapshot_load(\"%s\", verify-hash=%s, check-hash=%s, FD_SNAPSHOT_TYPE_UNSPECIFIED)", ctx->snapshot_src, ctx->verify_hash ? "true" : "false", ctx->check_hash ? "true" : "false"));
114 0 : break;
115 0 : case FD_SNAPSHOT_TYPE_FULL:
116 0 : FD_LOG_NOTICE(("fd_snapshot_load(\"%s\", verify-hash=%s, check-hash=%s, FD_SNAPSHOT_TYPE_FULL)", ctx->snapshot_src, ctx->verify_hash ? "true" : "false", ctx->check_hash ? "true" : "false"));
117 0 : break;
118 0 : case FD_SNAPSHOT_TYPE_INCREMENTAL:
119 0 : FD_LOG_NOTICE(("fd_snapshot_load(\"%s\", verify-hash=%s, check-hash=%s, FD_SNAPSHOT_TYPE_INCREMENTAL)", ctx->snapshot_src, ctx->verify_hash ? "true" : "false", ctx->check_hash ? "true" : "false"));
120 0 : break;
121 0 : default:
122 0 : FD_LOG_ERR(("fd_snapshot_load(\"%s\", verify-hash=%s, check-hash=%s, huh?)", ctx->snapshot_src, ctx->verify_hash ? "true" : "false", ctx->check_hash ? "true" : "false"));
123 0 : break;
124 0 : }
125 :
126 0 : ctx->par_txn = ctx->slot_ctx->funk_txn;
127 0 : ctx->child_txn = ctx->slot_ctx->funk_txn;
128 :
129 : // the hash in the incremental snapshot of an lt_hash contains all the accounts. This means we don't need a sub-txn for the incremental
130 0 : if( ctx->verify_hash &&
131 0 : (FD_FEATURE_ACTIVE_BANK( ctx->slot_ctx->bank, incremental_snapshot_only_incremental_hash_calculation )
132 0 : && !FD_FEATURE_ACTIVE_BANK( ctx->slot_ctx->bank, snapshots_lt_hash ) )) {
133 0 : fd_funk_txn_xid_t xid;
134 0 : memset( &xid, 0xc3, sizeof(xid) );
135 0 : fd_funk_txn_start_write( ctx->slot_ctx->funk );
136 0 : ctx->child_txn = fd_funk_txn_prepare( ctx->slot_ctx->funk, ctx->child_txn, &xid, 0 );
137 0 : fd_funk_txn_end_write( ctx->slot_ctx->funk );
138 0 : ctx->slot_ctx->funk_txn = ctx->child_txn;
139 0 : }
140 0 : }
141 :
142 : void
143 : fd_snapshot_load_manifest_and_status_cache( fd_snapshot_load_ctx_t * ctx,
144 : ulong * base_slot_override,
145 0 : int restore_manifest_flags ) {
146 :
147 0 : size_t slen = strlen( ctx->snapshot_src );
148 0 : char * snapshot_cstr = fd_spad_alloc( ctx->runtime_spad, 8UL, slen + 1 );
149 0 : fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( snapshot_cstr ), ctx->snapshot_src, slen ) );
150 :
151 0 : fd_snapshot_src_t src[1];
152 0 : if( FD_UNLIKELY( !fd_snapshot_src_parse( src, snapshot_cstr, ctx->snapshot_src_type ) ) ) {
153 0 : FD_LOG_ERR(( "Failed to parse snapshot src" ));
154 0 : }
155 0 : src->snapshot_dir = ctx->snapshot_dir;
156 :
157 0 : fd_funk_t * funk = ctx->slot_ctx->funk;
158 0 : fd_funk_txn_t * funk_txn = ctx->slot_ctx->funk_txn;
159 :
160 0 : void * restore_mem = fd_spad_alloc( ctx->runtime_spad, fd_snapshot_restore_align(), fd_snapshot_restore_footprint() );
161 0 : void * loader_mem = fd_spad_alloc( ctx->runtime_spad, fd_snapshot_loader_align(), fd_snapshot_loader_footprint( ZSTD_WINDOW_SZ ) );
162 :
163 0 : ctx->restore = fd_snapshot_restore_new( restore_mem,
164 0 : funk,
165 0 : funk_txn,
166 0 : ctx->runtime_spad,
167 0 : ctx->slot_ctx,
168 0 : (restore_manifest_flags & FD_SNAPSHOT_RESTORE_MANIFEST) ? restore_manifest : NULL,
169 0 : (restore_manifest_flags & FD_SNAPSHOT_RESTORE_STATUS_CACHE) ? restore_status_cache : NULL );
170 0 : if( FD_UNLIKELY( !ctx->restore ) ) {
171 0 : FD_LOG_ERR(( "Failed to fd_snapshot_restore_new" ));
172 0 : }
173 :
174 0 : ctx->loader = fd_snapshot_loader_new ( loader_mem, ZSTD_WINDOW_SZ );
175 :
176 0 : if( FD_UNLIKELY( !ctx->loader ) ) {
177 0 : FD_LOG_ERR(( "Failed to fd_snapshot_loader_new" ));
178 0 : }
179 :
180 0 : if( FD_UNLIKELY( !fd_snapshot_loader_init( ctx->loader,
181 0 : ctx->restore,
182 0 : src,
183 0 : base_slot_override ? *base_slot_override : fd_bank_slot_get( ctx->slot_ctx->bank ),
184 0 : 1 ) ) ) {
185 0 : FD_LOG_ERR(( "Failed to init snapshot loader" ));
186 0 : }
187 :
188 : /* First load in the manifest. */
189 0 : for(;;) {
190 0 : int err = fd_snapshot_loader_advance( ctx->loader );
191 0 : if( err==MANIFEST_DONE ) break; /* We have finished loading in the manifest. */
192 0 : if( FD_LIKELY( !err ) ) continue; /* Keep going. */
193 :
194 : /* If we have reached the end of the snapshot(err==-1), throw an error because
195 : this is not expected. */
196 0 : FD_LOG_ERR(( "Failed to load snapshot (%d-%s)", err, fd_io_strerror( err ) ));
197 0 : }
198 :
199 0 : }
200 :
201 : void
202 0 : fd_snapshot_load_accounts( fd_snapshot_load_ctx_t * ctx ) {
203 :
204 : /* Now, that the manifest is done being read in. Read in the rest of the accounts. */
205 0 : for(;;) {
206 0 : int err = fd_snapshot_loader_advance( ctx->loader );
207 0 : if( err==-1 ) break; /* We have finished loading in the snapshot. */
208 0 : if( FD_LIKELY( err==0 ) ) continue; /* Keep going. */
209 :
210 0 : FD_LOG_ERR(( "Failed to load snapshot (%d-%s)", err, fd_io_strerror( err ) ));
211 0 : }
212 :
213 0 : fd_snapshot_name_t const * name = fd_snapshot_loader_get_name( ctx->loader );
214 0 : if( FD_UNLIKELY( !name ) ) FD_LOG_ERR(( "name is NULL" ));
215 :
216 0 : FD_LOG_NOTICE(( "Done loading accounts" ));
217 :
218 0 : FD_LOG_NOTICE(( "Finished reading snapshot %s", ctx->snapshot_src ));
219 0 : }
220 :
221 : #define FD_LTHASH_SNAPSHOT_HACK
222 : void
223 0 : fd_snapshot_load_fini( fd_snapshot_load_ctx_t * ctx ) {
224 0 : fd_snapshot_name_t const * name = fd_snapshot_loader_get_name( ctx->loader );
225 0 : fd_hash_t const * fhash = &name->fhash;
226 :
227 0 : if( name->type != ctx->snapshot_type ) {
228 0 : FD_LOG_ERR(( "snapshot %s is wrong type", ctx->snapshot_src ));
229 0 : }
230 :
231 : // In order to calculate the snapshot hash, we need to know what features are active...
232 0 : fd_features_restore( ctx->slot_ctx, ctx->runtime_spad );
233 0 : fd_calculate_epoch_accounts_hash_values( ctx->slot_ctx );
234 :
235 0 : int snapshots_lt_hash = FD_FEATURE_ACTIVE_BANK( ctx->slot_ctx->bank, snapshots_lt_hash );
236 0 : int accounts_lt_hash = FD_FEATURE_ACTIVE_BANK( ctx->slot_ctx->bank, accounts_lt_hash );
237 0 : int incremental_snapshot_only_incremental_hash_calculation = FD_FEATURE_ACTIVE_BANK( ctx->slot_ctx->bank,
238 0 : incremental_snapshot_only_incremental_hash_calculation );
239 :
240 : // https://github.com/anza-xyz/agave/blob/766cd682423b8049ddeac3c0ec6cebe0a1356e9e/runtime/src/bank.rs#L1831
241 0 : if( accounts_lt_hash ) {
242 0 : fd_slot_lthash_t const * lthash = fd_bank_lthash_query( ctx->slot_ctx->bank );
243 0 : ulong *p = (ulong *) lthash->lthash;
244 0 : ulong *e = (ulong *) <hash->lthash[sizeof(lthash->lthash)];
245 0 : while (p < e) {
246 0 : if ( 0 != *(p++) )
247 0 : break;
248 0 : }
249 0 : if (p >= e) {
250 0 : if( ctx->snapshot_type==FD_SNAPSHOT_TYPE_FULL ) {
251 0 : FD_LOG_WARNING(( "re-calculating accounts lt hash for full snapshot" ));
252 0 : fd_lthash_value_t lthash_buf;
253 0 : fd_lthash_zero(<hash_buf);
254 0 : fd_hash_t accounts_hash;
255 0 : fd_snapshot_hash( ctx->slot_ctx, &accounts_hash, ctx->check_hash, ctx->runtime_spad, ctx->exec_para_ctx, <hash_buf );
256 0 : fd_slot_lthash_t * lthash_val = fd_bank_lthash_modify( ctx->slot_ctx->bank );
257 0 : fd_memcpy( (fd_lthash_value_t *)fd_type_pun(lthash_val->lthash), <hash_buf, sizeof(lthash_buf) );
258 0 : FD_LOG_NOTICE(( "re-calculated accounts_lthash for full snapshot %s", FD_LTHASH_ENC_32_ALLOCA( (fd_lthash_value_t *)fd_type_pun(lthash_val->lthash) ) ));
259 0 : }
260 0 : } else {
261 0 : FD_LOG_NOTICE(( "accounts_lthash found %s", FD_LTHASH_ENC_32_ALLOCA( (fd_lthash_value_t *)lthash->lthash ) ));
262 0 : }
263 0 : }
264 :
265 0 : if( ctx->verify_hash ) {
266 0 : fd_hash_t accounts_hash;
267 0 : fd_lthash_value_t *lthash = NULL;
268 0 : fd_lthash_value_t lthash_buf;
269 0 : if ( snapshots_lt_hash ) {
270 0 : fd_lthash_zero(<hash_buf);
271 0 : lthash = <hash_buf;
272 0 : }
273 :
274 0 : if( ctx->snapshot_type==FD_SNAPSHOT_TYPE_FULL ) {
275 0 : FD_SPAD_FRAME_BEGIN( ctx->runtime_spad ) {
276 0 : fd_snapshot_hash( ctx->slot_ctx, &accounts_hash, ctx->check_hash, ctx->runtime_spad, ctx->exec_para_ctx, lthash );
277 0 : } FD_SPAD_FRAME_END;
278 :
279 0 : if ( snapshots_lt_hash ) {
280 0 : fd_slot_lthash_t const * lthash_val = fd_bank_lthash_query( ctx->slot_ctx->bank );
281 0 : if( memcmp( (fd_lthash_value_t *)lthash_val->lthash, lthash, sizeof(lthash_buf) ) ) {
282 0 : FD_LOG_ERR(( "snapshot accounts_hash (calculated) %s != (expected) %s",
283 0 : FD_LTHASH_ENC_32_ALLOCA( (fd_lthash_value_t *)lthash_val->lthash ), FD_LTHASH_ENC_32_ALLOCA( lthash ) ));
284 0 : } else {
285 0 : FD_LOG_NOTICE(( "accounts_lthash found %s verified successfully", FD_LTHASH_ENC_32_ALLOCA( (fd_lthash_value_t *)lthash_val->lthash ) ));
286 0 : }
287 0 : } else {
288 0 : if( memcmp( fhash->uc, accounts_hash.uc, sizeof(fd_hash_t) ) ) {
289 0 : FD_LOG_ERR(( "snapshot accounts_hash (calculated) %s != (expected) %s", FD_BASE58_ENC_32_ALLOCA( accounts_hash.hash ), FD_BASE58_ENC_32_ALLOCA( fhash->uc ) ));
290 0 : } else {
291 0 : FD_LOG_NOTICE(( "snapshot accounts_hash %s verified successfully", FD_BASE58_ENC_32_ALLOCA( accounts_hash.hash ) ));
292 0 : }
293 0 : }
294 0 : } else if( ctx->snapshot_type == FD_SNAPSHOT_TYPE_INCREMENTAL ) {
295 0 : fd_hash_t accounts_hash;
296 :
297 0 : if( incremental_snapshot_only_incremental_hash_calculation && !snapshots_lt_hash ) {
298 0 : FD_LOG_NOTICE(( "hashing incremental snapshot with only deltas" ));
299 0 : fd_snapshot_inc_hash( ctx->slot_ctx, &accounts_hash, ctx->child_txn, ctx->check_hash, ctx->runtime_spad, NULL);
300 0 : } else {
301 0 : FD_LOG_NOTICE(( "hashing incremental snapshot with all accounts" ));
302 0 : fd_snapshot_hash( ctx->slot_ctx, &accounts_hash, ctx->check_hash, ctx->runtime_spad, ctx->exec_para_ctx, lthash );
303 0 : }
304 :
305 0 : if ( snapshots_lt_hash ) {
306 0 : fd_slot_lthash_t const * lthash_val = fd_bank_lthash_query( ctx->slot_ctx->bank );
307 0 : if( memcmp( (fd_lthash_value_t *)lthash_val->lthash, lthash, sizeof(lthash_buf) ) ) {
308 0 : FD_LOG_ERR(( "snapshot accounts_hash (calculated) %s != (expected) %s",
309 0 : FD_LTHASH_ENC_32_ALLOCA( (fd_lthash_value_t *)lthash_val->lthash ), FD_LTHASH_ENC_32_ALLOCA( lthash ) ));
310 0 : } else {
311 0 : FD_LOG_NOTICE(( "accounts_lthash found %s verified successfully", FD_LTHASH_ENC_32_ALLOCA( (fd_lthash_value_t *)lthash_val->lthash ) ));
312 0 : }
313 0 : } else {
314 0 : if( memcmp( fhash->uc, accounts_hash.uc, sizeof(fd_hash_t) ) ) {
315 0 : FD_LOG_ERR(( "incremental accounts_hash %s != %s", FD_BASE58_ENC_32_ALLOCA( accounts_hash.hash ), FD_BASE58_ENC_32_ALLOCA( fhash->uc ) ));
316 0 : } else {
317 0 : FD_LOG_NOTICE(( "incremental accounts_hash %s verified successfully", FD_BASE58_ENC_32_ALLOCA( accounts_hash.hash ) ));
318 0 : }
319 0 : }
320 0 : } else {
321 0 : FD_LOG_ERR(( "invalid snapshot type %d", ctx->snapshot_type ));
322 0 : }
323 :
324 0 : }
325 0 : if( ctx->child_txn != ctx->par_txn ) {
326 0 : fd_funk_txn_start_write( ctx->slot_ctx->funk );
327 0 : fd_funk_txn_publish( ctx->slot_ctx->funk, ctx->child_txn, 0 );
328 0 : fd_funk_txn_end_write( ctx->slot_ctx->funk );
329 0 : ctx->slot_ctx->funk_txn = ctx->par_txn;
330 0 : }
331 :
332 0 : fd_hashes_load( ctx->slot_ctx );
333 :
334 : /* We don't need to free any of the loader memory since it is allocated
335 : from a spad. */
336 0 : }
337 :
338 : void
339 : fd_snapshot_load_all( const char * source_cstr,
340 : int source_type,
341 : const char * snapshot_dir,
342 : fd_exec_slot_ctx_t * slot_ctx,
343 : ulong * base_slot_override,
344 : fd_tpool_t * tpool,
345 : uint verify_hash,
346 : uint check_hash,
347 : int snapshot_type,
348 : fd_spad_t * * exec_spads,
349 : ulong exec_spad_cnt,
350 0 : fd_spad_t * runtime_spad ) {
351 0 : FD_SPAD_FRAME_BEGIN( runtime_spad ) {
352 :
353 0 : fd_exec_para_cb_ctx_t exec_para_ctx = {
354 0 : .func = fd_accounts_hash_counter_and_gather_tpool_cb,
355 0 : .para_arg_1 = tpool
356 0 : };
357 :
358 0 : uchar * mem = fd_spad_alloc( runtime_spad, fd_snapshot_load_ctx_align(), fd_snapshot_load_ctx_footprint() );
359 0 : fd_snapshot_load_ctx_t * ctx = fd_snapshot_load_new( mem,
360 0 : source_cstr,
361 0 : source_type,
362 0 : snapshot_dir,
363 0 : slot_ctx,
364 0 : verify_hash,
365 0 : check_hash,
366 0 : snapshot_type,
367 0 : exec_spads,
368 0 : exec_spad_cnt,
369 0 : runtime_spad,
370 0 : &exec_para_ctx );
371 :
372 0 : fd_snapshot_load_init( ctx );
373 0 : fd_runtime_update_slots_per_epoch( slot_ctx->bank, FD_DEFAULT_SLOTS_PER_EPOCH );
374 0 : fd_snapshot_load_manifest_and_status_cache( ctx, base_slot_override,
375 0 : FD_SNAPSHOT_RESTORE_STATUS_CACHE | FD_SNAPSHOT_RESTORE_MANIFEST );
376 0 : fd_snapshot_load_accounts( ctx );
377 0 : fd_snapshot_load_fini( ctx );
378 :
379 0 : } FD_SPAD_FRAME_END;
380 :
381 0 : }
382 :
383 : void
384 0 : fd_snapshot_load_prefetch_manifest( fd_snapshot_load_ctx_t * ctx ) {
385 :
386 0 : size_t slen = strlen( ctx->snapshot_src );
387 0 : char * snapshot_cstr = fd_spad_alloc( ctx->runtime_spad, 8UL, slen + 1 );
388 0 : fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( snapshot_cstr ), ctx->snapshot_src, slen ) );
389 :
390 0 : fd_snapshot_src_t src[1];
391 0 : if( FD_UNLIKELY( !fd_snapshot_src_parse( src, snapshot_cstr, ctx->snapshot_src_type ) ) ) {
392 0 : FD_LOG_ERR(( "Failed to parse snapshot src" ));
393 0 : }
394 0 : src->snapshot_dir = ctx->snapshot_dir;
395 :
396 0 : fd_funk_t * funk = ctx->slot_ctx->funk;
397 0 : fd_funk_txn_t * funk_txn = ctx->slot_ctx->funk_txn;
398 :
399 0 : void * restore_mem = fd_spad_alloc( ctx->runtime_spad, fd_snapshot_restore_align(), fd_snapshot_restore_footprint() );
400 0 : void * loader_mem = fd_spad_alloc( ctx->runtime_spad, fd_snapshot_loader_align(), fd_snapshot_loader_footprint( ZSTD_WINDOW_SZ ) );
401 :
402 0 : ctx->restore = fd_snapshot_restore_new( restore_mem, funk, funk_txn, ctx->runtime_spad, ctx->slot_ctx, restore_manifest, restore_status_cache );
403 0 : if( FD_UNLIKELY( !ctx->restore ) ) {
404 0 : FD_LOG_ERR(( "Failed to fd_snapshot_restore_new" ));
405 0 : }
406 0 : ctx->loader = fd_snapshot_loader_new( loader_mem, ZSTD_WINDOW_SZ );
407 0 : if( FD_UNLIKELY( !ctx->loader ) ) {
408 0 : FD_LOG_ERR(( "Failed to fd_snapshot_loader_new" ));
409 0 : }
410 :
411 0 : if( FD_UNLIKELY( !fd_snapshot_loader_init( ctx->loader, ctx->restore, src, 0UL, 0 ) ) ) {
412 0 : FD_LOG_ERR(( "Failed to init snapshot loader" ));
413 0 : }
414 :
415 : /* First load in the manifest. */
416 0 : for(;;) {
417 0 : int err = fd_snapshot_loader_advance( ctx->loader );
418 0 : if( err==MANIFEST_DONE ) break; /* We have finished loading in the manifest. */
419 0 : if( FD_LIKELY( !err ) ) continue; /* Keep going. */
420 :
421 : /* If we have reached the end of the snapshot(err==-1), throw an error because
422 : this is not expected. */
423 0 : FD_LOG_ERR(( "Failed to load snapshot (%d-%s)", err, fd_io_strerror( err ) ));
424 0 : }
425 :
426 0 : fd_snapshot_loader_delete( ctx->loader );
427 0 : fd_snapshot_restore_delete( ctx->restore );
428 0 : }
429 :
430 : static int
431 0 : fd_should_snapshot_include_epoch_accounts_hash(fd_exec_slot_ctx_t * slot_ctx) {
432 0 : if( FD_FEATURE_ACTIVE_BANK( slot_ctx->bank, snapshots_lt_hash ) ) {
433 0 : return 0;
434 0 : }
435 :
436 : // We need to find the correct logic
437 0 : if( fd_bank_eah_start_slot_get( slot_ctx->bank ) != ULONG_MAX ) {
438 0 : return 0;
439 0 : }
440 0 : if( fd_bank_eah_stop_slot_get( slot_ctx->bank ) == ULONG_MAX ) {
441 0 : return 0;
442 0 : }
443 0 : return 1;
444 0 : }
445 :
446 : ulong
447 0 : fd_snapshot_get_slot( fd_snapshot_load_ctx_t * ctx ) {
448 0 : return fd_snapshot_restore_get_slot( ctx->restore );
449 0 : }
450 :
451 : int
452 : fd_snapshot_hash( fd_exec_slot_ctx_t * slot_ctx,
453 : fd_hash_t * accounts_hash,
454 : uint check_hash,
455 : fd_spad_t * runtime_spad,
456 : fd_exec_para_cb_ctx_t * exec_para_ctx,
457 0 : fd_lthash_value_t * lt_hash ) {
458 0 : (void)check_hash;
459 :
460 0 : if( fd_should_snapshot_include_epoch_accounts_hash( slot_ctx ) ) {
461 0 : FD_LOG_NOTICE(( "snapshot is including epoch account hash" ));
462 0 : fd_sha256_t h;
463 0 : fd_hash_t hash;
464 0 : fd_accounts_hash( slot_ctx->funk,
465 0 : fd_bank_slot_get( slot_ctx->bank ),
466 0 : &hash,
467 0 : runtime_spad,
468 0 : fd_bank_features_query( slot_ctx->bank ),
469 0 : exec_para_ctx,
470 0 : lt_hash );
471 :
472 0 : fd_sha256_init( &h );
473 0 : fd_sha256_append( &h, (uchar const *) hash.hash, sizeof( fd_hash_t ) );
474 0 : fd_sha256_append( &h, (uchar const *) fd_bank_epoch_account_hash_query( slot_ctx->bank ), sizeof( fd_hash_t ) );
475 0 : fd_sha256_fini( &h, accounts_hash );
476 0 : return 0;
477 0 : }
478 :
479 0 : return fd_accounts_hash( slot_ctx->funk,
480 0 : fd_bank_slot_get( slot_ctx->bank ),
481 0 : accounts_hash,
482 0 : runtime_spad,
483 0 : fd_bank_features_query( slot_ctx->bank ),
484 0 : exec_para_ctx,
485 0 : lt_hash );
486 0 : }
487 :
488 : int
489 : fd_snapshot_inc_hash( fd_exec_slot_ctx_t * slot_ctx,
490 : fd_hash_t * accounts_hash,
491 : fd_funk_txn_t * child_txn,
492 : uint do_hash_verify,
493 : fd_spad_t * spad,
494 0 : fd_lthash_value_t * lt_hash ) {
495 :
496 0 : (void) lt_hash;
497 :
498 0 : if( fd_should_snapshot_include_epoch_accounts_hash( slot_ctx ) ) {
499 0 : fd_sha256_t h;
500 0 : fd_hash_t hash;
501 0 : fd_accounts_hash_inc_only( slot_ctx, &hash, child_txn, do_hash_verify, spad );
502 :
503 0 : fd_sha256_init( &h );
504 0 : fd_sha256_append( &h, (uchar const *) hash.hash, sizeof( fd_hash_t ) );
505 : //fd_sha256_append( &h, (uchar const *) slot_ctx->slot_bank.epoch_account_hash.hash, sizeof( fd_hash_t ) );
506 0 : fd_sha256_fini( &h, accounts_hash );
507 :
508 0 : return 0;
509 0 : }
510 0 : return fd_accounts_hash_inc_only( slot_ctx, accounts_hash, child_txn, do_hash_verify, spad );
511 0 : }
|