From a1de28933c97eeb277a503f52964f24642d2ec12 Mon Sep 17 00:00:00 2001 From: bee Date: Wed, 2 Jul 2025 16:49:44 +0500 Subject: [PATCH] fix: replace funk reference in syscall handler with sysvar cache lookup (#5030) --- src/discof/bank/fd_bank_abi.c | 4 +- .../vm/syscall/fd_vm_syscall_runtime.c | 59 +++++++++++++++---- 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/discof/bank/fd_bank_abi.c b/src/discof/bank/fd_bank_abi.c index c27f08f7dc..2c6d4aa6a9 100644 --- a/src/discof/bank/fd_bank_abi.c +++ b/src/discof/bank/fd_bank_abi.c @@ -24,8 +24,8 @@ fd_bank_abi_resolve_address_lookup_tables( void const * bank FD_PARAM_UNUSED } /* Look up the pubkeys from the ALTs */ - fd_slot_hashes_global_t const * slot_hashes_global = fd_sysvar_cache_slot_hashes( - ctx->slot_ctx->sysvar_cache, ctx->runtime_public_wksp ); + fd_slot_hashes_global_t const * slot_hashes_global = fd_sysvar_slot_hashes_read( + ctx->txn_ctx->funk, ctx->txn_ctx->funk_txn, ctx->txn_ctx->spad ); if( FD_UNLIKELY( !slot_hashes_global ) ) { FD_LOG_ERR(( "failed to get slot hashes global" )); } diff --git a/src/flamenco/vm/syscall/fd_vm_syscall_runtime.c b/src/flamenco/vm/syscall/fd_vm_syscall_runtime.c index c4282a38ae..329ebc8027 100644 --- a/src/flamenco/vm/syscall/fd_vm_syscall_runtime.c +++ b/src/flamenco/vm/syscall/fd_vm_syscall_runtime.c @@ -197,18 +197,55 @@ fd_vm_syscall_sol_get_sysvar( /**/ void * _vm, return FD_VM_SUCCESS; } - /* we know that the account data won't be changed for the lifetime of this view, because sysvars don't change inter-block */ - FD_TXN_ACCOUNT_DECL( sysvar_account ); - err = fd_txn_account_init_from_funk_readonly( sysvar_account, sysvar_id, vm->instr_ctx->txn_ctx->funk, vm->instr_ctx->txn_ctx->funk_txn ); - if( FD_UNLIKELY( err ) ) { - *_ret = 2UL; - return FD_VM_SUCCESS; + /* Select the correct sysvar by pubkey and read it directly from the sysvar cache. */ + const uchar * sysvar_buf = NULL; + ulong sysvar_buf_len = 0; + + if( memcmp( sysvar_id->uc, fd_sysvar_clock_id.uc, FD_PUBKEY_FOOTPRINT ) == 0 ) { + const fd_sol_sysvar_clock_t *clock = fd_sysvar_clock_read( + vm->instr_ctx->txn_ctx->funk, + vm->instr_ctx->txn_ctx->funk_txn, + vm->instr_ctx->txn_ctx->spad + ); + sysvar_buf = (const uchar *)clock; + sysvar_buf_len = sizeof(fd_sol_sysvar_clock_t); + } else if( memcmp( sysvar_id->uc, fd_sysvar_epoch_schedule_id.uc, FD_PUBKEY_FOOTPRINT ) == 0 ) { + const fd_epoch_schedule_t *schedule = fd_sysvar_epoch_schedule_read( + vm->instr_ctx->txn_ctx->funk, + vm->instr_ctx->txn_ctx->funk_txn, + vm->instr_ctx->txn_ctx->spad + ); + sysvar_buf = (const uchar *)schedule; + sysvar_buf_len = sizeof(fd_epoch_schedule_t); + } else if( memcmp( sysvar_id->uc, fd_sysvar_epoch_rewards_id.uc, FD_PUBKEY_FOOTPRINT ) == 0 ) { + const fd_sysvar_epoch_rewards_t *epoch_rewards = fd_sysvar_epoch_rewards_read( + vm->instr_ctx->txn_ctx->funk, + vm->instr_ctx->txn_ctx->funk_txn, + vm->instr_ctx->txn_ctx->spad + ); + sysvar_buf = (const uchar *)epoch_rewards; + sysvar_buf_len = sizeof(fd_sysvar_epoch_rewards_t); + } else if( memcmp( sysvar_id->uc, fd_sysvar_rent_id.uc, FD_PUBKEY_FOOTPRINT ) == 0 ) { + const fd_rent_t *rent = fd_sysvar_rent_read( + vm->instr_ctx->txn_ctx->funk, + vm->instr_ctx->txn_ctx->funk_txn, + vm->instr_ctx->txn_ctx->spad + ); + sysvar_buf = (const uchar *)rent; + sysvar_buf_len = sizeof(fd_rent_t); + } else if( memcmp( sysvar_id->uc, fd_sysvar_last_restart_slot_id.uc, FD_PUBKEY_FOOTPRINT ) == 0 ) { + const fd_sol_sysvar_last_restart_slot_t *slot = fd_sysvar_last_restart_slot_read( + vm->instr_ctx->txn_ctx->funk, + vm->instr_ctx->txn_ctx->funk_txn, + vm->instr_ctx->txn_ctx->spad + ); + sysvar_buf = (const uchar *)slot; + sysvar_buf_len = sizeof(fd_sol_sysvar_last_restart_slot_t); + } else { + *_ret = 2UL; + return FD_VM_SUCCESS; } - - /* https://github.com/anza-xyz/agave/blob/v2.1.0/programs/bpf_loader/src/syscalls/sysvar.rs#L223-L228 - Note the length check is at the very end to fail after performing sufficient checks. */ - const uchar * sysvar_buf = sysvar_account->vt->get_data( sysvar_account ); - ulong sysvar_buf_len = sysvar_account->vt->get_data_len( sysvar_account ); + if( FD_UNLIKELY( offset_length>sysvar_buf_len ) ) { *_ret = 1UL;