Line data Source code
1 : #include "fd_sysvar.h" 2 : #include "../fd_system_ids.h" 3 : #include "../fd_hashes.h" 4 : #include "../fd_runtime.h" 5 : #include "fd_sysvar_rent.h" 6 : #include "../../accdb/fd_accdb_sync.h" 7 : 8 : /* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank.rs#L1813 */ 9 : void 10 : fd_sysvar_account_update( fd_bank_t * bank, 11 : fd_accdb_user_t * accdb, 12 : fd_funk_txn_xid_t const * xid, 13 : fd_capture_ctx_t * capture_ctx, 14 : fd_pubkey_t const * address, 15 : void const * data, 16 753 : ulong sz ) { 17 753 : fd_rent_t const * rent = fd_bank_rent_query( bank ); 18 753 : ulong const min_bal = fd_rent_exempt_minimum_balance( rent, sz ); 19 : 20 753 : fd_accdb_rw_t rw[1]; 21 753 : fd_accdb_open_rw( accdb, rw, xid, address, sz, FD_ACCDB_FLAG_CREATE ); 22 753 : fd_lthash_value_t prev_hash[1]; 23 753 : fd_hashes_account_lthash( address, rw->meta, fd_accdb_ref_data_const( rw->ro ), prev_hash ); 24 : 25 753 : ulong const lamports_before = fd_accdb_ref_lamports( rw->ro ); 26 753 : ulong const lamports_after = fd_ulong_max( lamports_before, min_bal ); 27 753 : fd_accdb_ref_lamports_set( rw, lamports_after ); 28 753 : fd_accdb_ref_owner_set ( rw, &fd_sysvar_owner_id ); 29 753 : fd_accdb_ref_data_set ( accdb, rw, data, sz ); 30 : 31 753 : ulong lamports_minted; 32 753 : if( FD_UNLIKELY( __builtin_usubl_overflow( lamports_after, lamports_before, &lamports_minted ) ) ) { 33 0 : char name[ FD_BASE58_ENCODED_32_SZ ]; fd_base58_encode_32( address->uc, NULL, name ); 34 0 : FD_LOG_CRIT(( "fd_sysvar_account_update: lamports overflowed: address=%s lamports_before=%lu lamports_after=%lu", 35 0 : name, lamports_before, lamports_after )); 36 0 : } 37 : 38 753 : if( lamports_minted ) { 39 189 : ulong cap = fd_bank_capitalization_get( bank ); 40 189 : fd_bank_capitalization_set( bank, cap+lamports_minted ); 41 189 : } 42 : 43 753 : fd_hashes_update_lthash( fd_accdb_ref_address( rw->ro ), rw->meta, prev_hash, bank, capture_ctx ); 44 753 : fd_accdb_close_rw( accdb, rw ); 45 : 46 753 : if( FD_UNLIKELY( fd_log_level_logfile()<=0 || fd_log_level_stderr()<=0 ) ) { 47 0 : char name[ FD_BASE58_ENCODED_32_SZ ]; fd_base58_encode_32( address->uc, NULL, name ); 48 0 : FD_LOG_DEBUG(( "Updated sysvar: address=%s data_sz=%lu lamports=%lu lamports_minted=%lu", 49 0 : name, sz, lamports_after, lamports_minted )); 50 0 : } 51 753 : } 52 : 53 : int 54 : fd_sysvar_instr_acct_check( fd_exec_instr_ctx_t const * ctx, 55 : ulong idx, 56 0 : fd_pubkey_t const * addr_want ) { 57 : 58 0 : if( FD_UNLIKELY( idx >= ctx->instr->acct_cnt ) ) { 59 0 : return FD_EXECUTOR_INSTR_ERR_MISSING_ACC; 60 0 : } 61 : 62 0 : ushort idx_in_txn = ctx->instr->accounts[idx].index_in_transaction; 63 0 : fd_pubkey_t const * addr_have = &ctx->txn_out->accounts.keys[ idx_in_txn ]; 64 0 : if( FD_UNLIKELY( 0!=memcmp( addr_have, addr_want, sizeof(fd_pubkey_t) ) ) ) { 65 0 : return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; 66 0 : } 67 : 68 0 : return FD_EXECUTOR_INSTR_SUCCESS; 69 0 : }