Line data Source code
1 : #include "fd_accdb_fsck.h" 2 : #include "../../funk/fd_funk.h" 3 : #include "../../flamenco/fd_flamenco_base.h" 4 : #include "../../ballet/base58/fd_base58.h" 5 : #include "../../ballet/lthash/fd_lthash_adder.h" 6 : 7 : static void 8 : process_rec( fd_funk_t * funk, 9 : fd_funk_rec_t const * rec, 10 : fd_lthash_adder_t * adder, 11 0 : fd_lthash_value_t * sum ) { 12 0 : if( FD_UNLIKELY( !fd_funk_txn_xid_eq_root( rec->pair.xid ) ) ) return; 13 0 : fd_account_meta_t const * meta = fd_funk_val_const( rec, funk->wksp ); 14 0 : if( FD_UNLIKELY( !meta ) ) return; 15 0 : void const * data = (void const *)( meta+1 ); 16 0 : ulong data_sz = meta->dlen; 17 0 : void const * pubkey = rec->pair.key->uc; 18 0 : ulong lamports = meta->lamports; 19 0 : _Bool executable = !!meta->executable; 20 0 : void const * owner = meta->owner; 21 0 : if( adder && FD_LIKELY( lamports ) ) { 22 0 : fd_lthash_adder_push_solana_account( adder, sum, pubkey, data, data_sz, lamports, executable, owner ); 23 0 : } 24 0 : } 25 : 26 : static void 27 : process_chain( fd_funk_t * funk, 28 : ulong chain_idx, 29 : fd_lthash_adder_t * adder, 30 0 : fd_lthash_value_t * sum ) { 31 0 : fd_funk_rec_map_t * rec_map = fd_funk_rec_map( funk ); 32 0 : for( 33 0 : fd_funk_rec_map_iter_t iter = fd_funk_rec_map_iter( rec_map, chain_idx ); 34 0 : !fd_funk_rec_map_iter_done( iter ); 35 0 : iter = fd_funk_rec_map_iter_next( iter ) 36 0 : ) { 37 0 : fd_funk_rec_t const * rec = fd_funk_rec_map_iter_ele_const( iter ); 38 0 : process_rec( funk, rec, adder, sum ); 39 0 : } 40 0 : } 41 : 42 : uint 43 : fd_accdb_fsck_funk( fd_funk_t * funk, 44 0 : uint flags ) { 45 0 : _Bool const lthash = !!( flags & FD_ACCDB_FSCK_FLAGS_LTHASH ); 46 : 47 0 : FD_LOG_NOTICE(( "FSCK starting integrity checks ..." )); 48 0 : long dt = -fd_log_wallclock(); 49 0 : int funk_err = fd_funk_verify( funk ); 50 0 : dt += fd_log_wallclock(); 51 0 : if( FD_UNLIKELY( funk_err ) ) { 52 0 : FD_LOG_WARNING(( "FSCK: detected database integrity errors (took %g seconds)", (double)dt/1e9 )); 53 0 : } else { 54 0 : FD_LOG_NOTICE(( "FSCK: funk integrity OK (took %g seconds)", (double)dt/1e9 )); 55 0 : } 56 : 57 0 : FD_LOG_NOTICE(( "FSCK computing lthash ..." )); 58 0 : fd_lthash_value_t sum[1]; fd_lthash_zero( sum ); 59 0 : fd_lthash_adder_t adder_[1]; 60 0 : fd_lthash_adder_t * adder = NULL; 61 0 : if( lthash ) { 62 0 : adder = fd_lthash_adder_new( adder_ ); 63 0 : FD_TEST( adder ); 64 0 : } 65 0 : dt = -fd_log_wallclock(); 66 : 67 0 : fd_funk_rec_map_t * rec_map = fd_funk_rec_map( funk ); 68 0 : ulong chain_cnt = fd_funk_rec_map_chain_cnt( rec_map ); 69 0 : for( ulong i=0UL; i<chain_cnt; i++ ) process_chain( funk, i, adder, sum ); 70 : 71 0 : dt += fd_log_wallclock(); 72 0 : if( lthash ) { 73 0 : fd_lthash_adder_flush( adder, sum ); 74 0 : uchar hash32[32]; fd_blake3_hash( sum->bytes, FD_LTHASH_LEN_BYTES, hash32 ); 75 0 : FD_BASE58_ENCODE_32_BYTES( sum->bytes, sum_enc ); 76 0 : FD_BASE58_ENCODE_32_BYTES( hash32, hash32_enc ); 77 0 : FD_LOG_NOTICE(( "FSCK: lthash[..32]=%s blake3(lthash)=%s", sum_enc, hash32_enc )); 78 0 : } 79 : 80 0 : return funk_err==FD_FUNK_SUCCESS ? FD_ACCDB_FSCK_NO_ERROR : FD_ACCDB_FSCK_CORRUPT; 81 0 : }