LCOV - code coverage report
Current view: top level - flamenco/snapshot - fd_snapshot.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 144 0.0 %
Date: 2024-11-13 11:58:15 Functions: 0 5 0.0 %

          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/context/fd_exec_epoch_ctx.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             : static void
      16           0 : fd_hashes_load(fd_exec_slot_ctx_t * slot_ctx) {
      17           0 :   FD_BORROWED_ACCOUNT_DECL(block_hashes_rec);
      18           0 :   int err = fd_acc_mgr_view(slot_ctx->acc_mgr, slot_ctx->funk_txn, &fd_sysvar_recent_block_hashes_id, block_hashes_rec);
      19             : 
      20           0 :   if( err != FD_ACC_MGR_SUCCESS )
      21           0 :     FD_LOG_ERR(( "missing recent block hashes account" ));
      22             : 
      23           0 :   fd_bincode_decode_ctx_t ctx = {
      24           0 :     .data       = block_hashes_rec->const_data,
      25           0 :     .dataend    = block_hashes_rec->const_data + block_hashes_rec->const_meta->dlen,
      26           0 :     .valloc     = slot_ctx->valloc
      27           0 :   };
      28             : 
      29           0 :   fd_recent_block_hashes_decode( &slot_ctx->slot_bank.recent_block_hashes, &ctx );
      30             : 
      31           0 :   slot_ctx->slot_bank.stake_account_keys.stake_accounts_root = NULL;
      32           0 :   slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool = fd_stake_accounts_pair_t_map_alloc(slot_ctx->valloc, 100000);
      33             : 
      34           0 :   slot_ctx->slot_bank.vote_account_keys.vote_accounts_root = NULL;
      35           0 :   slot_ctx->slot_bank.vote_account_keys.vote_accounts_pool = fd_vote_accounts_pair_t_map_alloc(slot_ctx->valloc, 100000);
      36             : 
      37           0 :   slot_ctx->slot_bank.collected_execution_fees = 0;
      38           0 :   slot_ctx->slot_bank.collected_priority_fees = 0;
      39           0 :   slot_ctx->slot_bank.collected_rent = 0;
      40             : 
      41           0 :   fd_runtime_save_slot_bank( slot_ctx );
      42           0 :   fd_runtime_save_epoch_bank( slot_ctx );
      43           0 : }
      44             : 
      45             : 
      46             : static int
      47             : restore_manifest( void *                 ctx,
      48           0 :                   fd_solana_manifest_t * manifest ) {
      49           0 :   return (!!fd_exec_slot_ctx_recover( ctx, manifest ) ? 0 : EINVAL);
      50           0 : }
      51             : 
      52             : static int
      53             : restore_status_cache( void *                 ctx,
      54           0 :                       fd_bank_slot_deltas_t * slot_deltas ) {
      55           0 :   return (!!fd_exec_slot_ctx_recover_status_cache( ctx, slot_deltas ) ? 0 : EINVAL);
      56           0 : }
      57             : 
      58             : static void
      59             : load_one_snapshot( fd_exec_slot_ctx_t * slot_ctx,
      60             :                    char *               source_cstr,
      61           0 :                    fd_snapshot_name_t * name_out ) {
      62             : 
      63             :   /* FIXME don't hardcode this param */
      64           0 :   static ulong const zstd_window_sz = 33554432UL;
      65             : 
      66           0 :   fd_snapshot_src_t src[1];
      67           0 :   if( FD_UNLIKELY( !fd_snapshot_src_parse( src, source_cstr ) ) ) {
      68           0 :     FD_LOG_ERR(( "Failed to load snapshot" ));
      69           0 :   }
      70             : 
      71           0 :   if( src->type == FD_SNAPSHOT_SRC_ARCHIVE ) {
      72           0 :     if( FD_UNLIKELY( fd_funk_unarchive( slot_ctx->acc_mgr->funk, src->file.path ) ) ) {
      73           0 :       FD_LOG_ERR(( "Failed to load snapshot" ));
      74           0 :     }
      75           0 :     fd_runtime_recover_banks( slot_ctx, 0, 1 );
      76           0 :     memset( name_out, 0, sizeof(fd_snapshot_name_t) );
      77           0 :     name_out->type = FD_SNAPSHOT_TYPE_FULL;
      78           0 :     name_out->slot = slot_ctx->slot_bank.slot;
      79           0 :     return;
      80           0 :   }
      81           0 :   fd_exec_epoch_ctx_bank_mem_clear( slot_ctx->epoch_ctx );
      82             : 
      83           0 :   fd_valloc_t     valloc   = slot_ctx->valloc;
      84           0 :   fd_acc_mgr_t *  acc_mgr  = slot_ctx->acc_mgr;
      85           0 :   fd_funk_txn_t * funk_txn = slot_ctx->funk_txn;
      86             : 
      87           0 :   void * restore_mem = fd_valloc_malloc( valloc, fd_snapshot_restore_align(), fd_snapshot_restore_footprint() );
      88           0 :   void * loader_mem  = fd_valloc_malloc( valloc, fd_snapshot_loader_align(),  fd_snapshot_loader_footprint( zstd_window_sz ) );
      89             : 
      90           0 :   fd_snapshot_restore_t * restore = fd_snapshot_restore_new( restore_mem, acc_mgr, funk_txn, valloc, slot_ctx, restore_manifest, restore_status_cache );
      91           0 :   fd_snapshot_loader_t *  loader  = fd_snapshot_loader_new ( loader_mem, zstd_window_sz );
      92             : 
      93           0 :   if( FD_UNLIKELY( !restore || !loader ) ) {
      94           0 :     fd_valloc_free( valloc, fd_snapshot_loader_delete ( loader_mem  ) );
      95           0 :     fd_valloc_free( valloc, fd_snapshot_restore_delete( restore_mem ) );
      96           0 :     FD_LOG_ERR(( "Failed to load snapshot" ));
      97           0 :   }
      98             : 
      99           0 :   if( FD_UNLIKELY( !fd_snapshot_loader_init( loader, restore, src, slot_ctx->slot_bank.slot ) ) ) {
     100           0 :     FD_LOG_ERR(( "Failed to init snapshot loader" ));
     101           0 :   }
     102             : 
     103           0 :   for(;;) {
     104           0 :     int err = fd_snapshot_loader_advance( loader );
     105           0 :     if( FD_LIKELY( err == 0 ) ) continue;
     106           0 :     if( err == -1 ) break;
     107             : 
     108           0 :     FD_LOG_ERR(( "Failed to load snapshot (%d-%s)", err, fd_io_strerror( err ) ));
     109           0 :   }
     110             : 
     111           0 :   fd_snapshot_name_t const * name = fd_snapshot_loader_get_name( loader );
     112           0 :   if( FD_UNLIKELY( !name ) ) FD_LOG_ERR(( "name is NULL" ));
     113           0 :   *name_out = *name;
     114             : 
     115           0 :   fd_valloc_free( valloc, fd_snapshot_loader_delete ( loader_mem  ) );
     116           0 :   fd_valloc_free( valloc, fd_snapshot_restore_delete( restore_mem ) );
     117             : 
     118           0 :   FD_LOG_NOTICE(( "Finished reading snapshot %s", source_cstr ));
     119           0 : }
     120             : 
     121             : 
     122             : void
     123             : fd_snapshot_load( const char *         snapshotfile,
     124             :                   fd_exec_slot_ctx_t * slot_ctx,
     125             :                   fd_tpool_t *         tpool,
     126             :                   uint                 verify_hash,
     127             :                   uint                 check_hash,
     128           0 :                   int                  snapshot_type ) {
     129             : 
     130           0 :   switch (snapshot_type) {
     131           0 :   case FD_SNAPSHOT_TYPE_UNSPECIFIED:
     132           0 :     FD_LOG_ERR(("fd_snapshot_load(\"%s\", verify-hash=%s, check-hash=%s, FD_SNAPSHOT_TYPE_UNSPECIFIED)", snapshotfile, verify_hash ? "true" : "false", check_hash ? "true" : "false"));
     133           0 :     break;
     134           0 :   case FD_SNAPSHOT_TYPE_FULL:
     135           0 :     FD_LOG_NOTICE(("fd_snapshot_load(\"%s\", verify-hash=%s, check-hash=%s, FD_SNAPSHOT_TYPE_FULL)", snapshotfile, verify_hash ? "true" : "false", check_hash ? "true" : "false"));
     136           0 :     break;
     137           0 :   case FD_SNAPSHOT_TYPE_INCREMENTAL:
     138           0 :     FD_LOG_NOTICE(("fd_snapshot_load(\"%s\", verify-hash=%s, check-hash=%s, FD_SNAPSHOT_TYPE_INCREMENTAL)", snapshotfile, verify_hash ? "true" : "false", check_hash ? "true" : "false"));
     139           0 :     break;
     140           0 :   default:
     141           0 :     FD_LOG_ERR(("fd_snapshot_load(\"%s\", verify-hash=%s, check-hash=%s, huh?)", snapshotfile, verify_hash ? "true" : "false", check_hash ? "true" : "false"));
     142           0 :     break;
     143           0 :   }
     144             : 
     145           0 :   fd_funk_start_write( slot_ctx->acc_mgr->funk );
     146             :   /* Speed load currently has long term memory usage consequences
     147             :      which are unacceptable. Consider turning it back on when we have a
     148             :      better design. */
     149           0 :   fd_funk_speed_load_mode( slot_ctx->acc_mgr->funk, 0 );
     150             : 
     151           0 :   fd_funk_txn_t * par_txn = slot_ctx->funk_txn;
     152           0 :   fd_funk_txn_t * child_txn = slot_ctx->funk_txn;
     153           0 :   if( verify_hash && FD_FEATURE_ACTIVE(slot_ctx, incremental_snapshot_only_incremental_hash_calculation) ) {
     154           0 :     fd_funk_txn_xid_t xid;
     155           0 :     memset( &xid, 0xc3, sizeof( xid ) );
     156           0 :     child_txn = fd_funk_txn_prepare( slot_ctx->acc_mgr->funk, child_txn, &xid, 0 );
     157           0 :     slot_ctx->funk_txn = child_txn;
     158           0 :   }
     159             : 
     160           0 :   fd_scratch_push();
     161           0 :   size_t slen = strlen( snapshotfile );
     162           0 :   char * snapshot_cstr = fd_scratch_alloc( 1UL, slen + 1 );
     163           0 :   fd_cstr_fini( fd_cstr_append_text( fd_cstr_init( snapshot_cstr ), snapshotfile, slen ) );
     164           0 :   fd_snapshot_name_t name = {0};
     165           0 :   load_one_snapshot( slot_ctx, snapshot_cstr, &name );
     166           0 :   fd_hash_t const * fhash = &name.fhash;
     167           0 :   fd_scratch_pop();
     168             : 
     169           0 :   if( name.type != snapshot_type ) {
     170           0 :     FD_LOG_ERR(( "snapshot %s is wrong type", snapshotfile ));
     171           0 :   }
     172             : 
     173             :   // In order to calculate the snapshot hash, we need to know what features are active...
     174           0 :   fd_features_restore( slot_ctx );
     175           0 :   fd_calculate_epoch_accounts_hash_values( slot_ctx );
     176             : 
     177           0 :   if( verify_hash ) {
     178           0 :     if (snapshot_type == FD_SNAPSHOT_TYPE_FULL) {
     179           0 :       fd_hash_t accounts_hash;
     180           0 :       fd_snapshot_hash(slot_ctx, tpool, &accounts_hash, check_hash);
     181             : 
     182           0 :       if (memcmp(fhash->uc, accounts_hash.uc, 32) != 0)
     183           0 :         FD_LOG_ERR(( "snapshot accounts_hash %s != %s", FD_BASE58_ENC_32_ALLOCA( accounts_hash.hash ), FD_BASE58_ENC_32_ALLOCA( fhash->uc ) ));
     184           0 :       else
     185           0 :         FD_LOG_NOTICE(( "snapshot accounts_hash %s verified successfully", FD_BASE58_ENC_32_ALLOCA( accounts_hash.hash) ));
     186           0 :     } else if (snapshot_type == FD_SNAPSHOT_TYPE_INCREMENTAL) {
     187           0 :       fd_hash_t accounts_hash;
     188             : 
     189           0 :       if (FD_FEATURE_ACTIVE(slot_ctx, incremental_snapshot_only_incremental_hash_calculation)) {
     190           0 :         FD_LOG_NOTICE(( "hashing incremental snapshot with only deltas" ));
     191           0 :         fd_accounts_hash_inc_only(slot_ctx, &accounts_hash, child_txn, check_hash);
     192           0 :       } else {
     193           0 :         FD_LOG_NOTICE(( "hashing incremental snapshot with all accounts" ));
     194           0 :         fd_snapshot_hash(slot_ctx, tpool, &accounts_hash, check_hash);
     195           0 :       }
     196             : 
     197           0 :       if (memcmp(fhash->uc, accounts_hash.uc, 32) != 0)
     198           0 :         FD_LOG_ERR(("incremental accounts_hash %s != %s", FD_BASE58_ENC_32_ALLOCA( accounts_hash.hash ), FD_BASE58_ENC_32_ALLOCA( fhash->uc ) ));
     199           0 :       else
     200           0 :         FD_LOG_NOTICE(("incremental accounts_hash %s verified successfully", FD_BASE58_ENC_32_ALLOCA( accounts_hash.hash ) ));
     201           0 :     } else {
     202           0 :       FD_LOG_ERR(( "invalid snapshot type %d", snapshot_type ));
     203           0 :     }
     204           0 :   }
     205             : 
     206           0 :   if( child_txn != par_txn ) {
     207           0 :     fd_funk_txn_publish( slot_ctx->acc_mgr->funk, child_txn, 0 );
     208           0 :     slot_ctx->funk_txn = par_txn;
     209           0 :   }
     210             : 
     211           0 :   fd_hashes_load(slot_ctx);
     212             : 
     213           0 :   fd_rewards_recalculate_partitioned_rewards( slot_ctx );
     214             : 
     215           0 :   fd_funk_speed_load_mode( slot_ctx->acc_mgr->funk, 0 );
     216           0 :   fd_funk_end_write( slot_ctx->acc_mgr->funk );
     217           0 : }

Generated by: LCOV version 1.14