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