Line data Source code
1 : /* fd_sysvar_cache_db.c contains database interactions between the 2 : sysvar cache and the account database. */ 3 : 4 : #include "fd_sysvar.h" 5 : #include "fd_sysvar_cache.h" 6 : #include "fd_sysvar_cache_private.h" 7 : #include "../../accdb/fd_accdb_sync.h" 8 : 9 : static int 10 : sysvar_data_fill( fd_sysvar_cache_t * cache, 11 : fd_accdb_user_t * accdb, 12 : fd_funk_txn_xid_t const * xid, 13 : ulong idx, 14 52541 : int log_fails ) { 15 52541 : fd_sysvar_pos_t const * pos = &fd_sysvar_pos_tbl[ idx ]; 16 52541 : fd_pubkey_t const * key = &fd_sysvar_key_tbl[ idx ]; 17 52541 : fd_sysvar_desc_t * desc = &cache->desc [ idx ]; 18 : 19 : /* Read account from database */ 20 52541 : fd_accdb_ro_t ro[1]; 21 52541 : if( FD_UNLIKELY( !fd_accdb_open_ro( accdb, ro, xid, key ) ) ) { 22 11279 : if( log_fails ) FD_LOG_DEBUG(( "Sysvar %s not found", pos->name )); 23 11279 : return 0; 24 11279 : } 25 : 26 : /* Work around instruction fuzzer quirk */ 27 41262 : if( FD_UNLIKELY( fd_accdb_ref_lamports( ro )==0 ) ) { 28 0 : fd_accdb_close_ro( accdb, ro ); 29 0 : if( log_fails ) FD_LOG_WARNING(( "Skipping sysvar %s: zero balance", pos->name )); 30 0 : return 0; 31 0 : } 32 : 33 : /* Fill data cache entry */ 34 41262 : ulong data_sz = fd_accdb_ref_data_sz( ro ); 35 41262 : /* */ data_sz = fd_ulong_min( data_sz, pos->data_max ); 36 41262 : uchar * data = (uchar *)cache+pos->data_off; 37 41262 : fd_memcpy( data, fd_accdb_ref_data_const( ro ), data_sz ); 38 41262 : desc->data_sz = (uint)data_sz; 39 41262 : fd_accdb_close_ro( accdb, ro ); 40 : 41 : /* Recover object cache entry from data cache entry */ 42 41262 : return fd_sysvar_obj_restore( cache, desc, pos ); 43 41262 : } 44 : 45 : static int 46 : fd_sysvar_cache_restore1( fd_bank_t * bank, 47 : fd_accdb_user_t * accdb, 48 : fd_funk_txn_xid_t const * xid, 49 5839 : int log_fails ) { 50 5839 : fd_sysvar_cache_t * cache = fd_sysvar_cache_join( fd_sysvar_cache_new( 51 5839 : fd_bank_sysvar_cache_modify( bank ) ) ); 52 : 53 5839 : int saw_err = 0; 54 58381 : for( ulong i=0UL; i<FD_SYSVAR_CACHE_ENTRY_CNT; i++ ) { 55 52542 : int err = sysvar_data_fill( cache, accdb, xid, i, log_fails ); 56 52542 : if( err ) saw_err = 1; 57 52542 : } 58 : 59 5839 : fd_sysvar_cache_leave( cache ); 60 : 61 5839 : return !saw_err; 62 5839 : } 63 : 64 : int 65 : fd_sysvar_cache_restore( fd_bank_t * bank, 66 : fd_accdb_user_t * accdb, 67 299 : fd_funk_txn_xid_t const * xid ) { 68 299 : return fd_sysvar_cache_restore1( bank, accdb, xid, 1 ); 69 299 : } 70 : 71 : void 72 : fd_sysvar_cache_restore_fuzz( fd_bank_t * bank, 73 : fd_accdb_user_t * accdb, 74 5540 : fd_funk_txn_xid_t const * xid ) { 75 5540 : (void)fd_sysvar_cache_restore1( bank, accdb, xid, 0 ); 76 5540 : } 77 : 78 : void 79 : fd_sysvar_cache_restore_from_ref( fd_sysvar_cache_t * cache, 80 327395 : fd_accdb_ro_t const * ro ) { 81 327395 : ulong idx; 82 2407821 : for( idx=0UL; idx<FD_SYSVAR_CACHE_ENTRY_CNT; idx++ ) { 83 2238300 : if( 0==memcmp( fd_accdb_ref_address( ro ), fd_sysvar_key_tbl[ idx ].uc, sizeof(fd_pubkey_t) ) ) break; 84 2238300 : } 85 327395 : if( FD_UNLIKELY( idx==FD_SYSVAR_CACHE_ENTRY_CNT ) ) return; 86 157837 : if( FD_UNLIKELY( fd_accdb_ref_lamports( ro )==0UL ) ) return; 87 : 88 157795 : fd_sysvar_pos_t const * pos = &fd_sysvar_pos_tbl[ idx ]; 89 157795 : fd_sysvar_desc_t * desc = &cache->desc [ idx ]; 90 : 91 157795 : ulong data_sz = fd_accdb_ref_data_sz( ro ); 92 157795 : /* */ data_sz = fd_ulong_min( data_sz, pos->data_max ); 93 157795 : uchar * data = (uchar *)cache+pos->data_off; 94 157795 : fd_memcpy( data, fd_accdb_ref_data_const( ro ), data_sz ); 95 157795 : desc->data_sz = (uint)data_sz; 96 : 97 : /* Recover object cache entry from data cache entry */ 98 157795 : fd_sysvar_obj_restore( cache, desc, pos ); 99 157795 : }