Line data Source code
1 : #include "fd_sysvar.h" 2 : #include "../fd_system_ids.h" 3 : #include "../fd_acc_mgr.h" 4 : #include "../context/fd_exec_slot_ctx.h" 5 : #include "../context/fd_exec_instr_ctx.h" 6 : #include "../context/fd_exec_txn_ctx.h" 7 : 8 : #include "fd_sysvar_rent.h" 9 : 10 : /* https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank.rs#L1813 */ 11 : void 12 : fd_sysvar_account_update( fd_exec_slot_ctx_t * slot_ctx, 13 : fd_pubkey_t const * address, 14 : void const * data, 15 462 : ulong sz ) { 16 462 : fd_rent_t const * rent = fd_bank_rent_query( slot_ctx->bank ); 17 462 : ulong const min_bal = fd_rent_exempt_minimum_balance( rent, sz ); 18 : 19 462 : FD_TXN_ACCOUNT_DECL( rec ); 20 462 : fd_txn_account_init_from_funk_mutable( rec, address, slot_ctx->funk, slot_ctx->funk_txn, 1, sz ); 21 : 22 462 : ulong const slot = fd_bank_slot_get( slot_ctx->bank ); 23 462 : ulong const lamports_before = rec->vt->get_lamports( rec ); 24 462 : ulong const lamports_after = fd_ulong_max( lamports_before, min_bal ); 25 462 : rec->vt->set_lamports( rec, lamports_after ); 26 462 : rec->vt->set_owner ( rec, &fd_sysvar_owner_id ); 27 462 : rec->vt->set_slot ( rec, slot ); 28 462 : rec->vt->set_data( rec, data, sz ); 29 : 30 462 : ulong lamports_minted; 31 462 : if( FD_UNLIKELY( __builtin_usubl_overflow( lamports_after, lamports_before, &lamports_minted ) ) ) { 32 0 : char name[ FD_BASE58_ENCODED_32_SZ ]; fd_base58_encode_32( address->uc, NULL, name ); 33 0 : FD_LOG_CRIT(( "fd_sysvar_account_update: lamports overflowed: address=%s lamports_before=%lu lamports_after=%lu", 34 0 : name, lamports_before, lamports_after )); 35 0 : } 36 : 37 462 : if( lamports_minted ) { 38 9 : ulong cap = fd_bank_capitalization_get( slot_ctx->bank ); 39 9 : fd_bank_capitalization_set( slot_ctx->bank, cap+lamports_minted ); 40 453 : } else if( lamports_before==lamports_after ) { 41 : /* no balance change */ 42 453 : } else { 43 0 : __builtin_unreachable(); 44 0 : } 45 : 46 462 : fd_txn_account_mutable_fini( rec, slot_ctx->funk, slot_ctx->funk_txn ); 47 : 48 462 : FD_LOG_DEBUG(( "Updated sysvar: address=%s data_sz=%lu slot=%lu lamports=%lu lamports_minted=%lu", 49 462 : FD_BASE58_ENC_32_ALLOCA( address ), sz, slot, lamports_after, lamports_minted )); 50 462 : } 51 : 52 : int 53 : fd_sysvar_instr_acct_check( fd_exec_instr_ctx_t const * ctx, 54 : ulong idx, 55 0 : fd_pubkey_t const * addr_want ) { 56 : 57 0 : if( FD_UNLIKELY( idx >= ctx->instr->acct_cnt ) ) { 58 0 : return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS; 59 0 : } 60 : 61 0 : ushort idx_in_txn = ctx->instr->accounts[idx].index_in_transaction; 62 0 : fd_pubkey_t const * addr_have = &ctx->txn_ctx->account_keys[ idx_in_txn ]; 63 0 : if( FD_UNLIKELY( 0!=memcmp( addr_have, addr_want, sizeof(fd_pubkey_t) ) ) ) { 64 0 : return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; 65 0 : } 66 : 67 0 : return FD_EXECUTOR_INSTR_SUCCESS; 68 0 : }