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 4563 : int log_fails ) { 15 4563 : fd_sysvar_pos_t const * pos = &fd_sysvar_pos_tbl[ idx ]; 16 4563 : fd_pubkey_t const * key = &fd_sysvar_key_tbl[ idx ]; 17 4563 : fd_sysvar_desc_t * desc = &cache->desc [ idx ]; 18 : 19 : /* Read account from database */ 20 4563 : fd_accdb_ro_t ro[1]; 21 4563 : if( FD_UNLIKELY( !fd_accdb_open_ro( accdb, ro, xid, key ) ) ) { 22 3810 : if( log_fails ) FD_LOG_DEBUG(( "Sysvar %s not found", pos->name )); 23 3810 : return 0; 24 3810 : } 25 : 26 : /* Work around instruction fuzzer quirk */ 27 753 : 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 753 : ulong data_sz = fd_accdb_ref_data_sz( ro ); 35 753 : /* */ data_sz = fd_ulong_min( data_sz, pos->data_max ); 36 753 : uchar * data = (uchar *)cache+pos->data_off; 37 753 : fd_memcpy( data, fd_accdb_ref_data_const( ro ), data_sz ); 38 753 : desc->data_sz = (uint)data_sz; 39 753 : fd_accdb_close_ro( accdb, ro ); 40 : 41 : /* Recover object cache entry from data cache entry */ 42 753 : return fd_sysvar_obj_restore( cache, desc, pos ); 43 753 : } 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 507 : int log_fails ) { 50 507 : fd_sysvar_cache_t * cache = fd_sysvar_cache_join( fd_sysvar_cache_new( 51 507 : fd_bank_sysvar_cache_modify( bank ) ) ); 52 : 53 507 : int saw_err = 0; 54 5070 : for( ulong i=0UL; i<FD_SYSVAR_CACHE_ENTRY_CNT; i++ ) { 55 4563 : int err = sysvar_data_fill( cache, accdb, xid, i, log_fails ); 56 4563 : if( err ) saw_err = 1; 57 4563 : } 58 : 59 507 : fd_sysvar_cache_leave( cache ); 60 : 61 507 : return !saw_err; 62 507 : } 63 : 64 : int 65 : fd_sysvar_cache_restore( fd_bank_t * bank, 66 : fd_accdb_user_t * accdb, 67 507 : fd_funk_txn_xid_t const * xid ) { 68 507 : return fd_sysvar_cache_restore1( bank, accdb, xid, 1 ); 69 507 : } 70 : 71 : void 72 : fd_sysvar_cache_restore_fuzz( fd_bank_t * bank, 73 : fd_accdb_user_t * accdb, 74 0 : fd_funk_txn_xid_t const * xid ) { 75 0 : (void)fd_sysvar_cache_restore1( bank, accdb, xid, 0 ); 76 0 : } 77 : 78 : void 79 : fd_sysvar_cache_restore_from_ref( fd_sysvar_cache_t * cache, 80 0 : fd_accdb_ro_t const * ro ) { 81 0 : ulong idx; 82 0 : for( idx=0UL; idx<FD_SYSVAR_CACHE_ENTRY_CNT; idx++ ) { 83 0 : if( 0==memcmp( fd_accdb_ref_address( ro ), fd_sysvar_key_tbl[ idx ].uc, sizeof(fd_pubkey_t) ) ) break; 84 0 : } 85 0 : if( FD_UNLIKELY( idx==FD_SYSVAR_CACHE_ENTRY_CNT ) ) return; 86 0 : if( FD_UNLIKELY( fd_accdb_ref_lamports( ro )==0UL ) ) return; 87 : 88 0 : fd_sysvar_pos_t const * pos = &fd_sysvar_pos_tbl[ idx ]; 89 0 : fd_sysvar_desc_t * desc = &cache->desc [ idx ]; 90 : 91 0 : ulong data_sz = fd_accdb_ref_data_sz( ro ); 92 0 : /* */ data_sz = fd_ulong_min( data_sz, pos->data_max ); 93 0 : uchar * data = (uchar *)cache+pos->data_off; 94 0 : fd_memcpy( data, fd_accdb_ref_data_const( ro ), data_sz ); 95 0 : desc->data_sz = (uint)data_sz; 96 : 97 : /* Recover object cache entry from data cache entry */ 98 0 : fd_sysvar_obj_restore( cache, desc, pos ); 99 0 : }