From c6779f4893a20fdd3cc2e8f79b9857c24aaee884 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 21 Nov 2025 19:24:52 +0000 Subject: [PATCH 01/32] initial --- src/flamenco/fd_flamenco_base.h | 11 +++++++++++ src/flamenco/runtime/fd_executor.c | 3 +++ src/flamenco/runtime/fd_runtime.h | 3 +++ 3 files changed, 17 insertions(+) diff --git a/src/flamenco/fd_flamenco_base.h b/src/flamenco/fd_flamenco_base.h index 87ac0713ae..7ea6ffa428 100644 --- a/src/flamenco/fd_flamenco_base.h +++ b/src/flamenco/fd_flamenco_base.h @@ -116,6 +116,17 @@ struct fd_account_meta { }; typedef struct fd_account_meta fd_account_meta_t; +struct fd_account { + uchar pubkey[32UL]; + fd_account_meta_t * meta; +}; +typedef struct fd_account fd_account_t; + +FD_FN_PURE static inline uchar * +fd_account_data( fd_account_t const * acc ) { + return (uchar *)( acc->meta+1 ); +} + FD_PROTOTYPES_BEGIN /* fd_acct_addr_cstr converts the given Solana address into a base58- diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 4e07c44635..f9054a8d2a 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -1535,6 +1535,9 @@ fd_executor_setup_txn_account( fd_runtime_t * runtime, FD_LOG_CRIT(( "Failed to join txn account" )); } + memcpy( &txn_out->accounts.pubkeys[idx], acc, sizeof(fd_pubkey_t) ); + txn_out->accounts.metas[ idx ] = account_meta; + return txn_account; } diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index def1dba88c..3a2661c948 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -216,6 +216,9 @@ struct fd_txn_out { /* If the transaction has a nonce account that must be advanced, this would be !=ULONG_MAX. */ fd_txn_account_t rollback_fee_payer[ 1 ]; + + fd_pubkey_t pubkeys[ MAX_TX_ACCOUNT_LOCKS ]; + fd_account_meta_t * metas[ MAX_TX_ACCOUNT_LOCKS ]; } accounts; }; typedef struct fd_txn_out fd_txn_out_t; From af9eb20ff19e3ba31a65d6068ef4080c19b5df31 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 21 Nov 2025 20:51:40 +0000 Subject: [PATCH 02/32] wip --- src/flamenco/runtime/fd_executor.c | 4 ++-- src/flamenco/runtime/fd_runtime.c | 8 ++++---- src/flamenco/runtime/fd_runtime.h | 6 +++--- src/flamenco/runtime/tests/fd_dump_pb.c | 8 ++++---- src/flamenco/runtime/tests/fd_instr_harness.c | 6 +++--- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index f9054a8d2a..247ca0df79 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -1562,7 +1562,7 @@ fd_executor_setup_executable_account( fd_runtime_t * runtime, account will not exist within the executable accounts list. */ fd_pubkey_t * programdata_acc = &program_loader_state->inner.program.programdata_address; fd_funk_txn_xid_t xid = { .ul = { fd_bank_slot_get( bank ), bank->idx } }; - if( FD_LIKELY( fd_txn_account_init_from_funk_readonly( &runtime->executable.accounts[ *executable_idx ], + if( FD_LIKELY( fd_txn_account_init_from_funk_readonly( &runtime->accounts.executables[ *executable_idx ], programdata_acc, runtime->funk, &xid )==0 ) ) { @@ -1601,7 +1601,7 @@ fd_executor_setup_accounts_for_txn( fd_runtime_t * runtime, # endif txn_out->accounts.nonce_idx_in_txn = ULONG_MAX; - runtime->executable.cnt = executable_idx; + runtime->accounts.executable_cnt = executable_idx; /* Set up instr infos from the txn descriptor. No Agave equivalent to this function. */ fd_executor_setup_instr_infos_from_txn_instrs( runtime, bank, txn_in, txn_out ); diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 337704ef69..00691998c6 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1334,7 +1334,7 @@ fd_runtime_prepare_and_execute_txn( fd_runtime_t * runtime, memset( txn_out->details.return_data.program_id.key, 0, sizeof(fd_pubkey_t) ); fd_compute_budget_details_new( &txn_out->details.compute_budget ); - runtime->executable.cnt = 0UL; + runtime->accounts.executable_cnt = 0UL; runtime->log.enable_log_collector = 0; runtime->instr.info_cnt = 0UL; runtime->instr.trace_length = 0UL; @@ -1794,9 +1794,9 @@ fd_runtime_get_executable_account( fd_runtime_t * runtime, return FD_ACC_MGR_SUCCESS; } - for( ushort i=0; iexecutable.cnt; i++ ) { - if( memcmp( pubkey->uc, runtime->executable.accounts[i].pubkey->uc, sizeof(fd_pubkey_t) )==0 ) { - fd_txn_account_t * txn_account = &runtime->executable.accounts[i]; + for( ushort i=0; iaccounts.executable_cnt; i++ ) { + if( memcmp( pubkey->uc, runtime->accounts.executables[i].pubkey->uc, sizeof(fd_pubkey_t) )==0 ) { + fd_txn_account_t * txn_account = &runtime->accounts.executables[i]; *account = txn_account; if( FD_LIKELY( condition != NULL ) ) { diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index 3a2661c948..11bf0afc52 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -127,9 +127,9 @@ struct fd_runtime { } stake_program; struct { - ulong cnt; /* Number of BPF upgradeable loader accounts. */ - fd_txn_account_t accounts[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */ - } executable; + ulong executable_cnt; /* Number of BPF upgradeable loader accounts. */ + fd_txn_account_t executables[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */ + } accounts; }; typedef struct fd_runtime fd_runtime_t; diff --git a/src/flamenco/runtime/tests/fd_dump_pb.c b/src/flamenco/runtime/tests/fd_dump_pb.c index 45b42388c5..5ab1db31c0 100644 --- a/src/flamenco/runtime/tests/fd_dump_pb.c +++ b/src/flamenco/runtime/tests/fd_dump_pb.c @@ -901,7 +901,7 @@ create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t * /* Accounts */ instr_context->accounts_count = (pb_size_t) txn_out->accounts.accounts_cnt; - instr_context->accounts = fd_spad_alloc( spad, alignof(fd_exec_test_acct_state_t), (instr_context->accounts_count + num_sysvar_entries + runtime->executable.cnt) * sizeof(fd_exec_test_acct_state_t)); + instr_context->accounts = fd_spad_alloc( spad, alignof(fd_exec_test_acct_state_t), (instr_context->accounts_count + num_sysvar_entries + runtime->accounts.executable_cnt) * sizeof(fd_exec_test_acct_state_t)); for( ulong i = 0; i < txn_out->accounts.accounts_cnt; i++ ) { // Copy account information over fd_txn_account_t const * txn_account = &txn_out->accounts.accounts[i]; @@ -933,16 +933,16 @@ create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t * } /* Add executable accounts */ - for( ulong i = 0; i < runtime->executable.cnt; i++ ) { + for( ulong i = 0; i < runtime->accounts.executable_cnt; i++ ) { fd_txn_account_t txn_account[1]; - int ret = fd_txn_account_init_from_funk_readonly( txn_account, runtime->executable.accounts[i].pubkey, runtime->funk, &xid ); + int ret = fd_txn_account_init_from_funk_readonly( txn_account, runtime->accounts.executables[i].pubkey, runtime->funk, &xid ); if( ret != FD_ACC_MGR_SUCCESS ) { continue; } // Make sure the account doesn't exist in the output accounts yet bool account_exists = false; for( ulong j = 0; j < instr_context->accounts_count; j++ ) { - if( 0 == memcmp( instr_context->accounts[j].address, runtime->executable.accounts[i].pubkey->uc, sizeof(fd_pubkey_t) ) ) { + if( 0 == memcmp( instr_context->accounts[j].address, runtime->accounts.executables[i].pubkey->uc, sizeof(fd_pubkey_t) ) ) { account_exists = true; break; } diff --git a/src/flamenco/runtime/tests/fd_instr_harness.c b/src/flamenco/runtime/tests/fd_instr_harness.c index e58a65f8af..e833eb8d39 100644 --- a/src/flamenco/runtime/tests/fd_instr_harness.c +++ b/src/flamenco/runtime/tests/fd_instr_harness.c @@ -104,7 +104,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, fd_compute_budget_details_new( &txn_out->details.compute_budget ); runtime->instr.stack_sz = 0; txn_out->accounts.accounts_cnt = 0UL; - runtime->executable.cnt = 0UL; + runtime->accounts.executable_cnt = 0UL; txn_out->details.programs_to_reverify_cnt = 0UL; txn_out->details.loaded_accounts_data_size = 0UL; @@ -243,13 +243,13 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, } fd_pubkey_t * programdata_acc = &program_loader_state->inner.program.programdata_address; - if( FD_UNLIKELY( fd_txn_account_init_from_funk_readonly( &runtime->executable.accounts[runtime->executable.cnt], + if( FD_UNLIKELY( fd_txn_account_init_from_funk_readonly( &runtime->accounts.executables[runtime->accounts.executable_cnt], programdata_acc, runtime->funk, xid ) ) ) { continue; } - runtime->executable.cnt++; + runtime->accounts.executable_cnt++; } } From 8cdaccacf9e92272c2c6142ca65847fc46138b28 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 21 Nov 2025 21:27:20 +0000 Subject: [PATCH 03/32] wip --- src/flamenco/runtime/fd_executor.c | 108 +++++++++++++---------------- src/flamenco/runtime/fd_executor.h | 8 --- src/flamenco/runtime/fd_runtime.h | 2 + 3 files changed, 51 insertions(+), 67 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 247ca0df79..4414cf808e 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -1045,7 +1045,6 @@ fd_executor_validate_transaction_fee_payer( fd_runtime_t * runtime, return FD_RUNTIME_TXN_ERR_ACCOUNT_NOT_FOUND; } - /* Calculate transaction fees https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/transaction_processor.rs#L597-L606 */ ulong execution_fee = 0UL; @@ -1070,6 +1069,7 @@ fd_executor_validate_transaction_fee_payer( fd_runtime_t * runtime, /* Set the starting lamports (to avoid unbalanced lamports issues in instruction execution) */ fee_payer_rec->starting_lamports = fd_txn_account_get_lamports( fee_payer_rec ); /* TODO: why do we do this everywhere? */ + runtime->accounts.starting_lamports[FD_FEE_PAYER_TXN_IDX] = fee_payer_rec->starting_lamports; txn_out->details.execution_fee = execution_fee; txn_out->details.priority_fee = priority_fee; @@ -1535,6 +1535,8 @@ fd_executor_setup_txn_account( fd_runtime_t * runtime, FD_LOG_CRIT(( "Failed to join txn account" )); } + runtime->accounts.starting_lamports[idx] = fd_txn_account_get_lamports( txn_account ); + runtime->accounts.starting_dlen[idx] = fd_txn_account_get_data_len( txn_account ); memcpy( &txn_out->accounts.pubkeys[idx], acc, sizeof(fd_pubkey_t) ); txn_out->accounts.metas[ idx ] = account_meta; @@ -1625,43 +1627,9 @@ fd_executor_txn_verify( fd_txn_p_t * txn_p, return FD_RUNTIME_EXECUTE_SUCCESS; } -int -fd_execute_txn( fd_runtime_t * runtime, - fd_bank_t * bank, - fd_txn_in_t const * txn_in, - fd_txn_out_t * txn_out ) { - - bool dump_insn = runtime->log.capture_ctx && fd_bank_slot_get( bank ) >= runtime->log.capture_ctx->dump_proto_start_slot && runtime->log.capture_ctx->dump_instr_to_pb; - (void)dump_insn; - - /* Initialize log collection. */ - fd_log_collector_init( runtime->log.log_collector, runtime->log.enable_log_collector ); - - for( ushort i=0; itxn )->instr_cnt; i++ ) { - runtime->instr.current_idx = i; -# if FD_HAS_FLATCC - if( FD_UNLIKELY( dump_insn ) ) { - // Capture the input and convert it into a Protobuf message - fd_dump_instr_to_protobuf( runtime, bank, txn_in, txn_out, &runtime->instr.infos[i], i ); - } -# endif - - int instr_exec_result = fd_execute_instr( runtime, bank, txn_in, txn_out, &runtime->instr.infos[i] ); - if( FD_UNLIKELY( instr_exec_result!=FD_EXECUTOR_INSTR_SUCCESS ) ) { - if( txn_out->err.exec_err_idx==INT_MAX ) { - txn_out->err.exec_err_idx = i; - } - return FD_RUNTIME_TXN_ERR_INSTRUCTION_ERROR; - } - } - - /* TODO: This function needs to be split out of fd_execute_txn and be placed - into the replay tile once it is implemented. */ - return fd_executor_txn_check( bank, txn_out ); -} - -int -fd_executor_txn_check( fd_bank_t * bank, +static int +fd_executor_txn_check( fd_runtime_t * runtime, + fd_bank_t * bank, fd_txn_out_t * txn_out ) { fd_rent_t const * rent = fd_bank_rent_query( bank ); @@ -1674,6 +1642,8 @@ fd_executor_txn_check( fd_bank_t * bank, /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L63 */ for( ulong idx = 0; idx < txn_out->accounts.accounts_cnt; idx++ ) { fd_txn_account_t * b = &txn_out->accounts.accounts[idx]; + ulong starting_lamports = runtime->accounts.starting_lamports[idx]; + ulong starting_dlen = runtime->accounts.starting_dlen[idx]; // Was this account written to? /* TODO: Clean this logic up... lots of redundant checks with our newer account loading model. @@ -1697,41 +1667,25 @@ fd_executor_txn_check( fd_bank_t * bank, // no-op } else { /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L45-L59 */ - uchar before_uninitialized = b->starting_dlen == ULONG_MAX || b->starting_lamports == 0; - uchar before_rent_exempt = b->starting_dlen != ULONG_MAX && b->starting_lamports >= fd_rent_exempt_minimum_balance( rent, b->starting_dlen ); + uchar before_uninitialized = starting_dlen == ULONG_MAX || starting_lamports == 0; + uchar before_rent_exempt = starting_dlen != ULONG_MAX && starting_lamports >= fd_rent_exempt_minimum_balance( rent, starting_dlen ); /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L50 */ if( before_uninitialized || before_rent_exempt ) { - FD_LOG_DEBUG(( "Rent exempt error for %s Curr len %lu Starting len %lu Curr lamports %lu Starting lamports %lu Curr exempt %lu Starting exempt %lu", - FD_BASE58_ENC_32_ALLOCA( b->pubkey->uc ), - fd_txn_account_get_data_len( b ), - b->starting_dlen, - fd_txn_account_get_lamports( b ), - b->starting_lamports, - fd_rent_exempt_minimum_balance( rent, fd_txn_account_get_data_len( b ) ), - fd_rent_exempt_minimum_balance( rent, b->starting_dlen ) )); /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L104 */ return FD_RUNTIME_TXN_ERR_INSUFFICIENT_FUNDS_FOR_RENT; /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L56 */ - } else if( (fd_txn_account_get_data_len( b ) == b->starting_dlen) && fd_txn_account_get_lamports( b ) <= b->starting_lamports ) { + } else if( (fd_txn_account_get_data_len( b ) == starting_dlen) && fd_txn_account_get_lamports( b ) <= starting_lamports ) { // no-op } else { - FD_LOG_DEBUG(( "Rent exempt error for %s Curr len %lu Starting len %lu Curr lamports %lu Starting lamports %lu Curr exempt %lu Starting exempt %lu", - FD_BASE58_ENC_32_ALLOCA( b->pubkey->uc ), - fd_txn_account_get_data_len( b ), - b->starting_dlen, - fd_txn_account_get_lamports( b ), - b->starting_lamports, - fd_rent_exempt_minimum_balance( rent, fd_txn_account_get_data_len( b ) ), - fd_rent_exempt_minimum_balance( rent, b->starting_dlen ) )); /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L104 */ return FD_RUNTIME_TXN_ERR_INSUFFICIENT_FUNDS_FOR_RENT; } } } - if( b->starting_lamports != ULONG_MAX ) { - fd_uwide_inc( &starting_lamports_h, &starting_lamports_l, starting_lamports_h, starting_lamports_l, b->starting_lamports ); + if( starting_lamports != ULONG_MAX ) { + fd_uwide_inc( &starting_lamports_h, &starting_lamports_l, starting_lamports_h, starting_lamports_l, starting_lamports ); } } } @@ -1745,6 +1699,42 @@ fd_executor_txn_check( fd_bank_t * bank, return FD_RUNTIME_EXECUTE_SUCCESS; } + +int +fd_execute_txn( fd_runtime_t * runtime, + fd_bank_t * bank, + fd_txn_in_t const * txn_in, + fd_txn_out_t * txn_out ) { + + bool dump_insn = runtime->log.capture_ctx && fd_bank_slot_get( bank ) >= runtime->log.capture_ctx->dump_proto_start_slot && runtime->log.capture_ctx->dump_instr_to_pb; + (void)dump_insn; + + /* Initialize log collection. */ + fd_log_collector_init( runtime->log.log_collector, runtime->log.enable_log_collector ); + + for( ushort i=0; itxn )->instr_cnt; i++ ) { + runtime->instr.current_idx = i; +# if FD_HAS_FLATCC + if( FD_UNLIKELY( dump_insn ) ) { + // Capture the input and convert it into a Protobuf message + fd_dump_instr_to_protobuf( runtime, bank, txn_in, txn_out, &runtime->instr.infos[i], i ); + } +# endif + + int instr_exec_result = fd_execute_instr( runtime, bank, txn_in, txn_out, &runtime->instr.infos[i] ); + if( FD_UNLIKELY( instr_exec_result!=FD_EXECUTOR_INSTR_SUCCESS ) ) { + if( txn_out->err.exec_err_idx==INT_MAX ) { + txn_out->err.exec_err_idx = i; + } + return FD_RUNTIME_TXN_ERR_INSTRUCTION_ERROR; + } + } + + /* TODO: This function needs to be split out of fd_execute_txn and be placed + into the replay tile once it is implemented. */ + return fd_executor_txn_check( runtime, bank, txn_out ); +} + int fd_executor_consume_cus( fd_txn_out_t * txn_out, ulong cus ) { diff --git a/src/flamenco/runtime/fd_executor.h b/src/flamenco/runtime/fd_executor.h index dd9e5216d0..926bcf0b28 100644 --- a/src/flamenco/runtime/fd_executor.h +++ b/src/flamenco/runtime/fd_executor.h @@ -100,14 +100,6 @@ fd_executor_setup_txn_alut_account_keys( fd_runtime_t * runtime, fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out ); -/* - Validate the txn after execution for violations of various lamport balance and size rules - */ - -int -fd_executor_txn_check( fd_bank_t * bank, - fd_txn_out_t * txn_out ); - void fd_executor_reclaim_account( fd_txn_account_t * account, ulong slot ); diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index 11bf0afc52..925ea3b639 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -129,6 +129,8 @@ struct fd_runtime { struct { ulong executable_cnt; /* Number of BPF upgradeable loader accounts. */ fd_txn_account_t executables[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */ + ulong starting_lamports[ MAX_TX_ACCOUNT_LOCKS ]; /* Starting lamports for each account */ + ulong starting_dlen[ MAX_TX_ACCOUNT_LOCKS ]; /* Starting data length for each account */ } accounts; }; typedef struct fd_runtime fd_runtime_t; From 5c4fad1b1456500bd3cf74842ba983385ea2056a Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Fri, 21 Nov 2025 21:49:08 +0000 Subject: [PATCH 04/32] wip --- src/flamenco/progcache/test_progcache.c | 2 -- src/flamenco/runtime/fd_executor.c | 8 ++++---- src/flamenco/runtime/fd_runtime.c | 2 +- src/flamenco/runtime/fd_txn_account.c | 5 +---- src/flamenco/runtime/fd_txn_account.h | 3 --- src/flamenco/runtime/sysvar/fd_sysvar_instructions.c | 6 ++++-- src/flamenco/runtime/sysvar/fd_sysvar_instructions.h | 3 ++- src/flamenco/runtime/test_runtime_alut.c | 2 -- src/flamenco/runtime/tests/fd_block_harness.c | 2 +- src/flamenco/runtime/tests/fd_harness_common.c | 11 +++++++---- src/flamenco/runtime/tests/fd_instr_harness.c | 2 +- src/flamenco/runtime/tests/fd_solfuzz_private.h | 6 ++++-- src/flamenco/runtime/tests/fd_txn_harness.c | 2 +- src/flamenco/runtime/tests/test_dump_block.c | 2 -- 14 files changed, 26 insertions(+), 30 deletions(-) diff --git a/src/flamenco/progcache/test_progcache.c b/src/flamenco/progcache/test_progcache.c index d2e545e0c3..d6d28dc727 100644 --- a/src/flamenco/progcache/test_progcache.c +++ b/src/flamenco/progcache/test_progcache.c @@ -147,8 +147,6 @@ create_test_account( test_env_t * env, fd_txn_account_set_data( acc, data, data_len ); } - acc->starting_lamports = 1UL; - acc->starting_dlen = data_len; fd_txn_account_set_lamports( acc, 1UL ); fd_txn_account_set_executable( acc, executable ); fd_txn_account_set_owner( acc, &owner ); diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 4414cf808e..4a4b9f9496 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -471,7 +471,7 @@ load_transaction_account( fd_runtime_t * runtime, constructed by the SVM and modified within each transaction's instruction execution only, so it incurs a loaded size cost of 0. */ - fd_sysvar_instructions_serialize_account( txn_in, txn_out, (fd_instr_info_t const *)runtime->instr.infos, TXN( txn_in->txn )->instr_cnt, txn_idx ); + fd_sysvar_instructions_serialize_account( runtime, txn_in, txn_out, (fd_instr_info_t const *)runtime->instr.infos, TXN( txn_in->txn )->instr_cnt, txn_idx ); return 0UL; } @@ -490,7 +490,8 @@ load_transaction_account( fd_runtime_t * runtime, /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L828-L835 */ if( is_writable ) { - acct->starting_lamports = fd_txn_account_get_lamports( acct ); /* TODO: why do we do this everywhere? */ + /* TODO:FIXME: DO WE REALLY NEED THIS */ + runtime->accounts.starting_lamports[txn_idx] = fd_txn_account_get_lamports( acct ); } return fd_ulong_sat_add( base_account_size, fd_txn_account_get_data_len( acct ) ); } @@ -1068,8 +1069,7 @@ fd_executor_validate_transaction_fee_payer( fd_runtime_t * runtime, fd_executor_create_rollback_fee_payer_account( runtime, bank, txn_in, txn_out, total_fee ); /* Set the starting lamports (to avoid unbalanced lamports issues in instruction execution) */ - fee_payer_rec->starting_lamports = fd_txn_account_get_lamports( fee_payer_rec ); /* TODO: why do we do this everywhere? */ - runtime->accounts.starting_lamports[FD_FEE_PAYER_TXN_IDX] = fee_payer_rec->starting_lamports; + runtime->accounts.starting_lamports[FD_FEE_PAYER_TXN_IDX] = fd_txn_account_get_lamports( fee_payer_rec ); txn_out->details.execution_fee = execution_fee; txn_out->details.priority_fee = priority_fee; diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 00691998c6..14915b3cb6 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1233,7 +1233,7 @@ fd_runtime_commit_txn( fd_runtime_t * runtime, bundle must include a instruction that transfers lamports to a specific tip account. Tips accumulated through the slot. */ if( fd_pack_tip_is_tip_account( fd_type_pun( acc_rec->pubkey->uc ) ) ) { - txn_out->details.tips += fd_ulong_sat_sub( acc_rec->meta->lamports, acc_rec->starting_lamports ); + txn_out->details.tips += fd_ulong_sat_sub( acc_rec->meta->lamports, runtime->accounts.starting_lamports[i] ); FD_ATOMIC_FETCH_AND_ADD( fd_bank_tips_modify( bank ), txn_out->details.tips ); } diff --git a/src/flamenco/runtime/fd_txn_account.c b/src/flamenco/runtime/fd_txn_account.c index f6843ed665..4d8a361c51 100644 --- a/src/flamenco/runtime/fd_txn_account.c +++ b/src/flamenco/runtime/fd_txn_account.c @@ -32,10 +32,7 @@ fd_txn_account_new( void * mem, fd_memcpy( txn_account->pubkey, pubkey, sizeof(fd_pubkey_t) ); - txn_account->magic = FD_TXN_ACCOUNT_MAGIC; - - txn_account->starting_dlen = meta->dlen; - txn_account->starting_lamports = meta->lamports; + txn_account->magic = FD_TXN_ACCOUNT_MAGIC; uchar * data = (uchar *)meta + sizeof(fd_account_meta_t); diff --git a/src/flamenco/runtime/fd_txn_account.h b/src/flamenco/runtime/fd_txn_account.h index 271caa55ce..5b9b2cbf82 100644 --- a/src/flamenco/runtime/fd_txn_account.h +++ b/src/flamenco/runtime/fd_txn_account.h @@ -35,9 +35,6 @@ struct __attribute__((aligned(8UL))) fd_txn_account { int is_mutable; long meta_soff; - ulong starting_dlen; - ulong starting_lamports; - /* Provide borrowing semantics. Used for single-threaded logic only, thus not comparable to a data synchronization lock. */ ushort refcnt_excl; diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c index 1fa56730bc..ba2caf81b4 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c @@ -33,7 +33,8 @@ instructions_serialized_size( fd_instr_info_t const * instrs, /* https://github.com/anza-xyz/agave/blob/v2.1.1/svm/src/account_loader.rs#L547-L576 */ void -fd_sysvar_instructions_serialize_account( fd_txn_in_t const * txn_in, +fd_sysvar_instructions_serialize_account( fd_runtime_t * runtime, + fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, fd_instr_info_t const * instrs, ushort instrs_cnt, @@ -78,7 +79,8 @@ fd_sysvar_instructions_serialize_account( fd_txn_in_t const * txn_in, fd_txn_account_set_lamports( rec, 0UL ); fd_txn_account_set_executable( rec, 0 ); fd_txn_account_set_data_len( rec, serialized_sz ); - rec->starting_lamports = 0UL; + runtime->accounts.starting_lamports[txn_idx] = 0UL; + runtime->accounts.starting_dlen[txn_idx] = serialized_sz; uchar * serialized_instructions = fd_txn_account_get_data_mut( rec ); ulong offset = 0; diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.h b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.h index 60428b3d26..3a8d08794e 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.h +++ b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.h @@ -8,7 +8,8 @@ FD_PROTOTYPES_BEGIN void -fd_sysvar_instructions_serialize_account( fd_txn_in_t const * txn_in, +fd_sysvar_instructions_serialize_account( fd_runtime_t * runtime, + fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, fd_instr_info_t const * instrs, ushort instrs_cnt, diff --git a/src/flamenco/runtime/test_runtime_alut.c b/src/flamenco/runtime/test_runtime_alut.c index 6ba49c0825..1621c40127 100644 --- a/src/flamenco/runtime/test_runtime_alut.c +++ b/src/flamenco/runtime/test_runtime_alut.c @@ -117,8 +117,6 @@ create_test_account( test_ctx_t * ctx, fd_txn_account_set_data( acc, data, data_len ); } - acc->starting_lamports = lamports; - acc->starting_dlen = data_len; fd_txn_account_set_lamports( acc, lamports ); fd_txn_account_set_executable( acc, executable ); fd_txn_account_set_owner( acc, &owner ); diff --git a/src/flamenco/runtime/tests/fd_block_harness.c b/src/flamenco/runtime/tests/fd_block_harness.c index 08adff2b4e..13ee2c9126 100644 --- a/src/flamenco/runtime/tests/fd_block_harness.c +++ b/src/flamenco/runtime/tests/fd_block_harness.c @@ -344,7 +344,7 @@ fd_solfuzz_pb_block_ctx_create( fd_solfuzz_runner_t * runner, vote_states = fd_bank_vote_states_locking_modify( bank ); for( ushort i=0; iacct_states_count; i++ ) { fd_txn_account_t acc[1]; - fd_solfuzz_pb_load_account( acc, accdb, xid, &test_ctx->acct_states[i], 1 ); + fd_solfuzz_pb_load_account( runner->runtime, acc, accdb, xid, &test_ctx->acct_states[i], 1, i ); /* Update vote accounts cache for epoch T */ fd_pubkey_t pubkey; diff --git a/src/flamenco/runtime/tests/fd_harness_common.c b/src/flamenco/runtime/tests/fd_harness_common.c index cbc7bfd41d..fd6669020f 100644 --- a/src/flamenco/runtime/tests/fd_harness_common.c +++ b/src/flamenco/runtime/tests/fd_harness_common.c @@ -1,15 +1,18 @@ #include "fd_solfuzz_private.h" #include "generated/context.pb.h" #include "../fd_acc_mgr.h" +#include "../fd_runtime.h" #include "../../features/fd_features.h" #include int -fd_solfuzz_pb_load_account( fd_txn_account_t * acc, +fd_solfuzz_pb_load_account( fd_runtime_t * runtime, + fd_txn_account_t * acc, fd_accdb_user_t * accdb, fd_funk_txn_xid_t const * xid, fd_exec_test_acct_state_t const * state, - uchar reject_zero_lamports ) { + uchar reject_zero_lamports, + ulong acc_idx ) { if( reject_zero_lamports && state->lamports==0UL ) { return 0; } @@ -39,8 +42,8 @@ fd_solfuzz_pb_load_account( fd_txn_account_t * acc, fd_txn_account_set_data( acc, state->data->bytes, size ); } - acc->starting_lamports = state->lamports; - acc->starting_dlen = size; + runtime->accounts.starting_lamports[acc_idx] = state->lamports; + runtime->accounts.starting_dlen[acc_idx] = size; fd_txn_account_set_lamports( acc, state->lamports ); fd_txn_account_set_executable( acc, state->executable ); fd_txn_account_set_owner( acc, (fd_pubkey_t const *)state->owner ); diff --git a/src/flamenco/runtime/tests/fd_instr_harness.c b/src/flamenco/runtime/tests/fd_instr_harness.c index e833eb8d39..4f54f92b91 100644 --- a/src/flamenco/runtime/tests/fd_instr_harness.c +++ b/src/flamenco/runtime/tests/fd_instr_harness.c @@ -164,7 +164,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, fd_pubkey_t * acc_key = (fd_pubkey_t *)test_ctx->accounts[j].address; memcpy( &(txn_out->accounts.account_keys[j]), test_ctx->accounts[j].address, sizeof(fd_pubkey_t) ); - if( !fd_solfuzz_pb_load_account( &accts[j], runner->accdb, xid, &test_ctx->accounts[j], 0 ) ) { + if( !fd_solfuzz_pb_load_account( runtime, &accts[j], runner->accdb, xid, &test_ctx->accounts[j], 0, j ) ) { return 0; } diff --git a/src/flamenco/runtime/tests/fd_solfuzz_private.h b/src/flamenco/runtime/tests/fd_solfuzz_private.h index 5b9d78f3b1..1176c56b8b 100644 --- a/src/flamenco/runtime/tests/fd_solfuzz_private.h +++ b/src/flamenco/runtime/tests/fd_solfuzz_private.h @@ -27,11 +27,13 @@ FD_PROTOTYPES_BEGIN On success, loads the account into acc. Optionally, reject any zero-lamport accounts from being loaded in. */ int -fd_solfuzz_pb_load_account( fd_txn_account_t * acc, +fd_solfuzz_pb_load_account( fd_runtime_t * runtime, + fd_txn_account_t * acc, fd_accdb_user_t * accdb, fd_funk_txn_xid_t const * xid, fd_exec_test_acct_state_t const * state, - uchar reject_zero_lamports ); + uchar reject_zero_lamports, + ulong acc_idx ); /* Activates features in the runtime given an input feature set. Fails if a passed-in feature is unknown / not supported. */ diff --git a/src/flamenco/runtime/tests/fd_txn_harness.c b/src/flamenco/runtime/tests/fd_txn_harness.c index a2d21c059b..521375e80c 100644 --- a/src/flamenco/runtime/tests/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/fd_txn_harness.c @@ -83,7 +83,7 @@ fd_solfuzz_pb_txn_ctx_create( fd_solfuzz_runner_t * runner, /* Load the accounts into the account manager Borrowed accounts get reset anyways - we just need to load the account somewhere */ fd_txn_account_t acc[1]; - fd_solfuzz_pb_load_account( acc, accdb, &xid, &test_ctx->account_shared_data[i], 1 ); + fd_solfuzz_pb_load_account( runner->runtime, acc, accdb, &xid, &test_ctx->account_shared_data[i], 1, i ); } /* Setup Bank manager */ diff --git a/src/flamenco/runtime/tests/test_dump_block.c b/src/flamenco/runtime/tests/test_dump_block.c index 31315251f7..aaf4ff3a93 100644 --- a/src/flamenco/runtime/tests/test_dump_block.c +++ b/src/flamenco/runtime/tests/test_dump_block.c @@ -321,8 +321,6 @@ load_accounts_from_proto( fd_accdb_user_t * accdb, } /* Set account metadata */ - acc->starting_lamports = state->lamports; - acc->starting_dlen = size; fd_txn_account_set_lamports( acc, state->lamports ); fd_txn_account_set_executable( acc, state->executable ); fd_txn_account_set_owner( acc, (fd_pubkey_t const *)state->owner ); From cf81e85ff0d56a1e4934dde91ab32320f0f05d06 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Mon, 24 Nov 2025 14:07:00 +0000 Subject: [PATCH 05/32] wip --- src/flamenco/runtime/fd_executor.c | 10 +++++----- src/flamenco/runtime/sysvar/fd_sysvar_instructions.c | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 4a4b9f9496..0e86ae5034 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -1436,7 +1436,6 @@ fd_executor_setup_txn_account( fd_runtime_t * runtime, fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx ) { - /* To setup a transaction account, we need to first retrieve a read-only handle to the account from the database. */ @@ -1650,15 +1649,16 @@ fd_executor_txn_check( fd_runtime_t * runtime, We should be using the rent transition checking logic instead, along with a small refactor to keep check ordering consistent. */ if( fd_txn_account_get_meta( b )!=NULL ) { - fd_uwide_inc( &ending_lamports_h, &ending_lamports_l, ending_lamports_h, ending_lamports_l, fd_txn_account_get_lamports( b ) ); + + fd_uwide_inc( &ending_lamports_h, &ending_lamports_l, ending_lamports_h, ending_lamports_l, b->meta->lamports ); /* Rent states are defined as followed: - lamports == 0 -> Uninitialized - 0 < lamports < rent_exempt_minimum -> RentPaying - lamports >= rent_exempt_minimum -> RentExempt In Agave, 'self' refers to our 'after' state. */ - uchar after_uninitialized = fd_txn_account_get_lamports( b ) == 0; - uchar after_rent_exempt = fd_txn_account_get_lamports( b ) >= fd_rent_exempt_minimum_balance( rent, fd_txn_account_get_data_len( b ) ); + uchar after_uninitialized = b->meta->lamports == 0; + uchar after_rent_exempt = b->meta->lamports >= fd_rent_exempt_minimum_balance( rent, b->meta->dlen ); /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L96 */ if( FD_LIKELY( memcmp( b->pubkey->key, fd_sysvar_incinerator_id.key, sizeof(fd_pubkey_t) ) != 0 ) ) { @@ -1675,7 +1675,7 @@ fd_executor_txn_check( fd_runtime_t * runtime, /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L104 */ return FD_RUNTIME_TXN_ERR_INSUFFICIENT_FUNDS_FOR_RENT; /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L56 */ - } else if( (fd_txn_account_get_data_len( b ) == starting_dlen) && fd_txn_account_get_lamports( b ) <= starting_lamports ) { + } else if( (b->meta->dlen == starting_dlen) && b->meta->lamports <= starting_lamports ) { // no-op } else { /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L104 */ diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c index ba2caf81b4..edbfaa3297 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c @@ -70,6 +70,7 @@ fd_sysvar_instructions_serialize_account( fd_runtime_t * runtime, if( FD_UNLIKELY( !acc ) ) { FD_LOG_CRIT(( "Failed to join txn account" )); } + txn_out->accounts.metas[txn_idx] = acc->meta; } /* Agave sets up the borrowed account for the instructions sysvar to contain From 75eee2912241a08d0a3fe71bff91307e49b016d5 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Mon, 24 Nov 2025 14:33:53 +0000 Subject: [PATCH 06/32] wip --- src/flamenco/fd_flamenco_base.h | 10 +--- src/flamenco/rewards/fd_rewards.c | 4 +- src/flamenco/runtime/fd_core_bpf_migration.c | 2 +- src/flamenco/runtime/fd_executor.c | 29 +++++------ src/flamenco/runtime/fd_executor.h | 4 +- src/flamenco/runtime/fd_hashes.c | 25 +++++----- src/flamenco/runtime/fd_hashes.h | 3 +- src/flamenco/runtime/fd_runtime.c | 50 +++++++++++++------ src/flamenco/runtime/info/fd_instr_info.c | 14 +++--- .../runtime/program/fd_builtin_programs.c | 2 +- src/flamenco/runtime/sysvar/fd_sysvar.c | 2 +- src/flamenco/runtime/tests/fd_instr_harness.c | 2 + 12 files changed, 84 insertions(+), 63 deletions(-) diff --git a/src/flamenco/fd_flamenco_base.h b/src/flamenco/fd_flamenco_base.h index 7ea6ffa428..38ed53872b 100644 --- a/src/flamenco/fd_flamenco_base.h +++ b/src/flamenco/fd_flamenco_base.h @@ -116,15 +116,9 @@ struct fd_account_meta { }; typedef struct fd_account_meta fd_account_meta_t; -struct fd_account { - uchar pubkey[32UL]; - fd_account_meta_t * meta; -}; -typedef struct fd_account fd_account_t; - FD_FN_PURE static inline uchar * -fd_account_data( fd_account_t const * acc ) { - return (uchar *)( acc->meta+1 ); +fd_account_data( fd_account_meta_t const * acc ) { + return (uchar *)( acc+1 ); } FD_PROTOTYPES_BEGIN diff --git a/src/flamenco/rewards/fd_rewards.c b/src/flamenco/rewards/fd_rewards.c index 67377e1090..5ca9fbabe6 100644 --- a/src/flamenco/rewards/fd_rewards.c +++ b/src/flamenco/rewards/fd_rewards.c @@ -819,7 +819,7 @@ calculate_rewards_and_distribute_vote_rewards( fd_bank_t * ba FD_LOG_ERR(( "Adding lamports to vote account would cause overflow" )); } - fd_hashes_update_lthash( vote_rec, prev_hash,bank, capture_ctx ); + fd_hashes_update_lthash( vote_rec->pubkey, vote_rec->meta, prev_hash,bank, capture_ctx ); fd_txn_account_mutable_fini( vote_rec, accdb, &prepare ); distributed_rewards = fd_ulong_sat_add( distributed_rewards, rewards ); @@ -932,7 +932,7 @@ distribute_epoch_reward_to_stake_acc( fd_bank_t * bank, FD_LOG_ERR(( "write_stake_state failed" )); } - fd_hashes_update_lthash( stake_acc_rec, prev_hash, bank, capture_ctx ); + fd_hashes_update_lthash( stake_acc_rec->pubkey, stake_acc_rec->meta, prev_hash, bank, capture_ctx ); fd_txn_account_mutable_fini( stake_acc_rec, accdb, &prepare ); return 0; diff --git a/src/flamenco/runtime/fd_core_bpf_migration.c b/src/flamenco/runtime/fd_core_bpf_migration.c index ef7de79c9a..d1d45672ff 100644 --- a/src/flamenco/runtime/fd_core_bpf_migration.c +++ b/src/flamenco/runtime/fd_core_bpf_migration.c @@ -85,7 +85,7 @@ tmp_account_store( fd_tmp_account_t * acc, fd_txn_account_set_lamports ( rec, acc->meta.lamports ); fd_txn_account_set_data ( rec, acc->data, acc->data_sz ); - fd_hashes_update_lthash( rec, prev_hash, bank, capture_ctx ); + fd_hashes_update_lthash( rec->pubkey, rec->meta, prev_hash, bank, capture_ctx ); fd_txn_account_mutable_fini( rec, accdb, &prepare ); } diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 0e86ae5034..70b9815061 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -1421,12 +1421,12 @@ fd_execute_instr( fd_runtime_t * runtime, } void -fd_executor_reclaim_account( fd_txn_account_t * account, +fd_executor_reclaim_account( fd_account_meta_t * meta, ulong slot ) { - fd_txn_account_set_slot( account, slot ); - if( FD_UNLIKELY( fd_txn_account_get_lamports( account )==0UL ) ) { - fd_txn_account_set_data_len( account, 0UL ); - fd_txn_account_clear_owner( account ); + meta->slot = slot; + if( FD_UNLIKELY( meta->lamports==0UL ) ) { + meta->dlen = 0UL; + memset( meta->owner, 0, sizeof(fd_pubkey_t) ); } } @@ -1640,28 +1640,29 @@ fd_executor_txn_check( fd_runtime_t * runtime, /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L63 */ for( ulong idx = 0; idx < txn_out->accounts.accounts_cnt; idx++ ) { - fd_txn_account_t * b = &txn_out->accounts.accounts[idx]; - ulong starting_lamports = runtime->accounts.starting_lamports[idx]; - ulong starting_dlen = runtime->accounts.starting_dlen[idx]; + ulong starting_lamports = runtime->accounts.starting_lamports[idx]; + ulong starting_dlen = runtime->accounts.starting_dlen[idx]; + fd_account_meta_t * meta = txn_out->accounts.metas[idx]; + fd_pubkey_t * pubkey = &txn_out->accounts.account_keys[idx]; // Was this account written to? /* TODO: Clean this logic up... lots of redundant checks with our newer account loading model. We should be using the rent transition checking logic instead, along with a small refactor to keep check ordering consistent. */ - if( fd_txn_account_get_meta( b )!=NULL ) { + if( meta!=NULL ) { - fd_uwide_inc( &ending_lamports_h, &ending_lamports_l, ending_lamports_h, ending_lamports_l, b->meta->lamports ); + fd_uwide_inc( &ending_lamports_h, &ending_lamports_l, ending_lamports_h, ending_lamports_l, meta->lamports ); /* Rent states are defined as followed: - lamports == 0 -> Uninitialized - 0 < lamports < rent_exempt_minimum -> RentPaying - lamports >= rent_exempt_minimum -> RentExempt In Agave, 'self' refers to our 'after' state. */ - uchar after_uninitialized = b->meta->lamports == 0; - uchar after_rent_exempt = b->meta->lamports >= fd_rent_exempt_minimum_balance( rent, b->meta->dlen ); + uchar after_uninitialized = meta->lamports == 0; + uchar after_rent_exempt = meta->lamports >= fd_rent_exempt_minimum_balance( rent, meta->dlen ); /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L96 */ - if( FD_LIKELY( memcmp( b->pubkey->key, fd_sysvar_incinerator_id.key, sizeof(fd_pubkey_t) ) != 0 ) ) { + if( FD_LIKELY( memcmp( pubkey, fd_sysvar_incinerator_id.key, sizeof(fd_pubkey_t) ) != 0 ) ) { /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L44 */ if( after_uninitialized || after_rent_exempt ) { // no-op @@ -1675,7 +1676,7 @@ fd_executor_txn_check( fd_runtime_t * runtime, /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L104 */ return FD_RUNTIME_TXN_ERR_INSUFFICIENT_FUNDS_FOR_RENT; /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L56 */ - } else if( (b->meta->dlen == starting_dlen) && b->meta->lamports <= starting_lamports ) { + } else if( (meta->dlen == starting_dlen) && meta->lamports <= starting_lamports ) { // no-op } else { /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L104 */ diff --git a/src/flamenco/runtime/fd_executor.h b/src/flamenco/runtime/fd_executor.h index 926bcf0b28..e513baa34b 100644 --- a/src/flamenco/runtime/fd_executor.h +++ b/src/flamenco/runtime/fd_executor.h @@ -101,8 +101,8 @@ fd_executor_setup_txn_alut_account_keys( fd_runtime_t * runtime, fd_txn_out_t * txn_out ); void -fd_executor_reclaim_account( fd_txn_account_t * account, - ulong slot ); +fd_executor_reclaim_account( fd_account_meta_t * meta, + ulong slot ); /* fd_io_strerror converts an FD_EXECUTOR_INSTR_ERR_{...} code into a human readable cstr. The lifetime of the returned pointer is diff --git a/src/flamenco/runtime/fd_hashes.c b/src/flamenco/runtime/fd_hashes.c index ce2515d3b1..863d12e19e 100644 --- a/src/flamenco/runtime/fd_hashes.c +++ b/src/flamenco/runtime/fd_hashes.c @@ -76,15 +76,15 @@ fd_hashes_hash_bank( fd_lthash_value_t const * lthash, } void -fd_hashes_update_lthash( fd_txn_account_t const * account, +fd_hashes_update_lthash( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, fd_lthash_value_t const * prev_account_hash, fd_bank_t * bank, fd_capture_ctx_t * capture_ctx ) { /* Hash the new version of the account */ fd_lthash_value_t new_hash[1]; - fd_account_meta_t const * meta = fd_txn_account_get_meta( account ); - fd_hashes_account_lthash( account->pubkey, meta, fd_txn_account_get_data( account ), new_hash ); + fd_hashes_account_lthash( pubkey, meta, fd_account_data( meta ), new_hash ); /* Subtract the old hash of the account from the bank lthash */ fd_lthash_value_t * bank_lthash = fd_type_pun( fd_bank_lthash_locking_modify( bank ) ); @@ -99,19 +99,20 @@ fd_hashes_update_lthash( fd_txn_account_t const * account, if( capture_ctx && capture_ctx->capture && fd_bank_slot_get( bank )>=capture_ctx->solcap_start_slot && memcmp( prev_account_hash->bytes, new_hash->bytes, sizeof(fd_lthash_value_t))!=0 ) { - fd_solana_account_meta_t meta[1]; + fd_solana_account_meta_t solana_meta[1]; fd_solana_account_meta_init( - meta, - fd_txn_account_get_lamports ( account ), - fd_txn_account_get_owner ( account ), - fd_txn_account_is_executable( account ) + solana_meta, + meta->lamports, + meta->owner, + meta->executable ); int err = fd_solcap_write_account( capture_ctx->capture, - account->pubkey, - meta, - fd_txn_account_get_data( account ), - fd_txn_account_get_data_len( account ) ); + pubkey, + solana_meta, + fd_account_data( meta ), + meta->dlen + ); if( FD_UNLIKELY( err ) ) { FD_LOG_ERR(( "Failed to write account to capture file" )); } diff --git a/src/flamenco/runtime/fd_hashes.h b/src/flamenco/runtime/fd_hashes.h index 55e6179f6d..fc0ff7688b 100644 --- a/src/flamenco/runtime/fd_hashes.h +++ b/src/flamenco/runtime/fd_hashes.h @@ -106,7 +106,8 @@ fd_hashes_account_lthash_simple( uchar const pubkey[ static FD_HASH_FOOT execution. This includes sysvar accounts. */ void -fd_hashes_update_lthash( fd_txn_account_t const * account, +fd_hashes_update_lthash( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, fd_lthash_value_t const * prev_account_hash, fd_bank_t * bank, fd_capture_ctx_t * capture_ctx ); diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 5c73e0812d..dda8f2745d 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -237,7 +237,7 @@ fd_runtime_run_incinerator( fd_bank_t * bank, fd_bank_capitalization_set( bank, new_capitalization ); fd_txn_account_set_lamports( rec, 0UL ); - fd_hashes_update_lthash( rec, prev_hash, bank, capture_ctx ); + fd_hashes_update_lthash( rec->pubkey, rec->meta, prev_hash, bank, capture_ctx ); fd_txn_account_mutable_fini( rec, accdb, &prepare ); return 0; @@ -321,7 +321,7 @@ fd_runtime_freeze( fd_bank_t * bank, fd_txn_account_checked_add_lamports( rec, fees ); fd_txn_account_set_slot( rec, fd_bank_slot_get( bank ) ); - fd_hashes_update_lthash( rec, prev_hash, bank, capture_ctx ); + fd_hashes_update_lthash( rec->pubkey, rec->meta, prev_hash, bank, capture_ctx ); fd_txn_account_mutable_fini( rec, accdb, &prepare ); } while(0); @@ -538,7 +538,7 @@ fd_feature_activate( fd_bank_t * bank, FD_LOG_ERR(( "Failed to encode feature account %s (%d)", addr_b58, decode_err )); } - fd_hashes_update_lthash( modify_acct_rec, prev_hash, bank, capture_ctx ); + fd_hashes_update_lthash( modify_acct_rec->pubkey, modify_acct_rec->meta, prev_hash, bank, capture_ctx ); fd_txn_account_mutable_fini( modify_acct_rec, accdb, &modify_acct_prepare ); } } @@ -975,7 +975,7 @@ fd_runtime_pre_execute_check( fd_runtime_t * runtime, https://github.com/anza-xyz/agave/blob/v2.1.14/runtime/src/bank.rs#L4116 In any case, we should always add the dlen of the fee payer. */ - txn_out->details.loaded_accounts_data_size = fd_txn_account_get_data_len( &txn_out->accounts.accounts[FD_FEE_PAYER_TXN_IDX] ); + txn_out->details.loaded_accounts_data_size = txn_out->accounts.metas[ FD_FEE_PAYER_TXN_IDX ]->dlen; /* Special case handling for if a nonce account is present in the transaction. */ if( txn_out->accounts.nonce_idx_in_txn!=ULONG_MAX ) { @@ -1142,7 +1142,8 @@ fd_runtime_buffer_solcap_account_update( fd_txn_account_t * account, static void fd_runtime_save_account( fd_funk_t * funk, fd_funk_txn_xid_t const * xid, - fd_txn_account_t * account, + fd_pubkey_t const * pubkey, + fd_account_meta_t * meta, fd_bank_t * bank, fd_capture_ctx_t * capture_ctx ) { /* Look up the previous version of the account from Funk */ @@ -1151,7 +1152,7 @@ fd_runtime_save_account( fd_funk_t * funk, fd_account_meta_t const * prev_meta = fd_funk_get_acc_meta_readonly( funk, xid, - account->pubkey, + pubkey, fd_type_pun( &funk_prev_rec ), &err, NULL ); @@ -1162,17 +1163,23 @@ fd_runtime_save_account( fd_funk_t * funk, fd_lthash_zero( prev_hash ); if( err != FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ) { fd_hashes_account_lthash( - account->pubkey, + pubkey, prev_meta, prev_data, prev_hash ); } /* Mix in the account hash into the bank hash */ - fd_hashes_update_lthash( account, prev_hash, bank, NULL ); + fd_hashes_update_lthash( pubkey, meta, prev_hash, bank, NULL ); /* Publish account update to replay tile for solcap writing TODO: write in the exec tile with solcap v2 */ + fd_txn_account_t account[1]; + memcpy( account->pubkey, pubkey, sizeof(fd_pubkey_t) ); + account->meta = meta; + account->data = fd_account_data( meta ); + account->is_mutable = 1; + fd_runtime_buffer_solcap_account_update( account, bank, capture_ctx ); /* Save the new version of the account to Funk */ @@ -1210,12 +1217,22 @@ fd_runtime_commit_txn( fd_runtime_t * runtime, We should always rollback the nonce account first. Note that the nonce account may be the fee payer (case 2). */ if( txn_out->accounts.nonce_idx_in_txn!=ULONG_MAX ) { - fd_runtime_save_account( runtime->funk, &xid, txn_out->accounts.rollback_nonce, bank, runtime->log.capture_ctx ); + fd_runtime_save_account( runtime->funk, + &xid, + txn_out->accounts.rollback_nonce->pubkey, + txn_out->accounts.rollback_nonce->meta, + bank, + runtime->log.capture_ctx ); } /* Now, we must only save the fee payer if the nonce account was not the fee payer (because that was already saved above) */ if( FD_LIKELY( txn_out->accounts.nonce_idx_in_txn!=FD_FEE_PAYER_TXN_IDX ) ) { - fd_runtime_save_account( runtime->funk, &xid, txn_out->accounts.rollback_fee_payer, bank, runtime->log.capture_ctx ); + fd_runtime_save_account( runtime->funk, + &xid, + txn_out->accounts.rollback_fee_payer->pubkey, + txn_out->accounts.rollback_fee_payer->meta, + bank, + runtime->log.capture_ctx ); } } else { @@ -1226,7 +1243,7 @@ fd_runtime_commit_txn( fd_runtime_t * runtime, continue; } - fd_txn_account_t * acc_rec = fd_txn_account_join( &txn_out->accounts.accounts[i] ); + fd_txn_account_t * acc_rec = &txn_out->accounts.accounts[i]; if( FD_UNLIKELY( !acc_rec ) ) { FD_LOG_CRIT(( "fd_runtime_commit_txn: failed to join account at idx %u", i )); } @@ -1249,9 +1266,14 @@ fd_runtime_commit_txn( fd_runtime_t * runtime, /* Reclaim any accounts that have 0-lamports, now that any related cache updates have been applied. */ - fd_executor_reclaim_account( &txn_out->accounts.accounts[i], fd_bank_slot_get( bank ) ); - - fd_runtime_save_account( runtime->funk, &xid, &txn_out->accounts.accounts[i], bank, runtime->log.capture_ctx ); + fd_executor_reclaim_account( txn_out->accounts.metas[i], fd_bank_slot_get( bank ) ); + + fd_runtime_save_account( runtime->funk, + &xid, + txn_out->accounts.accounts[i].pubkey, + txn_out->accounts.accounts[i].meta, + bank, + runtime->log.capture_ctx ); } /* We need to queue any existing program accounts that may have diff --git a/src/flamenco/runtime/info/fd_instr_info.c b/src/flamenco/runtime/info/fd_instr_info.c index 61fe017017..b07555940f 100644 --- a/src/flamenco/runtime/info/fd_instr_info.c +++ b/src/flamenco/runtime/info/fd_instr_info.c @@ -8,12 +8,13 @@ fd_instr_info_accumulate_starting_lamports( fd_instr_info_t * instr, ushort idx_in_callee, ushort idx_in_txn ) { if( FD_LIKELY( !instr->is_duplicate[ idx_in_callee ] ) ) { - fd_txn_account_t const * account = &txn_out->accounts.accounts[ idx_in_txn ]; - if( fd_txn_account_get_meta( account ) ) { + + fd_account_meta_t const * meta = txn_out->accounts.metas[ idx_in_txn ]; + if( meta ) { fd_uwide_inc( &instr->starting_lamports_h, &instr->starting_lamports_l, instr->starting_lamports_h, instr->starting_lamports_l, - fd_txn_account_get_lamports( account ) ); + meta->lamports ); } } } @@ -65,9 +66,9 @@ fd_instr_info_sum_account_lamports( fd_instr_info_t const * instr, *total_lamports_l = 0UL; for( ulong i=0UL; iacct_cnt; ++i ) { ushort idx_in_txn = instr->accounts[i].index_in_transaction; - fd_txn_account_t const * account = &txn_out->accounts.accounts[ idx_in_txn ]; + fd_account_meta_t const * meta = txn_out->accounts.metas[ idx_in_txn ]; - if( !fd_txn_account_get_meta( account ) || + if( !meta || instr->is_duplicate[i] ) { continue; } @@ -76,8 +77,7 @@ fd_instr_info_sum_account_lamports( fd_instr_info_t const * instr, ulong tmp_total_lamports_h = 0UL; ulong tmp_total_lamports_l = 0UL; - fd_uwide_inc( &tmp_total_lamports_h, &tmp_total_lamports_l, *total_lamports_h, *total_lamports_l, - fd_txn_account_get_lamports( account ) ); + fd_uwide_inc( &tmp_total_lamports_h, &tmp_total_lamports_l, *total_lamports_h, *total_lamports_l, meta->lamports ); if( tmp_total_lamports_h < *total_lamports_h ) { return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW; diff --git a/src/flamenco/runtime/program/fd_builtin_programs.c b/src/flamenco/runtime/program/fd_builtin_programs.c index 1aefc0fd36..4e9068959b 100644 --- a/src/flamenco/runtime/program/fd_builtin_programs.c +++ b/src/flamenco/runtime/program/fd_builtin_programs.c @@ -230,7 +230,7 @@ fd_write_builtin_account( fd_bank_t * bank, fd_txn_account_set_executable( rec, 1 ); fd_txn_account_set_owner( rec, &fd_solana_native_loader_id ); - fd_hashes_update_lthash( rec, prev_hash, bank, capture_ctx ); + fd_hashes_update_lthash( rec->pubkey, rec->meta, prev_hash, bank, capture_ctx ); fd_txn_account_mutable_fini( rec, accdb, &prepare ); diff --git a/src/flamenco/runtime/sysvar/fd_sysvar.c b/src/flamenco/runtime/sysvar/fd_sysvar.c index 4eb6df193a..bad8f6bc3d 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar.c @@ -47,7 +47,7 @@ fd_sysvar_account_update( fd_bank_t * bank, __builtin_unreachable(); } - fd_hashes_update_lthash( rec, prev_hash, bank, capture_ctx ); + fd_hashes_update_lthash( rec->pubkey, rec->meta, prev_hash, bank, capture_ctx ); fd_txn_account_mutable_fini( rec, accdb, &prepare ); if( FD_UNLIKELY( fd_log_level_logfile()<=0 || fd_log_level_stderr()<=0 ) ) { diff --git a/src/flamenco/runtime/tests/fd_instr_harness.c b/src/flamenco/runtime/tests/fd_instr_harness.c index 4f54f92b91..d3a24d9864 100644 --- a/src/flamenco/runtime/tests/fd_instr_harness.c +++ b/src/flamenco/runtime/tests/fd_instr_harness.c @@ -51,6 +51,8 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, txn_in->exec_accounts = runner->exec_accounts; + memset( txn_out->accounts.metas, 0, sizeof(fd_account_meta_t) * MAX_TX_ACCOUNT_LOCKS ); + /* Bank manager */ fd_banks_clear_bank( runner->banks, runner->bank ); From 29340bb9e180399d703307e8b0ed6aed627d2554 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Mon, 24 Nov 2025 14:51:14 +0000 Subject: [PATCH 07/32] wip --- src/flamenco/runtime/fd_runtime.c | 25 ++++++---------- src/flamenco/stakes/fd_stakes.c | 48 +++++++++++++++++-------------- src/flamenco/stakes/fd_stakes.h | 10 ++++--- 3 files changed, 42 insertions(+), 41 deletions(-) diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index dda8f2745d..be569caf35 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1243,37 +1243,30 @@ fd_runtime_commit_txn( fd_runtime_t * runtime, continue; } - fd_txn_account_t * acc_rec = &txn_out->accounts.accounts[i]; - if( FD_UNLIKELY( !acc_rec ) ) { - FD_LOG_CRIT(( "fd_runtime_commit_txn: failed to join account at idx %u", i )); - } + fd_pubkey_t const * pubkey = &txn_out->accounts.account_keys[i]; + fd_account_meta_t * meta = txn_out->accounts.metas[i]; /* Tips for bundles are collected in the bank: a user submitting a bundle must include a instruction that transfers lamports to a specific tip account. Tips accumulated through the slot. */ - if( fd_pack_tip_is_tip_account( fd_type_pun( acc_rec->pubkey->uc ) ) ) { - txn_out->details.tips += fd_ulong_sat_sub( acc_rec->meta->lamports, runtime->accounts.starting_lamports[i] ); + if( fd_pack_tip_is_tip_account( fd_type_pun_const( pubkey->uc ) ) ) { + txn_out->details.tips += fd_ulong_sat_sub( meta->lamports, runtime->accounts.starting_lamports[i] ); FD_ATOMIC_FETCH_AND_ADD( fd_bank_tips_modify( bank ), txn_out->details.tips ); } - if( 0==memcmp( fd_txn_account_get_owner( acc_rec ), &fd_solana_vote_program_id, sizeof(fd_pubkey_t) ) ) { - fd_stakes_update_vote_state( acc_rec, bank ); + if( 0==memcmp( meta->owner, &fd_solana_vote_program_id, sizeof(fd_pubkey_t) ) ) { + fd_stakes_update_vote_state( pubkey, meta, bank ); } - if( 0==memcmp( fd_txn_account_get_owner( acc_rec ), &fd_solana_stake_program_id, sizeof(fd_pubkey_t) ) ) { - fd_stakes_update_stake_delegation( acc_rec, bank ); + if( 0==memcmp( meta->owner, &fd_solana_stake_program_id, sizeof(fd_pubkey_t) ) ) { + fd_stakes_update_stake_delegation( pubkey, meta, bank ); } /* Reclaim any accounts that have 0-lamports, now that any related cache updates have been applied. */ fd_executor_reclaim_account( txn_out->accounts.metas[i], fd_bank_slot_get( bank ) ); - fd_runtime_save_account( runtime->funk, - &xid, - txn_out->accounts.accounts[i].pubkey, - txn_out->accounts.accounts[i].meta, - bank, - runtime->log.capture_ctx ); + fd_runtime_save_account( runtime->funk, &xid, pubkey, meta, bank, runtime->log.capture_ctx ); } /* We need to queue any existing program accounts that may have diff --git a/src/flamenco/stakes/fd_stakes.c b/src/flamenco/stakes/fd_stakes.c index 2d34b7b655..061fe1f7c1 100644 --- a/src/flamenco/stakes/fd_stakes.c +++ b/src/flamenco/stakes/fd_stakes.c @@ -171,50 +171,53 @@ write_stake_state( fd_txn_account_t * stake_acc_rec, } void -fd_stakes_update_stake_delegation( fd_txn_account_t * stake_account, - fd_bank_t * bank ) { - - if( !stake_account->is_mutable ) return; +fd_stakes_update_stake_delegation( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, + fd_bank_t * bank ) { fd_stake_delegations_t * stake_delegations_delta = fd_bank_stake_delegations_delta_locking_modify( bank ); if( FD_UNLIKELY( !stake_delegations_delta ) ) { FD_LOG_CRIT(( "unable to retrieve join to stake delegation delta" )); } - if( fd_txn_account_get_lamports( stake_account )==0UL ) { - fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); + if( meta->lamports==0UL ) { + fd_stake_delegations_remove( stake_delegations_delta, pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); return; } + fd_txn_account_t stake_account[1]; + stake_account->data = (uchar *)fd_account_data( meta ); + stake_account->meta = (fd_account_meta_t *)meta; + fd_stake_state_v2_t stake_state; int err = fd_stake_get_state( stake_account, &stake_state ); if( FD_UNLIKELY( err!=0 ) ) { - fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); + fd_stake_delegations_remove( stake_delegations_delta, pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); return; } if( FD_UNLIKELY( !fd_stake_state_v2_is_stake( &stake_state ) ) ) { - fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); + fd_stake_delegations_remove( stake_delegations_delta, pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); return; } if( FD_UNLIKELY( fd_stake_state_v2_is_uninitialized( &stake_state ) ) ) { - fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); + fd_stake_delegations_remove( stake_delegations_delta, pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); return; } if( FD_UNLIKELY( stake_state.inner.stake.stake.delegation.stake==0UL ) ) { - fd_stake_delegations_remove( stake_delegations_delta, stake_account->pubkey ); + fd_stake_delegations_remove( stake_delegations_delta, pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); return; } fd_stake_delegations_update( stake_delegations_delta, - stake_account->pubkey, + pubkey, &stake_state.inner.stake.stake.delegation.voter_pubkey, stake_state.inner.stake.stake.delegation.stake, stake_state.inner.stake.stake.delegation.activation_epoch, @@ -226,28 +229,31 @@ fd_stakes_update_stake_delegation( fd_txn_account_t * stake_account, } void -fd_stakes_update_vote_state( fd_txn_account_t * vote_account, - fd_bank_t * bank ) { - - if( !vote_account->is_mutable ) return; +fd_stakes_update_vote_state( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, + fd_bank_t * bank ) { fd_vote_states_t * vote_states = fd_bank_vote_states_locking_modify( bank ); - if( fd_txn_account_get_lamports( vote_account )==0UL ) { - fd_vote_states_remove( vote_states, vote_account->pubkey ); + if( meta->lamports==0UL ) { + fd_vote_states_remove( vote_states, pubkey ); fd_bank_vote_states_end_locking_modify( bank ); return; } + fd_txn_account_t vote_account[1]; + vote_account->data = (uchar *)fd_account_data( meta ); + vote_account->meta = (fd_account_meta_t *)meta; + if( !fd_vote_state_versions_is_correct_and_initialized( vote_account ) ) { - fd_vote_states_remove( vote_states, vote_account->pubkey ); + fd_vote_states_remove( vote_states, pubkey ); fd_bank_vote_states_end_locking_modify( bank ); return; } fd_vote_states_update_from_account( vote_states, - vote_account->pubkey, - fd_txn_account_get_data( vote_account ), - fd_txn_account_get_data_len( vote_account ) ); + pubkey, + fd_account_data( meta ), + meta->dlen ); fd_bank_vote_states_end_locking_modify( bank ); } diff --git a/src/flamenco/stakes/fd_stakes.h b/src/flamenco/stakes/fd_stakes.h index 9ad42096f5..9163027289 100644 --- a/src/flamenco/stakes/fd_stakes.h +++ b/src/flamenco/stakes/fd_stakes.h @@ -62,8 +62,9 @@ fd_refresh_vote_accounts( fd_bank_t * bank, the stake account. */ void -fd_stakes_update_stake_delegation( fd_txn_account_t * stake_account, - fd_bank_t * bank ); +fd_stakes_update_stake_delegation( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, + fd_bank_t * bank ); /* fd_stakes_update_vote_state is used to maintain the in-memory cache of the vote states that is used at the epoch boundary. Entries in @@ -71,8 +72,9 @@ fd_stakes_update_stake_delegation( fd_txn_account_t * stake_account, the vote account. */ void -fd_stakes_update_vote_state( fd_txn_account_t * vote_account, - fd_bank_t * bank ); +fd_stakes_update_vote_state( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, + fd_bank_t * bank ); FD_PROTOTYPES_END From 0c1e75b5172375184a17cf7e4966957cd34e8ed8 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Mon, 24 Nov 2025 15:32:11 +0000 Subject: [PATCH 08/32] wip --- src/flamenco/runtime/fd_executor.c | 35 ++++++++++--------- .../runtime/program/fd_bpf_loader_program.c | 16 ++++++--- .../runtime/program/fd_bpf_loader_program.h | 4 +++ 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 70b9815061..cab4331a50 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -459,14 +459,15 @@ load_transaction_account( fd_runtime_t * runtime, fd_bank_t * bank, fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, - fd_txn_account_t * acct, + fd_pubkey_t const * pubkey, + fd_account_meta_t * meta, uchar is_writable, uchar unknown_acc, ulong txn_idx ) { /* Handling the sysvar instructions account explictly. https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L817-L824 */ - if( FD_UNLIKELY( !memcmp( acct->pubkey->key, fd_sysvar_instructions_id.key, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( !memcmp( pubkey, fd_sysvar_instructions_id.key, sizeof(fd_pubkey_t) ) ) ) { /* The sysvar instructions account cannot be "loaded" since it's constructed by the SVM and modified within each transaction's instruction execution only, so it incurs a loaded size cost @@ -491,9 +492,9 @@ load_transaction_account( fd_runtime_t * runtime, /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L828-L835 */ if( is_writable ) { /* TODO:FIXME: DO WE REALLY NEED THIS */ - runtime->accounts.starting_lamports[txn_idx] = fd_txn_account_get_lamports( acct ); + runtime->accounts.starting_lamports[txn_idx] = meta->lamports; } - return fd_ulong_sat_add( base_account_size, fd_txn_account_get_data_len( acct ) ); + return fd_ulong_sat_add( base_account_size, meta->dlen ); } /* The rest of this function is a no-op for us since we already set up @@ -549,7 +550,7 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, } /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L733-L740 */ - ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, acct, is_writable, unknown_acc, i ); + ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, acct->pubkey, acct->meta, is_writable, unknown_acc, i ); int err = accumulate_and_check_loaded_account_data_size( loaded_acc_size, requested_loaded_accounts_data_size, &txn_out->details.loaded_accounts_data_size ); @@ -671,13 +672,13 @@ fd_increase_calculated_data_size( fd_txn_out_t * txn_out, /* This function is represented as a closure in Agave. https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L578-L640 */ static int -fd_collect_loaded_account( fd_runtime_t * runtime, - fd_txn_out_t * txn_out, - fd_bank_t * bank, - fd_txn_account_t const * account, - ulong loaded_acc_size, - fd_pubkey_t * additional_loaded_account_keys, - ulong * additional_loaded_account_keys_cnt ) { +fd_collect_loaded_account( fd_runtime_t * runtime, + fd_txn_out_t * txn_out, + fd_bank_t * bank, + fd_account_meta_t const * account_meta, + ulong loaded_acc_size, + fd_pubkey_t * additional_loaded_account_keys, + ulong * additional_loaded_account_keys_cnt ) { /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L586-L590 */ int err = fd_increase_calculated_data_size( txn_out, loaded_acc_size ); @@ -692,14 +693,14 @@ fd_collect_loaded_account( fd_runtime_t * runtime, loading logic. https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L611 */ - if( FD_LIKELY( memcmp( fd_txn_account_get_owner( account ), fd_solana_bpf_loader_upgradeable_program_id.key, sizeof(fd_pubkey_t) ) ) ) { + if( FD_LIKELY( memcmp( account_meta->owner, fd_solana_bpf_loader_upgradeable_program_id.key, sizeof(fd_pubkey_t) ) ) ) { return FD_RUNTIME_EXECUTE_SUCCESS; } /* Try to read the program state https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L612-L634 */ fd_bpf_upgradeable_loader_state_t loader_state[1]; - err = fd_bpf_loader_program_get_state( account, loader_state ); + err = fd_bpf_loader_program_get_state_inner( account_meta, loader_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return FD_RUNTIME_EXECUTE_SUCCESS; } @@ -812,7 +813,7 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, runtime, txn_out, bank, - acct, + acct->meta, loaded_acc_size, additional_loaded_account_keys, &additional_loaded_account_keys_cnt ); @@ -824,12 +825,12 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, /* Load and collect any remaining accounts https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L652-L659 */ - ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, acct, is_writable, unknown_acc, i ); + ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, acct->pubkey, acct->meta, is_writable, unknown_acc, i ); int err = fd_collect_loaded_account( runtime, txn_out, bank, - acct, + acct->meta, loaded_acc_size, additional_loaded_account_keys, &additional_loaded_account_keys_cnt ); diff --git a/src/flamenco/runtime/program/fd_bpf_loader_program.c b/src/flamenco/runtime/program/fd_bpf_loader_program.c index 2e4a435e2b..e50d728a6a 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_program.c +++ b/src/flamenco/runtime/program/fd_bpf_loader_program.c @@ -262,14 +262,14 @@ write_program_data( fd_exec_instr_ctx_t * instr_ctx, } int -fd_bpf_loader_program_get_state( fd_txn_account_t const * acct, - fd_bpf_upgradeable_loader_state_t * state ) { +fd_bpf_loader_program_get_state_inner( fd_account_meta_t const * meta, + fd_bpf_upgradeable_loader_state_t * state ) { int err = 0; fd_bincode_decode_static( bpf_upgradeable_loader_state, state, - fd_txn_account_get_data( acct ), - fd_txn_account_get_data_len( acct ), + fd_account_data( meta ), + meta->dlen, &err ); if( FD_UNLIKELY( err ) ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; @@ -277,6 +277,14 @@ fd_bpf_loader_program_get_state( fd_txn_account_t const * acct, return FD_EXECUTOR_INSTR_SUCCESS; } + +int +fd_bpf_loader_program_get_state( fd_txn_account_t const * acct, + fd_bpf_upgradeable_loader_state_t * state ) { + + return fd_bpf_loader_program_get_state_inner( acct->meta, state ); +} + /* Mirrors solana_sdk::transaction_context::BorrowedAccount::set_state() https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L973 */ int diff --git a/src/flamenco/runtime/program/fd_bpf_loader_program.h b/src/flamenco/runtime/program/fd_bpf_loader_program.h index 817a93d722..4fa4646a0c 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_program.h +++ b/src/flamenco/runtime/program/fd_bpf_loader_program.h @@ -55,6 +55,10 @@ FD_PROTOTYPES_BEGIN +int +fd_bpf_loader_program_get_state_inner( fd_account_meta_t const * meta, + fd_bpf_upgradeable_loader_state_t * state ); + /* Mirrors solana_sdk::transaction_context::BorrowedAccount::get_state() Acts on a fd_txn_account_t for ease of API use. From a067b5fac5483ba2f89ba56f42056d7783d41737 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Mon, 24 Nov 2025 15:51:45 +0000 Subject: [PATCH 09/32] wip --- src/flamenco/runtime/fd_executor.c | 30 +++++++++---------- src/flamenco/runtime/fd_executor.h | 2 +- src/flamenco/runtime/tests/fd_instr_harness.c | 6 +++- src/flamenco/runtime/tests/fd_txn_harness.c | 2 +- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index cab4331a50..6ceb59c16a 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -102,8 +102,7 @@ typedef struct fd_native_prog_info fd_native_prog_info_t; #undef PERFECT_HASH fd_exec_instr_fn_t -fd_executor_lookup_native_precompile_program( fd_txn_account_t const * prog_acc ) { - fd_pubkey_t const * pubkey = prog_acc->pubkey; +fd_executor_lookup_native_precompile_program( fd_pubkey_t const * pubkey ) { const fd_native_prog_info_t null_function = {0}; return fd_native_precompile_program_fn_lookup_tbl_query( pubkey, &null_function )->fn; } @@ -128,20 +127,20 @@ fd_executor_program_is_active( fd_bank_t * bank, native program ID. Returns NULL if given ID is not a recognized native program. https://github.com/anza-xyz/agave/blob/v2.2.6/program-runtime/src/invoke_context.rs#L520-L544 */ static int -fd_executor_lookup_native_program( fd_txn_account_t const * prog_acc, - fd_bank_t * bank, - fd_exec_instr_fn_t * native_prog_fn, - uchar * is_precompile ) { +fd_executor_lookup_native_program( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, + fd_bank_t * bank, + fd_exec_instr_fn_t * native_prog_fn, + uchar * is_precompile ) { /* First lookup to see if the program key is a precompile */ *is_precompile = 0; - *native_prog_fn = fd_executor_lookup_native_precompile_program( prog_acc ); + *native_prog_fn = fd_executor_lookup_native_precompile_program( pubkey ); if( FD_UNLIKELY( *native_prog_fn!=NULL ) ) { *is_precompile = 1; return 0; } - fd_pubkey_t const * pubkey = prog_acc->pubkey; - fd_pubkey_t const * owner = fd_txn_account_get_owner( prog_acc ); + fd_pubkey_t const * owner = (fd_pubkey_t const *)meta->owner; /* Native programs should be owned by the native loader... This will not be the case though once core programs are migrated to BPF. */ @@ -212,10 +211,10 @@ fd_executor_rent_transition_allowed( fd_rent_state_t const * pre_rent_state, /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm-rent-collector/src/svm_rent_collector.rs#L61-L77 */ static int -fd_executor_check_rent_state_with_account( fd_txn_account_t const * account, - fd_rent_state_t const * pre_rent_state, - fd_rent_state_t const * post_rent_state ) { - if( FD_UNLIKELY( memcmp( account->pubkey->key, fd_sysvar_incinerator_id.key, sizeof(fd_pubkey_t) ) && +fd_executor_check_rent_state_with_account( fd_pubkey_t const * pubkey, + fd_rent_state_t const * pre_rent_state, + fd_rent_state_t const * post_rent_state ) { + if( FD_UNLIKELY( memcmp( pubkey, fd_sysvar_incinerator_id.key, sizeof(fd_pubkey_t) ) && !fd_executor_rent_transition_allowed( pre_rent_state, post_rent_state ) ) ) { return FD_RUNTIME_TXN_ERR_INSUFFICIENT_FUNDS_FOR_RENT; } @@ -292,7 +291,7 @@ fd_validate_fee_payer( fd_txn_account_t * account, fd_rent_state_t payer_post_rent_state = fd_executor_get_account_rent_state( account, rent ); /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L335-L342 */ - return fd_executor_check_rent_state_with_account( account, &payer_pre_rent_state, &payer_post_rent_state ); + return fd_executor_check_rent_state_with_account( account->pubkey, &payer_pre_rent_state, &payer_post_rent_state ); } static int @@ -1363,7 +1362,8 @@ fd_execute_instr( fd_runtime_t * runtime, https://github.com/anza-xyz/agave/blob/v2.1.6/svm/src/message_processor.rs#L88 */ fd_exec_instr_fn_t native_prog_fn; uchar is_precompile; - int err = fd_executor_lookup_native_program( &txn_out->accounts.accounts[ instr->program_id ], + int err = fd_executor_lookup_native_program( &txn_out->accounts.account_keys[ instr->program_id ], + txn_out->accounts.metas[ instr->program_id ], bank, &native_prog_fn, &is_precompile ); diff --git a/src/flamenco/runtime/fd_executor.h b/src/flamenco/runtime/fd_executor.h index e513baa34b..b2a8d1ab8c 100644 --- a/src/flamenco/runtime/fd_executor.h +++ b/src/flamenco/runtime/fd_executor.h @@ -32,7 +32,7 @@ FD_PROTOTYPES_BEGIN typedef int (* fd_exec_instr_fn_t)( fd_exec_instr_ctx_t * ctx ); fd_exec_instr_fn_t -fd_executor_lookup_native_precompile_program( fd_txn_account_t const * prog_acc ); +fd_executor_lookup_native_precompile_program( fd_pubkey_t const * pubkey ); /* Returns 1 if the given pubkey matches one of the BPF loader v1/v2/v3/v4 program IDs, and 0 otherwise. */ diff --git a/src/flamenco/runtime/tests/fd_instr_harness.c b/src/flamenco/runtime/tests/fd_instr_harness.c index d3a24d9864..2b4252bf6d 100644 --- a/src/flamenco/runtime/tests/fd_instr_harness.c +++ b/src/flamenco/runtime/tests/fd_instr_harness.c @@ -169,6 +169,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, if( !fd_solfuzz_pb_load_account( runtime, &accts[j], runner->accdb, xid, &test_ctx->accounts[j], 0, j ) ) { return 0; } + txn_out->accounts.metas[j] = accts[j].meta; fd_txn_account_t * acc = &accts[j]; if( fd_txn_account_get_meta( acc ) ) { @@ -181,6 +182,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, } } + if( !memcmp( accts[j].pubkey, test_ctx->program_id, sizeof(fd_pubkey_t) ) ) { has_program_id = 1; info->program_id = (uchar)txn_out->accounts.accounts_cnt; @@ -209,6 +211,8 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, FD_LOG_CRIT(( "Failed to join and new a txn account" )); } + txn_out->accounts.metas[test_ctx->accounts_count] = meta; + info->program_id = (uchar)txn_out->accounts.accounts_cnt; txn_out->accounts.accounts_cnt++; } @@ -420,7 +424,7 @@ fd_solfuzz_pb_instr_run( fd_solfuzz_runner_t * runner, if( FD_LIKELY( effects->result ) ) { int program_id_idx = ctx->instr[ 0UL ].program_id; if( exec_result==FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR && - fd_executor_lookup_native_precompile_program( &ctx->txn_out->accounts.accounts[ program_id_idx ] )==NULL ) { + fd_executor_lookup_native_precompile_program( &ctx->txn_out->accounts.account_keys[ program_id_idx ] )==NULL ) { effects->custom_err = ctx->txn_out->err.custom_err; } } diff --git a/src/flamenco/runtime/tests/fd_txn_harness.c b/src/flamenco/runtime/tests/fd_txn_harness.c index 521375e80c..8c74d9369a 100644 --- a/src/flamenco/runtime/tests/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/fd_txn_harness.c @@ -456,7 +456,7 @@ fd_solfuzz_pb_txn_run( fd_solfuzz_runner_t * runner, /* If the exec err was a custom instr error and came from a precompile instruction, don't capture the custom error code. */ if( txn_out->err.exec_err==FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR && - fd_executor_lookup_native_precompile_program( &txn_out->accounts.accounts[ program_id_idx ] )==NULL ) { + fd_executor_lookup_native_precompile_program( &txn_out->accounts.account_keys[ program_id_idx ] )==NULL ) { txn_result->custom_error = txn_out->err.custom_err; } } From 9e445f244cb74227804d7c3439c5063aae96281e Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Mon, 24 Nov 2025 16:02:15 +0000 Subject: [PATCH 10/32] wip --- src/flamenco/runtime/fd_executor.c | 40 ++++++++++--------- src/flamenco/runtime/fd_txn_account.c | 14 +++++++ src/flamenco/runtime/fd_txn_account.h | 3 ++ .../runtime/program/fd_system_program.c | 12 +++--- .../runtime/program/fd_system_program.h | 2 +- 5 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 6ceb59c16a..e478bc41cb 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -223,16 +223,16 @@ fd_executor_check_rent_state_with_account( fd_pubkey_t const * pubkey, /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm-rent-collector/src/svm_rent_collector.rs#L87-L101 */ fd_rent_state_t -fd_executor_get_account_rent_state( fd_txn_account_t const * account, fd_rent_t const * rent ) { +fd_executor_get_account_rent_state( fd_account_meta_t const * meta, fd_rent_t const * rent ) { /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm-rent-collector/src/svm_rent_collector.rs#L88-L89 */ - if( fd_txn_account_get_lamports( account )==0UL ) { + if( meta->lamports==0UL ) { return (fd_rent_state_t){ .discriminant = fd_rent_state_enum_uninitialized }; } /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm-rent-collector/src/svm_rent_collector.rs#L90-L94 */ - if( fd_txn_account_get_lamports( account )>=fd_rent_exempt_minimum_balance( rent, fd_txn_account_get_data_len( account ) ) ) { + if( meta->lamports>=fd_rent_exempt_minimum_balance( rent, meta->dlen ) ) { return (fd_rent_state_t){ .discriminant = fd_rent_state_enum_rent_exempt }; @@ -243,8 +243,8 @@ fd_executor_get_account_rent_state( fd_txn_account_t const * account, fd_rent_t .discriminant = fd_rent_state_enum_rent_paying, .inner = { .rent_paying = { - .lamports = fd_txn_account_get_lamports( account ), - .data_size = fd_txn_account_get_data_len( account ) + .lamports = meta->lamports, + .data_size = meta->dlen } } }; @@ -252,16 +252,18 @@ fd_executor_get_account_rent_state( fd_txn_account_t const * account, fd_rent_t /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L293-L342 */ static int -fd_validate_fee_payer( fd_txn_account_t * account, - fd_rent_t const * rent, - ulong fee ) { +fd_validate_fee_payer( fd_pubkey_t const * pubkey, + fd_account_meta_t * meta, + fd_rent_t const * rent, + ulong fee ) { + /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L301-L304 */ - if( FD_UNLIKELY( fd_txn_account_get_lamports( account )==0UL ) ) { + if( FD_UNLIKELY( meta->lamports==0UL ) ) { return FD_RUNTIME_TXN_ERR_ACCOUNT_NOT_FOUND; } /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L305-L308 */ - int system_account_kind = fd_get_system_account_kind( account ); + int system_account_kind = fd_get_system_account_kind( meta ); if( FD_UNLIKELY( system_account_kind==FD_SYSTEM_PROGRAM_NONCE_ACCOUNT_KIND_UNKNOWN ) ) { return FD_RUNTIME_TXN_ERR_INVALID_ACCOUNT_FOR_FEE; } @@ -273,25 +275,24 @@ fd_validate_fee_payer( fd_txn_account_t * account, } /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L320-L327 */ - if( FD_UNLIKELY( min_balance>fd_txn_account_get_lamports( account ) || - fee>fd_txn_account_get_lamports( account )-min_balance ) ) { + if( FD_UNLIKELY( min_balance>meta->lamports || fee>meta->lamports-min_balance ) ) { return FD_RUNTIME_TXN_ERR_INSUFFICIENT_FUNDS_FOR_FEE; } /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L329 */ - fd_rent_state_t payer_pre_rent_state = fd_executor_get_account_rent_state( account, rent ); + fd_rent_state_t payer_pre_rent_state = fd_executor_get_account_rent_state( meta, rent ); /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L330-L332 */ - int err = fd_txn_account_checked_sub_lamports( account, fee ); + int err = fd_account_meta_checked_sub_lamports( meta, fee ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return FD_RUNTIME_TXN_ERR_INSUFFICIENT_FUNDS_FOR_FEE; } /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L334 */ - fd_rent_state_t payer_post_rent_state = fd_executor_get_account_rent_state( account, rent ); + fd_rent_state_t payer_post_rent_state = fd_executor_get_account_rent_state( meta, rent ); /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/account_loader.rs#L335-L342 */ - return fd_executor_check_rent_state_with_account( account->pubkey, &payer_pre_rent_state, &payer_post_rent_state ); + return fd_executor_check_rent_state_with_account( pubkey, &payer_pre_rent_state, &payer_post_rent_state ); } static int @@ -1046,6 +1047,9 @@ fd_executor_validate_transaction_fee_payer( fd_runtime_t * runtime, return FD_RUNTIME_TXN_ERR_ACCOUNT_NOT_FOUND; } + fd_pubkey_t * fee_payer_key = &txn_out->accounts.account_keys[FD_FEE_PAYER_TXN_IDX]; + fd_account_meta_t * fee_payer_meta = txn_out->accounts.metas[FD_FEE_PAYER_TXN_IDX]; + /* Calculate transaction fees https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/transaction_processor.rs#L597-L606 */ ulong execution_fee = 0UL; @@ -1059,7 +1063,7 @@ fd_executor_validate_transaction_fee_payer( fd_runtime_t * runtime, } /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/transaction_processor.rs#L609-L616 */ - err = fd_validate_fee_payer( fee_payer_rec, fd_bank_rent_query( bank ), total_fee ); + err = fd_validate_fee_payer( fee_payer_key, fee_payer_meta, fd_bank_rent_query( bank ), total_fee ); if( FD_UNLIKELY( err ) ) { return err; } @@ -1069,7 +1073,7 @@ fd_executor_validate_transaction_fee_payer( fd_runtime_t * runtime, fd_executor_create_rollback_fee_payer_account( runtime, bank, txn_in, txn_out, total_fee ); /* Set the starting lamports (to avoid unbalanced lamports issues in instruction execution) */ - runtime->accounts.starting_lamports[FD_FEE_PAYER_TXN_IDX] = fd_txn_account_get_lamports( fee_payer_rec ); + runtime->accounts.starting_lamports[FD_FEE_PAYER_TXN_IDX] = fee_payer_meta->lamports; txn_out->details.execution_fee = execution_fee; txn_out->details.priority_fee = priority_fee; diff --git a/src/flamenco/runtime/fd_txn_account.c b/src/flamenco/runtime/fd_txn_account.c index 4d8a361c51..7c10a06643 100644 --- a/src/flamenco/runtime/fd_txn_account.c +++ b/src/flamenco/runtime/fd_txn_account.c @@ -365,6 +365,20 @@ fd_txn_account_checked_add_lamports( fd_txn_account_t * acct, ulong lamports ) { return FD_EXECUTOR_INSTR_SUCCESS; } +int +fd_account_meta_checked_sub_lamports( fd_account_meta_t * meta, ulong lamports ) { + ulong balance_post = 0UL; + int err = fd_ulong_checked_sub( meta->lamports, + lamports, + &balance_post ); + if( FD_UNLIKELY( err ) ) { + return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW; + } + + meta->lamports = balance_post; + return FD_EXECUTOR_INSTR_SUCCESS; +} + int fd_txn_account_checked_sub_lamports( fd_txn_account_t * acct, ulong lamports ) { ulong balance_post = 0UL; diff --git a/src/flamenco/runtime/fd_txn_account.h b/src/flamenco/runtime/fd_txn_account.h index 5b9b2cbf82..fee8993ff8 100644 --- a/src/flamenco/runtime/fd_txn_account.h +++ b/src/flamenco/runtime/fd_txn_account.h @@ -217,6 +217,9 @@ fd_txn_account_set_readonly( fd_txn_account_t * acct ); void fd_txn_account_set_mutable( fd_txn_account_t * acct ); +int +fd_account_meta_checked_sub_lamports( fd_account_meta_t * meta, ulong lamports ); + FD_PROTOTYPES_END #endif /* HEADER_fd_src_flamenco_runtime_fd_txn_account_h */ diff --git a/src/flamenco/runtime/program/fd_system_program.c b/src/flamenco/runtime/program/fd_system_program.c index ea6b303c67..cd1f114532 100644 --- a/src/flamenco/runtime/program/fd_system_program.c +++ b/src/flamenco/runtime/program/fd_system_program.c @@ -724,19 +724,19 @@ fd_system_program_execute( fd_exec_instr_ctx_t * ctx ) { /**********************************************************************/ int -fd_get_system_account_kind( fd_txn_account_t * account ) { +fd_get_system_account_kind( fd_account_meta_t const * meta ) { /* https://github.com/anza-xyz/solana-sdk/blob/nonce-account%40v2.2.1/nonce-account/src/lib.rs#L56 */ - if( FD_UNLIKELY( memcmp( fd_txn_account_get_owner( account ), fd_solana_system_program_id.uc, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( memcmp( meta->owner, fd_solana_system_program_id.uc, sizeof(fd_pubkey_t) ) ) ) { return FD_SYSTEM_PROGRAM_NONCE_ACCOUNT_KIND_UNKNOWN; } /* https://github.com/anza-xyz/solana-sdk/blob/nonce-account%40v2.2.1/nonce-account/src/lib.rs#L57-L58 */ - if( FD_LIKELY( !fd_txn_account_get_data_len( account ) ) ) { + if( FD_LIKELY( !meta->dlen ) ) { return FD_SYSTEM_PROGRAM_NONCE_ACCOUNT_KIND_SYSTEM; } /* https://github.com/anza-xyz/solana-sdk/blob/nonce-account%40v2.2.1/nonce-account/src/lib.rs#L59 */ - if( FD_UNLIKELY( fd_txn_account_get_data_len( account )!=FD_SYSTEM_PROGRAM_NONCE_DLEN ) ) { + if( FD_UNLIKELY( meta->dlen!=FD_SYSTEM_PROGRAM_NONCE_DLEN ) ) { return FD_SYSTEM_PROGRAM_NONCE_ACCOUNT_KIND_UNKNOWN; } @@ -744,8 +744,8 @@ fd_get_system_account_kind( fd_txn_account_t * account ) { fd_nonce_state_versions_t versions[1]; if( FD_UNLIKELY( !fd_bincode_decode_static( nonce_state_versions, versions, - fd_txn_account_get_data( account ), - fd_txn_account_get_data_len( account ), + fd_account_data( meta ), + meta->dlen, NULL ) ) ) { return FD_SYSTEM_PROGRAM_NONCE_ACCOUNT_KIND_UNKNOWN; } diff --git a/src/flamenco/runtime/program/fd_system_program.h b/src/flamenco/runtime/program/fd_system_program.h index 54a8f88d32..b88b24c4c6 100644 --- a/src/flamenco/runtime/program/fd_system_program.h +++ b/src/flamenco/runtime/program/fd_system_program.h @@ -68,7 +68,7 @@ fd_check_transaction_age( fd_runtime_t * runtime, https://github.com/anza-xyz/solana-sdk/blob/nonce-account%40v2.2.1/nonce-account/src/lib.rs#L55-L71 */ int -fd_get_system_account_kind( fd_txn_account_t * account ); +fd_get_system_account_kind( fd_account_meta_t const * meta ); FD_PROTOTYPES_END From ba1f3c5a72d68a10548304f9758256e6d696a6ef Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Mon, 24 Nov 2025 16:50:45 +0000 Subject: [PATCH 11/32] wip --- src/flamenco/runtime/context/fd_exec_instr_ctx.c | 4 ++-- src/flamenco/runtime/fd_borrowed_account.c | 2 +- src/flamenco/runtime/fd_executor.c | 16 ++++++---------- src/flamenco/runtime/fd_runtime.c | 13 +++++++------ src/flamenco/runtime/fd_runtime_helpers.h | 3 +-- .../runtime/sysvar/fd_sysvar_instructions.c | 8 +++++--- 6 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/flamenco/runtime/context/fd_exec_instr_ctx.c b/src/flamenco/runtime/context/fd_exec_instr_ctx.c index 9f8087d712..faecaedda4 100644 --- a/src/flamenco/runtime/context/fd_exec_instr_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_instr_ctx.c @@ -46,11 +46,9 @@ fd_exec_instr_ctx_try_borrow_account( fd_exec_instr_ctx_t const * ctx, fd_borrowed_account_t * account ) { /* Get the account from the transaction context using idx_in_txn. https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L600-L602 */ - fd_txn_account_t * txn_account = NULL; int err = fd_runtime_get_account_at_index( ctx->txn_in, ctx->txn_out, idx_in_txn, - &txn_account, NULL ); if( FD_UNLIKELY( err ) ) { /* Return a MissingAccount error if the account is not found. @@ -59,6 +57,8 @@ fd_exec_instr_ctx_try_borrow_account( fd_exec_instr_ctx_t const * ctx, return FD_EXECUTOR_INSTR_ERR_MISSING_ACC; } + fd_txn_account_t * txn_account = &ctx->txn_out->accounts.accounts[idx_in_txn]; + /* Return an AccountBorrowFailed error if the write is not acquirable. https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L605 */ int borrow_res = fd_txn_account_try_borrow_mut( txn_account ); diff --git a/src/flamenco/runtime/fd_borrowed_account.c b/src/flamenco/runtime/fd_borrowed_account.c index 870a9076f4..a1a10ce3c6 100644 --- a/src/flamenco/runtime/fd_borrowed_account.c +++ b/src/flamenco/runtime/fd_borrowed_account.c @@ -52,7 +52,7 @@ fd_borrowed_account_set_owner( fd_borrowed_account_t * borrowed_acct, /* Don't copy the account if the owner does not change https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L757 */ - if( !memcmp( fd_txn_account_get_owner( acct ), owner, sizeof( fd_pubkey_t ) ) ) { + if( !memcmp( fd_txn_account_get_owner( acct ), owner, sizeof(fd_pubkey_t) ) ) { return FD_EXECUTOR_INSTR_SUCCESS; } diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index e478bc41cb..9b7c9a4910 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -526,7 +526,7 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L429-L443 */ for( ushort i=0; iaccounts.accounts_cnt; i++ ) { fd_txn_account_t * acct = &txn_out->accounts.accounts[i]; - uchar unknown_acc = !!(fd_runtime_get_account_at_index( txn_in, txn_out, i, &acct, fd_runtime_account_check_exists ) || + uchar unknown_acc = !!(fd_runtime_get_account_at_index( txn_in, txn_out, i, fd_runtime_account_check_exists ) || fd_txn_account_get_lamports( acct )==0UL); uchar is_writable = !!(fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, i )); @@ -578,11 +578,10 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, /* Mimicking `load_account()` here with 0-lamport check as well. https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L455-L462 */ - fd_txn_account_t * program_account = NULL; + fd_txn_account_t * program_account = &txn_out->accounts.accounts[instr->program_id]; int err = fd_runtime_get_account_at_index( txn_in, txn_out, instr->program_id, - &program_account, fd_runtime_account_check_exists ); if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS || fd_txn_account_get_lamports( program_account )==0UL ) ) { return FD_RUNTIME_TXN_ERR_PROGRAM_ACCOUNT_NOT_FOUND; @@ -793,7 +792,7 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L642-L660 */ for( ushort i=0; iaccounts.accounts_cnt; i++ ) { fd_txn_account_t * acct = &txn_out->accounts.accounts[i]; - uchar unknown_acc = !!(fd_runtime_get_account_at_index( txn_in, txn_out, i, &acct, fd_runtime_account_check_exists ) || + uchar unknown_acc = !!(fd_runtime_get_account_at_index( txn_in, txn_out, i, fd_runtime_account_check_exists ) || fd_txn_account_get_lamports( acct )==0UL); uchar is_writable = !!(fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, i )); @@ -846,11 +845,10 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, /* Mimicking `load_account()` here with 0-lamport check as well. https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L663-L666 */ - fd_txn_account_t * program_account; + fd_txn_account_t * program_account = &txn_out->accounts.accounts[instr->program_id]; int err = fd_runtime_get_account_at_index( txn_in, txn_out, instr->program_id, - &program_account, fd_runtime_account_check_exists ); if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS || fd_txn_account_get_lamports( program_account )==0UL ) ) { return FD_RUNTIME_TXN_ERR_PROGRAM_ACCOUNT_NOT_FOUND; @@ -1037,11 +1035,9 @@ fd_executor_validate_transaction_fee_payer( fd_runtime_t * runtime, fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out ) { /* https://github.com/anza-xyz/agave/blob/v2.2.13/svm/src/transaction_processor.rs#L574-L580 */ - fd_txn_account_t * fee_payer_rec = NULL; int err = fd_runtime_get_account_at_index( txn_in, txn_out, FD_FEE_PAYER_TXN_IDX, - &fee_payer_rec, fd_runtime_account_check_fee_payer_writable ); if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { return FD_RUNTIME_TXN_ERR_ACCOUNT_NOT_FOUND; @@ -1192,8 +1188,8 @@ fd_txn_ctx_push( fd_runtime_t * runtime, int idx = fd_runtime_find_index_of_account( txn_out, &fd_sysvar_instructions_id ); if( FD_UNLIKELY( idx!=-1 ) ) { /* https://github.com/anza-xyz/agave/blob/v2.2.12/transaction-context/src/lib.rs#L397-L400 */ - fd_txn_account_t * sysvar_instructions_account = NULL; - err = fd_runtime_get_account_at_index( txn_in, txn_out, (ushort)idx, &sysvar_instructions_account, NULL ); + fd_txn_account_t * sysvar_instructions_account = &txn_out->accounts.accounts[idx]; + err = fd_runtime_get_account_at_index( txn_in, txn_out, (ushort)idx, NULL ); if( FD_UNLIKELY( err ) ) { return FD_EXECUTOR_INSTR_ERR_MISSING_ACC; } diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index be569caf35..6eb382a549 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1755,17 +1755,15 @@ int fd_runtime_get_account_at_index( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx, - fd_txn_account_t * * account, fd_txn_account_condition_fn_t * condition ) { if( FD_UNLIKELY( idx>=txn_out->accounts.accounts_cnt ) ) { return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT; } fd_txn_account_t * txn_account = &txn_out->accounts.accounts[idx]; - *account = txn_account; if( FD_LIKELY( condition != NULL ) ) { - if( FD_UNLIKELY( !condition( *account, txn_in, txn_out, idx ) ) ) { + if( FD_UNLIKELY( !condition( txn_account, txn_in, txn_out, idx ) ) ) { return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT; } } @@ -1777,17 +1775,18 @@ int fd_runtime_get_account_with_key( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, fd_pubkey_t const * pubkey, - fd_txn_account_t * * account, + int * index_out, fd_txn_account_condition_fn_t * condition ) { int index = fd_runtime_find_index_of_account( txn_out, pubkey ); if( FD_UNLIKELY( index==-1 ) ) { return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT; } + *index_out = index; + return fd_runtime_get_account_at_index( txn_in, txn_out, (uchar)index, - account, condition ); } @@ -1803,12 +1802,14 @@ fd_runtime_get_executable_account( fd_runtime_t * runtime, borrowed account since it reflects changes from prior instructions. Referencing the read-only executable accounts list is incorrect behavior when the program data account is written to in a prior instruction (e.g. program upgrade + invoke within the same txn) */ + int index; int err = fd_runtime_get_account_with_key( txn_in, txn_out, pubkey, - account, + &index, condition ); if( FD_UNLIKELY( err==FD_ACC_MGR_SUCCESS ) ) { + *account = &txn_out->accounts.accounts[index]; return FD_ACC_MGR_SUCCESS; } diff --git a/src/flamenco/runtime/fd_runtime_helpers.h b/src/flamenco/runtime/fd_runtime_helpers.h index 4cbd4bbec4..bff3d85383 100644 --- a/src/flamenco/runtime/fd_runtime_helpers.h +++ b/src/flamenco/runtime/fd_runtime_helpers.h @@ -151,7 +151,6 @@ int fd_runtime_get_account_at_index( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx, - fd_txn_account_t * * account, fd_txn_account_condition_fn_t * condition ); /* A wrapper around fd_exec_txn_ctx_get_account_at_index that obtains an @@ -161,7 +160,7 @@ int fd_runtime_get_account_with_key( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, fd_pubkey_t const * pubkey, - fd_txn_account_t * * account, + int * index_out, fd_txn_account_condition_fn_t * condition ); /* Gets an executable (program data) account via its pubkey. */ diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c index edbfaa3297..8be5c9e7a7 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c @@ -41,19 +41,21 @@ fd_sysvar_instructions_serialize_account( fd_runtime_t * runtime, ulong txn_idx ) { ulong serialized_sz = instructions_serialized_size( instrs, instrs_cnt ); - fd_txn_account_t * rec = NULL; + int index; int err = fd_runtime_get_account_with_key( txn_in, txn_out, &fd_sysvar_instructions_id, - &rec, + &index, fd_runtime_account_check_exists ); - if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS && rec==NULL ) ) { + if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS && index==-1 ) ) { /* The way we use this, this should NEVER hit since the borrowed accounts should be set up before this is called, and this is only called if the sysvar instructions account is in the borrowed accounts list. */ FD_LOG_ERR(( "Failed to view sysvar instructions borrowed account. It may not be included in the txn account keys." )); } + fd_txn_account_t * rec = &txn_out->accounts.accounts[index]; + /* This stays within the FD spad allocation bounds because... 1. Case 1: rec->meta!=NULL - rec->meta was set up in `fd_executor_setup_accounts_for_txn()` and data was allocated from the spad From eb6702d800351ead28ae942cf1ba5c3160503fca Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Mon, 24 Nov 2025 17:23:38 +0000 Subject: [PATCH 12/32] wip --- src/flamenco/runtime/fd_executor.c | 21 +++++++++++---------- src/flamenco/runtime/fd_runtime.c | 15 ++++++--------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 9b7c9a4910..ef495e3561 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -525,9 +525,9 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L429-L443 */ for( ushort i=0; iaccounts.accounts_cnt; i++ ) { - fd_txn_account_t * acct = &txn_out->accounts.accounts[i]; + fd_account_meta_t * meta = txn_out->accounts.metas[i]; uchar unknown_acc = !!(fd_runtime_get_account_at_index( txn_in, txn_out, i, fd_runtime_account_check_exists ) || - fd_txn_account_get_lamports( acct )==0UL); + meta->lamports==0UL); uchar is_writable = !!(fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, i )); /* Collect the fee payer account separately (since it was already) @@ -540,7 +540,7 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, We also don't need to add a base account size to this value because this branch would only be taken BEFORE SIMD-0186 is enabled. */ - int err = accumulate_and_check_loaded_account_data_size( fd_txn_account_get_data_len( acct ), + int err = accumulate_and_check_loaded_account_data_size( meta->dlen, requested_loaded_accounts_data_size, &txn_out->details.loaded_accounts_data_size ); if( FD_UNLIKELY( err!=FD_RUNTIME_EXECUTE_SUCCESS ) ) { @@ -550,7 +550,7 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, } /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L733-L740 */ - ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, acct->pubkey, acct->meta, is_writable, unknown_acc, i ); + ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, &txn_out->accounts.account_keys[i], meta, is_writable, unknown_acc, i ); int err = accumulate_and_check_loaded_account_data_size( loaded_acc_size, requested_loaded_accounts_data_size, &txn_out->details.loaded_accounts_data_size ); @@ -791,9 +791,10 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L642-L660 */ for( ushort i=0; iaccounts.accounts_cnt; i++ ) { - fd_txn_account_t * acct = &txn_out->accounts.accounts[i]; + fd_account_meta_t * meta = txn_out->accounts.metas[i]; + uchar unknown_acc = !!(fd_runtime_get_account_at_index( txn_in, txn_out, i, fd_runtime_account_check_exists ) || - fd_txn_account_get_lamports( acct )==0UL); + meta->lamports==0UL); uchar is_writable = !!(fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, i )); /* Collect the fee payer account separately (since it was already) @@ -807,12 +808,12 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, because this branch would only be taken AFTER SIMD-0186 is enabled. */ ulong loaded_acc_size = fd_ulong_sat_add( FD_TRANSACTION_ACCOUNT_BASE_SIZE, - fd_txn_account_get_data_len( acct ) ); + meta->dlen ); int err = fd_collect_loaded_account( runtime, txn_out, bank, - acct->meta, + meta, loaded_acc_size, additional_loaded_account_keys, &additional_loaded_account_keys_cnt ); @@ -824,12 +825,12 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, /* Load and collect any remaining accounts https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L652-L659 */ - ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, acct->pubkey, acct->meta, is_writable, unknown_acc, i ); + ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, &txn_out->accounts.account_keys[i], meta, is_writable, unknown_acc, i ); int err = fd_collect_loaded_account( runtime, txn_out, bank, - acct->meta, + meta, loaded_acc_size, additional_loaded_account_keys, &additional_loaded_account_keys_cnt ); diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 6eb382a549..9119807f89 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1010,21 +1010,18 @@ fd_runtime_pre_execute_check( fd_runtime_t * runtime, static void fd_runtime_finalize_account( fd_funk_t * funk, fd_funk_txn_xid_t const * xid, - fd_txn_account_t * acc, + fd_pubkey_t const * pubkey, + fd_account_meta_t * meta, fd_funk_rec_t * prev_rec ) { - if( FD_UNLIKELY( !fd_txn_account_is_mutable( acc ) ) ) { - FD_LOG_CRIT(( "fd_runtime_finalize_account: account is not mutable" )); - } - fd_pubkey_t const * key = acc->pubkey; - uchar const * record_data = (uchar *)fd_txn_account_get_meta( acc ); - ulong record_sz = fd_account_meta_get_record_sz( acc->meta ); + uchar const * record_data = (uchar *)meta; + ulong record_sz = fd_account_meta_get_record_sz( meta ); int err = FD_FUNK_SUCCESS; if( !prev_rec || !fd_funk_txn_xid_eq( prev_rec->pair.xid, xid ) ) { - fd_funk_rec_key_t funk_key = fd_funk_acc_key( key ); + fd_funk_rec_key_t funk_key = fd_funk_acc_key( pubkey ); fd_funk_rec_prepare_t prepare[1]; fd_funk_rec_t * rec = fd_funk_rec_prepare( funk, xid, &funk_key, prepare, &err ); if( FD_UNLIKELY( !rec || err!=FD_FUNK_SUCCESS ) ) { @@ -1183,7 +1180,7 @@ fd_runtime_save_account( fd_funk_t * funk, fd_runtime_buffer_solcap_account_update( account, bank, capture_ctx ); /* Save the new version of the account to Funk */ - fd_runtime_finalize_account( funk, xid, account, funk_prev_rec ); + fd_runtime_finalize_account( funk, xid, pubkey, meta, funk_prev_rec ); } /* fd_runtime_commit_txn is a helper used by the non-tpool transaction From 0fe1debae19c7b86e7607dece9c407b246488a8f Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Mon, 24 Nov 2025 17:34:56 +0000 Subject: [PATCH 13/32] wip --- src/flamenco/runtime/fd_executor.c | 22 +++++++++++----------- src/flamenco/runtime/fd_runtime.h | 1 + 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index ef495e3561..e954679041 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -578,30 +578,30 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, /* Mimicking `load_account()` here with 0-lamport check as well. https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L455-L462 */ - fd_txn_account_t * program_account = &txn_out->accounts.accounts[instr->program_id]; + fd_account_meta_t * program_meta = txn_out->accounts.metas[instr->program_id]; int err = fd_runtime_get_account_at_index( txn_in, txn_out, instr->program_id, fd_runtime_account_check_exists ); - if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS || fd_txn_account_get_lamports( program_account )==0UL ) ) { + if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS || program_meta->lamports==0UL ) ) { return FD_RUNTIME_TXN_ERR_PROGRAM_ACCOUNT_NOT_FOUND; } /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L464-L471 */ if( FD_UNLIKELY( !FD_FEATURE_ACTIVE_BANK( bank, remove_accounts_executable_flag_checks ) && - !fd_txn_account_is_executable( program_account ) ) ) { + !program_meta->executable ) ) { return FD_RUNTIME_TXN_ERR_INVALID_PROGRAM_FOR_EXECUTION; } /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L474-L477 */ - if( !memcmp( fd_txn_account_get_owner( program_account ), fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) ) { + if( !memcmp( program_meta->owner, fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) ) { continue; } /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L479-L522 */ uchar loader_seen = 0; for( ushort j=0; jowner, sizeof(fd_pubkey_t) ) ) { /* If the owner account has already been seen, skip the owner checks and do not acccumulate the account size. */ loader_seen = 1; @@ -617,7 +617,7 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L496-L517 */ fd_txn_account_t owner_account[1]; err = fd_txn_account_init_from_funk_readonly( owner_account, - fd_txn_account_get_owner( program_account ), + (fd_pubkey_t const *)program_meta->owner, runtime->funk, &xid ); if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { @@ -846,23 +846,23 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, /* Mimicking `load_account()` here with 0-lamport check as well. https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L663-L666 */ - fd_txn_account_t * program_account = &txn_out->accounts.accounts[instr->program_id]; + fd_account_meta_t * program_meta = txn_out->accounts.metas[ instr->program_id ]; int err = fd_runtime_get_account_at_index( txn_in, txn_out, instr->program_id, fd_runtime_account_check_exists ); - if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS || fd_txn_account_get_lamports( program_account )==0UL ) ) { + if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS || program_meta->lamports==0UL ) ) { return FD_RUNTIME_TXN_ERR_PROGRAM_ACCOUNT_NOT_FOUND; } /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L668-L675 */ if( FD_UNLIKELY( !FD_FEATURE_ACTIVE_BANK( bank, remove_accounts_executable_flag_checks ) && - !fd_txn_account_is_executable( program_account ) ) ) { + !program_meta->executable ) ) { return FD_RUNTIME_TXN_ERR_INVALID_PROGRAM_FOR_EXECUTION; } /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L677-L681 */ - fd_pubkey_t const * owner_id = fd_txn_account_get_owner( program_account ); + fd_pubkey_t const * owner_id = (fd_pubkey_t const *)program_meta->owner; if( FD_UNLIKELY( memcmp( owner_id->key, fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) && !fd_executor_pubkey_is_bpf_loader( owner_id ) ) ) { return FD_RUNTIME_TXN_ERR_INVALID_PROGRAM_FOR_EXECUTION; @@ -990,7 +990,7 @@ fd_executor_create_rollback_fee_payer_account( fd_runtime_t * runtime, if( !memcmp( &prev_txn_out->accounts.account_keys[ j ], fee_payer_key, sizeof(fd_pubkey_t) ) && fd_runtime_account_is_writable_idx( prev_txn_in, prev_txn_out, bank, j ) ) { /* Found the account in a previous transaction */ - meta = prev_txn_out->accounts.accounts[ j ].meta; + meta = prev_txn_out->accounts.metas[ j ]; is_found = 1; break; } diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index 3e2d34b5e5..597ff66d14 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -131,6 +131,7 @@ struct fd_runtime { fd_txn_account_t executables[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */ ulong starting_lamports[ MAX_TX_ACCOUNT_LOCKS ]; /* Starting lamports for each account */ ulong starting_dlen[ MAX_TX_ACCOUNT_LOCKS ]; /* Starting data length for each account */ + ulong refcnt[ MAX_TX_ACCOUNT_LOCKS ]; /* Reference count for each account */ } accounts; }; typedef struct fd_runtime fd_runtime_t; From 41025684e5c9c59e52d214b47b37fbfcaab38a4c Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Mon, 24 Nov 2025 18:31:47 +0000 Subject: [PATCH 14/32] wip --- .../runtime/context/fd_exec_instr_ctx.c | 7 ++- src/flamenco/runtime/fd_borrowed_account.h | 9 ++- src/flamenco/runtime/fd_executor.c | 12 ++-- src/flamenco/runtime/fd_txn_account.c | 55 ------------------- src/flamenco/runtime/fd_txn_account.h | 14 ----- src/flamenco/runtime/tests/fd_instr_harness.c | 1 + 6 files changed, 20 insertions(+), 78 deletions(-) diff --git a/src/flamenco/runtime/context/fd_exec_instr_ctx.c b/src/flamenco/runtime/context/fd_exec_instr_ctx.c index faecaedda4..d7bf408fbd 100644 --- a/src/flamenco/runtime/context/fd_exec_instr_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_instr_ctx.c @@ -61,17 +61,18 @@ fd_exec_instr_ctx_try_borrow_account( fd_exec_instr_ctx_t const * ctx, /* Return an AccountBorrowFailed error if the write is not acquirable. https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L605 */ - int borrow_res = fd_txn_account_try_borrow_mut( txn_account ); - if( FD_UNLIKELY( !borrow_res ) ) { + if( FD_UNLIKELY( ctx->runtime->accounts.refcnt[idx_in_txn]!=0UL ) ) { return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_FAILED; } + ctx->runtime->accounts.refcnt[idx_in_txn]++; /* Create a BorrowedAccount upon success. https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L606 */ fd_borrowed_account_init( account, txn_account, ctx, - idx_in_instr ); + idx_in_instr, + &ctx->runtime->accounts.refcnt[idx_in_txn] ); return FD_EXECUTOR_INSTR_SUCCESS; } diff --git a/src/flamenco/runtime/fd_borrowed_account.h b/src/flamenco/runtime/fd_borrowed_account.h index 9a8f2e5fdb..de649ea654 100644 --- a/src/flamenco/runtime/fd_borrowed_account.h +++ b/src/flamenco/runtime/fd_borrowed_account.h @@ -22,6 +22,8 @@ struct fd_borrowed_account { /* index_in_instruction will be USHORT_MAX for borrowed program accounts because they are not stored in the list of instruction accounts in the instruction context */ ushort index_in_instruction; + + ulong * refcnt; }; typedef struct fd_borrowed_account fd_borrowed_account_t; @@ -37,10 +39,12 @@ static inline void fd_borrowed_account_init( fd_borrowed_account_t * borrowed_acct, fd_txn_account_t * acct, fd_exec_instr_ctx_t const * instr_ctx, - ushort index_in_instruction ) { + ushort index_in_instruction, + ulong * refcnt ) { borrowed_acct->acct = acct; borrowed_acct->instr_ctx = instr_ctx; borrowed_acct->index_in_instruction = index_in_instruction; + borrowed_acct->refcnt = refcnt; FD_COMPILER_MFENCE(); borrowed_acct->magic = FD_BORROWED_ACCOUNT_MAGIC; @@ -52,7 +56,8 @@ fd_borrowed_account_init( fd_borrowed_account_t * borrowed_acct, static inline void fd_borrowed_account_drop( fd_borrowed_account_t * borrowed_acct ) { - fd_txn_account_drop( borrowed_acct->acct ); + //fd_txn_account_drop( borrowed_acct->acct ); + (*borrowed_acct->refcnt) = 0; } /* Destructor */ diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index e954679041..687f7d3f88 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -1195,14 +1195,17 @@ fd_txn_ctx_push( fd_runtime_t * runtime, return FD_EXECUTOR_INSTR_ERR_MISSING_ACC; } + ulong refcnt = runtime->accounts.refcnt[idx]; + /* https://github.com/anza-xyz/agave/blob/v2.2.12/transaction-context/src/lib.rs#L401-L402 */ - if( FD_UNLIKELY( !fd_txn_account_try_borrow_mut( sysvar_instructions_account ) ) ) { + if( FD_UNLIKELY( refcnt!=0UL ) ) { return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_FAILED; } + refcnt++; /* https://github.com/anza-xyz/agave/blob/v2.2.12/transaction-context/src/lib.rs#L403-L406 */ fd_sysvar_instructions_update_current_instr_idx( sysvar_instructions_account, (ushort)runtime->instr.current_idx ); - fd_txn_account_drop( sysvar_instructions_account ); + refcnt--; } return FD_EXECUTOR_INSTR_SUCCESS; @@ -1284,8 +1287,8 @@ fd_instr_stack_pop( fd_runtime_t * runtime, for( ushort i=0; iacct_cnt; i++ ) { ushort idx_in_txn = instr->accounts[i].index_in_transaction; fd_txn_account_t * account = &txn_out->accounts.accounts[ idx_in_txn ]; - if( FD_UNLIKELY( fd_txn_account_is_executable( account ) && - fd_txn_account_is_borrowed( account ) ) ) { + ulong refcnt = runtime->accounts.refcnt[idx_in_txn]; + if( FD_UNLIKELY( fd_txn_account_is_executable( account ) && refcnt!=0UL ) ) { return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_OUTSTANDING; } } @@ -1538,6 +1541,7 @@ fd_executor_setup_txn_account( fd_runtime_t * runtime, runtime->accounts.starting_lamports[idx] = fd_txn_account_get_lamports( txn_account ); runtime->accounts.starting_dlen[idx] = fd_txn_account_get_data_len( txn_account ); + runtime->accounts.refcnt[idx] = 0UL; memcpy( &txn_out->accounts.pubkeys[idx], acc, sizeof(fd_pubkey_t) ); txn_out->accounts.metas[ idx ] = account_meta; diff --git a/src/flamenco/runtime/fd_txn_account.c b/src/flamenco/runtime/fd_txn_account.c index 7c10a06643..077c470c8f 100644 --- a/src/flamenco/runtime/fd_txn_account.c +++ b/src/flamenco/runtime/fd_txn_account.c @@ -216,46 +216,6 @@ fd_txn_account_mutable_fini( fd_txn_account_t * acct, } } -/* read/write mutual exclusion */ - -FD_FN_PURE int -fd_txn_account_acquire_write_is_safe( fd_txn_account_t const * acct ) { - return !acct->refcnt_excl; -} - -/* fd_txn_account_acquire_write acquires write/exclusive access. - Causes all other write or read acquire attempts will fail. Returns 1 - on success, 0 on failure. - - Mirrors a try_borrow_mut() call in Agave. */ -int -fd_txn_account_acquire_write( fd_txn_account_t * acct ) { - if( FD_UNLIKELY( !fd_txn_account_acquire_write_is_safe( acct ) ) ) { - return 0; - } - acct->refcnt_excl = (ushort)1; - return 1; -} - -/* fd_txn_account_release_write{_private} releases a write/exclusive - access handle. The private version should only be used by fd_borrowed_account_drop - and fd_borrowed_account_destroy. */ -void -fd_txn_account_release_write( fd_txn_account_t * acct ) { - if( FD_UNLIKELY( acct->refcnt_excl!=1 ) ) { - FD_LOG_CRIT(( "refcnt_excl is %d, expected 1", acct->refcnt_excl )); - } - acct->refcnt_excl = (ushort)0; -} - -void -fd_txn_account_release_write_private( fd_txn_account_t * acct ) { - /* Only release if it is not yet released */ - if( !fd_txn_account_acquire_write_is_safe( acct ) ) { - fd_txn_account_release_write( acct ); - } -} - fd_pubkey_t const * fd_txn_account_get_owner( fd_txn_account_t const * acct ) { if( FD_UNLIKELY( !acct->meta ) ) { @@ -460,11 +420,6 @@ fd_txn_account_resize( fd_txn_account_t * acct, acct->meta->dlen = (uint)dlen; } -ushort -fd_txn_account_is_borrowed( fd_txn_account_t const * acct ) { - return !!acct->refcnt_excl; -} - int fd_txn_account_is_mutable( fd_txn_account_t const * acct ) { /* A txn account is mutable if meta is non NULL */ @@ -477,16 +432,6 @@ fd_txn_account_is_readonly( fd_txn_account_t const * acct ) { return !acct->is_mutable; } -int -fd_txn_account_try_borrow_mut( fd_txn_account_t * acct ) { - return fd_txn_account_acquire_write( acct ); -} - -void -fd_txn_account_drop( fd_txn_account_t * acct ) { - fd_txn_account_release_write_private( acct ); -} - void fd_txn_account_set_readonly( fd_txn_account_t * acct ) { acct->is_mutable = 0; diff --git a/src/flamenco/runtime/fd_txn_account.h b/src/flamenco/runtime/fd_txn_account.h index fee8993ff8..fbe6658db1 100644 --- a/src/flamenco/runtime/fd_txn_account.h +++ b/src/flamenco/runtime/fd_txn_account.h @@ -34,11 +34,6 @@ struct __attribute__((aligned(8UL))) fd_txn_account { int is_mutable; long meta_soff; - - /* Provide borrowing semantics. Used for single-threaded logic only, - thus not comparable to a data synchronization lock. */ - ushort refcnt_excl; - }; typedef struct fd_txn_account fd_txn_account_t; #define FD_TXN_ACCOUNT_FOOTPRINT (sizeof(fd_txn_account_t)) @@ -196,21 +191,12 @@ fd_txn_account_clear_owner( fd_txn_account_t * acct ); void fd_txn_account_resize( fd_txn_account_t * acct, ulong dlen ); -ushort -fd_txn_account_is_borrowed( fd_txn_account_t const * acct ); - int fd_txn_account_is_mutable( fd_txn_account_t const * acct ); int fd_txn_account_is_readonly( fd_txn_account_t const * acct ); -int -fd_txn_account_try_borrow_mut( fd_txn_account_t * acct ); - -void -fd_txn_account_drop( fd_txn_account_t * acct ); - void fd_txn_account_set_readonly( fd_txn_account_t * acct ); diff --git a/src/flamenco/runtime/tests/fd_instr_harness.c b/src/flamenco/runtime/tests/fd_instr_harness.c index 2b4252bf6d..bc3be333b1 100644 --- a/src/flamenco/runtime/tests/fd_instr_harness.c +++ b/src/flamenco/runtime/tests/fd_instr_harness.c @@ -170,6 +170,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, return 0; } txn_out->accounts.metas[j] = accts[j].meta; + runtime->accounts.refcnt[j] = 0UL; fd_txn_account_t * acc = &accts[j]; if( fd_txn_account_get_meta( acc ) ) { From 9b6bb09ad97ea0ad0d75f589649f789d1c7fbcbf Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Mon, 24 Nov 2025 19:33:18 +0000 Subject: [PATCH 15/32] wip --- .../runtime/context/fd_exec_instr_ctx.c | 3 +- src/flamenco/runtime/fd_borrowed_account.h | 60 +++++++------------ src/flamenco/runtime/fd_txn_account.c | 10 ++++ src/flamenco/runtime/fd_txn_account.h | 4 ++ .../program/fd_address_lookup_table_program.c | 4 +- .../runtime/program/fd_bpf_loader_program.c | 42 ++++++------- .../program/fd_bpf_loader_serialization.c | 2 +- .../runtime/program/fd_config_program.c | 4 +- .../runtime/program/fd_stake_program.c | 8 +-- .../runtime/program/fd_vote_program.c | 28 ++++----- .../runtime/program/fd_vote_program.h | 4 +- src/flamenco/runtime/program/zksdk/fd_zksdk.c | 8 +-- src/flamenco/vm/fd_vm.h | 2 +- src/flamenco/vm/fd_vm_private.h | 2 +- .../vm/syscall/fd_vm_syscall_cpi_common.c | 12 ++-- 15 files changed, 96 insertions(+), 97 deletions(-) diff --git a/src/flamenco/runtime/context/fd_exec_instr_ctx.c b/src/flamenco/runtime/context/fd_exec_instr_ctx.c index d7bf408fbd..b637ac13ef 100644 --- a/src/flamenco/runtime/context/fd_exec_instr_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_instr_ctx.c @@ -69,7 +69,8 @@ fd_exec_instr_ctx_try_borrow_account( fd_exec_instr_ctx_t const * ctx, /* Create a BorrowedAccount upon success. https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L606 */ fd_borrowed_account_init( account, - txn_account, + &ctx->txn_out->accounts.account_keys[idx_in_txn], + txn_account->meta, ctx, idx_in_instr, &ctx->runtime->accounts.refcnt[idx_in_txn] ); diff --git a/src/flamenco/runtime/fd_borrowed_account.h b/src/flamenco/runtime/fd_borrowed_account.h index de649ea654..290c4ed977 100644 --- a/src/flamenco/runtime/fd_borrowed_account.h +++ b/src/flamenco/runtime/fd_borrowed_account.h @@ -16,7 +16,8 @@ struct fd_borrowed_account { ulong magic; - fd_txn_account_t * acct; + fd_pubkey_t const * pubkey; + fd_account_meta_t * meta; fd_exec_instr_ctx_t const * instr_ctx; /* index_in_instruction will be USHORT_MAX for borrowed program accounts because @@ -37,11 +38,13 @@ FD_PROTOTYPES_BEGIN static inline void fd_borrowed_account_init( fd_borrowed_account_t * borrowed_acct, - fd_txn_account_t * acct, + fd_pubkey_t const * pubkey, + fd_account_meta_t * meta, fd_exec_instr_ctx_t const * instr_ctx, ushort index_in_instruction, ulong * refcnt ) { - borrowed_acct->acct = acct; + borrowed_acct->pubkey = pubkey; + borrowed_acct->meta = meta; borrowed_acct->instr_ctx = instr_ctx; borrowed_acct->index_in_instruction = index_in_instruction; borrowed_acct->refcnt = refcnt; @@ -56,7 +59,6 @@ fd_borrowed_account_init( fd_borrowed_account_t * borrowed_acct, static inline void fd_borrowed_account_drop( fd_borrowed_account_t * borrowed_acct ) { - //fd_txn_account_drop( borrowed_acct->acct ); (*borrowed_acct->refcnt) = 0; } @@ -84,12 +86,12 @@ fd_borrowed_account_destroy( fd_borrowed_account_t * borrowed_acct ) { static inline uchar const * fd_borrowed_account_get_data( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_get_data( borrowed_acct->acct ); + return fd_account_data( borrowed_acct->meta ); } static inline ulong fd_borrowed_account_get_data_len( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_get_data_len( borrowed_acct->acct ); + return borrowed_acct->meta->dlen; } /* fd_borrowed_account_get_data_mut mirrors Agave function @@ -108,7 +110,7 @@ fd_borrowed_account_get_data_mut( fd_borrowed_account_t * borrowed_acct, static inline fd_pubkey_t const * fd_borrowed_account_get_owner( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_get_owner( borrowed_acct->acct ); + return (fd_pubkey_t const *)borrowed_acct->meta->owner; } /* fd_borrowed_account_get_lamports mirrors Agave function @@ -121,22 +123,12 @@ fd_borrowed_account_get_owner( fd_borrowed_account_t const * borrowed_acct ) { static inline ulong fd_borrowed_account_get_lamports( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_get_lamports( borrowed_acct->acct ); -} - -/* fd_borrowed_account_get_rent_epoch mirrors Agave function - solana_sdk::transaction_context::BorrowedAccount::get_rent_epoch. - - https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1034 */ - -static inline ulong -fd_borrowed_account_get_rent_epoch( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_get_rent_epoch( borrowed_acct->acct ); + return borrowed_acct->meta->lamports; } static inline fd_account_meta_t const * fd_borrowed_account_get_acc_meta( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_get_meta( borrowed_acct->acct ); + return borrowed_acct->meta; } /* Setters */ @@ -215,7 +207,7 @@ static inline int fd_borrowed_account_checked_add_lamports( fd_borrowed_account_t * borrowed_acct, ulong lamports ) { ulong balance_post = 0UL; - int err = fd_ulong_checked_add( fd_txn_account_get_lamports( borrowed_acct->acct ), + int err = fd_ulong_checked_add( borrowed_acct->meta->lamports, lamports, &balance_post ); if( FD_UNLIKELY( err ) ) { @@ -238,7 +230,7 @@ static inline int fd_borrowed_account_checked_sub_lamports( fd_borrowed_account_t * borrowed_acct, ulong lamports ) { ulong balance_post = 0UL; - int err = fd_ulong_checked_sub( fd_txn_account_get_lamports( borrowed_acct->acct ), + int err = fd_ulong_checked_sub( borrowed_acct->meta->lamports, lamports, &balance_post ); if( FD_UNLIKELY( err ) ) { @@ -255,8 +247,8 @@ fd_borrowed_account_checked_sub_lamports( fd_borrowed_account_t * borrowed_acct, int fd_borrowed_account_update_accounts_resize_delta( fd_borrowed_account_t * borrowed_acct, - ulong new_len, - int * err ); + ulong new_len, + int * err ); /* Accessors */ @@ -269,14 +261,13 @@ fd_borrowed_account_update_accounts_resize_delta( fd_borrowed_account_t * borrow static inline int fd_borrowed_account_is_rent_exempt_at_data_length( fd_borrowed_account_t const * borrowed_acct ) { - fd_txn_account_t * acct = borrowed_acct->acct; - if( FD_UNLIKELY( !fd_txn_account_get_meta( acct ) ) ) FD_LOG_ERR(( "account is not setup" )); + if( FD_UNLIKELY( !borrowed_acct->meta ) ) FD_LOG_ERR(( "account is not setup" )); /* TODO: Add an is_exempt rent API to better match Agave and clean up code https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L990 */ fd_rent_t const * rent = fd_bank_rent_query( borrowed_acct->instr_ctx->bank ); - ulong min_balance = fd_rent_exempt_minimum_balance( rent, fd_txn_account_get_data_len( acct ) ); - return fd_txn_account_get_lamports( acct )>=min_balance; + ulong min_balance = fd_rent_exempt_minimum_balance( rent, borrowed_acct->meta->dlen ); + return borrowed_acct->meta->lamports>=min_balance; } /* fd_borrowed_account_is_executable mirrors Agave function @@ -289,7 +280,7 @@ fd_borrowed_account_is_rent_exempt_at_data_length( fd_borrowed_account_t const * FD_FN_PURE static inline int fd_borrowed_account_is_executable( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_is_executable( borrowed_acct->acct ); + return borrowed_acct->meta->executable; } /* fd_borrowed_account_is_executable_internal is a private function for deprecating the `is_executable` flag. @@ -305,11 +296,6 @@ fd_borrowed_account_is_executable_internal( fd_borrowed_account_t const * borrow fd_borrowed_account_is_executable( borrowed_acct ); } -FD_FN_PURE static inline int -fd_borrowed_account_is_mutable( fd_borrowed_account_t const * borrowed_acct ) { - return fd_txn_account_is_mutable( borrowed_acct->acct ); -} - /* fd_borrowed_account_is_signer mirrors the Agave function solana_sdk::transaction_context::BorrowedAccount::is_signer. Returns 1 if the account is a signer or is writable and 0 otherwise. @@ -363,8 +349,7 @@ fd_borrowed_account_is_owned_by_current_program( fd_borrowed_account_t const * b return 0; } - return !memcmp( program_id_pubkey->key, - fd_txn_account_get_owner( borrowed_acct->acct ), sizeof(fd_pubkey_t) ); + return !memcmp( program_id_pubkey->key, borrowed_acct->meta->owner, sizeof(fd_pubkey_t) ); } /* fd_borrowed_account_can_data_be changed mirrors Agave function @@ -412,10 +397,9 @@ fd_borrowed_account_can_data_be_resized( fd_borrowed_account_t const * borrowed_ FD_FN_PURE static inline int fd_borrowed_account_is_zeroed( fd_borrowed_account_t const * borrowed_acct ) { - fd_txn_account_t * acct = borrowed_acct->acct; /* TODO: optimize this */ - uchar const * data = fd_txn_account_get_data( acct ); - for( ulong i=0UL; imeta ); + for( ulong i=0UL; imeta->dlen; i++ ) { if( data[i] != 0 ) { return 0; } diff --git a/src/flamenco/runtime/fd_txn_account.c b/src/flamenco/runtime/fd_txn_account.c index 077c470c8f..ca1e7d8ba3 100644 --- a/src/flamenco/runtime/fd_txn_account.c +++ b/src/flamenco/runtime/fd_txn_account.c @@ -400,6 +400,16 @@ fd_txn_account_clear_owner( fd_txn_account_t * acct ) { fd_memset( acct->meta->owner, 0, sizeof(fd_pubkey_t) ); } +void +fd_account_meta_resize( fd_account_meta_t * meta, + ulong dlen ) { + ulong old_sz = meta->dlen; + ulong new_sz = dlen; + ulong memset_sz = fd_ulong_sat_sub( new_sz, old_sz ); + fd_memset( fd_account_data( meta ) + old_sz, 0, memset_sz ); + meta->dlen = (uint)dlen; +} + void fd_txn_account_resize( fd_txn_account_t * acct, ulong dlen ) { diff --git a/src/flamenco/runtime/fd_txn_account.h b/src/flamenco/runtime/fd_txn_account.h index fbe6658db1..b95e86fad4 100644 --- a/src/flamenco/runtime/fd_txn_account.h +++ b/src/flamenco/runtime/fd_txn_account.h @@ -206,6 +206,10 @@ fd_txn_account_set_mutable( fd_txn_account_t * acct ); int fd_account_meta_checked_sub_lamports( fd_account_meta_t * meta, ulong lamports ); +void +fd_account_meta_resize( fd_account_meta_t * meta, + ulong dlen ); + FD_PROTOTYPES_END #endif /* HEADER_fd_src_flamenco_runtime_fd_txn_account_h */ diff --git a/src/flamenco/runtime/program/fd_address_lookup_table_program.c b/src/flamenco/runtime/program/fd_address_lookup_table_program.c index ff8222d8ce..9612ccf01f 100644 --- a/src/flamenco/runtime/program/fd_address_lookup_table_program.c +++ b/src/flamenco/runtime/program/fd_address_lookup_table_program.c @@ -822,7 +822,7 @@ deactivate_lookup_table( fd_exec_instr_ctx_t * ctx ) { fd_guarded_borrowed_account_t authority_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_AUTHORITY, &authority_acct ); - authority_key = authority_acct.acct->pubkey; + authority_key = authority_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L356-L359 */ if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_AUTHORITY, NULL ) ) ) { @@ -930,7 +930,7 @@ close_lookup_table( fd_exec_instr_ctx_t * ctx ) { fd_guarded_borrowed_account_t authority_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_AUTHORITY, &authority_acct ); - authority_key = authority_acct.acct->pubkey; + authority_key = authority_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L405-L408 */ if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_AUTHORITY, NULL ) ) ) { diff --git a/src/flamenco/runtime/program/fd_bpf_loader_program.c b/src/flamenco/runtime/program/fd_bpf_loader_program.c index e50d728a6a..0a777f925a 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_program.c +++ b/src/flamenco/runtime/program/fd_bpf_loader_program.c @@ -663,7 +663,7 @@ common_extend_program( fd_exec_instr_ctx_t * instr_ctx, /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/lib.rs#L1379-L1381 */ fd_guarded_borrowed_account_t programdata_account = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, PROGRAM_DATA_ACCOUNT_INDEX, &programdata_account ); - fd_pubkey_t * programdata_key = programdata_account.acct->pubkey; + fd_pubkey_t const * programdata_key = programdata_account.pubkey; /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/lib.rs#L1383-L1386 */ if( FD_UNLIKELY( memcmp( program_id, fd_borrowed_account_get_owner( &programdata_account ), sizeof(fd_pubkey_t) ) ) ) { @@ -695,7 +695,7 @@ common_extend_program( fd_exec_instr_ctx_t * instr_ctx, /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/lib.rs#L1403-L1419 */ fd_bpf_upgradeable_loader_state_t program_state[1]; - err = fd_bpf_loader_program_get_state( program_account.acct, program_state ); + err = fd_bpf_loader_program_get_state_inner( program_account.meta, program_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -733,7 +733,7 @@ common_extend_program( fd_exec_instr_ctx_t * instr_ctx, /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/lib.rs#L1439-L1478 */ fd_pubkey_t * upgrade_authority_address = NULL; fd_bpf_upgradeable_loader_state_t programdata_state[1]; - err = fd_bpf_loader_program_get_state( programdata_account.acct, programdata_state ); + err = fd_bpf_loader_program_get_state_inner( programdata_account.meta, programdata_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -865,7 +865,7 @@ common_extend_program( fd_exec_instr_ctx_t * instr_ctx, ulong programdata_size = new_len - PROGRAMDATA_METADATA_SIZE; /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/lib.rs#L1512-L1522 */ - err = fd_deploy_program( instr_ctx, program_account.acct->pubkey, programdata_data, programdata_size ); + err = fd_deploy_program( instr_ctx, program_account.pubkey, programdata_data, programdata_size ); if( FD_UNLIKELY( err ) ) { return err; } @@ -941,7 +941,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 0UL, &buffer ); fd_bpf_upgradeable_loader_state_t buffer_state[1]; - err = fd_bpf_loader_program_get_state( buffer.acct, buffer_state ); + err = fd_bpf_loader_program_get_state_inner( buffer.meta, buffer_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { return err; } @@ -982,7 +982,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 0UL, &buffer ); fd_bpf_upgradeable_loader_state_t loader_state[1]; - err = fd_bpf_loader_program_get_state( buffer.acct, loader_state ); + err = fd_bpf_loader_program_get_state_inner( buffer.meta, loader_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1082,15 +1082,15 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { /* https://github.com/anza-xyz/agave/blob/574bae8fefc0ed256b55340b9d87b7689bcdf222/programs/bpf_loader/src/lib.rs#L542-L560 */ /* Verify Program account */ - fd_pubkey_t * new_program_id = NULL; - fd_rent_t const * rent = fd_bank_rent_query( instr_ctx->bank ); + fd_pubkey_t const * new_program_id = NULL; + fd_rent_t const * rent = fd_bank_rent_query( instr_ctx->bank ); /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/bpf_loader/src/lib.rs#L545 */ fd_guarded_borrowed_account_t program = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 2UL, &program ); fd_bpf_upgradeable_loader_state_t loader_state[1]; - int err = fd_bpf_loader_program_get_state( program.acct, loader_state ); + int err = fd_bpf_loader_program_get_state_inner( program.meta, loader_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { return err; } @@ -1107,7 +1107,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_log_collector_msg_literal( instr_ctx, "Program account not rent-exempt" ); return FD_EXECUTOR_INSTR_ERR_EXECUTABLE_ACCOUNT_NOT_RENT_EXEMPT; } - new_program_id = program.acct->pubkey; + new_program_id = program.pubkey; /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/bpf_loader/src/lib.rs#L560 */ fd_borrowed_account_drop( &program ); @@ -1115,17 +1115,17 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { /* https://github.com/anza-xyz/agave/blob/574bae8fefc0ed256b55340b9d87b7689bcdf222/programs/bpf_loader/src/lib.rs#L561-L600 */ /* Verify Buffer account */ - fd_pubkey_t * buffer_key = NULL; - ulong buffer_data_offset = 0UL; - ulong buffer_data_len = 0UL; - ulong programdata_len = 0UL; + fd_pubkey_t const* buffer_key = NULL; + ulong buffer_data_offset = 0UL; + ulong buffer_data_len = 0UL; + ulong programdata_len = 0UL; /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/bpf_loader/src/lib.rs#L564-L565 */ fd_guarded_borrowed_account_t buffer = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 3UL, &buffer ); fd_bpf_upgradeable_loader_state_t buffer_state[1]; - err = fd_bpf_loader_program_get_state( buffer.acct, buffer_state ); + err = fd_bpf_loader_program_get_state_inner( buffer.meta, buffer_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1146,7 +1146,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_log_collector_msg_literal( instr_ctx, "Invalid Buffer account" ); return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; } - buffer_key = buffer.acct->pubkey; + buffer_key = buffer.pubkey; buffer_data_offset = BUFFER_METADATA_SIZE; buffer_data_len = fd_ulong_sat_sub( fd_borrowed_account_get_data_len( &buffer ), buffer_data_offset ); /* UpgradeableLoaderState::size_of_program_data( max_data_len ) */ @@ -1280,7 +1280,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { const uchar * buffer_data = fd_borrowed_account_get_data( &buffer ) + buffer_data_offset; - err = fd_deploy_program( instr_ctx, program.acct->pubkey, buffer_data, buffer_data_len ); + err = fd_deploy_program( instr_ctx, program.pubkey, buffer_data, buffer_data_len ); if( FD_UNLIKELY( err ) ) { return err; } @@ -1363,7 +1363,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { return err; } - FD_LOG_INFO(( "Program deployed %s", FD_BASE58_ENC_32_ALLOCA( program.acct->pubkey ) )); + FD_LOG_INFO(( "Program deployed %s", FD_BASE58_ENC_32_ALLOCA( program.pubkey ) )); /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/bpf_loader/src/lib.rs#L700 */ fd_borrowed_account_drop( &program ); @@ -1427,7 +1427,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID; } fd_bpf_upgradeable_loader_state_t program_state[1]; - err = fd_bpf_loader_program_get_state( program.acct, program_state ); + err = fd_bpf_loader_program_get_state_inner( program.meta, program_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1456,7 +1456,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 2UL, &buffer ); fd_bpf_upgradeable_loader_state_t buffer_state[1]; - err = fd_bpf_loader_program_get_state( buffer.acct, buffer_state ); + err = fd_bpf_loader_program_get_state_inner( buffer.meta, buffer_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1560,7 +1560,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { } const uchar * buffer_data = fd_borrowed_account_get_data( &buffer ) + buffer_data_offset; - err = fd_deploy_program( instr_ctx, program.acct->pubkey, buffer_data, buffer_data_len ); + err = fd_deploy_program( instr_ctx, program.pubkey, buffer_data, buffer_data_len ); if( FD_UNLIKELY( err ) ) { return err; } diff --git a/src/flamenco/runtime/program/fd_bpf_loader_serialization.c b/src/flamenco/runtime/program/fd_bpf_loader_serialization.c index 8a0c0076ed..1ead99b460 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_serialization.c +++ b/src/flamenco/runtime/program/fd_bpf_loader_serialization.c @@ -162,7 +162,7 @@ write_account( fd_borrowed_account_t * account, ulong dlen = account ? fd_borrowed_account_get_data_len( account ) : 0UL; acc_region_metas[instr_acc_idx].original_data_len = dlen; - acc_region_metas[instr_acc_idx].acct = account->acct; + acc_region_metas[instr_acc_idx].meta = account->meta; /* Legacy behavior: no stricter_abi_and_runtime_constraints (also implies no direct mapping) https://github.com/anza-xyz/agave/blob/v3.0.0/program-runtime/src/serialization.rs#L131-L140 */ diff --git a/src/flamenco/runtime/program/fd_config_program.c b/src/flamenco/runtime/program/fd_config_program.c index 090527e1ed..31ba1d5c3b 100644 --- a/src/flamenco/runtime/program/fd_config_program.c +++ b/src/flamenco/runtime/program/fd_config_program.c @@ -57,7 +57,7 @@ _process_config_instr( fd_exec_instr_ctx_t * ctx ) { fd_guarded_borrowed_account_t config_acc_rec = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_CONFIG, &config_acc_rec ); - config_account_key = config_acc_rec.acct->pubkey; + config_account_key = config_acc_rec.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.17/programs/config/src/config_processor.rs#L27 */ @@ -148,7 +148,7 @@ _process_config_instr( fd_exec_instr_ctx_t * ctx ) { /* https://github.com/solana-labs/solana/blob/v1.17.17/programs/config/src/config_processor.rs#L80-L87 */ - if( FD_UNLIKELY( 0!=memcmp( signer_account.acct->pubkey, signer, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( 0!=memcmp( signer_account.pubkey, signer, sizeof(fd_pubkey_t) ) ) ) { /* Max msg_sz: 53 - 3 + 20 = 70 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, "account[%lu].signer_key() does not match Config data)", counter+1 ); diff --git a/src/flamenco/runtime/program/fd_stake_program.c b/src/flamenco/runtime/program/fd_stake_program.c index 5c9c9e7dc0..ef2fef9d1d 100644 --- a/src/flamenco/runtime/program/fd_stake_program.c +++ b/src/flamenco/runtime/program/fd_stake_program.c @@ -142,13 +142,13 @@ typedef struct effective_activating effective_activating_t; /**********************************************************************/ static int -get_state( fd_txn_account_t const * self, - fd_stake_state_v2_t * out ) { +get_state( fd_account_meta_t const * meta, + fd_stake_state_v2_t * out ) { int rc; fd_bincode_decode_ctx_t bincode_ctx = { - .data = fd_txn_account_get_data( self ), - .dataend = fd_txn_account_get_data( self ) + fd_txn_account_get_data_len( self ), + .data = fd_account_data( meta ), + .dataend = fd_account_data( meta ) + meta->dlen, }; ulong total_sz = 0UL; diff --git a/src/flamenco/runtime/program/fd_vote_program.c b/src/flamenco/runtime/program/fd_vote_program.c index 2ff36f0a80..2a9043009c 100644 --- a/src/flamenco/runtime/program/fd_vote_program.c +++ b/src/flamenco/runtime/program/fd_vote_program.c @@ -145,12 +145,12 @@ from_vote_state_1_14_11( fd_vote_state_t * vote_state, /* https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L1074 */ static int -get_state( fd_txn_account_t const * self, - uchar * res ) { +get_state( fd_account_meta_t const * meta, + uchar * res ) { fd_bincode_decode_ctx_t decode = { - .data = fd_txn_account_get_data( self ), - .dataend = fd_txn_account_get_data( self ) + fd_txn_account_get_data_len( self ), + .data = fd_account_data( meta ), + .dataend = fd_account_data( meta ) + meta->dlen, }; ulong total_sz = 0UL; @@ -1462,7 +1462,7 @@ authorize( fd_borrowed_account_t * vote_account, // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L857 - rc = get_state( vote_account->acct, ctx->runtime->vote_program.authorize.vote_state_mem ); + rc = get_state( vote_account->meta, ctx->runtime->vote_program.authorize.vote_state_mem ); if( FD_UNLIKELY( rc ) ) return rc; fd_vote_state_versioned_t * vote_state_versioned = (fd_vote_state_versioned_t *)ctx->runtime->vote_program.authorize.vote_state_mem; @@ -1525,7 +1525,7 @@ update_validator_identity( fd_borrowed_account_t * vote_account, int rc = 0; // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L900 - rc = get_state( vote_account->acct, ctx->runtime->vote_program.update_validator_identity.vote_state_mem ); + rc = get_state( vote_account->meta, ctx->runtime->vote_program.update_validator_identity.vote_state_mem ); if( FD_UNLIKELY( rc ) ) return rc; fd_vote_state_versioned_t * vote_state_versioned = (fd_vote_state_versioned_t *)ctx->runtime->vote_program.update_validator_identity.vote_state_mem; convert_to_current( vote_state_versioned, @@ -1577,7 +1577,7 @@ update_commission( fd_borrowed_account_t * vote_account, // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L927 int enforce_commission_update_rule = 1; - rc = get_state( vote_account->acct, ctx->runtime->vote_program.update_commission.vote_state_mem ); + rc = get_state( vote_account->meta, ctx->runtime->vote_program.update_commission.vote_state_mem ); if( FD_LIKELY( rc==FD_EXECUTOR_INSTR_SUCCESS ) ) { vote_state_versioned = (fd_vote_state_versioned_t *)ctx->runtime->vote_program.update_commission.vote_state_mem; convert_to_current( vote_state_versioned, @@ -1597,7 +1597,7 @@ update_commission( fd_borrowed_account_t * vote_account, // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L949 if( !vote_state ) { - rc = get_state( vote_account->acct, ctx->runtime->vote_program.update_commission.vote_state_mem ); + rc = get_state( vote_account->meta, ctx->runtime->vote_program.update_commission.vote_state_mem ); if( FD_UNLIKELY( rc ) ) return rc; vote_state_versioned = (fd_vote_state_versioned_t *)ctx->runtime->vote_program.update_commission.vote_state_mem; convert_to_current( vote_state_versioned, @@ -1629,7 +1629,7 @@ withdraw( fd_exec_instr_ctx_t const * ctx, int rc = 0; // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L1010 - rc = get_state( vote_account->acct, ctx->runtime->vote_program.withdraw.vote_state_mem ); + rc = get_state( vote_account->meta, ctx->runtime->vote_program.withdraw.vote_state_mem ); if( FD_UNLIKELY( rc ) ) return rc; fd_vote_state_versioned_t * vote_state_versioned = (fd_vote_state_versioned_t *)ctx->runtime->vote_program.withdraw.vote_state_mem; @@ -1804,7 +1804,7 @@ initialize_account( fd_borrowed_account_t * vote_account, } // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L1074 - rc = get_state( vote_account->acct, ctx->runtime->vote_program.init_account.vote_state_mem ); + rc = get_state( vote_account->meta, ctx->runtime->vote_program.init_account.vote_state_mem ); if( FD_UNLIKELY( rc ) ) return rc; fd_vote_state_versioned_t * versioned = (fd_vote_state_versioned_t *)ctx->runtime->vote_program.init_account.vote_state_mem; @@ -1849,7 +1849,7 @@ verify_and_get_vote_state( fd_borrowed_account_t * vote_account, int rc = 0; // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/vote/src/vote_state/mod.rs#L1091 - rc = get_state( vote_account->acct, vote_state_mem ); + rc = get_state( vote_account->meta, vote_state_mem ); if( FD_UNLIKELY( rc ) ) return rc; fd_vote_state_versioned_t * versioned = (fd_vote_state_versioned_t *)vote_state_mem; @@ -2741,10 +2741,10 @@ fd_vote_state_versions_is_correct_and_initialized( fd_txn_account_t * vote_accou } fd_vote_state_versioned_t * -fd_vote_get_state( fd_txn_account_t const * self, - uchar * mem /* out */ ) { +fd_vote_get_state( fd_account_meta_t const * meta, + uchar * mem /* out */ ) { - int err = get_state( self, mem ); + int err = get_state( meta, mem ); return err ? NULL : (fd_vote_state_versioned_t *)mem; } diff --git a/src/flamenco/runtime/program/fd_vote_program.h b/src/flamenco/runtime/program/fd_vote_program.h index a8d5a618d3..52a8b37c80 100644 --- a/src/flamenco/runtime/program/fd_vote_program.h +++ b/src/flamenco/runtime/program/fd_vote_program.h @@ -55,8 +55,8 @@ fd_vote_state_versions_is_correct_and_initialized( fd_txn_account_t * vote_accou https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L965 */ fd_vote_state_versioned_t * -fd_vote_get_state( fd_txn_account_t const * self, - uchar * mem ); +fd_vote_get_state( fd_account_meta_t const * meta, + uchar * mem ); void fd_vote_convert_to_current( fd_vote_state_versioned_t * self, diff --git a/src/flamenco/runtime/program/zksdk/fd_zksdk.c b/src/flamenco/runtime/program/zksdk/fd_zksdk.c index cb7bbfa62c..e327e35305 100644 --- a/src/flamenco/runtime/program/zksdk/fd_zksdk.c +++ b/src/flamenco/runtime/program/zksdk/fd_zksdk.c @@ -26,7 +26,7 @@ fd_zksdk_process_close_context_state( fd_exec_instr_ctx_t * ctx ) { } FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_OWNER, &owner_acc ); - *owner_pubkey = *owner_acc.acct->pubkey; + *owner_pubkey = *owner_acc.pubkey; /* implicit drop of borrowed owner_acc */ } while (0); @@ -37,13 +37,13 @@ fd_zksdk_process_close_context_state( fd_exec_instr_ctx_t * ctx ) { /* Obtain the proof account pubkey by borrowing the proof account. https://github.com/anza-xyz/agave/blob/master/programs/zk-elgamal-proof/src/lib.rs#L143-L145 */ FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK(ctx, ACC_IDX_PROOF, &proof_acc ); - *proof_pubkey = *proof_acc.acct->pubkey; + *proof_pubkey = *proof_acc.pubkey; fd_borrowed_account_drop( &proof_acc ); /* Obtain the dest account pubkey by borrowing the dest account. https://github.com/anza-xyz/agave/blob/master/programs/zk-elgamal-proof/src/lib.rs#L146-L148*/ FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_DEST, &dest_acc ); - *dest_pubkey = *dest_acc.acct->pubkey; + *dest_pubkey = *dest_acc.pubkey; fd_borrowed_account_drop( &dest_acc ); if( FD_UNLIKELY( fd_memeq( proof_pubkey, dest_pubkey, sizeof(fd_pubkey_t) ) ) ) { @@ -237,7 +237,7 @@ fd_zksdk_process_verify_proof( fd_exec_instr_ctx_t * ctx ) { do { fd_guarded_borrowed_account_t _acc = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, (ushort)(accessed_accounts+1), &_acc ); - *context_state_authority = *_acc.acct->pubkey; + *context_state_authority = *_acc.pubkey; } while(0); /* Borrow the proof context account diff --git a/src/flamenco/vm/fd_vm.h b/src/flamenco/vm/fd_vm.h index c6a1026ded..fe67a352f8 100644 --- a/src/flamenco/vm/fd_vm.h +++ b/src/flamenco/vm/fd_vm.h @@ -44,7 +44,7 @@ struct __attribute((aligned(8UL))) fd_vm_acc_region_meta { original data len. */ ulong original_data_len; /* The transaction account corresponding to this account. */ - fd_txn_account_t * acct; + fd_account_meta_t * meta; /* The expected virtual offsets of the serialized pubkey, lamports and owner for the account corresponding to this region. Relative to the start of the account's input region vaddr. diff --git a/src/flamenco/vm/fd_vm_private.h b/src/flamenco/vm/fd_vm_private.h index 64c54e3675..da638ad9cf 100644 --- a/src/flamenco/vm/fd_vm_private.h +++ b/src/flamenco/vm/fd_vm_private.h @@ -370,7 +370,7 @@ fd_vm_handle_input_mem_region_oob( fd_vm_t const * vm, fd_ulong_sat_add( vm->instr_ctx->txn_out->details.accounts_resize_delta, new_region_sz ), region->region_sz ); - fd_txn_account_resize( vm->acc_region_metas[ region->acc_region_meta_idx ].acct, new_region_sz ); + fd_txn_account_resize( vm->acc_region_metas[ region->acc_region_meta_idx ].meta, new_region_sz ); region->region_sz = (uint)new_region_sz; } } diff --git a/src/flamenco/vm/syscall/fd_vm_syscall_cpi_common.c b/src/flamenco/vm/syscall/fd_vm_syscall_cpi_common.c index 0d07044206..d99cd61337 100644 --- a/src/flamenco/vm/syscall/fd_vm_syscall_cpi_common.c +++ b/src/flamenco/vm/syscall/fd_vm_syscall_cpi_common.c @@ -286,7 +286,7 @@ VM_SYSCALL_CPI_TRANSLATE_AND_UPDATE_ACCOUNTS_FUNC( fd_guarded_borrowed_account_t callee_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( vm->instr_ctx, instruction_accounts[i].index_in_caller, &callee_acct ); - fd_pubkey_t const * account_key = callee_acct.acct->pubkey; + fd_pubkey_t const * account_key = callee_acct.pubkey; fd_account_meta_t const * acc_meta = fd_borrowed_account_get_acc_meta( &callee_acct ); /* If the account is known and executable, we only need to consume the compute units. @@ -540,21 +540,21 @@ VM_SYSCALL_CPI_UPDATE_CALLER_ACC_FUNC( fd_vm_t * vm, return 1; } - fd_txn_account_t * callee_acc = borrowed_callee_acc.acct; + fd_account_meta_t * callee_meta = borrowed_callee_acc.meta; /* Update the caller account lamports with the value from the callee https://github.com/anza-xyz/agave/blob/v3.0.4/syscalls/src/cpi.rs#L1191 */ - *(caller_account->lamports) = fd_txn_account_get_lamports( callee_acc ); + *(caller_account->lamports) = callee_meta->lamports; /* Update the caller account owner with the value from the callee https://github.com/anza-xyz/agave/blob/v3.0.4/syscalls/src/cpi.rs#L1192 */ - fd_pubkey_t const * updated_owner = fd_txn_account_get_owner( callee_acc ); + fd_pubkey_t const * updated_owner = (fd_pubkey_t const *)callee_meta->owner; if( updated_owner ) *caller_account->owner = *updated_owner; else fd_memset( caller_account->owner, 0, sizeof(fd_pubkey_t) ); /* Update the caller account data with the value from the callee https://github.com/anza-xyz/agave/blob/v3.0.4/syscalls/src/cpi.rs#L1194-L1195 */ ulong prev_len = *caller_account->ref_to_len_in_vm; - ulong post_len = fd_txn_account_get_data_len( callee_acc ); + ulong post_len = callee_meta->dlen; /* Calculate the address space reserved for the account. With stricter_abi_and_runtime_constraints and deprecated loader, the reserved space equals original length (no realloc space). @@ -637,7 +637,7 @@ VM_SYSCALL_CPI_UPDATE_CALLER_ACC_FUNC( fd_vm_t * vm, https://github.com/anza-xyz/agave/blob/v3.0.4/syscalls/src/cpi.rs#L1254-L1265 */ if( !(vm->stricter_abi_and_runtime_constraints && vm->direct_mapping) ) { - fd_memcpy( caller_account->serialized_data, fd_txn_account_get_data( callee_acc ), post_len ); + fd_memcpy( caller_account->serialized_data, fd_account_data( callee_meta ), post_len ); } From 0809ace77083d205fe1c4bb8ca8be952bf69659d Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Mon, 24 Nov 2025 21:09:40 +0000 Subject: [PATCH 16/32] wip --- src/flamenco/progcache/fd_prog_load.c | 2 +- src/flamenco/runtime/fd_borrowed_account.c | 43 ++++++++----------- .../program/fd_address_lookup_table_program.c | 16 +++---- .../runtime/program/fd_bpf_loader_program.c | 18 ++++---- .../runtime/program/fd_loader_v4_program.c | 18 ++++---- .../runtime/program/fd_loader_v4_program.h | 4 +- .../runtime/program/fd_stake_program.c | 42 +++++++++--------- .../runtime/program/fd_system_program.c | 16 +++---- .../runtime/program/fd_system_program_nonce.c | 16 +++---- src/flamenco/vm/fd_vm_private.h | 2 +- src/flamenco/vm/syscall/fd_vm_syscall_cpi.c | 6 +-- 11 files changed, 88 insertions(+), 95 deletions(-) diff --git a/src/flamenco/progcache/fd_prog_load.c b/src/flamenco/progcache/fd_prog_load.c index 9750b18ff4..2e4c948d93 100644 --- a/src/flamenco/progcache/fd_prog_load.c +++ b/src/flamenco/progcache/fd_prog_load.c @@ -17,7 +17,7 @@ fd_get_executable_program_content_for_v4_loader( fd_txn_account_t const * progra int err; /* Get the current loader v4 state. This implicitly also checks the dlen. */ - fd_loader_v4_state_t const * state = fd_loader_v4_get_state( program_acc, &err ); + fd_loader_v4_state_t const * state = fd_loader_v4_get_state( program_acc->meta, &err ); if( FD_UNLIKELY( err ) ) { return NULL; } diff --git a/src/flamenco/runtime/fd_borrowed_account.c b/src/flamenco/runtime/fd_borrowed_account.c index a1a10ce3c6..1a2c671558 100644 --- a/src/flamenco/runtime/fd_borrowed_account.c +++ b/src/flamenco/runtime/fd_borrowed_account.c @@ -4,7 +4,6 @@ int fd_borrowed_account_get_data_mut( fd_borrowed_account_t * borrowed_acct, uchar * * data_out, ulong * dlen_out ) { - fd_txn_account_t * acct = borrowed_acct->acct; /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L824 */ int err; @@ -14,9 +13,9 @@ fd_borrowed_account_get_data_mut( fd_borrowed_account_t * borrowed_acct, } if ( data_out != NULL ) - *data_out = fd_txn_account_get_data_mut( acct ); + *data_out = fd_account_data( borrowed_acct->meta ); if ( dlen_out != NULL ) - *dlen_out = fd_txn_account_get_data_len( acct ); + *dlen_out = borrowed_acct->meta->dlen; return FD_EXECUTOR_INSTR_SUCCESS; } @@ -24,7 +23,6 @@ fd_borrowed_account_get_data_mut( fd_borrowed_account_t * borrowed_acct, int fd_borrowed_account_set_owner( fd_borrowed_account_t * borrowed_acct, fd_pubkey_t const * owner ) { - fd_txn_account_t * acct = borrowed_acct->acct; /* Only the owner can assign a new owner https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L741 */ @@ -52,7 +50,7 @@ fd_borrowed_account_set_owner( fd_borrowed_account_t * borrowed_acct, /* Don't copy the account if the owner does not change https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L757 */ - if( !memcmp( fd_txn_account_get_owner( acct ), owner, sizeof(fd_pubkey_t) ) ) { + if( !memcmp( borrowed_acct->meta->owner, owner, sizeof(fd_pubkey_t) ) ) { return FD_EXECUTOR_INSTR_SUCCESS; } @@ -60,7 +58,7 @@ fd_borrowed_account_set_owner( fd_borrowed_account_t * borrowed_acct, /* Copy into owner https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L761 */ - fd_txn_account_set_owner( acct, owner ); + fd_memcpy( borrowed_acct->meta->owner, owner, sizeof(fd_pubkey_t) ); return FD_EXECUTOR_INSTR_SUCCESS; } @@ -69,12 +67,11 @@ fd_borrowed_account_set_owner( fd_borrowed_account_t * borrowed_acct, int fd_borrowed_account_set_lamports( fd_borrowed_account_t * borrowed_acct, ulong lamports ) { - fd_txn_account_t * acct = borrowed_acct->acct; /* An account not owned by the program cannot have its blanace decrease https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L775 */ if( FD_UNLIKELY( (!fd_borrowed_account_is_owned_by_current_program( borrowed_acct )) && - (lamportsmeta->lamports) ) ) { return FD_EXECUTOR_INSTR_ERR_EXTERNAL_ACCOUNT_LAMPORT_SPEND; } @@ -92,13 +89,13 @@ fd_borrowed_account_set_lamports( fd_borrowed_account_t * borrowed_acct, /* Don't copy the account if the lamports do not change https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L787 */ - if( fd_txn_account_get_lamports( acct )==lamports ) { + if( borrowed_acct->meta->lamports==lamports ) { return FD_EXECUTOR_INSTR_SUCCESS; } /* Agave self.touch() is a no-op */ - fd_txn_account_set_lamports( acct, lamports ); + borrowed_acct->meta->lamports = lamports; return FD_EXECUTOR_INSTR_SUCCESS; } @@ -106,7 +103,6 @@ int fd_borrowed_account_set_data_from_slice( fd_borrowed_account_t * borrowed_acct, uchar const * data, ulong data_sz ) { - fd_txn_account_t * acct = borrowed_acct->acct; /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L865 */ int err; @@ -127,7 +123,8 @@ fd_borrowed_account_set_data_from_slice( fd_borrowed_account_t * borrowed_acct, } /* AccountSharedData::set_data_from_slice() */ - fd_txn_account_set_data( acct, data, data_sz ); + borrowed_acct->meta->dlen = (uint)data_sz; + fd_memcpy( fd_account_data( borrowed_acct->meta ), data, data_sz ); return FD_EXECUTOR_INSTR_SUCCESS; } @@ -135,8 +132,7 @@ fd_borrowed_account_set_data_from_slice( fd_borrowed_account_t * borrowed_acct, int fd_borrowed_account_set_data_length( fd_borrowed_account_t * borrowed_acct, ulong new_len ) { - fd_txn_account_t * acct = borrowed_acct->acct; - int err = FD_EXECUTOR_INSTR_SUCCESS; + int err = FD_EXECUTOR_INSTR_SUCCESS; /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L883 */ if( FD_UNLIKELY( !fd_borrowed_account_can_data_be_resized( borrowed_acct, new_len, &err ) ) ) { @@ -148,7 +144,7 @@ fd_borrowed_account_set_data_length( fd_borrowed_account_t * borrowed_acct, return err; } - ulong old_len = fd_txn_account_get_data_len( acct ); + ulong old_len = borrowed_acct->meta->dlen; /* Don't copy the account if the length does not change https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L886 */ @@ -165,19 +161,18 @@ fd_borrowed_account_set_data_length( fd_borrowed_account_t * borrowed_acct, /* Resize the account https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L891 */ - fd_txn_account_resize( acct, new_len ); + fd_account_meta_resize( borrowed_acct->meta, new_len ); + return FD_EXECUTOR_INSTR_SUCCESS; } int fd_borrowed_account_set_executable( fd_borrowed_account_t * borrowed_acct, int is_executable ) { - fd_txn_account_t * acct = borrowed_acct->acct; - /* To become executable an account must be rent exempt https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1003-L1006 */ fd_rent_t const * rent = fd_bank_rent_query( borrowed_acct->instr_ctx->bank ); - if( FD_UNLIKELY( fd_txn_account_get_lamports( acct )meta->lamportsmeta->dlen ) ) ) { return FD_EXECUTOR_INSTR_ERR_EXECUTABLE_ACCOUNT_NOT_RENT_EXEMPT; } @@ -208,7 +203,7 @@ fd_borrowed_account_set_executable( fd_borrowed_account_t * borrowed_acct, /* Agave self.touch() is a no-op */ /* https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1027 */ - fd_txn_account_set_executable( acct, is_executable ); + borrowed_acct->meta->executable = !!is_executable; return FD_EXECUTOR_INSTR_SUCCESS; } @@ -218,8 +213,7 @@ fd_borrowed_account_update_accounts_resize_delta( fd_borrowed_account_t * borrow ulong new_len, int * err ) { fd_exec_instr_ctx_t const * instr_ctx = borrowed_acct->instr_ctx; - fd_txn_account_t * acct = borrowed_acct->acct; - ulong size_delta = fd_ulong_sat_sub( new_len, fd_txn_account_get_data_len( acct ) ); + ulong size_delta = fd_ulong_sat_sub( new_len, borrowed_acct->meta->dlen ); /* TODO: The size delta should never exceed the value of ULONG_MAX so this could be replaced with a normal addition. However to match execution with @@ -233,11 +227,10 @@ int fd_borrowed_account_can_data_be_resized( fd_borrowed_account_t const * borrowed_acct, ulong new_length, int * err ) { - fd_txn_account_t * acct = borrowed_acct->acct; /* Only the owner can change the length of the data https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1095 */ - if( FD_UNLIKELY( (fd_txn_account_get_data_len( acct )!=new_length) & + if( FD_UNLIKELY( (borrowed_acct->meta->dlen!=new_length) & (!fd_borrowed_account_is_owned_by_current_program( borrowed_acct )) ) ) { *err = FD_EXECUTOR_INSTR_ERR_ACC_DATA_SIZE_CHANGED; return 0; @@ -252,7 +245,7 @@ fd_borrowed_account_can_data_be_resized( fd_borrowed_account_t const * borrowed_ /* The resize can not exceed the per-transaction maximum https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L1104-L1108 */ - ulong length_delta = fd_ulong_sat_sub( new_length, fd_txn_account_get_data_len( acct ) ); + ulong length_delta = fd_ulong_sat_sub( new_length, borrowed_acct->meta->dlen ); ulong new_accounts_resize_delta = fd_ulong_sat_add( borrowed_acct->instr_ctx->txn_out->details.accounts_resize_delta, length_delta ); if( FD_UNLIKELY( new_accounts_resize_delta > MAX_PERMITTED_ACCOUNT_DATA_ALLOCS_PER_TXN ) ) { *err = FD_EXECUTOR_INSTR_ERR_MAX_ACCS_DATA_ALLOCS_EXCEEDED; diff --git a/src/flamenco/runtime/program/fd_address_lookup_table_program.c b/src/flamenco/runtime/program/fd_address_lookup_table_program.c index 9612ccf01f..6dc042a0d5 100644 --- a/src/flamenco/runtime/program/fd_address_lookup_table_program.c +++ b/src/flamenco/runtime/program/fd_address_lookup_table_program.c @@ -211,7 +211,7 @@ create_lookup_table( fd_exec_instr_ctx_t * ctx, /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L60-L62 */ lut_lamports = fd_borrowed_account_get_lamports( &lut_acct ); - lut_key = lut_acct.acct->pubkey; + lut_key = lut_acct.pubkey; lut_owner = fd_borrowed_account_get_owner( &lut_acct ); /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L63-L70 */ @@ -232,7 +232,7 @@ create_lookup_table( fd_exec_instr_ctx_t * ctx, /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L75 */ - authority_key = authority_acct.acct->pubkey; + authority_key = authority_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L76-L83 */ if( !FD_FEATURE_ACTIVE_BANK( ctx->bank, relax_authority_signer_check_for_lookup_table_creation ) @@ -250,7 +250,7 @@ create_lookup_table( fd_exec_instr_ctx_t * ctx, fd_guarded_borrowed_account_t payer_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_PAYER, &payer_acct ); - payer_key = payer_acct.acct->pubkey; + payer_key = payer_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L89-L92 */ if( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_PAYER, NULL ) ) { @@ -494,7 +494,7 @@ freeze_lookup_table( fd_exec_instr_ctx_t * ctx ) { fd_guarded_borrowed_account_t authority_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_AUTHORITY, &authority_acct ); - authority_key = authority_acct.acct->pubkey; + authority_key = authority_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L186-L189 */ if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_AUTHORITY, NULL ) ) ) { @@ -585,7 +585,7 @@ extend_lookup_table( fd_exec_instr_ctx_t * ctx, fd_guarded_borrowed_account_t lut_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_LUT, &lut_acct ); - lut_key = lut_acct.acct->pubkey; + lut_key = lut_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L233-235 */ if( FD_UNLIKELY( 0!=memcmp( fd_borrowed_account_get_owner( &lut_acct ), fd_solana_address_lookup_table_program_id.key, sizeof(fd_pubkey_t) ) ) ) @@ -602,7 +602,7 @@ extend_lookup_table( fd_exec_instr_ctx_t * ctx, fd_guarded_borrowed_account_t authority_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_AUTHORITY, &authority_acct ); - authority_key = authority_acct.acct->pubkey; + authority_key = authority_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L241-L244 */ if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_AUTHORITY, NULL ) ) ) { @@ -697,7 +697,7 @@ extend_lookup_table( fd_exec_instr_ctx_t * ctx, if( FD_UNLIKELY( err ) ) { return err; } - fd_txn_account_resize( lut_acct.acct, new_table_data_sz ); + fd_account_meta_resize( lut_acct.meta, new_table_data_sz ); /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L307-L310 */ err = fd_addrlut_serialize_meta( &lut->state, lut_data_mut, lut_data_mut_len ); @@ -732,7 +732,7 @@ extend_lookup_table( fd_exec_instr_ctx_t * ctx, fd_guarded_borrowed_account_t payer_acct = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_PAYER, &payer_acct ); - payer_key = payer_acct.acct->pubkey; + payer_key = payer_acct.pubkey; /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L327-L330 */ if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_PAYER, NULL ) ) ) { fd_log_collector_msg_literal( ctx, "Payer account must be a signer" ); diff --git a/src/flamenco/runtime/program/fd_bpf_loader_program.c b/src/flamenco/runtime/program/fd_bpf_loader_program.c index 0a777f925a..164da5ae40 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_program.c +++ b/src/flamenco/runtime/program/fd_bpf_loader_program.c @@ -1511,7 +1511,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { } fd_bpf_upgradeable_loader_state_t programdata_state[1]; - err = fd_bpf_loader_program_get_state( programdata.acct, programdata_state ); + err = fd_bpf_loader_program_get_state_inner( programdata.meta, programdata_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1678,7 +1678,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_exec_instr_ctx_get_key_of_account_at_index( instr_ctx, 2UL, &new_authority ); fd_bpf_upgradeable_loader_state_t account_state[1]; - err = fd_bpf_loader_program_get_state( account.acct, account_state ); + err = fd_bpf_loader_program_get_state_inner( account.meta, account_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { return err; } @@ -1783,7 +1783,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { if( FD_UNLIKELY( err ) ) return err; fd_bpf_upgradeable_loader_state_t account_state[1]; - err = fd_bpf_loader_program_get_state( account.acct, account_state ); + err = fd_bpf_loader_program_get_state_inner( account.meta, account_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1879,9 +1879,9 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_guarded_borrowed_account_t close_account = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 0UL, &close_account ); - fd_pubkey_t * close_key = close_account.acct->pubkey; + fd_pubkey_t const * close_key = close_account.pubkey; fd_bpf_upgradeable_loader_state_t close_account_state[1]; - err = fd_bpf_loader_program_get_state( close_account.acct, close_account_state ); + err = fd_bpf_loader_program_get_state_inner( close_account.meta, close_account_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1964,7 +1964,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { } fd_bpf_upgradeable_loader_state_t program_state[1]; - err = fd_bpf_loader_program_get_state( program_account.acct, program_state ); + err = fd_bpf_loader_program_get_state_inner( program_account.meta, program_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -2092,7 +2092,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { ulong program_len = 0UL; fd_pubkey_t * upgrade_authority_address = NULL; fd_bpf_upgradeable_loader_state_t programdata_state[1]; - err = fd_bpf_loader_program_get_state( programdata.acct, programdata_state ); + err = fd_bpf_loader_program_get_state_inner( programdata.meta, programdata_state ); if( FD_LIKELY( err==FD_EXECUTOR_INSTR_SUCCESS && fd_bpf_upgradeable_loader_state_is_program_data( programdata_state ) ) ) { /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/bpf_loader/src/lib.rs#L1374-L1377 */ @@ -2147,7 +2147,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/bpf_loader/src/lib.rs#L1415-L1426 */ fd_bpf_upgradeable_loader_state_t program_state[1]; - err = fd_bpf_loader_program_get_state( program.acct, program_state ); + err = fd_bpf_loader_program_get_state_inner( program.meta, program_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -2496,7 +2496,7 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * ctx ) { if( !memcmp( metadata->owner, &fd_solana_bpf_loader_upgradeable_program_id, sizeof(fd_pubkey_t) ) ) { fd_bpf_upgradeable_loader_state_t program_account_state[1]; - err = fd_bpf_loader_program_get_state( program_account.acct, program_account_state ); + err = fd_bpf_loader_program_get_state_inner( program_account.meta, program_account_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { fd_log_collector_msg_literal( ctx, "Program is not deployed" ); if( FD_FEATURE_ACTIVE_BANK( ctx->bank, remove_accounts_executable_flag_checks ) ) { diff --git a/src/flamenco/runtime/program/fd_loader_v4_program.c b/src/flamenco/runtime/program/fd_loader_v4_program.c index aab2cc4a09..fe81a2a040 100644 --- a/src/flamenco/runtime/program/fd_loader_v4_program.c +++ b/src/flamenco/runtime/program/fd_loader_v4_program.c @@ -62,17 +62,17 @@ fd_loader_v4_get_state_mut( uchar * data, https://github.com/anza-xyz/agave/blob/v2.2.6/programs/loader-v4/src/lib.rs#L32-L44 */ fd_loader_v4_state_t const * -fd_loader_v4_get_state( fd_txn_account_t const * program, - int * err ) { +fd_loader_v4_get_state( fd_account_meta_t const * meta, + int * err ) { *err = FD_EXECUTOR_INSTR_SUCCESS; /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/loader-v4/src/lib.rs#L35-L36 */ - if( FD_UNLIKELY( fd_txn_account_get_data_len( program )dlenacct, err ); + fd_loader_v4_state_t const * state = fd_loader_v4_get_state( program->meta, err ); if( FD_UNLIKELY( *err ) ) { return NULL; } @@ -528,7 +528,7 @@ fd_loader_v4_program_instruction_deploy( fd_exec_instr_ctx_t * instr_ctx ) { invoked until the next slot anyways, doing this is okay. https://github.com/anza-xyz/agave/blob/v2.2.13/programs/loader-v4/src/lib.rs#L309-L316 */ - err = fd_deploy_program( instr_ctx, program.acct->pubkey, programdata, buffer_dlen - LOADER_V4_PROGRAM_DATA_OFFSET ); + err = fd_deploy_program( instr_ctx, program.pubkey, programdata, buffer_dlen - LOADER_V4_PROGRAM_DATA_OFFSET ); if( FD_UNLIKELY( err ) ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; } @@ -752,7 +752,7 @@ fd_loader_v4_program_instruction_finalize( fd_exec_instr_ctx_t * instr_ctx ) { } /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/loader-v4/src/lib.rs#L454 */ - fd_loader_v4_state_t const * state_of_next_version = fd_loader_v4_get_state( next_version.acct, &err ); + fd_loader_v4_state_t const * state_of_next_version = fd_loader_v4_get_state( next_version.meta, &err ); if( FD_UNLIKELY( err ) ) { return err; } @@ -770,7 +770,7 @@ fd_loader_v4_program_instruction_finalize( fd_exec_instr_ctx_t * instr_ctx ) { } /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/loader-v4/src/lib.rs#L463 */ - fd_pubkey_t * address_of_next_version = next_version.acct->pubkey; + fd_pubkey_t const * address_of_next_version = next_version.pubkey; /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/loader-v4/src/lib.rs#L464 */ fd_borrowed_account_drop( &next_version ); @@ -890,7 +890,7 @@ fd_loader_v4_program_execute( fd_exec_instr_ctx_t * instr_ctx ) { Therefore, Firedancer recovers the DelayVisibility and Closed states on-the-fly before querying cahce. */ - fd_loader_v4_state_t const * state = fd_loader_v4_get_state( program.acct, &rc ); + fd_loader_v4_state_t const * state = fd_loader_v4_get_state( program.meta, &rc ); if( FD_UNLIKELY( rc ) ) { fd_log_collector_msg_literal( instr_ctx, "Program is not deployed" ); return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_PROGRAM_ID; diff --git a/src/flamenco/runtime/program/fd_loader_v4_program.h b/src/flamenco/runtime/program/fd_loader_v4_program.h index beac9cee52..f80a6bc19c 100644 --- a/src/flamenco/runtime/program/fd_loader_v4_program.h +++ b/src/flamenco/runtime/program/fd_loader_v4_program.h @@ -69,8 +69,8 @@ FD_FN_PURE uchar fd_loader_v4_status_is_finalized( fd_loader_v4_state_t const * state ); fd_loader_v4_state_t const * -fd_loader_v4_get_state( fd_txn_account_t const * program, - int * err ); +fd_loader_v4_get_state( fd_account_meta_t const * meta, + int * err ); int fd_loader_v4_program_execute( fd_exec_instr_ctx_t * instr_ctx ); diff --git a/src/flamenco/runtime/program/fd_stake_program.c b/src/flamenco/runtime/program/fd_stake_program.c index ef2fef9d1d..5a98b5e721 100644 --- a/src/flamenco/runtime/program/fd_stake_program.c +++ b/src/flamenco/runtime/program/fd_stake_program.c @@ -1277,7 +1277,7 @@ initialize( fd_borrowed_account_t * stake_account, // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L224 fd_stake_state_v2_t stake_state = {0}; do { - int rc = get_state( stake_account->acct, &stake_state ); + int rc = get_state( stake_account->meta, &stake_state ); if( FD_UNLIKELY( rc ) ) return rc; } while(0); @@ -1318,7 +1318,7 @@ authorize( fd_borrowed_account_t * stake_account, int rc; fd_stake_state_v2_t stake_state = {0}; // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L251 - rc = get_state( stake_account->acct, &stake_state ); + rc = get_state( stake_account->meta, &stake_state ); if( FD_UNLIKELY( rc ) ) return rc; switch( stake_state.discriminant ) { /* FIXME check if the compiler can optimize away branching (given the layout of `meta` in both @@ -1426,9 +1426,9 @@ delegate( fd_exec_instr_ctx_t const * ctx, if( FD_UNLIKELY( memcmp( fd_borrowed_account_get_owner( &vote_account ), fd_solana_vote_program_id.key, 32UL ) ) ) return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID; // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L3326 - vote_pubkey = vote_account.acct->pubkey; + vote_pubkey = vote_account.pubkey; // https://github.com/anza-xyz/agave/blob/a60fbc2288d626a4f1846052c8fcb98d3f9ea58d/programs/stake/src/stake_state.rs#L327 - vote_state = fd_vote_get_state( vote_account.acct, ctx->runtime->stake_program.delegate.vote_state_mem ); + vote_state = fd_vote_get_state( vote_account.meta, ctx->runtime->stake_program.delegate.vote_state_mem ); /* https://github.com/anza-xyz/agave/blob/v2.1.14/programs/stake/src/stake_state.rs#L328 */ fd_borrowed_account_drop( &vote_account ); @@ -1438,7 +1438,7 @@ delegate( fd_exec_instr_ctx_t const * ctx, fd_guarded_borrowed_account_t stake_account = {0}; FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, stake_account_index, &stake_account ); - rc = get_state( stake_account.acct, &stake_state ); + rc = get_state( stake_account.meta, &stake_state ); if( FD_UNLIKELY( rc ) ) return rc; // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L332 @@ -1533,7 +1533,7 @@ deactivate( fd_borrowed_account_t * stake_account, int rc; fd_stake_state_v2_t state = {0}; - rc = get_state( stake_account->acct, &state ); + rc = get_state( stake_account->meta, &state ); if( FD_UNLIKELY( rc ) ) return rc; // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L370 @@ -1565,7 +1565,7 @@ set_lockup( fd_borrowed_account_t * stake_account, // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L385 fd_stake_state_v2_t state = {0}; - rc = get_state( stake_account->acct, &state ); + rc = get_state( stake_account->meta, &state ); if( FD_UNLIKELY( rc ) ) return rc; switch( state.discriminant ) { @@ -1613,7 +1613,7 @@ split( fd_exec_instr_ctx_t const * ctx, // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L415 fd_stake_state_v2_t split_get_state = {0}; - rc = get_state( split.acct, &split_get_state ); + rc = get_state( split.meta, &split_get_state ); if( FD_UNLIKELY( rc ) ) return rc; if( FD_UNLIKELY( split_get_state.discriminant!=fd_stake_state_v2_enum_uninitialized ) ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; @@ -1633,7 +1633,7 @@ split( fd_exec_instr_ctx_t const * ctx, if( FD_UNLIKELY( lamports>fd_borrowed_account_get_lamports( &stake_account ) ) ) return FD_EXECUTOR_INSTR_ERR_INSUFFICIENT_FUNDS; - rc = get_state( stake_account.acct, &stake_state ); + rc = get_state( stake_account.meta, &stake_state ); if( FD_UNLIKELY( rc ) ) return rc; /* https://github.com/anza-xyz/agave/blob/v2.1.14/programs/stake/src/stake_state.rs#L426 */ @@ -1870,7 +1870,7 @@ merge( fd_exec_instr_ctx_t * ctx, // not const to log FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, stake_account_index, &stake_account ); fd_stake_state_v2_t stake_account_state = {0}; - rc = get_state( stake_account.acct, &stake_account_state ); + rc = get_state( stake_account.meta, &stake_account_state ); if( FD_UNLIKELY( rc ) ) return rc; merge_kind_t stake_merge_kind = {0}; @@ -1892,7 +1892,7 @@ merge( fd_exec_instr_ctx_t * ctx, // not const to log return rc; fd_stake_state_v2_t source_account_state = {0}; - rc = get_state( source_account.acct, &source_account_state ); + rc = get_state( source_account.meta, &source_account_state ); if( FD_UNLIKELY( rc ) ) return rc; merge_kind_t source_merge_kind = {0}; @@ -1971,7 +1971,7 @@ move_stake_or_lamports_shared_checks( fd_exec_instr_ctx_t * invoke_context, // return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID; // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L163 - if( FD_UNLIKELY( !memcmp( &source_account->acct->pubkey, &destination_account->acct->pubkey, sizeof(fd_pubkey_t) ) ) ) + if( FD_UNLIKELY( !memcmp( source_account->pubkey, destination_account->pubkey, sizeof(fd_pubkey_t) ) ) ) return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA; // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L168 @@ -1993,7 +1993,7 @@ move_stake_or_lamports_shared_checks( fd_exec_instr_ctx_t * invoke_context, // // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L182 fd_stake_state_v2_t source_account_state = {0}; - rc = get_state( source_account->acct, &source_account_state ); + rc = get_state( source_account->meta, &source_account_state ); if( FD_UNLIKELY( rc ) ) return rc; rc = get_if_mergeable( invoke_context, @@ -2011,7 +2011,7 @@ move_stake_or_lamports_shared_checks( fd_exec_instr_ctx_t * invoke_context, // // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L197 fd_stake_state_v2_t destination_account_state = {0}; - rc = get_state( destination_account->acct, &destination_account_state ); + rc = get_state( destination_account->meta, &destination_account_state ); if( FD_UNLIKELY( rc ) ) return rc; rc = get_if_mergeable( invoke_context, @@ -2283,7 +2283,7 @@ withdraw( fd_exec_instr_ctx_t const * ctx, // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L821 fd_stake_state_v2_t stake_state = {0}; - rc = get_state( stake_account.acct, &stake_state ); + rc = get_state( stake_account.meta, &stake_state ); if( FD_UNLIKELY( rc ) ) return rc; fd_stake_lockup_t lockup; @@ -2334,7 +2334,7 @@ withdraw( fd_exec_instr_ctx_t const * ctx, } case fd_stake_state_v2_enum_uninitialized: { // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L846 - if( FD_UNLIKELY( !fd_signers_contains( signers, stake_account.acct->pubkey ) ) ) { + if( FD_UNLIKELY( !fd_signers_contains( signers, stake_account.pubkey ) ) ) { return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE; } // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L850 @@ -2438,7 +2438,7 @@ deactivate_delinquent( fd_exec_instr_ctx_t * ctx, return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID; // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L920-L922 - fd_vote_state_versioned_t * delinquent_vote_state_versioned = fd_vote_get_state( delinquent_vote_account.acct, ctx->runtime->stake_program.deactivate_delinquent.delinquent_vote_state_mem ); + fd_vote_state_versioned_t * delinquent_vote_state_versioned = fd_vote_get_state( delinquent_vote_account.meta, ctx->runtime->stake_program.deactivate_delinquent.delinquent_vote_state_mem ); if( FD_UNLIKELY( !delinquent_vote_state_versioned ) ) return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; fd_vote_convert_to_current( delinquent_vote_state_versioned, ctx->runtime->stake_program.deactivate_delinquent.delinquent_authorized_voters_mem, @@ -2454,7 +2454,7 @@ deactivate_delinquent( fd_exec_instr_ctx_t * ctx, return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID; // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L929-L932 - fd_vote_state_versioned_t * reference_vote_state_versioned = fd_vote_get_state( reference_vote_account.acct, ctx->runtime->stake_program.deactivate_delinquent.reference_vote_state_mem ); + fd_vote_state_versioned_t * reference_vote_state_versioned = fd_vote_get_state( reference_vote_account.meta, ctx->runtime->stake_program.deactivate_delinquent.reference_vote_state_mem ); if( FD_UNLIKELY( !reference_vote_state_versioned ) ) return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; fd_vote_convert_to_current( reference_vote_state_versioned, ctx->runtime->stake_program.deactivate_delinquent.reference_authorized_voters_mem, @@ -2468,7 +2468,7 @@ deactivate_delinquent( fd_exec_instr_ctx_t * ctx, } fd_stake_state_v2_t stake_state = {0}; - rc = get_state( stake_account->acct, &stake_state ); + rc = get_state( stake_account->meta, &stake_state ); if( FD_UNLIKELY( rc ) ) return rc; // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L937 if( FD_LIKELY( stake_state.discriminant==fd_stake_state_v2_enum_stake ) ) { @@ -3289,8 +3289,8 @@ fd_stake_program_config_init( fd_accdb_user_t * accdb, int fd_stake_get_state( fd_txn_account_t const * self, - fd_stake_state_v2_t * out ) { - return get_state( self, out ); + fd_stake_state_v2_t * out ) { + return get_state( self->meta, out ); } fd_stake_history_entry_t diff --git a/src/flamenco/runtime/program/fd_system_program.c b/src/flamenco/runtime/program/fd_system_program.c index cd1f114532..2e0e2e654a 100644 --- a/src/flamenco/runtime/program/fd_system_program.c +++ b/src/flamenco/runtime/program/fd_system_program.c @@ -158,7 +158,7 @@ fd_system_program_allocate( fd_exec_instr_ctx_t * ctx, /* Max msg_sz: 35 - 2 + 125 = 158 */ fd_log_collector_printf_inefficient_max_512( ctx, "Allocate: 'to' (account %s, base %s) must sign", - FD_BASE58_ENC_32_ALLOCA( &account->acct->pubkey ), + FD_BASE58_ENC_32_ALLOCA( &account->pubkey ), base ? FD_BASE58_ENC_32_ALLOCA( base ) : "None" ); return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE; } @@ -170,7 +170,7 @@ fd_system_program_allocate( fd_exec_instr_ctx_t * ctx, /* Max msg_sz: 35 - 2 + 125 = 158 */ fd_log_collector_printf_inefficient_max_512( ctx, "Allocate: account (account %s, base %s) already in use", - FD_BASE58_ENC_32_ALLOCA( &account->acct->pubkey ), + FD_BASE58_ENC_32_ALLOCA( &account->pubkey ), base ? FD_BASE58_ENC_32_ALLOCA( base ) : "None" ); ctx->txn_out->err.custom_err = FD_SYSTEM_PROGRAM_ERR_ACCT_ALREADY_IN_USE; return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR; @@ -220,7 +220,7 @@ fd_system_program_assign( fd_exec_instr_ctx_t * ctx, /* Max msg_sz: 28 - 2 + 125 = 151 */ fd_log_collector_printf_inefficient_max_512( ctx, "Allocate: 'to' (account %s, base %s) must sign", - FD_BASE58_ENC_32_ALLOCA( &account->acct->pubkey ), + FD_BASE58_ENC_32_ALLOCA( &account->pubkey ), base ? FD_BASE58_ENC_32_ALLOCA( base ) : "None" ); return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE; } @@ -279,7 +279,7 @@ fd_system_program_create_account( fd_exec_instr_ctx_t * ctx, /* Max msg_sz: 41 - 2 + 125 = 164 */ fd_log_collector_printf_inefficient_max_512( ctx, "Allocate: 'to' (account %s, base %s) already in use", - FD_BASE58_ENC_32_ALLOCA( &to.acct->pubkey ), + FD_BASE58_ENC_32_ALLOCA( &to.pubkey ), base ? FD_BASE58_ENC_32_ALLOCA( base ) : "None" ); ctx->txn_out->err.custom_err = FD_SYSTEM_PROGRAM_ERR_ACCT_ALREADY_IN_USE; return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR; @@ -358,7 +358,7 @@ fd_system_program_exec_assign( fd_exec_instr_ctx_t * ctx, /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L392 */ - err = fd_system_program_assign( ctx, &account, owner, account.acct->pubkey, NULL ); + err = fd_system_program_assign( ctx, &account, owner, account.pubkey, NULL ); if( FD_UNLIKELY( err ) ) return err; /* Implicit drop */ @@ -453,7 +453,7 @@ fd_system_program_exec_allocate( fd_exec_instr_ctx_t * ctx, /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L515 Authorization check is lifted out from 'allocate' to here. */ - err = fd_system_program_allocate( ctx, &account, space, account.acct->pubkey, NULL ); + err = fd_system_program_allocate( ctx, &account, space, account.pubkey, NULL ); if( FD_UNLIKELY( err ) ) return err; /* Implicit drop */ @@ -484,7 +484,7 @@ fd_system_program_exec_allocate_with_seed( fd_exec_instr_ctx_t * err = verify_seed_address( ctx, - account.acct->pubkey, + account.pubkey, &args->base, (char const *)args->seed, args->seed_len, @@ -531,7 +531,7 @@ fd_system_program_exec_assign_with_seed( fd_exec_instr_ctx_t * err = verify_seed_address( ctx, - account.acct->pubkey, + account.pubkey, &args->base, (char const *)args->seed, args->seed_len, diff --git a/src/flamenco/runtime/program/fd_system_program_nonce.c b/src/flamenco/runtime/program/fd_system_program_nonce.c index 54fba071fe..9d7bb68f4b 100644 --- a/src/flamenco/runtime/program/fd_system_program_nonce.c +++ b/src/flamenco/runtime/program/fd_system_program_nonce.c @@ -135,7 +135,7 @@ fd_system_program_advance_nonce_account( fd_exec_instr_ctx_t * ctx, if( FD_UNLIKELY( !fd_instr_acc_is_writable_idx( ctx->instr, instr_acc_idx ) ) ) { /* Max msg_sz: 50 - 2 + 45 = 93 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, - "Advance nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( account->acct->pubkey) ); + "Advance nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( account->pubkey) ); return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; } @@ -226,7 +226,7 @@ fd_system_program_advance_nonce_account( fd_exec_instr_ctx_t * ctx, case fd_nonce_state_enum_uninitialized: { /* Max msg_sz: 50 - 2 + 45 = 93 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, - "Advance nonce account: Account %s state is invalid", FD_BASE58_ENC_32_ALLOCA( account->acct->pubkey ) ); + "Advance nonce account: Account %s state is invalid", FD_BASE58_ENC_32_ALLOCA( account->pubkey ) ); return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; } @@ -305,7 +305,7 @@ fd_system_program_withdraw_nonce_account( fd_exec_instr_ctx_t * ctx, if( FD_UNLIKELY( !fd_instr_acc_is_writable_idx( ctx->instr, from_acct_idx ) ) ) { /* Max msg_sz: 51 - 2 + 45 = 94 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, - "Withdraw nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( from.acct->pubkey ) ); + "Withdraw nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( from.pubkey ) ); return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; } @@ -349,7 +349,7 @@ fd_system_program_withdraw_nonce_account( fd_exec_instr_ctx_t * ctx, /* https://github.com/solana-labs/solana/blob/v1.17.23/programs/system/src/system_instruction.rs#L105 */ - *signer = *from.acct->pubkey; + *signer = *from.pubkey; break; } @@ -506,7 +506,7 @@ fd_system_program_initialize_nonce_account( fd_exec_instr_ctx_t * ctx, if( FD_UNLIKELY( !fd_borrowed_account_is_writable( account ) ) ) { /* Max msg_sz: 53 - 2 + 45 = 96 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, - "Initialize nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( account->acct->pubkey ) ); + "Initialize nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( account->pubkey ) ); return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; } @@ -593,7 +593,7 @@ fd_system_program_initialize_nonce_account( fd_exec_instr_ctx_t * ctx, /* Max msg_sz: 53 - 2 + 45 = 96 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, - "Initialize nonce account: Account %s state is invalid", FD_BASE58_ENC_32_ALLOCA( account->acct->pubkey ) ); + "Initialize nonce account: Account %s state is invalid", FD_BASE58_ENC_32_ALLOCA( account->pubkey ) ); return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; } @@ -677,7 +677,7 @@ fd_system_program_authorize_nonce_account( fd_exec_instr_ctx_t * ctx, if( FD_UNLIKELY( !fd_instr_acc_is_writable_idx( ctx->instr, instr_acc_idx ) ) ) { /* Max msg_sz: 52 - 2 + 45 = 95 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, - "Authorize nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( account->acct->pubkey ) ); + "Authorize nonce account: Account %s must be writeable", FD_BASE58_ENC_32_ALLOCA( account->pubkey ) ); return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; } @@ -716,7 +716,7 @@ fd_system_program_authorize_nonce_account( fd_exec_instr_ctx_t * ctx, /* Max msg_sz: 52 - 2 + 45 = 95 < 127 => we can use printf */ fd_log_collector_printf_dangerous_max_127( ctx, - "Authorize nonce account: Account %s state is invalid", FD_BASE58_ENC_32_ALLOCA( account->acct->pubkey ) ); + "Authorize nonce account: Account %s state is invalid", FD_BASE58_ENC_32_ALLOCA( account->pubkey ) ); return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; } diff --git a/src/flamenco/vm/fd_vm_private.h b/src/flamenco/vm/fd_vm_private.h index da638ad9cf..c93192f487 100644 --- a/src/flamenco/vm/fd_vm_private.h +++ b/src/flamenco/vm/fd_vm_private.h @@ -370,7 +370,7 @@ fd_vm_handle_input_mem_region_oob( fd_vm_t const * vm, fd_ulong_sat_add( vm->instr_ctx->txn_out->details.accounts_resize_delta, new_region_sz ), region->region_sz ); - fd_txn_account_resize( vm->acc_region_metas[ region->acc_region_meta_idx ].meta, new_region_sz ); + fd_account_meta_resize( vm->acc_region_metas[ region->acc_region_meta_idx ].meta, new_region_sz ); region->region_sz = (uint)new_region_sz; } } diff --git a/src/flamenco/vm/syscall/fd_vm_syscall_cpi.c b/src/flamenco/vm/syscall/fd_vm_syscall_cpi.c index 924692f173..8d2c5a3040 100644 --- a/src/flamenco/vm/syscall/fd_vm_syscall_cpi.c +++ b/src/flamenco/vm/syscall/fd_vm_syscall_cpi.c @@ -141,15 +141,15 @@ fd_vm_prepare_instruction( fd_instr_info_t * callee_instr, /* Check that the account is not read-only in the caller but writable in the callee */ if( FD_UNLIKELY( instruction_account->is_writable && !fd_borrowed_account_is_writable( &borrowed_caller_acct ) ) ) { - FD_BASE58_ENCODE_32_BYTES( borrowed_caller_acct.acct->pubkey->uc, id_b58 ); + FD_BASE58_ENCODE_32_BYTES( borrowed_caller_acct.pubkey->uc, id_b58 ); fd_log_collector_msg_many( instr_ctx, 2, id_b58, id_b58_len, "'s writable privilege escalated", 31UL ); FD_TXN_ERR_FOR_LOG_INSTR( instr_ctx->txn_out, FD_EXECUTOR_INSTR_ERR_PRIVILEGE_ESCALATION, instr_ctx->txn_out->err.exec_err_idx ); return FD_EXECUTOR_INSTR_ERR_PRIVILEGE_ESCALATION; } /* If the account is signed in the callee, it must be signed by the caller or the program */ - if ( FD_UNLIKELY( instruction_account->is_signer && !( fd_borrowed_account_is_signer( &borrowed_caller_acct ) || fd_vm_syscall_cpi_is_signer( borrowed_caller_acct.acct->pubkey, signers, signers_cnt) ) ) ) { - FD_BASE58_ENCODE_32_BYTES( borrowed_caller_acct.acct->pubkey->uc, id_b58 ); + if ( FD_UNLIKELY( instruction_account->is_signer && !( fd_borrowed_account_is_signer( &borrowed_caller_acct ) || fd_vm_syscall_cpi_is_signer( borrowed_caller_acct.pubkey, signers, signers_cnt) ) ) ) { + FD_BASE58_ENCODE_32_BYTES( borrowed_caller_acct.pubkey->uc, id_b58 ); fd_log_collector_msg_many( instr_ctx, 2, id_b58, id_b58_len, "'s signer privilege escalated", 29UL ); FD_TXN_ERR_FOR_LOG_INSTR( instr_ctx->txn_out, FD_EXECUTOR_INSTR_ERR_PRIVILEGE_ESCALATION, instr_ctx->txn_out->err.exec_err_idx ); return FD_EXECUTOR_INSTR_ERR_PRIVILEGE_ESCALATION; From f38967268a267ca25b1ab23be7c4234bc903ac8a Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Tue, 25 Nov 2025 17:20:52 +0000 Subject: [PATCH 17/32] wip --- src/discof/exec/fd_exec_tile.c | 2 + .../runtime/context/fd_exec_instr_ctx.c | 4 +- src/flamenco/runtime/fd_executor.c | 3 +- .../runtime/sysvar/fd_sysvar_instructions.c | 39 ++++++------------- .../runtime/sysvar/fd_sysvar_instructions.h | 4 +- src/flamenco/runtime/tests/fd_instr_harness.c | 3 +- 6 files changed, 20 insertions(+), 35 deletions(-) diff --git a/src/discof/exec/fd_exec_tile.c b/src/discof/exec/fd_exec_tile.c index 356eb5c93d..13c0e19429 100644 --- a/src/discof/exec/fd_exec_tile.c +++ b/src/discof/exec/fd_exec_tile.c @@ -311,6 +311,8 @@ unprivileged_init( fd_topo_t * topo, ctx->runtime->log.enable_log_collector = 0; ctx->runtime->log.dumping_mem = ctx->dumping_mem; ctx->runtime->log.tracing_mem = &ctx->tracing_mem[0][0]; + ctx->runtime->log.capture_ctx = ctx->capture_ctx; + ctx->runtime->log.enable_vm_tracing = 0; } /* Publish the next account update event buffered in the capture tile to the replay tile diff --git a/src/flamenco/runtime/context/fd_exec_instr_ctx.c b/src/flamenco/runtime/context/fd_exec_instr_ctx.c index b637ac13ef..c6877249cc 100644 --- a/src/flamenco/runtime/context/fd_exec_instr_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_instr_ctx.c @@ -57,7 +57,7 @@ fd_exec_instr_ctx_try_borrow_account( fd_exec_instr_ctx_t const * ctx, return FD_EXECUTOR_INSTR_ERR_MISSING_ACC; } - fd_txn_account_t * txn_account = &ctx->txn_out->accounts.accounts[idx_in_txn]; + fd_account_meta_t * meta = ctx->txn_out->accounts.metas[idx_in_txn]; /* Return an AccountBorrowFailed error if the write is not acquirable. https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L605 */ @@ -70,7 +70,7 @@ fd_exec_instr_ctx_try_borrow_account( fd_exec_instr_ctx_t const * ctx, https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L606 */ fd_borrowed_account_init( account, &ctx->txn_out->accounts.account_keys[idx_in_txn], - txn_account->meta, + meta, ctx, idx_in_instr, &ctx->runtime->accounts.refcnt[idx_in_txn] ); diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 687f7d3f88..ce203e8780 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -1189,7 +1189,6 @@ fd_txn_ctx_push( fd_runtime_t * runtime, int idx = fd_runtime_find_index_of_account( txn_out, &fd_sysvar_instructions_id ); if( FD_UNLIKELY( idx!=-1 ) ) { /* https://github.com/anza-xyz/agave/blob/v2.2.12/transaction-context/src/lib.rs#L397-L400 */ - fd_txn_account_t * sysvar_instructions_account = &txn_out->accounts.accounts[idx]; err = fd_runtime_get_account_at_index( txn_in, txn_out, (ushort)idx, NULL ); if( FD_UNLIKELY( err ) ) { return FD_EXECUTOR_INSTR_ERR_MISSING_ACC; @@ -1204,7 +1203,7 @@ fd_txn_ctx_push( fd_runtime_t * runtime, refcnt++; /* https://github.com/anza-xyz/agave/blob/v2.2.12/transaction-context/src/lib.rs#L403-L406 */ - fd_sysvar_instructions_update_current_instr_idx( sysvar_instructions_account, (ushort)runtime->instr.current_idx ); + fd_sysvar_instructions_update_current_instr_idx( txn_out->accounts.metas[idx], (ushort)runtime->instr.current_idx ); refcnt--; } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c index 8be5c9e7a7..05d912e780 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c @@ -55,33 +55,18 @@ fd_sysvar_instructions_serialize_account( fd_runtime_t * runtime, } fd_txn_account_t * rec = &txn_out->accounts.accounts[index]; + rec->is_mutable = 1; + rec->meta = txn_out->accounts.metas[txn_idx]; - /* This stays within the FD spad allocation bounds because... - 1. Case 1: rec->meta!=NULL - - rec->meta was set up in `fd_executor_setup_accounts_for_txn()` and data was allocated from the spad - - No need to allocate meta and data here - 2. Case 2: rec->meta==NULL - - `fd_executor_setup_accounts_for_txn()` did not make an spad allocation for this account - - spad memory is sized out for allocations for 128 (max number) accounts - - sizeof(fd_account_meta_t) + serialized_sz will always be less than FD_ACC_TOT_SZ_MAX - - at most 127 accounts could be using spad memory right now, so this allocation is safe */ - if( !fd_txn_account_is_mutable( rec ) ) { - uchar const * mem = txn_in->exec_accounts->accounts_mem[ txn_idx ]; - fd_account_meta_t * meta = (fd_account_meta_t *)mem; - fd_txn_account_t * acc = fd_txn_account_join( fd_txn_account_new( rec, &fd_sysvar_instructions_id, meta, 1 ) ); - if( FD_UNLIKELY( !acc ) ) { - FD_LOG_CRIT(( "Failed to join txn account" )); - } - txn_out->accounts.metas[txn_idx] = acc->meta; - } - + fd_account_meta_t * meta = txn_out->accounts.metas[ txn_idx ]; /* Agave sets up the borrowed account for the instructions sysvar to contain default values except for the data which is serialized into the account. */ - fd_txn_account_set_owner( rec, &fd_sysvar_owner_id ); - fd_txn_account_set_lamports( rec, 0UL ); - fd_txn_account_set_executable( rec, 0 ); - fd_txn_account_set_data_len( rec, serialized_sz ); + fd_memcpy( meta->owner, &fd_sysvar_owner_id, sizeof(fd_pubkey_t) ); + meta->lamports = 0UL; + meta->executable = 0; + meta->dlen = (uint)serialized_sz; + runtime->accounts.starting_lamports[txn_idx] = 0UL; runtime->accounts.starting_dlen[txn_idx] = serialized_sz; @@ -141,13 +126,13 @@ fd_sysvar_instructions_serialize_account( fd_runtime_t * runtime, /* Stores the current instruction index in the instructions sysvar account. https://github.com/anza-xyz/solana-sdk/blob/instructions-sysvar%40v2.2.1/instructions-sysvar/src/lib.rs#L164-L167 */ void -fd_sysvar_instructions_update_current_instr_idx( fd_txn_account_t * rec, - ushort current_instr_idx ) { +fd_sysvar_instructions_update_current_instr_idx( fd_account_meta_t * meta, + ushort current_instr_idx ) { /* Extra safety checks */ - if( FD_UNLIKELY( fd_txn_account_get_data_len( rec )dlendlen - sizeof(ushort)); FD_STORE( ushort, serialized_current_instr_idx, current_instr_idx ); } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.h b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.h index 3a8d08794e..609d925773 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.h +++ b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.h @@ -16,8 +16,8 @@ fd_sysvar_instructions_serialize_account( fd_runtime_t * runtime, ulong txn_idx ); void -fd_sysvar_instructions_update_current_instr_idx( fd_txn_account_t * rec, - ushort current_instr_idx ); +fd_sysvar_instructions_update_current_instr_idx( fd_account_meta_t * meta, + ushort current_instr_idx ); FD_PROTOTYPES_END diff --git a/src/flamenco/runtime/tests/fd_instr_harness.c b/src/flamenco/runtime/tests/fd_instr_harness.c index d363fe46f6..4ac14bea2a 100644 --- a/src/flamenco/runtime/tests/fd_instr_harness.c +++ b/src/flamenco/runtime/tests/fd_instr_harness.c @@ -157,7 +157,6 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, if( !fd_solfuzz_pb_load_account( runtime, &accts[j], runner->accdb, xid, &test_ctx->accounts[j], 0, j ) ) { return 0; } - txn_out->accounts.metas[j] = accts[j].meta; runtime->accounts.refcnt[j] = 0UL; fd_txn_account_t * acc = &accts[j]; @@ -170,7 +169,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, FD_LOG_CRIT(( "Failed to join and new a txn account" )); } } - + txn_out->accounts.metas[j] = accts[j].meta; if( !memcmp( accts[j].pubkey, test_ctx->program_id, sizeof(fd_pubkey_t) ) ) { has_program_id = 1; From 0b3f7a2f079b10c870a7314ef2554ba93d2837e3 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Tue, 25 Nov 2025 18:05:28 +0000 Subject: [PATCH 18/32] wip --- src/flamenco/runtime/fd_runtime.c | 54 +++++++++---------- src/flamenco/runtime/fd_runtime_helpers.h | 20 +++---- .../runtime/program/fd_bpf_loader_program.c | 11 ++-- 3 files changed, 37 insertions(+), 48 deletions(-) diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index ca514467b6..13fa1e1646 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1760,10 +1760,8 @@ fd_runtime_get_account_at_index( fd_txn_in_t const * txn_in, return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT; } - fd_txn_account_t * txn_account = &txn_out->accounts.accounts[idx]; - if( FD_LIKELY( condition != NULL ) ) { - if( FD_UNLIKELY( !condition( txn_account, txn_in, txn_out, idx ) ) ) { + if( FD_UNLIKELY( !condition( txn_in, txn_out, idx ) ) ) { return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT; } } @@ -1791,17 +1789,21 @@ fd_runtime_get_account_with_key( fd_txn_in_t const * txn_in, } int -fd_runtime_get_executable_account( fd_runtime_t * runtime, - fd_txn_in_t const * txn_in, - fd_txn_out_t * txn_out, - fd_pubkey_t const * pubkey, - fd_txn_account_t * * account, - fd_txn_account_condition_fn_t * condition ) { - /* First try to fetch the executable account from the existing borrowed accounts. - If the pubkey is in the account keys, then we want to re-use that - borrowed account since it reflects changes from prior instructions. Referencing the - read-only executable accounts list is incorrect behavior when the program - data account is written to in a prior instruction (e.g. program upgrade + invoke within the same txn) */ +fd_runtime_get_executable_account( fd_runtime_t * runtime, + fd_txn_in_t const * txn_in, + fd_txn_out_t * txn_out, + fd_pubkey_t const * pubkey, + fd_account_meta_t * * meta ) { + /* First try to fetch the executable account from the existing + borrowed accounts. If the pubkey is in the account keys, then we + want to re-use that borrowed account since it reflects changes from + prior instructions. Referencing the read-only executable accounts + list is incorrect behavior when the program data account is written + to in a prior instruction (e.g. program upgrade + invoke within the + same txn) */ + + fd_txn_account_condition_fn_t * condition = fd_runtime_account_check_exists; + int index; int err = fd_runtime_get_account_with_key( txn_in, txn_out, @@ -1809,21 +1811,17 @@ fd_runtime_get_executable_account( fd_runtime_t * runtime, &index, condition ); if( FD_UNLIKELY( err==FD_ACC_MGR_SUCCESS ) ) { - *account = &txn_out->accounts.accounts[index]; + *meta = txn_out->accounts.metas[index]; return FD_ACC_MGR_SUCCESS; } for( ushort i=0; iaccounts.executable_cnt; i++ ) { if( memcmp( pubkey->uc, runtime->accounts.executables[i].pubkey->uc, sizeof(fd_pubkey_t) )==0 ) { fd_txn_account_t * txn_account = &runtime->accounts.executables[i]; - *account = txn_account; - - if( FD_LIKELY( condition != NULL ) ) { - if( FD_UNLIKELY( !condition( *account, txn_in, txn_out, i ) ) ) { - return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT; - } + *meta = txn_account->meta; + if( FD_UNLIKELY( !fd_account_meta_exists( txn_account->meta ) ) ) { + return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT; } - return FD_ACC_MGR_SUCCESS; } } @@ -1924,22 +1922,18 @@ fd_runtime_account_is_writable_idx( fd_txn_in_t const * txn_in, /* Account pre-condition filtering functions */ int -fd_runtime_account_check_exists( fd_txn_account_t * acc, - fd_txn_in_t const * txn_in, +fd_runtime_account_check_exists( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx ) { (void) txn_in; - (void) txn_out; - (void) idx; - return fd_account_meta_exists( fd_txn_account_get_meta( acc ) ); + fd_txn_account_t * acc2 = &txn_out->accounts.accounts[idx]; + return fd_account_meta_exists( fd_txn_account_get_meta( acc2 ) ); } int -fd_runtime_account_check_fee_payer_writable( fd_txn_account_t * acc, - fd_txn_in_t const * txn_in, +fd_runtime_account_check_fee_payer_writable( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx ) { (void) txn_out; - (void) acc; return fd_txn_is_writable( TXN( txn_in->txn ), idx ); } diff --git a/src/flamenco/runtime/fd_runtime_helpers.h b/src/flamenco/runtime/fd_runtime_helpers.h index 6829bf9113..00e67c0f97 100644 --- a/src/flamenco/runtime/fd_runtime_helpers.h +++ b/src/flamenco/runtime/fd_runtime_helpers.h @@ -134,8 +134,7 @@ int fd_runtime_find_index_of_account( fd_txn_out_t const * txn_out, fd_pubkey_t const * pubkey ); -typedef int fd_txn_account_condition_fn_t ( fd_txn_account_t * acc, - fd_txn_in_t const * txn_in, +typedef int fd_txn_account_condition_fn_t ( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx ); @@ -166,12 +165,11 @@ fd_runtime_get_account_with_key( fd_txn_in_t const * txn_in, /* Gets an executable (program data) account via its pubkey. */ int -fd_runtime_get_executable_account( fd_runtime_t * runtime, - fd_txn_in_t const * txn_in, - fd_txn_out_t * txn_out, - fd_pubkey_t const * pubkey, - fd_txn_account_t * * account, - fd_txn_account_condition_fn_t * condition ); +fd_runtime_get_executable_account( fd_runtime_t * runtime, + fd_txn_in_t const * txn_in, + fd_txn_out_t * txn_out, + fd_pubkey_t const * pubkey, + fd_account_meta_t * * meta ); /* Mirrors Agave function solana_sdk::transaction_context::get_key_of_account_at_index @@ -207,8 +205,7 @@ fd_runtime_account_is_writable_idx( fd_txn_in_t const * txn_in, when obtaining accounts from the transaction context. Passed as a function pointer. */ int -fd_runtime_account_check_exists( fd_txn_account_t * acc, - fd_txn_in_t const * txn_in, +fd_runtime_account_check_exists( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx ); @@ -219,8 +216,7 @@ fd_runtime_account_check_exists( fd_txn_account_t * acc, doesn't have a writable signature. */ int -fd_runtime_account_check_fee_payer_writable( fd_txn_account_t * acc, - fd_txn_in_t const * txn_in, +fd_runtime_account_check_fee_payer_writable( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx ); diff --git a/src/flamenco/runtime/program/fd_bpf_loader_program.c b/src/flamenco/runtime/program/fd_bpf_loader_program.c index 5b04c47443..2cf12ed77c 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_program.c +++ b/src/flamenco/runtime/program/fd_bpf_loader_program.c @@ -2523,14 +2523,13 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * ctx ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; } - fd_txn_account_t * program_data_account = NULL; - fd_pubkey_t * programdata_pubkey = (fd_pubkey_t *)&program_account_state->inner.program.programdata_address; + fd_account_meta_t * programdata_meta = NULL; + fd_pubkey_t * programdata_pubkey = (fd_pubkey_t *)&program_account_state->inner.program.programdata_address; err = fd_runtime_get_executable_account( ctx->runtime, ctx->txn_in, ctx->txn_out, programdata_pubkey, - &program_data_account, - fd_runtime_account_check_exists ); + &programdata_meta ); if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { fd_log_collector_msg_literal( ctx, "Program is not deployed" ); if( FD_FEATURE_ACTIVE_BANK( ctx->bank, remove_accounts_executable_flag_checks ) ) { @@ -2539,7 +2538,7 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * ctx ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; } - if( FD_UNLIKELY( fd_txn_account_get_data_len( program_data_account )dlenbank, remove_accounts_executable_flag_checks ) ) { return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_PROGRAM_ID; @@ -2548,7 +2547,7 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * ctx ) { } fd_bpf_upgradeable_loader_state_t program_data_account_state[1]; - err = fd_bpf_loader_program_get_state( program_data_account, program_data_account_state ); + err = fd_bpf_loader_program_get_state_inner( programdata_meta, program_data_account_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { fd_log_collector_msg_literal( ctx, "Program is not deployed" ); if( FD_FEATURE_ACTIVE_BANK( ctx->bank, remove_accounts_executable_flag_checks ) ) { From f97cebf71fbd7c461cf6440f6c725cd151452bf1 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Tue, 25 Nov 2025 18:34:47 +0000 Subject: [PATCH 19/32] wi[ --- src/flamenco/runtime/fd_executor.c | 15 +++++++++++---- src/flamenco/runtime/fd_runtime.c | 7 +++---- src/flamenco/runtime/fd_runtime.h | 11 ++++++----- src/flamenco/runtime/tests/fd_dump_pb.c | 4 ++-- src/flamenco/runtime/tests/fd_instr_harness.c | 16 ++++++++++++---- 5 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index ce203e8780..b4282e4a43 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -1568,10 +1568,17 @@ fd_executor_setup_executable_account( fd_runtime_t * runtime, account will not exist within the executable accounts list. */ fd_pubkey_t * programdata_acc = &program_loader_state->inner.program.programdata_address; fd_funk_txn_xid_t xid = { .ul = { fd_bank_slot_get( bank ), bank->idx } }; - if( FD_LIKELY( fd_txn_account_init_from_funk_readonly( &runtime->accounts.executables[ *executable_idx ], - programdata_acc, - runtime->funk, - &xid )==0 ) ) { + + fd_account_meta_t const * meta = fd_funk_get_acc_meta_readonly( + runtime->funk, + &xid, + programdata_acc, + NULL, + &err, + NULL ); + if( FD_LIKELY( err==FD_ACC_MGR_SUCCESS ) ) { + runtime->accounts.executable_pubkeys[*executable_idx] = *programdata_acc; + runtime->accounts.executables_meta[*executable_idx] = (fd_account_meta_t *)meta; (*executable_idx)++; } } diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 13fa1e1646..131365a31f 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1816,10 +1816,9 @@ fd_runtime_get_executable_account( fd_runtime_t * runtime, } for( ushort i=0; iaccounts.executable_cnt; i++ ) { - if( memcmp( pubkey->uc, runtime->accounts.executables[i].pubkey->uc, sizeof(fd_pubkey_t) )==0 ) { - fd_txn_account_t * txn_account = &runtime->accounts.executables[i]; - *meta = txn_account->meta; - if( FD_UNLIKELY( !fd_account_meta_exists( txn_account->meta ) ) ) { + if( memcmp( pubkey->uc, runtime->accounts.executable_pubkeys[i].uc, sizeof(fd_pubkey_t) )==0 ) { + *meta = runtime->accounts.executables_meta[i]; + if( FD_UNLIKELY( !fd_account_meta_exists( *meta ) ) ) { return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT; } return FD_ACC_MGR_SUCCESS; diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index fa4d2375d0..6bddf6796a 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -128,11 +128,12 @@ struct fd_runtime { } stake_program; struct { - ulong executable_cnt; /* Number of BPF upgradeable loader accounts. */ - fd_txn_account_t executables[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */ - ulong starting_lamports[ MAX_TX_ACCOUNT_LOCKS ]; /* Starting lamports for each account */ - ulong starting_dlen[ MAX_TX_ACCOUNT_LOCKS ]; /* Starting data length for each account */ - ulong refcnt[ MAX_TX_ACCOUNT_LOCKS ]; /* Reference count for each account */ + ulong executable_cnt; /* Number of BPF upgradeable loader accounts. */ + fd_account_meta_t * executables_meta[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */ + fd_pubkey_t executable_pubkeys[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */ + ulong starting_lamports[ MAX_TX_ACCOUNT_LOCKS ]; /* Starting lamports for each account */ + ulong starting_dlen[ MAX_TX_ACCOUNT_LOCKS ]; /* Starting data length for each account */ + ulong refcnt[ MAX_TX_ACCOUNT_LOCKS ]; /* Reference count for each account */ } accounts; }; typedef struct fd_runtime fd_runtime_t; diff --git a/src/flamenco/runtime/tests/fd_dump_pb.c b/src/flamenco/runtime/tests/fd_dump_pb.c index 58570de089..5160bc4b92 100644 --- a/src/flamenco/runtime/tests/fd_dump_pb.c +++ b/src/flamenco/runtime/tests/fd_dump_pb.c @@ -935,14 +935,14 @@ create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t * /* Add executable accounts */ for( ulong i = 0; i < runtime->accounts.executable_cnt; i++ ) { fd_txn_account_t txn_account[1]; - int ret = fd_txn_account_init_from_funk_readonly( txn_account, runtime->accounts.executables[i].pubkey, runtime->funk, &xid ); + int ret = fd_txn_account_init_from_funk_readonly( txn_account, &runtime->accounts.executable_pubkeys[i], runtime->funk, &xid ); if( ret != FD_ACC_MGR_SUCCESS ) { continue; } // Make sure the account doesn't exist in the output accounts yet bool account_exists = false; for( ulong j = 0; j < instr_context->accounts_count; j++ ) { - if( 0 == memcmp( instr_context->accounts[j].address, runtime->accounts.executables[i].pubkey->uc, sizeof(fd_pubkey_t) ) ) { + if( 0 == memcmp( instr_context->accounts[j].address, runtime->accounts.executable_pubkeys[i].uc, sizeof(fd_pubkey_t) ) ) { account_exists = true; break; } diff --git a/src/flamenco/runtime/tests/fd_instr_harness.c b/src/flamenco/runtime/tests/fd_instr_harness.c index 4ac14bea2a..caf4fe16a4 100644 --- a/src/flamenco/runtime/tests/fd_instr_harness.c +++ b/src/flamenco/runtime/tests/fd_instr_harness.c @@ -237,12 +237,20 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, } fd_pubkey_t * programdata_acc = &program_loader_state->inner.program.programdata_address; - if( FD_UNLIKELY( fd_txn_account_init_from_funk_readonly( &runtime->accounts.executables[runtime->accounts.executable_cnt], - programdata_acc, - runtime->funk, - xid ) ) ) { + + fd_account_meta_t const * meta = fd_funk_get_acc_meta_readonly( + runtime->funk, + xid, + programdata_acc, + NULL, + &err, + NULL ); + + if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { continue; } + runtime->accounts.executable_pubkeys[runtime->accounts.executable_cnt] = *programdata_acc; + runtime->accounts.executables_meta[runtime->accounts.executable_cnt] = (fd_account_meta_t *)meta; runtime->accounts.executable_cnt++; } } From 3aa21f42317e4cfff3abca3fcff3064df1fb1fc7 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Tue, 25 Nov 2025 19:06:58 +0000 Subject: [PATCH 20/32] wip --- src/flamenco/runtime/fd_executor.c | 49 ++++++++----------- src/flamenco/runtime/fd_runtime.c | 13 +++-- src/flamenco/runtime/fd_runtime.h | 13 ++--- src/flamenco/runtime/fd_runtime_helpers.h | 10 ++-- .../runtime/program/fd_bpf_loader_program.c | 4 +- .../runtime/sysvar/fd_sysvar_instructions.c | 6 +-- src/flamenco/runtime/tests/fd_dump_pb.c | 39 ++++++++------- src/flamenco/runtime/tests/fd_txn_harness.c | 28 +++++------ 8 files changed, 75 insertions(+), 87 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index b4282e4a43..7cc3503f39 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -1285,9 +1285,9 @@ fd_instr_stack_pop( fd_runtime_t * runtime, https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L367-L371 */ for( ushort i=0; iacct_cnt; i++ ) { ushort idx_in_txn = instr->accounts[i].index_in_transaction; - fd_txn_account_t * account = &txn_out->accounts.accounts[ idx_in_txn ]; + fd_account_meta_t const * meta = txn_out->accounts.metas[ idx_in_txn ]; ulong refcnt = runtime->accounts.refcnt[idx_in_txn]; - if( FD_UNLIKELY( fd_txn_account_is_executable( account ) && refcnt!=0UL ) ) { + if( FD_UNLIKELY( meta->executable && refcnt!=0UL ) ) { return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_OUTSTANDING; } } @@ -1354,7 +1354,7 @@ fd_execute_instr( fd_runtime_t * runtime, .txn_out = txn_out, .bank = bank, }; - fd_base58_encode_32( txn_out->accounts.accounts[ instr->program_id ].pubkey->uc, NULL, ctx->program_id_base58 ); + fd_base58_encode_32( txn_out->accounts.account_keys[ instr->program_id ].uc, NULL, ctx->program_id_base58 ); runtime->instr.trace[ runtime->instr.trace_length - 1 ] = (fd_exec_instr_trace_entry_t) { .instr_info = instr, @@ -1434,7 +1434,7 @@ fd_executor_reclaim_account( fd_account_meta_t * meta, } } -static fd_txn_account_t * +static void fd_executor_setup_txn_account( fd_runtime_t * runtime, fd_bank_t * bank, fd_txn_in_t const * txn_in, @@ -1467,7 +1467,7 @@ fd_executor_setup_txn_account( fd_runtime_t * runtime, for( ushort j=0UL; jaccounts.accounts_cnt; j++ ) { if( !memcmp( &prev_txn_out->accounts.account_keys[ j ], acc, sizeof(fd_pubkey_t) ) && fd_runtime_account_is_writable_idx( prev_txn_in, prev_txn_out, bank, j ) ) { /* Found the account in a previous transaction */ - meta = prev_txn_out->accounts.accounts[ j ].meta; + meta = prev_txn_out->accounts.metas[ j ]; is_found = 1; break; } @@ -1492,7 +1492,6 @@ fd_executor_setup_txn_account( fd_runtime_t * runtime, FD_LOG_CRIT(( "fd_txn_account_init_from_funk_readonly err=%d", err )); } - fd_txn_account_t * txn_account = &txn_out->accounts.accounts[ idx ]; int is_writable = fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, idx ) || idx==FD_FEE_PAYER_TXN_IDX; fd_account_meta_t * account_meta = NULL; @@ -1530,30 +1529,20 @@ fd_executor_setup_txn_account( fd_runtime_t * runtime, } } - if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new( - txn_account, - acc, - account_meta, - is_writable ) ) ) ) { - FD_LOG_CRIT(( "Failed to join txn account" )); - } - - runtime->accounts.starting_lamports[idx] = fd_txn_account_get_lamports( txn_account ); - runtime->accounts.starting_dlen[idx] = fd_txn_account_get_data_len( txn_account ); + runtime->accounts.starting_lamports[idx] = account_meta->lamports; + runtime->accounts.starting_dlen[idx] = account_meta->dlen; runtime->accounts.refcnt[idx] = 0UL; memcpy( &txn_out->accounts.pubkeys[idx], acc, sizeof(fd_pubkey_t) ); txn_out->accounts.metas[ idx ] = account_meta; - - return txn_account; } static void -fd_executor_setup_executable_account( fd_runtime_t * runtime, - fd_bank_t * bank, - fd_txn_account_t const * account, - ushort * executable_idx ) { +fd_executor_setup_executable_account( fd_runtime_t * runtime, + fd_bank_t * bank, + fd_account_meta_t const * program_meta, + ushort * executable_idx ) { fd_bpf_upgradeable_loader_state_t program_loader_state[1]; - int err = fd_bpf_loader_program_get_state( account, program_loader_state ); + int err = fd_bpf_loader_program_get_state_inner( program_meta, program_loader_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return; } @@ -1590,14 +1579,13 @@ fd_executor_setup_accounts_for_txn( fd_runtime_t * runtime, fd_txn_out_t * txn_out ) { ushort executable_idx = 0U; - fd_memset( txn_out->accounts.accounts, 0, sizeof(fd_txn_account_t) * txn_out->accounts.accounts_cnt ); for( ushort i=0; iaccounts.accounts_cnt; i++ ) { - fd_txn_account_t * txn_account = fd_executor_setup_txn_account( runtime, bank, txn_in, txn_out, i ); + fd_executor_setup_txn_account( runtime, bank, txn_in, txn_out, i ); + fd_account_meta_t * meta = txn_out->accounts.metas[ i ]; - if( FD_UNLIKELY( txn_account && - memcmp( fd_txn_account_get_owner( txn_account ), fd_solana_bpf_loader_upgradeable_program_id.key, sizeof(fd_pubkey_t) ) == 0 ) ) { - fd_executor_setup_executable_account( runtime, bank, txn_account, &executable_idx ); + if( FD_UNLIKELY( meta && memcmp( meta->owner, fd_solana_bpf_loader_upgradeable_program_id.key, sizeof(fd_pubkey_t) ) == 0 ) ) { + fd_executor_setup_executable_account( runtime, bank, meta, &executable_idx ); } } @@ -1608,7 +1596,10 @@ fd_executor_setup_accounts_for_txn( fd_runtime_t * runtime, runtime->log.capture_ctx->dump_elf_to_pb; if( FD_UNLIKELY( dump_elf_to_pb ) ) { for( ushort i=0; iaccounts.accounts_cnt; i++ ) { - fd_dump_elf_to_protobuf( runtime, bank, txn_in, &txn_out->accounts.accounts[i] ); + fd_txn_account_t txn_account[1]; + txn_account->meta = txn_out->accounts.metas[i]; + fd_memcpy( txn_account->pubkey, &txn_out->accounts.account_keys[i], sizeof(fd_pubkey_t) ); + fd_dump_elf_to_protobuf( runtime, bank, txn_in, txn_account ); } } # endif diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 131365a31f..2cde4c1596 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1789,11 +1789,11 @@ fd_runtime_get_account_with_key( fd_txn_in_t const * txn_in, } int -fd_runtime_get_executable_account( fd_runtime_t * runtime, - fd_txn_in_t const * txn_in, - fd_txn_out_t * txn_out, - fd_pubkey_t const * pubkey, - fd_account_meta_t * * meta ) { +fd_runtime_get_executable_account( fd_runtime_t * runtime, + fd_txn_in_t const * txn_in, + fd_txn_out_t * txn_out, + fd_pubkey_t const * pubkey, + fd_account_meta_t const * * meta ) { /* First try to fetch the executable account from the existing borrowed accounts. If the pubkey is in the account keys, then we want to re-use that borrowed account since it reflects changes from @@ -1925,8 +1925,7 @@ fd_runtime_account_check_exists( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx ) { (void) txn_in; - fd_txn_account_t * acc2 = &txn_out->accounts.accounts[idx]; - return fd_account_meta_exists( fd_txn_account_get_meta( acc2 ) ); + return fd_account_meta_exists( txn_out->accounts.metas[idx] ); } int diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index 6bddf6796a..64a31e4c95 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -128,12 +128,13 @@ struct fd_runtime { } stake_program; struct { - ulong executable_cnt; /* Number of BPF upgradeable loader accounts. */ - fd_account_meta_t * executables_meta[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */ - fd_pubkey_t executable_pubkeys[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */ - ulong starting_lamports[ MAX_TX_ACCOUNT_LOCKS ]; /* Starting lamports for each account */ - ulong starting_dlen[ MAX_TX_ACCOUNT_LOCKS ]; /* Starting data length for each account */ - ulong refcnt[ MAX_TX_ACCOUNT_LOCKS ]; /* Reference count for each account */ + ulong executable_cnt; /* Number of BPF upgradeable loader accounts. */ + fd_account_meta_t const * executables_meta[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */ + fd_pubkey_t executable_pubkeys[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */ + + ulong starting_lamports[ MAX_TX_ACCOUNT_LOCKS ]; /* Starting lamports for each account */ + ulong starting_dlen[ MAX_TX_ACCOUNT_LOCKS ]; /* Starting data length for each account */ + ulong refcnt[ MAX_TX_ACCOUNT_LOCKS ]; /* Reference count for each account */ } accounts; }; typedef struct fd_runtime fd_runtime_t; diff --git a/src/flamenco/runtime/fd_runtime_helpers.h b/src/flamenco/runtime/fd_runtime_helpers.h index 00e67c0f97..d51e9f4364 100644 --- a/src/flamenco/runtime/fd_runtime_helpers.h +++ b/src/flamenco/runtime/fd_runtime_helpers.h @@ -165,11 +165,11 @@ fd_runtime_get_account_with_key( fd_txn_in_t const * txn_in, /* Gets an executable (program data) account via its pubkey. */ int -fd_runtime_get_executable_account( fd_runtime_t * runtime, - fd_txn_in_t const * txn_in, - fd_txn_out_t * txn_out, - fd_pubkey_t const * pubkey, - fd_account_meta_t * * meta ); +fd_runtime_get_executable_account( fd_runtime_t * runtime, + fd_txn_in_t const * txn_in, + fd_txn_out_t * txn_out, + fd_pubkey_t const * pubkey, + fd_account_meta_t const * * meta ); /* Mirrors Agave function solana_sdk::transaction_context::get_key_of_account_at_index diff --git a/src/flamenco/runtime/program/fd_bpf_loader_program.c b/src/flamenco/runtime/program/fd_bpf_loader_program.c index 2cf12ed77c..fd149b0b8a 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_program.c +++ b/src/flamenco/runtime/program/fd_bpf_loader_program.c @@ -2523,8 +2523,8 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * ctx ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA; } - fd_account_meta_t * programdata_meta = NULL; - fd_pubkey_t * programdata_pubkey = (fd_pubkey_t *)&program_account_state->inner.program.programdata_address; + fd_account_meta_t const * programdata_meta = NULL; + fd_pubkey_t * programdata_pubkey = (fd_pubkey_t *)&program_account_state->inner.program.programdata_address; err = fd_runtime_get_executable_account( ctx->runtime, ctx->txn_in, ctx->txn_out, diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c index 05d912e780..46a74cc4a4 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c @@ -54,10 +54,6 @@ fd_sysvar_instructions_serialize_account( fd_runtime_t * runtime, FD_LOG_ERR(( "Failed to view sysvar instructions borrowed account. It may not be included in the txn account keys." )); } - fd_txn_account_t * rec = &txn_out->accounts.accounts[index]; - rec->is_mutable = 1; - rec->meta = txn_out->accounts.metas[txn_idx]; - fd_account_meta_t * meta = txn_out->accounts.metas[ txn_idx ]; /* Agave sets up the borrowed account for the instructions sysvar to contain default values except for the data which is serialized into the account. */ @@ -70,7 +66,7 @@ fd_sysvar_instructions_serialize_account( fd_runtime_t * runtime, runtime->accounts.starting_lamports[txn_idx] = 0UL; runtime->accounts.starting_dlen[txn_idx] = serialized_sz; - uchar * serialized_instructions = fd_txn_account_get_data_mut( rec ); + uchar * serialized_instructions = fd_account_data( meta ); ulong offset = 0; // TODO: do we needs bounds checking? diff --git a/src/flamenco/runtime/tests/fd_dump_pb.c b/src/flamenco/runtime/tests/fd_dump_pb.c index 5160bc4b92..6f892bd68d 100644 --- a/src/flamenco/runtime/tests/fd_dump_pb.c +++ b/src/flamenco/runtime/tests/fd_dump_pb.c @@ -104,25 +104,26 @@ dump_sorted_features( fd_features_t const * features, /** ACCOUNT DUMPING **/ static void -dump_account_state( fd_txn_account_t const * txn_account, +dump_account_state( fd_pubkey_t const * account_key, + fd_account_meta_t const * account_meta, fd_exec_test_acct_state_t * output_account, fd_spad_t * spad ) { // Address - fd_memcpy(output_account->address, txn_account->pubkey, sizeof(fd_pubkey_t)); + fd_memcpy(output_account->address, account_key, sizeof(fd_pubkey_t)); // Lamports - output_account->lamports = (uint64_t)fd_txn_account_get_lamports( txn_account ); + output_account->lamports = (uint64_t)account_meta->lamports; // Data - output_account->data = fd_spad_alloc( spad, alignof(pb_bytes_array_t), PB_BYTES_ARRAY_T_ALLOCSIZE( fd_txn_account_get_data_len( txn_account ) ) ); - output_account->data->size = (pb_size_t) fd_txn_account_get_data_len( txn_account ); - fd_memcpy(output_account->data->bytes, fd_txn_account_get_data( txn_account ), fd_txn_account_get_data_len( txn_account ) ); + output_account->data = fd_spad_alloc( spad, alignof(pb_bytes_array_t), PB_BYTES_ARRAY_T_ALLOCSIZE( account_meta->dlen ) ); + output_account->data->size = (pb_size_t) account_meta->dlen; + fd_memcpy(output_account->data->bytes, fd_account_data( account_meta ), account_meta->dlen ); // Executable - output_account->executable = (bool)fd_txn_account_is_executable( txn_account ); + output_account->executable = (bool)account_meta->executable; // Owner - fd_memcpy(output_account->owner, fd_txn_account_get_owner( txn_account ), sizeof(fd_pubkey_t)); + fd_memcpy(output_account->owner, account_meta->owner, sizeof(fd_pubkey_t)); } static uchar @@ -155,7 +156,7 @@ dump_account_if_not_already_dumped( fd_funk_t const * funk, } if( !account_already_dumped( out_acct_states, *out_acct_states_cnt, account_key ) ) { - dump_account_state( account, &out_acct_states[*out_acct_states_cnt], spad ); + dump_account_state( account_key, account->meta, &out_acct_states[*out_acct_states_cnt], spad ); (*out_acct_states_cnt)++; } @@ -689,7 +690,7 @@ create_block_context_protobuf_from_block( fd_block_dump_ctx_t * dump_ctx, if( FD_UNLIKELY( ret ) ) { continue; } - dump_account_state( txn_account, &block_context->acct_states[block_context->acct_states_count++], spad ); + dump_account_state( txn_account->pubkey, txn_account->meta, &block_context->acct_states[block_context->acct_states_count++], spad ); } /* BlockContext -> blockhash_queue */ @@ -783,7 +784,7 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m // Make sure account is not a non-migrating builtin if( !is_builtin_account( &txn_out->accounts.account_keys[i] ) ) { - dump_account_state( txn_account, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); + dump_account_state( txn_account->pubkey, txn_account->meta, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); } } @@ -796,7 +797,7 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m int ret = fd_txn_account_init_from_funk_readonly( txn_account, alut_key, runtime->funk, &xid ); if( FD_UNLIKELY( ret ) ) continue; - dump_account_state( txn_account, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); + dump_account_state( txn_account->pubkey, txn_account->meta, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); fd_acct_addr_t * lookup_addrs = (fd_acct_addr_t *)&fd_txn_account_get_data( txn_account )[FD_LOOKUP_TABLE_META_SIZE]; ulong lookup_addrs_cnt = (fd_txn_account_get_data_len( txn_account ) - FD_LOOKUP_TABLE_META_SIZE) >> 5UL; // = (dlen - 56) / 32 @@ -813,7 +814,7 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m fd_txn_account_t referenced_account[1]; ret = fd_txn_account_init_from_funk_readonly( referenced_account, referenced_addr, runtime->funk, &xid ); if( FD_UNLIKELY( ret ) ) continue; - dump_account_state( referenced_account, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); + dump_account_state( referenced_account->pubkey, referenced_account->meta, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); } uchar const * readonly_lut_idxs = txn_payload + addr_lut->readonly_off; @@ -827,7 +828,7 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m fd_txn_account_t referenced_account[1]; ret = fd_txn_account_init_from_funk_readonly( referenced_account, referenced_addr, runtime->funk, &xid ); if( FD_UNLIKELY( ret ) ) continue; - dump_account_state( referenced_account, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); + dump_account_state( referenced_account->pubkey, referenced_account->meta, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); } } @@ -856,7 +857,7 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m } // Copy it into output if (!account_exists) { - dump_account_state( txn_account, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); + dump_account_state( txn_account->pubkey, txn_account->meta, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); } } @@ -904,9 +905,9 @@ create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t * instr_context->accounts = fd_spad_alloc( spad, alignof(fd_exec_test_acct_state_t), (instr_context->accounts_count + num_sysvar_entries + runtime->accounts.executable_cnt) * sizeof(fd_exec_test_acct_state_t)); for( ulong i = 0; i < txn_out->accounts.accounts_cnt; i++ ) { // Copy account information over - fd_txn_account_t const * txn_account = &txn_out->accounts.accounts[i]; + fd_account_meta_t * account_meta = txn_out->accounts.metas[i]; fd_exec_test_acct_state_t * output_account = &instr_context->accounts[i]; - dump_account_state( txn_account, output_account, spad ); + dump_account_state( &txn_out->accounts.account_keys[i], account_meta, output_account, spad ); } /* Add sysvar cache variables */ @@ -928,7 +929,7 @@ create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t * // Copy it into output if (!account_exists) { fd_exec_test_acct_state_t * output_account = &instr_context->accounts[instr_context->accounts_count++]; - dump_account_state( txn_account, output_account, spad ); + dump_account_state( txn_account->pubkey, txn_account->meta, output_account, spad ); } } @@ -950,7 +951,7 @@ create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t * // Copy it into output if( !account_exists ) { fd_exec_test_acct_state_t * output_account = &instr_context->accounts[instr_context->accounts_count++]; - dump_account_state( txn_account, output_account, spad ); + dump_account_state( txn_account->pubkey, txn_account->meta, output_account, spad ); } } diff --git a/src/flamenco/runtime/tests/fd_txn_harness.c b/src/flamenco/runtime/tests/fd_txn_harness.c index 13240dd30e..7f88c6068f 100644 --- a/src/flamenco/runtime/tests/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/fd_txn_harness.c @@ -490,27 +490,27 @@ fd_solfuzz_pb_txn_run( fd_solfuzz_runner_t * runner, } /* If the transaction is a fees-only transaction, we have to create rollback accounts to iterate over and save. */ - fd_txn_account_t * accounts_to_save = txn_out->accounts.accounts; - ulong accounts_cnt = txn_out->accounts.accounts_cnt; + fd_account_meta_t * * accounts_to_save = txn_out->accounts.metas; + ulong accounts_cnt = txn_out->accounts.accounts_cnt; if( txn_out->err.is_fees_only ) { accounts_to_save = fd_spad_alloc( runner->spad, alignof(fd_txn_account_t), sizeof(fd_txn_account_t) * 2 ); accounts_cnt = 0UL; if( FD_LIKELY( txn_out->accounts.nonce_idx_in_txn!=FD_FEE_PAYER_TXN_IDX ) ) { - accounts_to_save[accounts_cnt++] = *txn_out->accounts.rollback_fee_payer; + accounts_to_save[accounts_cnt++] = txn_out->accounts.rollback_fee_payer->meta; } if( txn_out->accounts.nonce_idx_in_txn!=ULONG_MAX ) { - accounts_to_save[accounts_cnt++] = *txn_out->accounts.rollback_nonce; + accounts_to_save[accounts_cnt++] = txn_out->accounts.rollback_nonce->meta; } } /* Capture borrowed accounts */ for( ulong j=0UL; jaccounts.account_keys[j]; if( !( fd_runtime_account_is_writable_idx( txn_in, txn_out, runner->bank, (ushort)j ) || j==FD_FEE_PAYER_TXN_IDX ) ) continue; - assert( fd_txn_account_is_mutable( acc ) ); ulong modified_idx = txn_result->resulting_state.acct_states_count; assert( modified_idx < modified_acct_cnt ); @@ -519,23 +519,23 @@ fd_solfuzz_pb_txn_run( fd_solfuzz_runner_t * runner, memset( out_acct, 0, sizeof(fd_exec_test_acct_state_t) ); /* Copy over account content */ - memcpy( out_acct->address, acc->pubkey, sizeof(fd_pubkey_t) ); + memcpy( out_acct->address, pubkey, sizeof(fd_pubkey_t) ); - out_acct->lamports = fd_txn_account_get_lamports( acc ); + out_acct->lamports = meta->lamports; - if( fd_txn_account_get_data_len( acc )>0UL ) { + if( meta->dlen>0UL ) { out_acct->data = FD_SCRATCH_ALLOC_APPEND( l, alignof(pb_bytes_array_t), - PB_BYTES_ARRAY_T_ALLOCSIZE( fd_txn_account_get_data_len( acc ) ) ); + PB_BYTES_ARRAY_T_ALLOCSIZE( meta->dlen ) ); if( FD_UNLIKELY( _l > output_end ) ) { abort(); } - out_acct->data->size = (pb_size_t)fd_txn_account_get_data_len( acc ); - fd_memcpy( out_acct->data->bytes, fd_txn_account_get_data( acc ), fd_txn_account_get_data_len( acc ) ); + out_acct->data->size = (pb_size_t)meta->dlen; + fd_memcpy( out_acct->data->bytes, fd_account_data( meta ), meta->dlen ); } - out_acct->executable = fd_txn_account_is_executable( acc ); - memcpy( out_acct->owner, fd_txn_account_get_owner( acc ), sizeof(fd_pubkey_t) ); + out_acct->executable = meta->executable; + memcpy( out_acct->owner, meta->owner, sizeof(fd_pubkey_t) ); txn_result->resulting_state.acct_states_count++; } From af8547466b29dd36f5519ea931193ea537923221 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Tue, 25 Nov 2025 19:56:57 +0000 Subject: [PATCH 21/32] wip --- src/flamenco/runtime/fd_runtime.h | 4 --- src/flamenco/runtime/tests/fd_block_harness.c | 3 +- .../runtime/tests/fd_harness_common.c | 12 +++++-- src/flamenco/runtime/tests/fd_instr_harness.c | 26 +++++++------- .../runtime/tests/fd_solfuzz_private.h | 4 +-- src/flamenco/runtime/tests/fd_txn_harness.c | 3 +- src/flamenco/runtime/tests/fd_vm_harness.c | 36 +++++++++---------- 7 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index 64a31e4c95..00b7a0439a 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -201,11 +201,7 @@ struct fd_txn_out { https://github.com/anza-xyz/agave/blob/838c1952595809a31520ff1603a13f2c9123aa51/accounts-db/src/account_locks.rs#L118 That is the limit we are going to use here. */ struct { - /* TODO: These fd_txn_account_t arrays should be replaced with an - array of fd_account_meta_t pointers. Currently, the - fd_txn_account_t is just a wrapper around uchar data pointers. */ ulong accounts_cnt; - fd_txn_account_t accounts[ MAX_TX_ACCOUNT_LOCKS ]; /* The account keys are used by the CU rebating mechanism in the bank tile (leader pipeline). */ fd_pubkey_t account_keys[ MAX_TX_ACCOUNT_LOCKS ]; diff --git a/src/flamenco/runtime/tests/fd_block_harness.c b/src/flamenco/runtime/tests/fd_block_harness.c index 911d814931..58e56dc67a 100644 --- a/src/flamenco/runtime/tests/fd_block_harness.c +++ b/src/flamenco/runtime/tests/fd_block_harness.c @@ -344,8 +344,7 @@ fd_solfuzz_pb_block_ctx_create( fd_solfuzz_runner_t * runner, /* Load in all accounts with > 0 lamports provided in the context. The input expects unique account pubkeys. */ vote_states = fd_bank_vote_states_locking_modify( bank ); for( ushort i=0; iacct_states_count; i++ ) { - fd_txn_account_t acc[1]; - fd_solfuzz_pb_load_account( runner->runtime, acc, accdb, xid, &test_ctx->acct_states[i], 1, i ); + fd_solfuzz_pb_load_account( runner->runtime, accdb, xid, &test_ctx->acct_states[i], 1, i, NULL ); /* Update vote accounts cache for epoch T */ fd_pubkey_t pubkey; diff --git a/src/flamenco/runtime/tests/fd_harness_common.c b/src/flamenco/runtime/tests/fd_harness_common.c index bbaa4ed853..2489631623 100644 --- a/src/flamenco/runtime/tests/fd_harness_common.c +++ b/src/flamenco/runtime/tests/fd_harness_common.c @@ -8,12 +8,12 @@ int fd_solfuzz_pb_load_account( fd_runtime_t * runtime, - fd_txn_account_t * acc, fd_accdb_user_t * accdb, fd_funk_txn_xid_t const * xid, fd_exec_test_acct_state_t const * state, uchar reject_zero_lamports, - ulong acc_idx ) { + ulong acc_idx, + fd_account_meta_t * * meta_out ) { if( reject_zero_lamports && state->lamports==0UL ) { return 0; } @@ -29,8 +29,13 @@ fd_solfuzz_pb_load_account( fd_runtime_t * runtime, return 0; } + /* TODO: break the txn account dependency completely from the + harnesses. */ + fd_funk_rec_prepare_t prepare = {0}; + fd_txn_account_t acc[1]; + int ok = !!fd_txn_account_init_from_funk_mutable( /* acc */ acc, /* pubkey */ pubkey, /* funk */ accdb, @@ -39,6 +44,9 @@ fd_solfuzz_pb_load_account( fd_runtime_t * runtime, /* min_data_sz */ size, /* prepare */ &prepare ); assert( ok ); + if( meta_out ) { + *meta_out = acc->meta; + } if( state->data ) { fd_txn_account_set_data( acc, state->data->bytes, size ); diff --git a/src/flamenco/runtime/tests/fd_instr_harness.c b/src/flamenco/runtime/tests/fd_instr_harness.c index caf4fe16a4..f77eeb856e 100644 --- a/src/flamenco/runtime/tests/fd_instr_harness.c +++ b/src/flamenco/runtime/tests/fd_instr_harness.c @@ -144,8 +144,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, /* Load accounts into database */ - fd_txn_account_t * accts = txn_out->accounts.accounts; - fd_memset( accts, 0, test_ctx->accounts_count * sizeof(fd_txn_account_t) ); + fd_txn_account_t accts[MAX_TX_ACCOUNT_LOCKS] = {0}; txn_out->accounts.accounts_cnt = test_ctx->accounts_count; int has_program_id = 0; @@ -154,7 +153,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, fd_pubkey_t * acc_key = (fd_pubkey_t *)test_ctx->accounts[j].address; memcpy( &(txn_out->accounts.account_keys[j]), test_ctx->accounts[j].address, sizeof(fd_pubkey_t) ); - if( !fd_solfuzz_pb_load_account( runtime, &accts[j], runner->accdb, xid, &test_ctx->accounts[j], 0, j ) ) { + if( !fd_solfuzz_pb_load_account( runtime, runner->accdb, xid, &test_ctx->accounts[j], 0, j, &accts[j].meta ) ) { return 0; } runtime->accounts.refcnt[j] = 0UL; @@ -432,8 +431,9 @@ fd_solfuzz_pb_instr_run( fd_solfuzz_runner_t * runner, /* Capture borrowed accounts */ for( ulong j=0UL; j < ctx->txn_out->accounts.accounts_cnt; j++ ) { - fd_txn_account_t * acc = &ctx->txn_out->accounts.accounts[j]; - if( !fd_txn_account_get_meta( acc ) ) { + fd_pubkey_t * acc_key = &ctx->txn_out->accounts.account_keys[j]; + fd_account_meta_t * acc = ctx->txn_out->accounts.metas[j]; + if( !acc ) { continue; } @@ -444,22 +444,22 @@ fd_solfuzz_pb_instr_run( fd_solfuzz_runner_t * runner, memset( out_acct, 0, sizeof(fd_exec_test_acct_state_t) ); /* Copy over account content */ - memcpy( out_acct->address, acc->pubkey, sizeof(fd_pubkey_t) ); - out_acct->lamports = fd_txn_account_get_lamports( acc ); - if( fd_txn_account_get_data_len( acc )>0UL ) { + memcpy( out_acct->address, acc_key, sizeof(fd_pubkey_t) ); + out_acct->lamports = acc->lamports; + if( acc->dlen>0UL ) { out_acct->data = FD_SCRATCH_ALLOC_APPEND( l, alignof(pb_bytes_array_t), - PB_BYTES_ARRAY_T_ALLOCSIZE( fd_txn_account_get_data_len( acc ) ) ); + PB_BYTES_ARRAY_T_ALLOCSIZE( acc->dlen ) ); if( FD_UNLIKELY( _l > output_end ) ) { fd_solfuzz_pb_instr_ctx_destroy( runner, ctx ); return 0UL; } - out_acct->data->size = (pb_size_t)fd_txn_account_get_data_len( acc ); - fd_memcpy( out_acct->data->bytes, fd_txn_account_get_data( acc ), fd_txn_account_get_data_len( acc ) ); + out_acct->data->size = (pb_size_t)acc->dlen; + fd_memcpy( out_acct->data->bytes, fd_account_data( acc ), acc->dlen ); } - out_acct->executable = fd_txn_account_is_executable( acc ); - memcpy( out_acct->owner, fd_txn_account_get_owner( acc ), sizeof(fd_pubkey_t) ); + out_acct->executable = acc->executable; + memcpy( out_acct->owner, acc->owner, sizeof(fd_pubkey_t) ); effects->modified_accounts_count++; } diff --git a/src/flamenco/runtime/tests/fd_solfuzz_private.h b/src/flamenco/runtime/tests/fd_solfuzz_private.h index 1176c56b8b..6a7044954b 100644 --- a/src/flamenco/runtime/tests/fd_solfuzz_private.h +++ b/src/flamenco/runtime/tests/fd_solfuzz_private.h @@ -28,12 +28,12 @@ FD_PROTOTYPES_BEGIN zero-lamport accounts from being loaded in. */ int fd_solfuzz_pb_load_account( fd_runtime_t * runtime, - fd_txn_account_t * acc, fd_accdb_user_t * accdb, fd_funk_txn_xid_t const * xid, fd_exec_test_acct_state_t const * state, uchar reject_zero_lamports, - ulong acc_idx ); + ulong acc_idx, + fd_account_meta_t * * meta_out ); /* Activates features in the runtime given an input feature set. Fails if a passed-in feature is unknown / not supported. */ diff --git a/src/flamenco/runtime/tests/fd_txn_harness.c b/src/flamenco/runtime/tests/fd_txn_harness.c index 7f88c6068f..22cbbf0a71 100644 --- a/src/flamenco/runtime/tests/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/fd_txn_harness.c @@ -81,8 +81,7 @@ fd_solfuzz_pb_txn_ctx_create( fd_solfuzz_runner_t * runner, for( ulong i = 0; i < test_ctx->account_shared_data_count; i++ ) { /* Load the accounts into the account manager Borrowed accounts get reset anyways - we just need to load the account somewhere */ - fd_txn_account_t acc[1]; - fd_solfuzz_pb_load_account( runner->runtime, acc, accdb, &xid, &test_ctx->account_shared_data[i], 1, i ); + fd_solfuzz_pb_load_account( runner->runtime, accdb, &xid, &test_ctx->account_shared_data[i], 1, i, NULL ); } /* Setup Bank manager */ diff --git a/src/flamenco/runtime/tests/fd_vm_harness.c b/src/flamenco/runtime/tests/fd_vm_harness.c index 2f5bd36dea..e78fd90040 100644 --- a/src/flamenco/runtime/tests/fd_vm_harness.c +++ b/src/flamenco/runtime/tests/fd_vm_harness.c @@ -148,19 +148,19 @@ do{ memcpy( rodata, input->vm_ctx.rodata->bytes, rodata_sz ); /* Setup input region */ - ulong input_sz = 0UL; - ulong pre_lens[256] = {0}; - fd_vm_input_region_t input_mem_regions[1000] = {0}; /* We can have a max of (3 * num accounts + 1) regions */ - fd_vm_acc_region_meta_t acc_region_metas[256] = {0}; /* instr acc idx to idx */ - uint input_mem_regions_cnt = 0UL; - int direct_mapping = FD_FEATURE_ACTIVE_BANK( instr_ctx->bank, account_data_direct_mapping ); - int stricter_abi_and_runtime_constraints = FD_FEATURE_ACTIVE_BANK( instr_ctx->bank, stricter_abi_and_runtime_constraints ); - - uchar * input_ptr = NULL; - uchar program_id_idx = instr_ctx->instr->program_id; - fd_txn_account_t const * program_acc = &instr_ctx->txn_out->accounts.accounts[program_id_idx]; - uchar is_deprecated = ( program_id_idx < instr_ctx->txn_out->accounts.accounts_cnt ) && - ( !memcmp( fd_txn_account_get_owner( program_acc ), fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ) ); + ulong input_sz = 0UL; + ulong pre_lens[256] = {0}; + fd_vm_input_region_t input_mem_regions[1000] = {0}; /* We can have a max of (3 * num accounts + 1) regions */ + fd_vm_acc_region_meta_t acc_region_metas[256] = {0}; /* instr acc idx to idx */ + uint input_mem_regions_cnt = 0UL; + int direct_mapping = FD_FEATURE_ACTIVE_BANK( instr_ctx->bank, account_data_direct_mapping ); + int stricter_abi_and_runtime_constraints = FD_FEATURE_ACTIVE_BANK( instr_ctx->bank, stricter_abi_and_runtime_constraints ); + + uchar * input_ptr = NULL; + uchar program_id_idx = instr_ctx->instr->program_id; + fd_account_meta_t const * program_acc = instr_ctx->txn_out->accounts.metas[program_id_idx]; + uchar is_deprecated = ( program_id_idx < instr_ctx->txn_out->accounts.accounts_cnt ) && + ( !memcmp( program_acc->owner, fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ) ); /* Push the instruction onto the stack. This may also modify the sysvar instructions account, if its present. */ int stack_push_err = fd_instr_stack_push( instr_ctx->runtime, instr_ctx->txn_in, instr_ctx->txn_out, (fd_instr_info_t *)instr_ctx->instr ); @@ -468,11 +468,11 @@ fd_solfuzz_pb_syscall_run( fd_solfuzz_runner_t * runner, int direct_mapping = FD_FEATURE_ACTIVE_BANK( ctx->bank, account_data_direct_mapping ); int stricter_abi_and_runtime_constraints = FD_FEATURE_ACTIVE_BANK( ctx->bank, stricter_abi_and_runtime_constraints ); - uchar * input_ptr = NULL; - uchar program_id_idx = ctx->instr->program_id; - fd_txn_account_t * program_acc = &ctx->txn_out->accounts.accounts[program_id_idx]; - uchar is_deprecated = ( program_id_idx < ctx->txn_out->accounts.accounts_cnt ) && - ( !memcmp( fd_txn_account_get_owner( program_acc ), fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ) ); + uchar * input_ptr = NULL; + uchar program_id_idx = ctx->instr->program_id; + fd_account_meta_t * program_acc = ctx->txn_out->accounts.metas[program_id_idx]; + uchar is_deprecated = ( program_id_idx < ctx->txn_out->accounts.accounts_cnt ) && + ( !memcmp( program_acc->owner, fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ) ); /* Push the instruction onto the stack. This may also modify the sysvar instructions account, if its present. */ int stack_push_err = fd_instr_stack_push( ctx->runtime, ctx->txn_in, ctx->txn_out, (fd_instr_info_t *)ctx->instr ); From 92c486aa8421492137cf326bb6981659d0d4b98e Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Tue, 25 Nov 2025 20:05:40 +0000 Subject: [PATCH 22/32] wip --- src/flamenco/runtime/fd_executor.c | 17 ++++------------- src/flamenco/runtime/fd_runtime.c | 4 ++-- src/flamenco/runtime/fd_runtime.h | 2 +- src/flamenco/runtime/tests/fd_txn_harness.c | 2 +- 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 7cc3503f39..7c44993780 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -970,15 +970,14 @@ fd_executor_create_rollback_fee_payer_account( fd_runtime_t * runtime, fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ulong total_fee ) { - fd_pubkey_t * fee_payer_key = &txn_out->accounts.account_keys[FD_FEE_PAYER_TXN_IDX]; - fd_txn_account_t * rollback_fee_payer_acc; + fd_pubkey_t * fee_payer_key = &txn_out->accounts.account_keys[FD_FEE_PAYER_TXN_IDX]; /* When setting the data of the rollback fee payer, there is an edge case where the fee payer is the nonce account. In this case, we can just deduct fees from the nonce account and return, because we save the nonce account in the commit phase anyways. */ if( FD_UNLIKELY( txn_out->accounts.nonce_idx_in_txn==FD_FEE_PAYER_TXN_IDX ) ) { - rollback_fee_payer_acc = txn_out->accounts.rollback_nonce; + txn_out->accounts.rollback_fee_payer = txn_out->accounts.rollback_nonce->meta; } else { fd_account_meta_t const * meta = NULL; if( FD_UNLIKELY( txn_in->bundle.is_bundle ) ) { @@ -1012,19 +1011,11 @@ fd_executor_create_rollback_fee_payer_account( fd_runtime_t * runtime, uchar * fee_payer_data = txn_in->exec_accounts->rollback_fee_payer_mem; fd_memcpy( fee_payer_data, (uchar *)meta, sizeof(fd_account_meta_t) + meta->dlen ); - if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new( - txn_out->accounts.rollback_fee_payer, - fee_payer_key, - (fd_account_meta_t *)fee_payer_data, - 1 ) ) ) ) { - FD_LOG_CRIT(( "Failed to join txn account" )); - } - - rollback_fee_payer_acc = txn_out->accounts.rollback_fee_payer; + txn_out->accounts.rollback_fee_payer = fd_type_pun( fee_payer_data ); } /* Deduct the transaction fees from the rollback account. Because of prior checks, this should never fail. */ - if( FD_UNLIKELY( fd_txn_account_checked_sub_lamports( rollback_fee_payer_acc, total_fee ) ) ) { + if( FD_UNLIKELY( fd_account_meta_checked_sub_lamports( txn_out->accounts.rollback_fee_payer, total_fee ) ) ) { FD_LOG_ERR(( "fd_executor_create_rollback_fee_payer_account(): failed to deduct fees from rollback account" )); } } diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 2cde4c1596..820906eced 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1228,8 +1228,8 @@ fd_runtime_commit_txn( fd_runtime_t * runtime, if( FD_LIKELY( txn_out->accounts.nonce_idx_in_txn!=FD_FEE_PAYER_TXN_IDX ) ) { fd_runtime_save_account( runtime->funk, &xid, - txn_out->accounts.rollback_fee_payer->pubkey, - txn_out->accounts.rollback_fee_payer->meta, + &txn_out->accounts.account_keys[FD_FEE_PAYER_TXN_IDX], + txn_out->accounts.rollback_fee_payer, bank, runtime->log.capture_ctx ); } diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index 00b7a0439a..107c1f8f5f 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -218,7 +218,7 @@ struct fd_txn_out { fd_txn_account_t rollback_nonce[ 1 ]; /* If the transaction has a nonce account that must be advanced, this would be !=ULONG_MAX. */ - fd_txn_account_t rollback_fee_payer[ 1 ]; + fd_account_meta_t * rollback_fee_payer; fd_pubkey_t pubkeys[ MAX_TX_ACCOUNT_LOCKS ]; fd_account_meta_t * metas[ MAX_TX_ACCOUNT_LOCKS ]; diff --git a/src/flamenco/runtime/tests/fd_txn_harness.c b/src/flamenco/runtime/tests/fd_txn_harness.c index 22cbbf0a71..803c553631 100644 --- a/src/flamenco/runtime/tests/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/fd_txn_harness.c @@ -496,7 +496,7 @@ fd_solfuzz_pb_txn_run( fd_solfuzz_runner_t * runner, accounts_cnt = 0UL; if( FD_LIKELY( txn_out->accounts.nonce_idx_in_txn!=FD_FEE_PAYER_TXN_IDX ) ) { - accounts_to_save[accounts_cnt++] = txn_out->accounts.rollback_fee_payer->meta; + accounts_to_save[accounts_cnt++] = txn_out->accounts.rollback_fee_payer; } if( txn_out->accounts.nonce_idx_in_txn!=ULONG_MAX ) { From d88f46e05c3fc6af77e352a2e136a7e08a8aae30 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Tue, 25 Nov 2025 20:10:47 +0000 Subject: [PATCH 23/32] wip --- src/flamenco/runtime/fd_executor.c | 2 +- src/flamenco/runtime/fd_runtime.c | 6 +++--- src/flamenco/runtime/fd_runtime.h | 2 +- .../runtime/program/fd_system_program_nonce.c | 14 ++++---------- src/flamenco/runtime/tests/fd_txn_harness.c | 2 +- 5 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 7c44993780..120e9103f5 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -977,7 +977,7 @@ fd_executor_create_rollback_fee_payer_account( fd_runtime_t * runtime, can just deduct fees from the nonce account and return, because we save the nonce account in the commit phase anyways. */ if( FD_UNLIKELY( txn_out->accounts.nonce_idx_in_txn==FD_FEE_PAYER_TXN_IDX ) ) { - txn_out->accounts.rollback_fee_payer = txn_out->accounts.rollback_nonce->meta; + txn_out->accounts.rollback_fee_payer = txn_out->accounts.rollback_nonce; } else { fd_account_meta_t const * meta = NULL; if( FD_UNLIKELY( txn_in->bundle.is_bundle ) ) { diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 820906eced..bcd9d0c6c1 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -984,7 +984,7 @@ fd_runtime_pre_execute_check( fd_runtime_t * runtime, /* If the nonce account is not the fee payer, then we separately add the dlen of the nonce account. Otherwise, we would be double counting the dlen of the fee payer. */ if( txn_out->accounts.nonce_idx_in_txn!=FD_FEE_PAYER_TXN_IDX ) { - txn_out->details.loaded_accounts_data_size += fd_txn_account_get_data_len( txn_out->accounts.rollback_nonce ); + txn_out->details.loaded_accounts_data_size += txn_out->accounts.rollback_nonce->dlen; } } } @@ -1218,8 +1218,8 @@ fd_runtime_commit_txn( fd_runtime_t * runtime, if( txn_out->accounts.nonce_idx_in_txn!=ULONG_MAX ) { fd_runtime_save_account( runtime->funk, &xid, - txn_out->accounts.rollback_nonce->pubkey, - txn_out->accounts.rollback_nonce->meta, + &txn_out->accounts.account_keys[txn_out->accounts.nonce_idx_in_txn], + txn_out->accounts.rollback_nonce, bank, runtime->log.capture_ctx ); } diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index 107c1f8f5f..09a6c4f292 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -215,7 +215,7 @@ struct fd_txn_out { in this state and then they are free to be committed to the accounts database. */ ulong nonce_idx_in_txn; - fd_txn_account_t rollback_nonce[ 1 ]; + fd_account_meta_t * rollback_nonce; /* If the transaction has a nonce account that must be advanced, this would be !=ULONG_MAX. */ fd_account_meta_t * rollback_fee_payer; diff --git a/src/flamenco/runtime/program/fd_system_program_nonce.c b/src/flamenco/runtime/program/fd_system_program_nonce.c index 9d7bb68f4b..d15a455848 100644 --- a/src/flamenco/runtime/program/fd_system_program_nonce.c +++ b/src/flamenco/runtime/program/fd_system_program_nonce.c @@ -1044,21 +1044,15 @@ fd_check_transaction_age( fd_runtime_t * runtime, } fd_memcpy( borrowed_account_data, meta, sizeof(fd_account_meta_t)+acc_data_len ); - if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new( - txn_out->accounts.rollback_nonce, - &txn_out->accounts.account_keys[ instr_accts[ 0UL ] ], - (fd_account_meta_t *)borrowed_account_data, - 1 ) ) ) ) { - FD_LOG_CRIT(( "Failed to join txn account" )); - } + txn_out->accounts.rollback_nonce = (fd_account_meta_t *)borrowed_account_data; - if( FD_UNLIKELY( fd_nonce_state_versions_size( &new_state )>fd_txn_account_get_data_len( txn_out->accounts.rollback_nonce ) ) ) { + if( FD_UNLIKELY( fd_nonce_state_versions_size( &new_state )>txn_out->accounts.rollback_nonce->dlen ) ) { return FD_RUNTIME_TXN_ERR_BLOCKHASH_FAIL_ADVANCE_NONCE_INSTR; } do { fd_bincode_encode_ctx_t encode_ctx = - { .data = fd_txn_account_get_data_mut( txn_out->accounts.rollback_nonce ), - .dataend = fd_txn_account_get_data_mut( txn_out->accounts.rollback_nonce ) + fd_txn_account_get_data_len( txn_out->accounts.rollback_nonce ) }; + { .data = fd_account_data( txn_out->accounts.rollback_nonce ), + .dataend = fd_account_data( txn_out->accounts.rollback_nonce ) + txn_out->accounts.rollback_nonce->dlen }; int err = fd_nonce_state_versions_encode( &new_state, &encode_ctx ); if( FD_UNLIKELY( err ) ) { return FD_RUNTIME_TXN_ERR_BLOCKHASH_FAIL_ADVANCE_NONCE_INSTR; diff --git a/src/flamenco/runtime/tests/fd_txn_harness.c b/src/flamenco/runtime/tests/fd_txn_harness.c index 803c553631..e025bc44e2 100644 --- a/src/flamenco/runtime/tests/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/fd_txn_harness.c @@ -500,7 +500,7 @@ fd_solfuzz_pb_txn_run( fd_solfuzz_runner_t * runner, } if( txn_out->accounts.nonce_idx_in_txn!=ULONG_MAX ) { - accounts_to_save[accounts_cnt++] = txn_out->accounts.rollback_nonce->meta; + accounts_to_save[accounts_cnt++] = txn_out->accounts.rollback_nonce; } } From 67f0d3c08db6160f3801a4fb95498a6f175a0685 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Tue, 25 Nov 2025 20:25:50 +0000 Subject: [PATCH 24/32] wip --- src/discof/bank/fd_bank_tile.c | 4 +- src/flamenco/log_collector/fd_log_collector.h | 2 +- .../runtime/context/fd_exec_instr_ctx.c | 8 +-- src/flamenco/runtime/fd_cost_tracker.c | 8 +-- src/flamenco/runtime/fd_executor.c | 61 +++++++++---------- src/flamenco/runtime/fd_runtime.c | 24 ++++---- src/flamenco/runtime/fd_runtime.h | 7 +-- .../program/fd_bpf_loader_serialization.c | 4 +- .../runtime/program/fd_system_program.c | 4 +- .../runtime/program/fd_system_program_nonce.c | 6 +- src/flamenco/runtime/sysvar/fd_sysvar.c | 2 +- .../runtime/sysvar/fd_sysvar_instructions.c | 4 +- src/flamenco/runtime/tests/fd_dump_pb.c | 22 +++---- src/flamenco/runtime/tests/fd_instr_harness.c | 26 ++++---- src/flamenco/runtime/tests/fd_txn_harness.c | 8 +-- src/flamenco/runtime/tests/fd_vm_harness.c | 4 +- .../vm/syscall/fd_vm_syscall_cpi_common.c | 6 +- 17 files changed, 99 insertions(+), 101 deletions(-) diff --git a/src/discof/bank/fd_bank_tile.c b/src/discof/bank/fd_bank_tile.c index dd93193580..50d72e8091 100644 --- a/src/discof/bank/fd_bank_tile.c +++ b/src/discof/bank/fd_bank_tile.c @@ -274,7 +274,7 @@ handle_microblock( fd_bank_ctx_t * ctx, that first the non-alt accounts are laid out, then the writable alt accounts, and finally the read-only alt accounts. */ fd_txn_t * txn_descriptor = TXN( txn_in->txn ); - fd_acct_addr_t const * writable_alt = fd_type_pun_const( txn_out->accounts.account_keys+txn_descriptor->acct_addr_cnt ); + fd_acct_addr_t const * writable_alt = fd_type_pun_const( txn_out->accounts.keys+txn_descriptor->acct_addr_cnt ); if( FD_LIKELY( ctx->enable_rebates ) ) fd_pack_rebate_sum_add_txn( ctx->rebater, txn, &writable_alt, 1UL ); /* The VM will stop executing and fail an instruction immediately if @@ -390,7 +390,7 @@ handle_bundle( fd_bank_ctx_t * ctx, continue; } - writable_alt[i] = fd_type_pun_const( txn_out->accounts.account_keys+TXN( txn_in->txn )->acct_addr_cnt ); + writable_alt[i] = fd_type_pun_const( txn_out->accounts.keys+TXN( txn_in->txn )->acct_addr_cnt ); } /* If all of the transactions in the bundle executed successfully, we diff --git a/src/flamenco/log_collector/fd_log_collector.h b/src/flamenco/log_collector/fd_log_collector.h index d59645c0df..1fc1b45242 100644 --- a/src/flamenco/log_collector/fd_log_collector.h +++ b/src/flamenco/log_collector/fd_log_collector.h @@ -387,7 +387,7 @@ fd_log_collector_program_invoke( fd_exec_instr_ctx_t * ctx ) { return; } - fd_pubkey_t const * program_id_pubkey = &ctx->txn_out->accounts.account_keys[ ctx->instr->program_id ]; + fd_pubkey_t const * program_id_pubkey = &ctx->txn_out->accounts.keys[ ctx->instr->program_id ]; /* Cache ctx->program_id_base58 */ fd_base58_encode_32( program_id_pubkey->uc, NULL, ctx->program_id_base58 ); /* Max msg_sz: 22 - 4 + 44 + 10 = 72 < 127 => we can use printf */ diff --git a/src/flamenco/runtime/context/fd_exec_instr_ctx.c b/src/flamenco/runtime/context/fd_exec_instr_ctx.c index c6877249cc..ceb0f84035 100644 --- a/src/flamenco/runtime/context/fd_exec_instr_ctx.c +++ b/src/flamenco/runtime/context/fd_exec_instr_ctx.c @@ -7,7 +7,7 @@ fd_exec_instr_ctx_find_idx_of_instr_account( fd_exec_instr_ctx_t const * ctx, fd_pubkey_t const * pubkey ) { for( int i=0; iinstr->acct_cnt; i++ ) { ushort idx_in_txn = ctx->instr->accounts[ i ].index_in_transaction; - if( memcmp( pubkey->uc, ctx->txn_out->accounts.account_keys[ idx_in_txn ].uc, sizeof(fd_pubkey_t) )==0 ) { + if( memcmp( pubkey->uc, ctx->txn_out->accounts.keys[ idx_in_txn ].uc, sizeof(fd_pubkey_t) )==0 ) { return i; } } @@ -69,7 +69,7 @@ fd_exec_instr_ctx_try_borrow_account( fd_exec_instr_ctx_t const * ctx, /* Create a BorrowedAccount upon success. https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L606 */ fd_borrowed_account_init( account, - &ctx->txn_out->accounts.account_keys[idx_in_txn], + &ctx->txn_out->accounts.keys[idx_in_txn], meta, ctx, idx_in_instr, @@ -103,7 +103,7 @@ fd_exec_instr_ctx_try_borrow_instr_account_with_key( fd_exec_instr_ctx_t const * fd_borrowed_account_t * account ) { for( ushort i=0; iinstr->acct_cnt; i++ ) { ushort idx_in_txn = ctx->instr->accounts[ i ].index_in_transaction; - if( memcmp( pubkey->uc, ctx->txn_out->accounts.account_keys[ idx_in_txn ].uc, sizeof(fd_pubkey_t) )==0 ) { + if( memcmp( pubkey->uc, ctx->txn_out->accounts.keys[ idx_in_txn ].uc, sizeof(fd_pubkey_t) )==0 ) { return fd_exec_instr_ctx_try_borrow_instr_account( ctx, i, account ); } } @@ -150,7 +150,7 @@ fd_exec_instr_ctx_any_signed( fd_exec_instr_ctx_t const * ctx, ushort idx_in_txn = ctx->instr->accounts[ j ].index_in_transaction; is_signer |= ( ( !!fd_instr_acc_is_signer_idx( ctx->instr, j, NULL ) ) & - ( 0==memcmp( pubkey->key, ctx->txn_out->accounts.account_keys[ idx_in_txn ].key, sizeof(fd_pubkey_t) ) ) ); + ( 0==memcmp( pubkey->key, ctx->txn_out->accounts.keys[ idx_in_txn ].key, sizeof(fd_pubkey_t) ) ) ); } return is_signer; } diff --git a/src/flamenco/runtime/fd_cost_tracker.c b/src/flamenco/runtime/fd_cost_tracker.c index 716eaff231..33eb29caf0 100644 --- a/src/flamenco/runtime/fd_cost_tracker.c +++ b/src/flamenco/runtime/fd_cost_tracker.c @@ -389,10 +389,10 @@ would_fit( fd_cost_tracker_t const * cost_tracker, account_cost_map_t const * map = fd_type_pun_const(((cost_tracker_outer_t const *)cost_tracker)+1UL); account_cost_t const * pool = fd_type_pun_const( (void*)((ulong)cost_tracker + ((cost_tracker_outer_t const *)cost_tracker)->pool_offset) ); - for( ulong i=0UL; iaccounts.accounts_cnt; i++ ) { + for( ulong i=0UL; iaccounts.cnt; i++ ) { if( !fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, (ushort)i ) ) continue; - fd_pubkey_t const * writable_acc = &txn_out->accounts.account_keys[i]; + fd_pubkey_t const * writable_acc = &txn_out->accounts.keys[i]; account_cost_t const * chained_cost = account_cost_map_ele_query_const( map, writable_acc, NULL, pool ); if( FD_UNLIKELY( chained_cost && fd_ulong_sat_add( chained_cost->cost, cost )>cost_tracker->account_cost_limit ) ) { @@ -415,10 +415,10 @@ add_transaction_execution_cost( fd_cost_tracker_t * _cost_tracker, account_cost_map_t * map = fd_type_pun( cost_tracker+1UL ); account_cost_t * pool = fd_type_pun( (void*)((ulong)cost_tracker+cost_tracker->pool_offset) ); - for( ulong i=0UL; iaccounts.accounts_cnt; i++ ) { + for( ulong i=0UL; iaccounts.cnt; i++ ) { if( FD_LIKELY( !fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, (ushort)i ) ) ) continue; - fd_pubkey_t const * writable_acc = &txn_out->accounts.account_keys[i]; + fd_pubkey_t const * writable_acc = &txn_out->accounts.keys[i]; account_cost_t * account_cost = account_cost_map_ele_query( map, writable_acc, NULL, pool ); if( FD_UNLIKELY( !account_cost ) ) { diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 120e9103f5..2ac9578f11 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -524,7 +524,7 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, ulong requested_loaded_accounts_data_size = txn_out->details.compute_budget.loaded_accounts_data_size_limit; /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L429-L443 */ - for( ushort i=0; iaccounts.accounts_cnt; i++ ) { + for( ushort i=0; iaccounts.cnt; i++ ) { fd_account_meta_t * meta = txn_out->accounts.metas[i]; uchar unknown_acc = !!(fd_runtime_get_account_at_index( txn_in, txn_out, i, fd_runtime_account_check_exists ) || meta->lamports==0UL); @@ -550,7 +550,7 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, } /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L733-L740 */ - ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, &txn_out->accounts.account_keys[i], meta, is_writable, unknown_acc, i ); + ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, &txn_out->accounts.keys[i], meta, is_writable, unknown_acc, i ); int err = accumulate_and_check_loaded_account_data_size( loaded_acc_size, requested_loaded_accounts_data_size, &txn_out->details.loaded_accounts_data_size ); @@ -572,7 +572,7 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, fd_txn_instr_t const * instr = &TXN( txn_in->txn )->instr[i]; /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L449-L451 */ - if( FD_UNLIKELY( !memcmp( txn_out->accounts.account_keys[ instr->program_id ].key, fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) ) ) { + if( FD_UNLIKELY( !memcmp( txn_out->accounts.keys[ instr->program_id ].key, fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) ) ) { continue; } @@ -712,8 +712,8 @@ fd_collect_loaded_account( fd_runtime_t * runtime, /* Iterate through the account keys and make sure the programdata account is not present so it doesn't get loaded twice. https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L617 */ - for( ushort i=0; iaccounts.accounts_cnt; i++ ) { - if( FD_UNLIKELY( !memcmp( &txn_out->accounts.account_keys[i], &loader_state->inner.program.programdata_address, sizeof(fd_pubkey_t) ) ) ) { + for( ushort i=0; iaccounts.cnt; i++ ) { + if( FD_UNLIKELY( !memcmp( &txn_out->accounts.keys[i], &loader_state->inner.program.programdata_address, sizeof(fd_pubkey_t) ) ) ) { return FD_RUNTIME_EXECUTE_SUCCESS; } } @@ -790,7 +790,7 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, } /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L642-L660 */ - for( ushort i=0; iaccounts.accounts_cnt; i++ ) { + for( ushort i=0; iaccounts.cnt; i++ ) { fd_account_meta_t * meta = txn_out->accounts.metas[i]; uchar unknown_acc = !!(fd_runtime_get_account_at_index( txn_in, txn_out, i, fd_runtime_account_check_exists ) || @@ -825,7 +825,7 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, /* Load and collect any remaining accounts https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L652-L659 */ - ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, &txn_out->accounts.account_keys[i], meta, is_writable, unknown_acc, i ); + ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, &txn_out->accounts.keys[i], meta, is_writable, unknown_acc, i ); int err = fd_collect_loaded_account( runtime, txn_out, @@ -892,15 +892,15 @@ fd_executor_validate_account_locks( fd_bank_t * bank, /* Ensure the number of account keys does not exceed the transaction lock limit https://github.com/anza-xyz/agave/blob/v2.2.17/accounts-db/src/account_locks.rs#L121 */ ulong tx_account_lock_limit = get_transaction_account_lock_limit( bank ); - if( FD_UNLIKELY( txn_out->accounts.accounts_cnt>tx_account_lock_limit ) ) { + if( FD_UNLIKELY( txn_out->accounts.cnt>tx_account_lock_limit ) ) { return FD_RUNTIME_TXN_ERR_TOO_MANY_ACCOUNT_LOCKS; } /* Duplicate account check https://github.com/anza-xyz/agave/blob/v2.2.17/accounts-db/src/account_locks.rs#L123 */ - for( ushort i=0; iaccounts.accounts_cnt; i++ ) { - for( ushort j=(ushort)(i+1U); jaccounts.accounts_cnt; j++ ) { - if( FD_UNLIKELY( !memcmp( &txn_out->accounts.account_keys[i], &txn_out->accounts.account_keys[j], sizeof(fd_pubkey_t) ) ) ) { + for( ushort i=0; iaccounts.cnt; i++ ) { + for( ushort j=(ushort)(i+1U); jaccounts.cnt; j++ ) { + if( FD_UNLIKELY( !memcmp( &txn_out->accounts.keys[i], &txn_out->accounts.keys[j], sizeof(fd_pubkey_t) ) ) ) { return FD_RUNTIME_TXN_ERR_ACCOUNT_LOADED_TWICE; } } @@ -933,7 +933,7 @@ fd_executor_calculate_fee( fd_bank_t * bank, ulong num_signatures = txn_descriptor->signature_cnt; for (ushort i=0; iinstr_cnt; ++i ) { fd_txn_instr_t const * txn_instr = &txn_descriptor->instr[i]; - fd_pubkey_t * program_id = &txn_out->accounts.account_keys[txn_instr->program_id]; + fd_pubkey_t * program_id = &txn_out->accounts.keys[txn_instr->program_id]; if( !memcmp(program_id->uc, fd_solana_keccak_secp_256k_program_id.key, sizeof(fd_pubkey_t)) || !memcmp(program_id->uc, fd_solana_ed25519_sig_verify_program_id.key, sizeof(fd_pubkey_t)) || (!memcmp(program_id->uc, fd_solana_secp256r1_program_id.key, sizeof(fd_pubkey_t)) && FD_FEATURE_ACTIVE_BANK( bank, enable_secp256r1_precompile )) ) { @@ -970,7 +970,7 @@ fd_executor_create_rollback_fee_payer_account( fd_runtime_t * runtime, fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ulong total_fee ) { - fd_pubkey_t * fee_payer_key = &txn_out->accounts.account_keys[FD_FEE_PAYER_TXN_IDX]; + fd_pubkey_t * fee_payer_key = &txn_out->accounts.keys[FD_FEE_PAYER_TXN_IDX]; /* When setting the data of the rollback fee payer, there is an edge case where the fee payer is the nonce account. In this case, we @@ -985,8 +985,8 @@ fd_executor_create_rollback_fee_payer_account( fd_runtime_t * runtime, for( ulong i=txn_in->bundle.prev_txn_cnt; i>0UL && !is_found; i-- ) {; fd_txn_in_t const * prev_txn_in = txn_in->bundle.prev_txn_ins[ i-1 ]; fd_txn_out_t const * prev_txn_out = txn_in->bundle.prev_txn_outs[ i-1 ]; - for( ushort j=0UL; jaccounts.accounts_cnt; j++ ) { - if( !memcmp( &prev_txn_out->accounts.account_keys[ j ], fee_payer_key, sizeof(fd_pubkey_t) ) && + for( ushort j=0UL; jaccounts.cnt; j++ ) { + if( !memcmp( &prev_txn_out->accounts.keys[ j ], fee_payer_key, sizeof(fd_pubkey_t) ) && fd_runtime_account_is_writable_idx( prev_txn_in, prev_txn_out, bank, j ) ) { /* Found the account in a previous transaction */ meta = prev_txn_out->accounts.metas[ j ]; @@ -1035,7 +1035,7 @@ fd_executor_validate_transaction_fee_payer( fd_runtime_t * runtime, return FD_RUNTIME_TXN_ERR_ACCOUNT_NOT_FOUND; } - fd_pubkey_t * fee_payer_key = &txn_out->accounts.account_keys[FD_FEE_PAYER_TXN_IDX]; + fd_pubkey_t * fee_payer_key = &txn_out->accounts.keys[FD_FEE_PAYER_TXN_IDX]; fd_account_meta_t * fee_payer_meta = txn_out->accounts.metas[FD_FEE_PAYER_TXN_IDX]; /* Calculate transaction fees @@ -1074,12 +1074,12 @@ fd_executor_validate_transaction_fee_payer( fd_runtime_t * runtime, void fd_executor_setup_txn_account_keys( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out ) { - txn_out->accounts.accounts_cnt = (uchar)TXN( txn_in->txn )->acct_addr_cnt; + txn_out->accounts.cnt = (uchar)TXN( txn_in->txn )->acct_addr_cnt; fd_pubkey_t * tx_accs = (fd_pubkey_t *)((uchar *)txn_in->txn->payload + TXN( txn_in->txn )->acct_addr_off); // Set up accounts in the transaction body and perform checks for( ulong i = 0UL; i < TXN( txn_in->txn )->acct_addr_cnt; i++ ) { - txn_out->accounts.account_keys[i] = tx_accs[i]; + txn_out->accounts.keys[i] = tx_accs[i]; } } @@ -1099,7 +1099,7 @@ fd_executor_setup_txn_alut_account_keys( fd_runtime_t * runtime, return FD_RUNTIME_TXN_ERR_ACCOUNT_NOT_FOUND; } fd_funk_txn_xid_t xid = { .ul = { fd_bank_slot_get( bank ), bank->idx } }; - fd_acct_addr_t * accts_alt = (fd_acct_addr_t *) fd_type_pun( &txn_out->accounts.account_keys[txn_out->accounts.accounts_cnt] ); + fd_acct_addr_t * accts_alt = (fd_acct_addr_t *) fd_type_pun( &txn_out->accounts.keys[txn_out->accounts.cnt] ); int err = fd_runtime_load_txn_address_lookup_tables( TXN( txn_in->txn ), txn_in->txn->payload, runtime->funk, @@ -1108,7 +1108,7 @@ fd_executor_setup_txn_alut_account_keys( fd_runtime_t * runtime, slot_hashes, accts_alt ); fd_sysvar_cache_slot_hashes_leave_const( sysvar_cache, slot_hashes ); - txn_out->accounts.accounts_cnt += TXN( txn_in->txn )->addr_table_adtl_cnt; + txn_out->accounts.cnt += TXN( txn_in->txn )->addr_table_adtl_cnt; if( FD_UNLIKELY( err!=FD_RUNTIME_EXECUTE_SUCCESS ) ) return err; } @@ -1345,7 +1345,7 @@ fd_execute_instr( fd_runtime_t * runtime, .txn_out = txn_out, .bank = bank, }; - fd_base58_encode_32( txn_out->accounts.account_keys[ instr->program_id ].uc, NULL, ctx->program_id_base58 ); + fd_base58_encode_32( txn_out->accounts.keys[ instr->program_id ].uc, NULL, ctx->program_id_base58 ); runtime->instr.trace[ runtime->instr.trace_length - 1 ] = (fd_exec_instr_trace_entry_t) { .instr_info = instr, @@ -1356,7 +1356,7 @@ fd_execute_instr( fd_runtime_t * runtime, https://github.com/anza-xyz/agave/blob/v2.1.6/svm/src/message_processor.rs#L88 */ fd_exec_instr_fn_t native_prog_fn; uchar is_precompile; - int err = fd_executor_lookup_native_program( &txn_out->accounts.account_keys[ instr->program_id ], + int err = fd_executor_lookup_native_program( &txn_out->accounts.keys[ instr->program_id ], txn_out->accounts.metas[ instr->program_id ], bank, &native_prog_fn, @@ -1434,7 +1434,7 @@ fd_executor_setup_txn_account( fd_runtime_t * runtime, /* To setup a transaction account, we need to first retrieve a read-only handle to the account from the database. */ - fd_pubkey_t * acc = &txn_out->accounts.account_keys[ idx ]; + fd_pubkey_t * acc = &txn_out->accounts.keys[ idx ]; fd_account_meta_t const * meta = NULL; @@ -1455,8 +1455,8 @@ fd_executor_setup_txn_account( fd_runtime_t * runtime, for( ulong i=txn_in->bundle.prev_txn_cnt; i>0UL && !is_found; i-- ) { fd_txn_in_t const * prev_txn_in = txn_in->bundle.prev_txn_ins[ i-1 ]; fd_txn_out_t const * prev_txn_out = txn_in->bundle.prev_txn_outs[ i-1 ]; - for( ushort j=0UL; jaccounts.accounts_cnt; j++ ) { - if( !memcmp( &prev_txn_out->accounts.account_keys[ j ], acc, sizeof(fd_pubkey_t) ) && fd_runtime_account_is_writable_idx( prev_txn_in, prev_txn_out, bank, j ) ) { + for( ushort j=0UL; jaccounts.cnt; j++ ) { + if( !memcmp( &prev_txn_out->accounts.keys[ j ], acc, sizeof(fd_pubkey_t) ) && fd_runtime_account_is_writable_idx( prev_txn_in, prev_txn_out, bank, j ) ) { /* Found the account in a previous transaction */ meta = prev_txn_out->accounts.metas[ j ]; is_found = 1; @@ -1523,7 +1523,6 @@ fd_executor_setup_txn_account( fd_runtime_t * runtime, runtime->accounts.starting_lamports[idx] = account_meta->lamports; runtime->accounts.starting_dlen[idx] = account_meta->dlen; runtime->accounts.refcnt[idx] = 0UL; - memcpy( &txn_out->accounts.pubkeys[idx], acc, sizeof(fd_pubkey_t) ); txn_out->accounts.metas[ idx ] = account_meta; } @@ -1571,7 +1570,7 @@ fd_executor_setup_accounts_for_txn( fd_runtime_t * runtime, ushort executable_idx = 0U; - for( ushort i=0; iaccounts.accounts_cnt; i++ ) { + for( ushort i=0; iaccounts.cnt; i++ ) { fd_executor_setup_txn_account( runtime, bank, txn_in, txn_out, i ); fd_account_meta_t * meta = txn_out->accounts.metas[ i ]; @@ -1586,10 +1585,10 @@ fd_executor_setup_accounts_for_txn( fd_runtime_t * runtime, fd_bank_slot_get( bank ) >= runtime->log.capture_ctx->dump_proto_start_slot && runtime->log.capture_ctx->dump_elf_to_pb; if( FD_UNLIKELY( dump_elf_to_pb ) ) { - for( ushort i=0; iaccounts.accounts_cnt; i++ ) { + for( ushort i=0; iaccounts.cnt; i++ ) { fd_txn_account_t txn_account[1]; txn_account->meta = txn_out->accounts.metas[i]; - fd_memcpy( txn_account->pubkey, &txn_out->accounts.account_keys[i], sizeof(fd_pubkey_t) ); + fd_memcpy( txn_account->pubkey, &txn_out->accounts.keys[i], sizeof(fd_pubkey_t) ); fd_dump_elf_to_protobuf( runtime, bank, txn_in, txn_account ); } } @@ -1633,11 +1632,11 @@ fd_executor_txn_check( fd_runtime_t * runtime, ulong ending_lamports_h = 0; /* https://github.com/anza-xyz/agave/blob/b2c388d6cbff9b765d574bbb83a4378a1fc8af32/svm/src/account_rent_state.rs#L63 */ - for( ulong idx = 0; idx < txn_out->accounts.accounts_cnt; idx++ ) { + for( ulong idx = 0; idx < txn_out->accounts.cnt; idx++ ) { ulong starting_lamports = runtime->accounts.starting_lamports[idx]; ulong starting_dlen = runtime->accounts.starting_dlen[idx]; fd_account_meta_t * meta = txn_out->accounts.metas[idx]; - fd_pubkey_t * pubkey = &txn_out->accounts.account_keys[idx]; + fd_pubkey_t * pubkey = &txn_out->accounts.keys[idx]; // Was this account written to? /* TODO: Clean this logic up... lots of redundant checks with our newer account loading model. diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index bcd9d0c6c1..627fd9d67e 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1218,7 +1218,7 @@ fd_runtime_commit_txn( fd_runtime_t * runtime, if( txn_out->accounts.nonce_idx_in_txn!=ULONG_MAX ) { fd_runtime_save_account( runtime->funk, &xid, - &txn_out->accounts.account_keys[txn_out->accounts.nonce_idx_in_txn], + &txn_out->accounts.keys[txn_out->accounts.nonce_idx_in_txn], txn_out->accounts.rollback_nonce, bank, runtime->log.capture_ctx ); @@ -1228,21 +1228,21 @@ fd_runtime_commit_txn( fd_runtime_t * runtime, if( FD_LIKELY( txn_out->accounts.nonce_idx_in_txn!=FD_FEE_PAYER_TXN_IDX ) ) { fd_runtime_save_account( runtime->funk, &xid, - &txn_out->accounts.account_keys[FD_FEE_PAYER_TXN_IDX], + &txn_out->accounts.keys[FD_FEE_PAYER_TXN_IDX], txn_out->accounts.rollback_fee_payer, bank, runtime->log.capture_ctx ); } } else { - for( ushort i=0; iaccounts.accounts_cnt; i++ ) { + for( ushort i=0; iaccounts.cnt; i++ ) { /* We are only interested in saving writable accounts and the fee payer account. */ if( !fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, i ) && i!=FD_FEE_PAYER_TXN_IDX ) { continue; } - fd_pubkey_t const * pubkey = &txn_out->accounts.account_keys[i]; + fd_pubkey_t const * pubkey = &txn_out->accounts.keys[i]; fd_account_meta_t * meta = txn_out->accounts.metas[i]; /* Tips for bundles are collected in the bank: a user submitting a @@ -1337,7 +1337,7 @@ fd_runtime_prepare_and_execute_txn( fd_runtime_t * runtime, txn_out->details.exec_start_timestamp = LONG_MAX; txn_out->details.commit_start_timestamp = LONG_MAX; - txn_out->accounts.accounts_cnt = 0UL; + txn_out->accounts.cnt = 0UL; txn_out->details.programs_to_reverify_cnt = 0UL; txn_out->details.loaded_accounts_data_size = 0UL; @@ -1743,8 +1743,8 @@ fd_runtime_block_execute_finalize( fd_bank_t * bank, int fd_runtime_find_index_of_account( fd_txn_out_t const * txn_out, fd_pubkey_t const * pubkey ) { - for( ulong i=txn_out->accounts.accounts_cnt; i>0UL; i-- ) { - if( 0==memcmp( pubkey, &txn_out->accounts.account_keys[ i-1UL ], sizeof(fd_pubkey_t) ) ) { + for( ulong i=txn_out->accounts.cnt; i>0UL; i-- ) { + if( 0==memcmp( pubkey, &txn_out->accounts.keys[ i-1UL ], sizeof(fd_pubkey_t) ) ) { return (int)(i-1UL); } } @@ -1756,7 +1756,7 @@ fd_runtime_get_account_at_index( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx, fd_txn_account_condition_fn_t * condition ) { - if( FD_UNLIKELY( idx>=txn_out->accounts.accounts_cnt ) ) { + if( FD_UNLIKELY( idx>=txn_out->accounts.cnt ) ) { return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT; } @@ -1834,11 +1834,11 @@ fd_runtime_get_key_of_account_at_index( fd_txn_out_t * txn_out, fd_pubkey_t const * * key ) { /* Return a NotEnoughAccountKeys error if idx is out of bounds. https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L218 */ - if( FD_UNLIKELY( idx>=txn_out->accounts.accounts_cnt ) ) { + if( FD_UNLIKELY( idx>=txn_out->accounts.cnt ) ) { return FD_EXECUTOR_INSTR_ERR_MISSING_ACC; } - *key = &txn_out->accounts.account_keys[ idx ]; + *key = &txn_out->accounts.keys[ idx ]; return FD_EXECUTOR_INSTR_SUCCESS; } @@ -1909,10 +1909,10 @@ fd_runtime_account_is_writable_idx( fd_txn_in_t const * txn_in, fd_txn_out_t const * txn_out, fd_bank_t * bank, ushort idx ) { - uint bpf_upgradeable = fd_txn_account_has_bpf_loader_upgradeable( txn_out->accounts.account_keys, txn_out->accounts.accounts_cnt ); + uint bpf_upgradeable = fd_txn_account_has_bpf_loader_upgradeable( txn_out->accounts.keys, txn_out->accounts.cnt ); return fd_runtime_account_is_writable_idx_flat( fd_bank_slot_get( bank ), idx, - &txn_out->accounts.account_keys[idx], + &txn_out->accounts.keys[idx], TXN( txn_in->txn ), fd_bank_features_query( bank ), bpf_upgradeable ); diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index 09a6c4f292..2436113c3a 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -201,10 +201,11 @@ struct fd_txn_out { https://github.com/anza-xyz/agave/blob/838c1952595809a31520ff1603a13f2c9123aa51/accounts-db/src/account_locks.rs#L118 That is the limit we are going to use here. */ struct { - ulong accounts_cnt; + ulong cnt; /* The account keys are used by the CU rebating mechanism in the bank tile (leader pipeline). */ - fd_pubkey_t account_keys[ MAX_TX_ACCOUNT_LOCKS ]; + fd_pubkey_t keys[ MAX_TX_ACCOUNT_LOCKS ]; + fd_account_meta_t * metas[ MAX_TX_ACCOUNT_LOCKS ]; /* The rollback accounts are special cased accounts that are still committed to the accounts database even if a transaction fails @@ -220,8 +221,6 @@ struct fd_txn_out { this would be !=ULONG_MAX. */ fd_account_meta_t * rollback_fee_payer; - fd_pubkey_t pubkeys[ MAX_TX_ACCOUNT_LOCKS ]; - fd_account_meta_t * metas[ MAX_TX_ACCOUNT_LOCKS ]; } accounts; }; typedef struct fd_txn_out fd_txn_out_t; diff --git a/src/flamenco/runtime/program/fd_bpf_loader_serialization.c b/src/flamenco/runtime/program/fd_bpf_loader_serialization.c index 1ead99b460..238252dd3f 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_serialization.c +++ b/src/flamenco/runtime/program/fd_bpf_loader_serialization.c @@ -263,7 +263,7 @@ fd_bpf_loader_input_serialize_aligned( fd_exec_instr_ctx_t * ctx, fd_vm_acc_region_meta_t * acc_region_metas, int stricter_abi_and_runtime_constraints, int direct_mapping ) { - fd_pubkey_t * txn_accs = ctx->txn_out->accounts.account_keys; + fd_pubkey_t * txn_accs = ctx->txn_out->accounts.keys; uchar acc_idx_seen[ FD_INSTR_ACCT_MAX ] = {0}; ushort dup_acc_idx[ FD_INSTR_ACCT_MAX ] = {0}; @@ -539,7 +539,7 @@ fd_bpf_loader_input_serialize_unaligned( fd_exec_instr_ctx_t * ctx, fd_vm_acc_region_meta_t * acc_region_metas, int stricter_abi_and_runtime_constraints, int direct_mapping ) { - fd_pubkey_t const * txn_accs = ctx->txn_out->accounts.account_keys; + fd_pubkey_t const * txn_accs = ctx->txn_out->accounts.keys; uchar acc_idx_seen[FD_INSTR_ACCT_MAX] = {0}; ushort dup_acc_idx[FD_INSTR_ACCT_MAX] = {0}; diff --git a/src/flamenco/runtime/program/fd_system_program.c b/src/flamenco/runtime/program/fd_system_program.c index 2e0e2e654a..ca77c00c41 100644 --- a/src/flamenco/runtime/program/fd_system_program.c +++ b/src/flamenco/runtime/program/fd_system_program.c @@ -128,7 +128,7 @@ fd_system_program_transfer( fd_exec_instr_ctx_t * ctx, /* Max msg_sz: 37 - 2 + 45 = 80 < 127 => we can use printf */ ushort idx_in_txn = ctx->instr->accounts[ from_acct_idx ].index_in_transaction; fd_log_collector_printf_dangerous_max_127( ctx, - "Transfer: `from` account %s must sign", FD_BASE58_ENC_32_ALLOCA( &ctx->txn_out->accounts.account_keys[ idx_in_txn ] ) ); + "Transfer: `from` account %s must sign", FD_BASE58_ENC_32_ALLOCA( &ctx->txn_out->accounts.keys[ idx_in_txn ] ) ); return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE; } @@ -576,7 +576,7 @@ fd_system_program_exec_transfer_with_seed( fd_exec_instr_ctx_t * /* Max msg_sz: 37 - 2 + 45 = 80 < 127 => we can use printf */ ushort idx_in_txn = ctx->instr->accounts[ from_base_idx ].index_in_transaction; fd_log_collector_printf_dangerous_max_127( ctx, - "Transfer: 'from' account %s must sign", FD_BASE58_ENC_32_ALLOCA( &ctx->txn_out->accounts.account_keys[ idx_in_txn ] ) ); + "Transfer: 'from' account %s must sign", FD_BASE58_ENC_32_ALLOCA( &ctx->txn_out->accounts.keys[ idx_in_txn ] ) ); return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE; } diff --git a/src/flamenco/runtime/program/fd_system_program_nonce.c b/src/flamenco/runtime/program/fd_system_program_nonce.c index d15a455848..18d47f082a 100644 --- a/src/flamenco/runtime/program/fd_system_program_nonce.c +++ b/src/flamenco/runtime/program/fd_system_program_nonce.c @@ -949,7 +949,7 @@ fd_check_transaction_age( fd_runtime_t * runtime, fd_txn_account_t durable_nonce_rec[1]; fd_funk_txn_xid_t xid = { .ul = { fd_bank_slot_get( bank ), bank->idx } }; int err = fd_txn_account_init_from_funk_readonly( durable_nonce_rec, - &txn_out->accounts.account_keys[ nonce_idx ], + &txn_out->accounts.keys[ nonce_idx ], runtime->funk, &xid ); if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { @@ -993,7 +993,7 @@ fd_check_transaction_age( fd_runtime_t * runtime, the nonce instruction are signers. This is a successful exit case. */ for( ushort i=0; iacct_cnt; ++i ) { if( fd_txn_is_signer( TXN( txn_in->txn ), (int)instr_accts[i] ) ) { - if( !memcmp( &txn_out->accounts.account_keys[ instr_accts[i] ], &state->inner.current.inner.initialized.authority, sizeof(fd_pubkey_t) ) ) { + if( !memcmp( &txn_out->accounts.keys[ instr_accts[i] ], &state->inner.current.inner.initialized.authority, sizeof(fd_pubkey_t) ) ) { /* Mark nonce account to make sure that we modify and hash the account even if the transaction failed to execute @@ -1007,7 +1007,7 @@ fd_check_transaction_age( fd_runtime_t * runtime, fd_account_meta_t const * meta = fd_funk_get_acc_meta_readonly( runtime->funk, &xid, - &txn_out->accounts.account_keys[ instr_accts[ 0UL ] ], + &txn_out->accounts.keys[ instr_accts[ 0UL ] ], NULL, &err, NULL ); diff --git a/src/flamenco/runtime/sysvar/fd_sysvar.c b/src/flamenco/runtime/sysvar/fd_sysvar.c index bad8f6bc3d..26333a4d02 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar.c @@ -67,7 +67,7 @@ fd_sysvar_instr_acct_check( fd_exec_instr_ctx_t const * ctx, } ushort idx_in_txn = ctx->instr->accounts[idx].index_in_transaction; - fd_pubkey_t const * addr_have = &ctx->txn_out->accounts.account_keys[ idx_in_txn ]; + fd_pubkey_t const * addr_have = &ctx->txn_out->accounts.keys[ idx_in_txn ]; if( FD_UNLIKELY( 0!=memcmp( addr_have, addr_want, sizeof(fd_pubkey_t) ) ) ) { return FD_EXECUTOR_INSTR_ERR_INVALID_ARG; } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c index 46a74cc4a4..f693a608c9 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c @@ -97,12 +97,12 @@ fd_sysvar_instructions_serialize_account( fd_runtime_t * runtime, // pubkey ushort idx_in_txn = instr->accounts[j].index_in_transaction; - FD_STORE( fd_pubkey_t, serialized_instructions + offset, txn_out->accounts.account_keys[ idx_in_txn ] ); + FD_STORE( fd_pubkey_t, serialized_instructions + offset, txn_out->accounts.keys[ idx_in_txn ] ); offset += sizeof(fd_pubkey_t); } // program_id_pubkey - FD_STORE( fd_pubkey_t, serialized_instructions + offset, txn_out->accounts.account_keys[ instr->program_id ] ); + FD_STORE( fd_pubkey_t, serialized_instructions + offset, txn_out->accounts.keys[ instr->program_id ] ); offset += sizeof(fd_pubkey_t); // instr_data_len diff --git a/src/flamenco/runtime/tests/fd_dump_pb.c b/src/flamenco/runtime/tests/fd_dump_pb.c index 6f892bd68d..490687350e 100644 --- a/src/flamenco/runtime/tests/fd_dump_pb.c +++ b/src/flamenco/runtime/tests/fd_dump_pb.c @@ -775,15 +775,15 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m alignof(fd_exec_test_acct_state_t), (256UL*2UL + txn_descriptor->addr_table_lookup_cnt + num_sysvar_entries) * sizeof(fd_exec_test_acct_state_t) ); fd_funk_txn_xid_t xid = { .ul = { fd_bank_slot_get( bank ), bank->idx } }; - for( ulong i = 0; i < txn_out->accounts.accounts_cnt; ++i ) { + for( ulong i = 0; i < txn_out->accounts.cnt; ++i ) { fd_txn_account_t txn_account[1]; - int ret = fd_txn_account_init_from_funk_readonly( txn_account, &txn_out->accounts.account_keys[i], runtime->funk, &xid ); + int ret = fd_txn_account_init_from_funk_readonly( txn_account, &txn_out->accounts.keys[i], runtime->funk, &xid ); if( FD_UNLIKELY( ret ) ) { continue; } // Make sure account is not a non-migrating builtin - if( !is_builtin_account( &txn_out->accounts.account_keys[i] ) ) { + if( !is_builtin_account( &txn_out->accounts.keys[i] ) ) { dump_account_state( txn_account->pubkey, txn_account->meta, &txn_context_msg->account_shared_data[txn_context_msg->account_shared_data_count++], spad ); } } @@ -849,8 +849,8 @@ create_txn_context_protobuf_from_txn( fd_exec_test_txn_context_t * txn_context_m // Make sure the account doesn't exist in the output accounts yet int account_exists = 0; - for( ulong j = 0; j < txn_out->accounts.accounts_cnt; j++ ) { - if ( 0 == memcmp( txn_out->accounts.account_keys[j].key, fd_dump_sysvar_ids[i], sizeof(fd_pubkey_t) ) ) { + for( ulong j = 0; j < txn_out->accounts.cnt; j++ ) { + if ( 0 == memcmp( txn_out->accounts.keys[j].key, fd_dump_sysvar_ids[i], sizeof(fd_pubkey_t) ) ) { account_exists = true; break; } @@ -896,18 +896,18 @@ create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t * fd_instr_info_t const * instr, fd_spad_t * spad ) { /* Program ID */ - fd_memcpy( instr_context->program_id, txn_out->accounts.account_keys[ instr->program_id ].uc, sizeof(fd_pubkey_t) ); + fd_memcpy( instr_context->program_id, txn_out->accounts.keys[ instr->program_id ].uc, sizeof(fd_pubkey_t) ); fd_funk_txn_xid_t xid = { .ul = { fd_bank_slot_get( bank ), bank->idx } }; /* Accounts */ - instr_context->accounts_count = (pb_size_t) txn_out->accounts.accounts_cnt; + instr_context->accounts_count = (pb_size_t) txn_out->accounts.cnt; instr_context->accounts = fd_spad_alloc( spad, alignof(fd_exec_test_acct_state_t), (instr_context->accounts_count + num_sysvar_entries + runtime->accounts.executable_cnt) * sizeof(fd_exec_test_acct_state_t)); - for( ulong i = 0; i < txn_out->accounts.accounts_cnt; i++ ) { + for( ulong i = 0; i < txn_out->accounts.cnt; i++ ) { // Copy account information over fd_account_meta_t * account_meta = txn_out->accounts.metas[i]; fd_exec_test_acct_state_t * output_account = &instr_context->accounts[i]; - dump_account_state( &txn_out->accounts.account_keys[i], account_meta, output_account, spad ); + dump_account_state( &txn_out->accounts.keys[i], account_meta, output_account, spad ); } /* Add sysvar cache variables */ @@ -919,8 +919,8 @@ create_instr_context_protobuf_from_instructions( fd_exec_test_instr_context_t * } // Make sure the account doesn't exist in the output accounts yet int account_exists = 0; - for( ulong j = 0; j < txn_out->accounts.accounts_cnt; j++ ) { - if ( 0 == memcmp( txn_out->accounts.account_keys[j].key, fd_dump_sysvar_ids[i], sizeof(fd_pubkey_t) ) ) { + for( ulong j = 0; j < txn_out->accounts.cnt; j++ ) { + if ( 0 == memcmp( txn_out->accounts.keys[j].key, fd_dump_sysvar_ids[i], sizeof(fd_pubkey_t) ) ) { account_exists = true; break; } diff --git a/src/flamenco/runtime/tests/fd_instr_harness.c b/src/flamenco/runtime/tests/fd_instr_harness.c index f77eeb856e..3856ac8bbe 100644 --- a/src/flamenco/runtime/tests/fd_instr_harness.c +++ b/src/flamenco/runtime/tests/fd_instr_harness.c @@ -93,7 +93,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, fd_compute_budget_details_new( &txn_out->details.compute_budget ); runtime->instr.stack_sz = 0; - txn_out->accounts.accounts_cnt = 0UL; + txn_out->accounts.cnt = 0UL; runtime->accounts.executable_cnt = 0UL; txn_out->details.programs_to_reverify_cnt = 0UL; @@ -145,14 +145,14 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, /* Load accounts into database */ fd_txn_account_t accts[MAX_TX_ACCOUNT_LOCKS] = {0}; - txn_out->accounts.accounts_cnt = test_ctx->accounts_count; + txn_out->accounts.cnt = test_ctx->accounts_count; int has_program_id = 0; for( ulong j=0UL; j < test_ctx->accounts_count; j++ ) { fd_pubkey_t * acc_key = (fd_pubkey_t *)test_ctx->accounts[j].address; - memcpy( &(txn_out->accounts.account_keys[j]), test_ctx->accounts[j].address, sizeof(fd_pubkey_t) ); + memcpy( &(txn_out->accounts.keys[j]), test_ctx->accounts[j].address, sizeof(fd_pubkey_t) ); if( !fd_solfuzz_pb_load_account( runtime, runner->accdb, xid, &test_ctx->accounts[j], 0, j, &accts[j].meta ) ) { return 0; } @@ -172,7 +172,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, if( !memcmp( accts[j].pubkey, test_ctx->program_id, sizeof(fd_pubkey_t) ) ) { has_program_id = 1; - info->program_id = (uchar)txn_out->accounts.accounts_cnt; + info->program_id = (uchar)txn_out->accounts.cnt; } /* Since the instructions sysvar is set as mutable at the txn level, we need to make it mutable here as well. */ @@ -184,7 +184,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, /* If the program id is not in the set of accounts it must be added to the set of accounts. */ if( FD_UNLIKELY( !has_program_id ) ) { fd_txn_account_t * program_acc = &accts[ test_ctx->accounts_count ]; - fd_pubkey_t * program_key = &txn_out->accounts.account_keys[ txn_out->accounts.accounts_cnt ]; + fd_pubkey_t * program_key = &txn_out->accounts.keys[ txn_out->accounts.cnt ]; memcpy( program_key, test_ctx->program_id, sizeof(fd_pubkey_t) ); fd_account_meta_t * meta = fd_spad_alloc( runner->spad, alignof(fd_account_meta_t), sizeof(fd_account_meta_t) ); @@ -200,12 +200,12 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, txn_out->accounts.metas[test_ctx->accounts_count] = meta; - info->program_id = (uchar)txn_out->accounts.accounts_cnt; - txn_out->accounts.accounts_cnt++; + info->program_id = (uchar)txn_out->accounts.cnt; + txn_out->accounts.cnt++; } /* Load in executable accounts */ - for( ulong i = 0; i < txn_out->accounts.accounts_cnt; i++ ) { + for( ulong i = 0; i < txn_out->accounts.cnt; i++ ) { fd_pubkey_t * acc_key = (fd_pubkey_t *)test_ctx->accounts[i].address; fd_txn_account_t * acc = &accts[i]; @@ -353,7 +353,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, runtime->log.enable_log_collector = 0; fd_log_collector_init( ctx->runtime->log.log_collector, 1 ); - fd_base58_encode_32( txn_out->accounts.account_keys[ ctx->instr->program_id ].uc, NULL, ctx->program_id_base58 ); + fd_base58_encode_32( txn_out->accounts.keys[ ctx->instr->program_id ].uc, NULL, ctx->program_id_base58 ); return 1; } @@ -410,13 +410,13 @@ fd_solfuzz_pb_instr_run( fd_solfuzz_runner_t * runner, if( FD_LIKELY( effects->result ) ) { int program_id_idx = ctx->instr[ 0UL ].program_id; if( exec_result==FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR && - fd_executor_lookup_native_precompile_program( &ctx->txn_out->accounts.account_keys[ program_id_idx ] )==NULL ) { + fd_executor_lookup_native_precompile_program( &ctx->txn_out->accounts.keys[ program_id_idx ] )==NULL ) { effects->custom_err = ctx->txn_out->err.custom_err; } } /* Allocate space for captured accounts */ - ulong modified_acct_cnt = ctx->txn_out->accounts.accounts_cnt; + ulong modified_acct_cnt = ctx->txn_out->accounts.cnt; fd_exec_test_acct_state_t * modified_accts = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_test_acct_state_t), @@ -430,8 +430,8 @@ fd_solfuzz_pb_instr_run( fd_solfuzz_runner_t * runner, /* Capture borrowed accounts */ - for( ulong j=0UL; j < ctx->txn_out->accounts.accounts_cnt; j++ ) { - fd_pubkey_t * acc_key = &ctx->txn_out->accounts.account_keys[j]; + for( ulong j=0UL; j < ctx->txn_out->accounts.cnt; j++ ) { + fd_pubkey_t * acc_key = &ctx->txn_out->accounts.keys[j]; fd_account_meta_t * acc = ctx->txn_out->accounts.metas[j]; if( !acc ) { continue; diff --git a/src/flamenco/runtime/tests/fd_txn_harness.c b/src/flamenco/runtime/tests/fd_txn_harness.c index e025bc44e2..1134c13b31 100644 --- a/src/flamenco/runtime/tests/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/fd_txn_harness.c @@ -451,7 +451,7 @@ fd_solfuzz_pb_txn_run( fd_solfuzz_runner_t * runner, /* If the exec err was a custom instr error and came from a precompile instruction, don't capture the custom error code. */ if( txn_out->err.exec_err==FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR && - fd_executor_lookup_native_precompile_program( &txn_out->accounts.account_keys[ program_id_idx ] )==NULL ) { + fd_executor_lookup_native_precompile_program( &txn_out->accounts.keys[ program_id_idx ] )==NULL ) { txn_result->custom_error = txn_out->err.custom_err; } } @@ -478,7 +478,7 @@ fd_solfuzz_pb_txn_run( fd_solfuzz_runner_t * runner, } /* Allocate space for captured accounts */ - ulong modified_acct_cnt = txn_out->accounts.accounts_cnt; + ulong modified_acct_cnt = txn_out->accounts.cnt; txn_result->has_resulting_state = true; txn_result->resulting_state.acct_states = @@ -490,7 +490,7 @@ fd_solfuzz_pb_txn_run( fd_solfuzz_runner_t * runner, /* If the transaction is a fees-only transaction, we have to create rollback accounts to iterate over and save. */ fd_account_meta_t * * accounts_to_save = txn_out->accounts.metas; - ulong accounts_cnt = txn_out->accounts.accounts_cnt; + ulong accounts_cnt = txn_out->accounts.cnt; if( txn_out->err.is_fees_only ) { accounts_to_save = fd_spad_alloc( runner->spad, alignof(fd_txn_account_t), sizeof(fd_txn_account_t) * 2 ); accounts_cnt = 0UL; @@ -507,7 +507,7 @@ fd_solfuzz_pb_txn_run( fd_solfuzz_runner_t * runner, /* Capture borrowed accounts */ for( ulong j=0UL; jaccounts.account_keys[j]; + fd_pubkey_t * pubkey = &txn_out->accounts.keys[j]; if( !( fd_runtime_account_is_writable_idx( txn_in, txn_out, runner->bank, (ushort)j ) || j==FD_FEE_PAYER_TXN_IDX ) ) continue; diff --git a/src/flamenco/runtime/tests/fd_vm_harness.c b/src/flamenco/runtime/tests/fd_vm_harness.c index e78fd90040..03bfaab67b 100644 --- a/src/flamenco/runtime/tests/fd_vm_harness.c +++ b/src/flamenco/runtime/tests/fd_vm_harness.c @@ -159,7 +159,7 @@ do{ uchar * input_ptr = NULL; uchar program_id_idx = instr_ctx->instr->program_id; fd_account_meta_t const * program_acc = instr_ctx->txn_out->accounts.metas[program_id_idx]; - uchar is_deprecated = ( program_id_idx < instr_ctx->txn_out->accounts.accounts_cnt ) && + uchar is_deprecated = ( program_id_idx < instr_ctx->txn_out->accounts.cnt ) && ( !memcmp( program_acc->owner, fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ) ); /* Push the instruction onto the stack. This may also modify the sysvar instructions account, if its present. */ @@ -471,7 +471,7 @@ fd_solfuzz_pb_syscall_run( fd_solfuzz_runner_t * runner, uchar * input_ptr = NULL; uchar program_id_idx = ctx->instr->program_id; fd_account_meta_t * program_acc = ctx->txn_out->accounts.metas[program_id_idx]; - uchar is_deprecated = ( program_id_idx < ctx->txn_out->accounts.accounts_cnt ) && + uchar is_deprecated = ( program_id_idx < ctx->txn_out->accounts.cnt ) && ( !memcmp( program_acc->owner, fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ) ); /* Push the instruction onto the stack. This may also modify the sysvar instructions account, if its present. */ diff --git a/src/flamenco/vm/syscall/fd_vm_syscall_cpi_common.c b/src/flamenco/vm/syscall/fd_vm_syscall_cpi_common.c index d99cd61337..d6d33c8cef 100644 --- a/src/flamenco/vm/syscall/fd_vm_syscall_cpi_common.c +++ b/src/flamenco/vm/syscall/fd_vm_syscall_cpi_common.c @@ -739,7 +739,7 @@ VM_SYSCALL_CPI_ENTRYPOINT( void * _vm, /* Derive PDA signers ************************************************/ fd_pubkey_t signers[ FD_CPI_MAX_SIGNER_CNT ] = {0}; - fd_pubkey_t * caller_program_id = &vm->instr_ctx->txn_out->accounts.account_keys[ vm->instr_ctx->instr->program_id ]; + fd_pubkey_t * caller_program_id = &vm->instr_ctx->txn_out->accounts.keys[ vm->instr_ctx->instr->program_id ]; /* This is the equivalent of translate_slice in translate_signers: https://github.com/solana-labs/solana/blob/dbf06e258ae418097049e845035d7d5502fe1327/programs/bpf_loader/src/syscalls/cpi.rs#L595 */ if( FD_LIKELY( signers_seeds_cnt > 0UL ) ) { @@ -904,7 +904,7 @@ VM_SYSCALL_CPI_ENTRYPOINT( void * _vm, caller accounts can't be changed during a CPI execution. */ if( fd_instr_acc_is_writable_idx( vm->instr_ctx->instr, callee_account_keys[i] ) ) { ushort idx_in_txn = vm->instr_ctx->instr->accounts[ callee_account_keys[i] ].index_in_transaction; - fd_pubkey_t const * callee = &vm->instr_ctx->txn_out->accounts.account_keys[ idx_in_txn ]; + fd_pubkey_t const * callee = &vm->instr_ctx->txn_out->accounts.keys[ idx_in_txn ]; err = VM_SYSCALL_CPI_UPDATE_CALLER_ACC_FUNC(vm, &acc_infos[ caller_accounts_to_update[i] ], caller_accounts + i, (uchar)callee_account_keys[i], callee); if( FD_UNLIKELY( err ) ) { return err; @@ -921,7 +921,7 @@ VM_SYSCALL_CPI_ENTRYPOINT( void * _vm, /* https://github.com/anza-xyz/agave/blob/v3.0.4/syscalls/src/cpi.rs#L1033-L1034 */ fd_guarded_borrowed_account_t borrowed_callee_acc = {0}; ushort idx_in_txn = vm->instr_ctx->instr->accounts[ callee_account_keys[i] ].index_in_transaction; - fd_pubkey_t const * callee = &vm->instr_ctx->txn_out->accounts.account_keys[ idx_in_txn ]; + fd_pubkey_t const * callee = &vm->instr_ctx->txn_out->accounts.keys[ idx_in_txn ]; err = fd_exec_instr_ctx_try_borrow_instr_account_with_key( vm->instr_ctx, callee, &borrowed_callee_acc ); if( FD_UNLIKELY( err && ( err != FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ) ) ) { return 1; From 7458a3b07156c5d474003b5ca7e557e96307f424 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Tue, 25 Nov 2025 20:51:28 +0000 Subject: [PATCH 25/32] wip --- src/discof/bank/fd_bank_tile.c | 11 +++-- src/flamenco/runtime/fd_executor.c | 4 +- src/flamenco/runtime/fd_runtime.h | 26 +++++------ .../runtime/program/fd_bpf_loader_program.c | 46 ++++++++----------- .../runtime/program/fd_bpf_loader_program.h | 6 +-- src/flamenco/runtime/tests/fd_instr_harness.c | 2 +- src/flamenco/vm/fd_vm.h | 10 ++-- 7 files changed, 46 insertions(+), 59 deletions(-) diff --git a/src/discof/bank/fd_bank_tile.c b/src/discof/bank/fd_bank_tile.c index 50d72e8091..90ef6c1282 100644 --- a/src/discof/bank/fd_bank_tile.c +++ b/src/discof/bank/fd_bank_tile.c @@ -596,12 +596,13 @@ unprivileged_init( fd_topo_t * topo, } } - ctx->runtime->accdb = accdb; - ctx->runtime->funk = fd_accdb_user_v1_funk( accdb ); - ctx->runtime->progcache = progcache; - ctx->runtime->status_cache = txncache; - ctx->runtime->log.log_collector = ctx->log_collector; + ctx->runtime->accdb = accdb; + ctx->runtime->funk = fd_accdb_user_v1_funk( accdb ); + ctx->runtime->progcache = progcache; + ctx->runtime->status_cache = txncache; + ctx->runtime->log.log_collector = ctx->log_collector; ctx->runtime->log.enable_log_collector = 0; + ctx->runtime->log.capture_ctx = NULL; ulong banks_obj_id = fd_pod_queryf_ulong( topo->props, ULONG_MAX, "banks" ); FD_TEST( banks_obj_id!=ULONG_MAX ); diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 2ac9578f11..b0c17722d6 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -699,7 +699,7 @@ fd_collect_loaded_account( fd_runtime_t * runtime, /* Try to read the program state https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L612-L634 */ fd_bpf_upgradeable_loader_state_t loader_state[1]; - err = fd_bpf_loader_program_get_state_inner( account_meta, loader_state ); + err = fd_bpf_loader_program_get_state( account_meta, loader_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return FD_RUNTIME_EXECUTE_SUCCESS; } @@ -1532,7 +1532,7 @@ fd_executor_setup_executable_account( fd_runtime_t * runtime, fd_account_meta_t const * program_meta, ushort * executable_idx ) { fd_bpf_upgradeable_loader_state_t program_loader_state[1]; - int err = fd_bpf_loader_program_get_state_inner( program_meta, program_loader_state ); + int err = fd_bpf_loader_program_get_state( program_meta, program_loader_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return; } diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index 2436113c3a..b859c29c10 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -202,25 +202,23 @@ struct fd_txn_out { That is the limit we are going to use here. */ struct { ulong cnt; - /* The account keys are used by the CU rebating mechanism in the - bank tile (leader pipeline). */ fd_pubkey_t keys[ MAX_TX_ACCOUNT_LOCKS ]; fd_account_meta_t * metas[ MAX_TX_ACCOUNT_LOCKS ]; - /* The rollback accounts are special cased accounts that are still - committed to the accounts database even if a transaction fails - to execute (but still lands on chain). The state of both the - nonce and fee payer account is saved after the nonce is advanced - and the fee payer is debited. If the transaction fails to - execute, the state must be rolled back to when the accounts were - in this state and then they are free to be committed to the - accounts database. */ - ulong nonce_idx_in_txn; - fd_account_meta_t * rollback_nonce; + /* The fee payer and nonce accounts are treated differently than + other accounts: if an on-transaction fails they are still + committed to the accounts database. However, they are saved at + the point where they were before the transaction was executed + because the failed transaction could have potentially modified + these accounts. The rollback fee payer and nonce are used to + store the state of these accounts after fees have been debited + and the nonce has been advanced, but before the transaction is + executed. */ + fd_account_meta_t * rollback_fee_payer; /* If the transaction has a nonce account that must be advanced, this would be !=ULONG_MAX. */ - fd_account_meta_t * rollback_fee_payer; - + ulong nonce_idx_in_txn; + fd_account_meta_t * rollback_nonce; } accounts; }; typedef struct fd_txn_out fd_txn_out_t; diff --git a/src/flamenco/runtime/program/fd_bpf_loader_program.c b/src/flamenco/runtime/program/fd_bpf_loader_program.c index fd149b0b8a..41b3c3e181 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_program.c +++ b/src/flamenco/runtime/program/fd_bpf_loader_program.c @@ -262,8 +262,8 @@ write_program_data( fd_exec_instr_ctx_t * instr_ctx, } int -fd_bpf_loader_program_get_state_inner( fd_account_meta_t const * meta, - fd_bpf_upgradeable_loader_state_t * state ) { +fd_bpf_loader_program_get_state( fd_account_meta_t const * meta, + fd_bpf_upgradeable_loader_state_t * state ) { int err = 0; fd_bincode_decode_static( bpf_upgradeable_loader_state, @@ -277,14 +277,6 @@ fd_bpf_loader_program_get_state_inner( fd_account_meta_t const * meta, return FD_EXECUTOR_INSTR_SUCCESS; } - -int -fd_bpf_loader_program_get_state( fd_txn_account_t const * acct, - fd_bpf_upgradeable_loader_state_t * state ) { - - return fd_bpf_loader_program_get_state_inner( acct->meta, state ); -} - /* Mirrors solana_sdk::transaction_context::BorrowedAccount::set_state() https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L973 */ int @@ -695,7 +687,7 @@ common_extend_program( fd_exec_instr_ctx_t * instr_ctx, /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/lib.rs#L1403-L1419 */ fd_bpf_upgradeable_loader_state_t program_state[1]; - err = fd_bpf_loader_program_get_state_inner( program_account.meta, program_state ); + err = fd_bpf_loader_program_get_state( program_account.meta, program_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -733,7 +725,7 @@ common_extend_program( fd_exec_instr_ctx_t * instr_ctx, /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/lib.rs#L1439-L1478 */ fd_pubkey_t * upgrade_authority_address = NULL; fd_bpf_upgradeable_loader_state_t programdata_state[1]; - err = fd_bpf_loader_program_get_state_inner( programdata_account.meta, programdata_state ); + err = fd_bpf_loader_program_get_state( programdata_account.meta, programdata_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -941,7 +933,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 0UL, &buffer ); fd_bpf_upgradeable_loader_state_t buffer_state[1]; - err = fd_bpf_loader_program_get_state_inner( buffer.meta, buffer_state ); + err = fd_bpf_loader_program_get_state( buffer.meta, buffer_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { return err; } @@ -982,7 +974,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 0UL, &buffer ); fd_bpf_upgradeable_loader_state_t loader_state[1]; - err = fd_bpf_loader_program_get_state_inner( buffer.meta, loader_state ); + err = fd_bpf_loader_program_get_state( buffer.meta, loader_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1090,7 +1082,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 2UL, &program ); fd_bpf_upgradeable_loader_state_t loader_state[1]; - int err = fd_bpf_loader_program_get_state_inner( program.meta, loader_state ); + int err = fd_bpf_loader_program_get_state( program.meta, loader_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { return err; } @@ -1125,7 +1117,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 3UL, &buffer ); fd_bpf_upgradeable_loader_state_t buffer_state[1]; - err = fd_bpf_loader_program_get_state_inner( buffer.meta, buffer_state ); + err = fd_bpf_loader_program_get_state( buffer.meta, buffer_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1427,7 +1419,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID; } fd_bpf_upgradeable_loader_state_t program_state[1]; - err = fd_bpf_loader_program_get_state_inner( program.meta, program_state ); + err = fd_bpf_loader_program_get_state( program.meta, program_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1456,7 +1448,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( instr_ctx, 2UL, &buffer ); fd_bpf_upgradeable_loader_state_t buffer_state[1]; - err = fd_bpf_loader_program_get_state_inner( buffer.meta, buffer_state ); + err = fd_bpf_loader_program_get_state( buffer.meta, buffer_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1511,7 +1503,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { } fd_bpf_upgradeable_loader_state_t programdata_state[1]; - err = fd_bpf_loader_program_get_state_inner( programdata.meta, programdata_state ); + err = fd_bpf_loader_program_get_state( programdata.meta, programdata_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1678,7 +1670,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_exec_instr_ctx_get_key_of_account_at_index( instr_ctx, 2UL, &new_authority ); fd_bpf_upgradeable_loader_state_t account_state[1]; - err = fd_bpf_loader_program_get_state_inner( account.meta, account_state ); + err = fd_bpf_loader_program_get_state( account.meta, account_state ); if( FD_UNLIKELY( err!=FD_BINCODE_SUCCESS ) ) { return err; } @@ -1783,7 +1775,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { if( FD_UNLIKELY( err ) ) return err; fd_bpf_upgradeable_loader_state_t account_state[1]; - err = fd_bpf_loader_program_get_state_inner( account.meta, account_state ); + err = fd_bpf_loader_program_get_state( account.meta, account_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1881,7 +1873,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { fd_pubkey_t const * close_key = close_account.pubkey; fd_bpf_upgradeable_loader_state_t close_account_state[1]; - err = fd_bpf_loader_program_get_state_inner( close_account.meta, close_account_state ); + err = fd_bpf_loader_program_get_state( close_account.meta, close_account_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -1964,7 +1956,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { } fd_bpf_upgradeable_loader_state_t program_state[1]; - err = fd_bpf_loader_program_get_state_inner( program_account.meta, program_state ); + err = fd_bpf_loader_program_get_state( program_account.meta, program_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -2092,7 +2084,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { ulong program_len = 0UL; fd_pubkey_t * upgrade_authority_address = NULL; fd_bpf_upgradeable_loader_state_t programdata_state[1]; - err = fd_bpf_loader_program_get_state_inner( programdata.meta, programdata_state ); + err = fd_bpf_loader_program_get_state( programdata.meta, programdata_state ); if( FD_LIKELY( err==FD_EXECUTOR_INSTR_SUCCESS && fd_bpf_upgradeable_loader_state_is_program_data( programdata_state ) ) ) { /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/bpf_loader/src/lib.rs#L1374-L1377 */ @@ -2147,7 +2139,7 @@ process_loader_upgradeable_instruction( fd_exec_instr_ctx_t * instr_ctx ) { /* https://github.com/anza-xyz/agave/blob/v2.2.6/programs/bpf_loader/src/lib.rs#L1415-L1426 */ fd_bpf_upgradeable_loader_state_t program_state[1]; - err = fd_bpf_loader_program_get_state_inner( program.meta, program_state ); + err = fd_bpf_loader_program_get_state( program.meta, program_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { return err; } @@ -2496,7 +2488,7 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * ctx ) { if( !memcmp( metadata->owner, &fd_solana_bpf_loader_upgradeable_program_id, sizeof(fd_pubkey_t) ) ) { fd_bpf_upgradeable_loader_state_t program_account_state[1]; - err = fd_bpf_loader_program_get_state_inner( program_account.meta, program_account_state ); + err = fd_bpf_loader_program_get_state( program_account.meta, program_account_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { fd_log_collector_msg_literal( ctx, "Program is not deployed" ); if( FD_FEATURE_ACTIVE_BANK( ctx->bank, remove_accounts_executable_flag_checks ) ) { @@ -2547,7 +2539,7 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * ctx ) { } fd_bpf_upgradeable_loader_state_t program_data_account_state[1]; - err = fd_bpf_loader_program_get_state_inner( programdata_meta, program_data_account_state ); + err = fd_bpf_loader_program_get_state( programdata_meta, program_data_account_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { fd_log_collector_msg_literal( ctx, "Program is not deployed" ); if( FD_FEATURE_ACTIVE_BANK( ctx->bank, remove_accounts_executable_flag_checks ) ) { diff --git a/src/flamenco/runtime/program/fd_bpf_loader_program.h b/src/flamenco/runtime/program/fd_bpf_loader_program.h index 4fa4646a0c..66ed9c25c6 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_program.h +++ b/src/flamenco/runtime/program/fd_bpf_loader_program.h @@ -55,10 +55,6 @@ FD_PROTOTYPES_BEGIN -int -fd_bpf_loader_program_get_state_inner( fd_account_meta_t const * meta, - fd_bpf_upgradeable_loader_state_t * state ); - /* Mirrors solana_sdk::transaction_context::BorrowedAccount::get_state() Acts on a fd_txn_account_t for ease of API use. @@ -66,7 +62,7 @@ fd_bpf_loader_program_get_state_inner( fd_account_meta_t const * meta, https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L965-L969 */ int -fd_bpf_loader_program_get_state( fd_txn_account_t const * acct, +fd_bpf_loader_program_get_state( fd_account_meta_t const * meta, fd_bpf_upgradeable_loader_state_t * state ); int diff --git a/src/flamenco/runtime/tests/fd_instr_harness.c b/src/flamenco/runtime/tests/fd_instr_harness.c index 3856ac8bbe..5b98b8f147 100644 --- a/src/flamenco/runtime/tests/fd_instr_harness.c +++ b/src/flamenco/runtime/tests/fd_instr_harness.c @@ -226,7 +226,7 @@ fd_solfuzz_pb_instr_ctx_create( fd_solfuzz_runner_t * runner, if( FD_UNLIKELY( !memcmp( meta->owner, fd_solana_bpf_loader_upgradeable_program_id.key, sizeof(fd_pubkey_t) ) ) ) { fd_bpf_upgradeable_loader_state_t program_loader_state[1]; - int err = fd_bpf_loader_program_get_state( acc, program_loader_state ); + int err = fd_bpf_loader_program_get_state( meta, program_loader_state ); if( FD_UNLIKELY( err!=FD_EXECUTOR_INSTR_SUCCESS ) ) { continue; } diff --git a/src/flamenco/vm/fd_vm.h b/src/flamenco/vm/fd_vm.h index fe67a352f8..348bb27e20 100644 --- a/src/flamenco/vm/fd_vm.h +++ b/src/flamenco/vm/fd_vm.h @@ -37,21 +37,21 @@ typedef struct fd_vm_input_region fd_vm_input_region_t; region location. */ struct __attribute((aligned(8UL))) fd_vm_acc_region_meta { - uint region_idx; + uint region_idx; /* FIXME: We can get rid of this field once DM is activated. This is only a hack to make the non-DM code path happy. When DM is activated, we could query the input_mem_region array for the original data len. */ - ulong original_data_len; + ulong original_data_len; /* The transaction account corresponding to this account. */ fd_account_meta_t * meta; /* The expected virtual offsets of the serialized pubkey, lamports and owner for the account corresponding to this region. Relative to the start of the account's input region vaddr. Used for CPI security checks. */ - uint expected_pubkey_offset; - uint expected_lamports_offset; - uint expected_owner_offset; + uint expected_pubkey_offset; + uint expected_lamports_offset; + uint expected_owner_offset; }; typedef struct fd_vm_acc_region_meta fd_vm_acc_region_meta_t; From 117563d102bc4fdd4112549d9676857600007939 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Tue, 25 Nov 2025 21:04:15 +0000 Subject: [PATCH 26/32] wip --- src/flamenco/rewards/fd_rewards.c | 2 +- src/flamenco/runtime/fd_hashes.h | 2 +- .../runtime/program/fd_bpf_loader_program.h | 4 +-- .../runtime/program/fd_stake_program.c | 6 ++-- .../runtime/program/fd_stake_program.h | 4 +-- .../runtime/program/fd_vote_program.c | 35 +++---------------- .../runtime/program/fd_vote_program.h | 6 +--- src/flamenco/runtime/tests/fd_block_harness.c | 4 +-- src/flamenco/runtime/tests/test_dump_block.c | 4 +-- src/flamenco/stakes/fd_stake_delegations.c | 2 +- src/flamenco/stakes/fd_stakes.c | 8 ++--- 11 files changed, 21 insertions(+), 56 deletions(-) diff --git a/src/flamenco/rewards/fd_rewards.c b/src/flamenco/rewards/fd_rewards.c index 7dd6a8c265..0f3ec14394 100644 --- a/src/flamenco/rewards/fd_rewards.c +++ b/src/flamenco/rewards/fd_rewards.c @@ -882,7 +882,7 @@ distribute_epoch_reward_to_stake_acc( fd_bank_t * bank, fd_txn_account_set_slot( stake_acc_rec, fd_bank_slot_get( bank ) ); fd_stake_state_v2_t stake_state[1] = {0}; - if( fd_stake_get_state( stake_acc_rec, stake_state ) != 0 ) { + if( fd_stake_get_state( stake_acc_rec->meta, stake_state ) != 0 ) { FD_LOG_DEBUG(( "failed to read stake state for %s", FD_BASE58_ENC_32_ALLOCA( stake_pubkey ) )); return 1; } diff --git a/src/flamenco/runtime/fd_hashes.h b/src/flamenco/runtime/fd_hashes.h index fc0ff7688b..3829b6f53f 100644 --- a/src/flamenco/runtime/fd_hashes.h +++ b/src/flamenco/runtime/fd_hashes.h @@ -84,7 +84,7 @@ fd_hashes_account_lthash_simple( uchar const pubkey[ static FD_HASH_FOOT maintained incrementally by subtracting the old account hash and adding the new account hash. - account is the modified account (via fd_txn_account_t interface). + meta is a pointer to the modified account's metadata and data. prev_hash contains the lthash of the account before modification (or zero for newly created accounts). bank is the bank whose lthash should be updated. capture_ctx is an optional capture context for diff --git a/src/flamenco/runtime/program/fd_bpf_loader_program.h b/src/flamenco/runtime/program/fd_bpf_loader_program.h index 66ed9c25c6..107ef3a48f 100644 --- a/src/flamenco/runtime/program/fd_bpf_loader_program.h +++ b/src/flamenco/runtime/program/fd_bpf_loader_program.h @@ -56,9 +56,6 @@ FD_PROTOTYPES_BEGIN /* Mirrors solana_sdk::transaction_context::BorrowedAccount::get_state() - - Acts on a fd_txn_account_t for ease of API use. - https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L965-L969 */ int @@ -92,6 +89,7 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * instr_ctx ); documentation for our `fd_deploy_program` for more information. https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L155-L233 */ + int fd_directly_invoke_loader_v3_deploy( fd_bank_t * bank, fd_funk_t * funk, diff --git a/src/flamenco/runtime/program/fd_stake_program.c b/src/flamenco/runtime/program/fd_stake_program.c index 5a98b5e721..0770da27d4 100644 --- a/src/flamenco/runtime/program/fd_stake_program.c +++ b/src/flamenco/runtime/program/fd_stake_program.c @@ -3288,9 +3288,9 @@ fd_stake_program_config_init( fd_accdb_user_t * accdb, } int -fd_stake_get_state( fd_txn_account_t const * self, - fd_stake_state_v2_t * out ) { - return get_state( self->meta, out ); +fd_stake_get_state( fd_account_meta_t const * meta, + fd_stake_state_v2_t * out ) { + return get_state( meta, out ); } fd_stake_history_entry_t diff --git a/src/flamenco/runtime/program/fd_stake_program.h b/src/flamenco/runtime/program/fd_stake_program.h index cf213e014e..d254ee3038 100644 --- a/src/flamenco/runtime/program/fd_stake_program.h +++ b/src/flamenco/runtime/program/fd_stake_program.h @@ -39,8 +39,8 @@ fd_stake_program_config_init( fd_accdb_user_t * accdb, fd_funk_txn_xid_t const * xid ); int -fd_stake_get_state( fd_txn_account_t const * self, - fd_stake_state_v2_t * out ); +fd_stake_get_state( fd_account_meta_t const * meta, + fd_stake_state_v2_t * out ); fd_stake_history_entry_t fd_stake_activating_and_deactivating( fd_delegation_t const * self, diff --git a/src/flamenco/runtime/program/fd_vote_program.c b/src/flamenco/runtime/program/fd_vote_program.c index 2a9043009c..e117c82772 100644 --- a/src/flamenco/runtime/program/fd_vote_program.c +++ b/src/flamenco/runtime/program/fd_vote_program.c @@ -2721,22 +2721,22 @@ fd_vote_program_execute( fd_exec_instr_ctx_t * ctx ) { /**********************************************************************/ uint -fd_vote_state_versions_is_correct_and_initialized( fd_txn_account_t * vote_account ) { +fd_vote_state_versions_is_correct_and_initialized( fd_account_meta_t const * meta ) { // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/mod.rs#L885 - uint data_len_check = fd_txn_account_get_data_len( vote_account )==FD_VOTE_STATE_V3_SZ; + uint data_len_check = meta->dlen==FD_VOTE_STATE_V3_SZ; uchar test_data[DEFAULT_PRIOR_VOTERS_OFFSET] = {0}; uint data_check = memcmp(( - fd_txn_account_get_data( vote_account )+VERSION_OFFSET), test_data, DEFAULT_PRIOR_VOTERS_OFFSET)!=0; + fd_account_data( meta )+VERSION_OFFSET), test_data, DEFAULT_PRIOR_VOTERS_OFFSET)!=0; if (data_check && data_len_check) { return 1; } // VoteState1_14_11::is_correct_size_and_initialized // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/vote_state_1_14_11.rs#L58 - data_len_check = fd_txn_account_get_data_len( vote_account )==FD_VOTE_STATE_V2_SZ; + data_len_check = meta->dlen==FD_VOTE_STATE_V2_SZ; uchar test_data_1_14_11[DEFAULT_PRIOR_VOTERS_OFFSET_1_14_11] = {0}; data_check = memcmp( ( - fd_txn_account_get_data( vote_account )+VERSION_OFFSET), test_data_1_14_11, DEFAULT_PRIOR_VOTERS_OFFSET_1_14_11)!=0; + fd_account_data( meta )+VERSION_OFFSET), test_data_1_14_11, DEFAULT_PRIOR_VOTERS_OFFSET_1_14_11)!=0; return data_check && data_len_check; } @@ -2754,28 +2754,3 @@ fd_vote_convert_to_current( fd_vote_state_versioned_t * self, uchar * landed_votes_mem ) { convert_to_current( self, authorized_voters_mem, landed_votes_mem ); } - -void -fd_vote_store_account( fd_txn_account_t * vote_account, - fd_bank_t * bank ) { - - fd_vote_states_t * vote_states = fd_bank_vote_states_locking_modify( bank ); - - if( fd_txn_account_get_lamports( vote_account )==0UL ) { - fd_vote_states_remove( vote_states, vote_account->pubkey ); - fd_bank_vote_states_end_locking_modify( bank ); - return; - } - - if( !fd_vote_state_versions_is_correct_and_initialized( vote_account ) ) { - fd_vote_states_remove( vote_states, vote_account->pubkey ); - fd_bank_vote_states_end_locking_modify( bank ); - return; - } - - fd_vote_states_update_from_account( vote_states, - vote_account->pubkey, - fd_txn_account_get_data( vote_account ), - fd_txn_account_get_data_len( vote_account ) ); - fd_bank_vote_states_end_locking_modify( bank ); -} diff --git a/src/flamenco/runtime/program/fd_vote_program.h b/src/flamenco/runtime/program/fd_vote_program.h index 52a8b37c80..f062ddc8ac 100644 --- a/src/flamenco/runtime/program/fd_vote_program.h +++ b/src/flamenco/runtime/program/fd_vote_program.h @@ -48,7 +48,7 @@ fd_vote_program_execute( fd_exec_instr_ctx_t * ctx ); /* https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/state/vote_state_versions.rs#L90 */ uint -fd_vote_state_versions_is_correct_and_initialized( fd_txn_account_t * vote_account ); +fd_vote_state_versions_is_correct_and_initialized( fd_account_meta_t const * meta ); /* An implementation of solana_sdk::transaction_context::BorrowedAccount::get_state for setting the vote state. @@ -63,10 +63,6 @@ fd_vote_convert_to_current( fd_vote_state_versioned_t * self, uchar * authorized_voters_mem, uchar * landed_votes_mem ); -void -fd_vote_store_account( fd_txn_account_t * vote_account, - fd_bank_t * bank ); - FD_PROTOTYPES_END #endif /* HEADER_fd_src_flamenco_runtime_program_fd_vote_program_h */ diff --git a/src/flamenco/runtime/tests/fd_block_harness.c b/src/flamenco/runtime/tests/fd_block_harness.c index 58e56dc67a..1d9ed0ce71 100644 --- a/src/flamenco/runtime/tests/fd_block_harness.c +++ b/src/flamenco/runtime/tests/fd_block_harness.c @@ -111,7 +111,7 @@ fd_solfuzz_block_register_vote_account( fd_funk_t * funk, } /* Account must be initialized correctly */ - if( FD_UNLIKELY( !fd_vote_state_versions_is_correct_and_initialized( acc ) ) ) { + if( FD_UNLIKELY( !fd_vote_state_versions_is_correct_and_initialized( acc->meta ) ) ) { return; } @@ -147,7 +147,7 @@ fd_solfuzz_block_register_stake_delegation( fd_funk_t * funk, /* Stake state must exist and be initialized correctly */ fd_stake_state_v2_t stake_state; - if( FD_UNLIKELY( fd_stake_get_state( acc, &stake_state ) || !fd_stake_state_v2_is_stake( &stake_state ) ) ) { + if( FD_UNLIKELY( fd_stake_get_state( acc->meta, &stake_state ) || !fd_stake_state_v2_is_stake( &stake_state ) ) ) { return; } diff --git a/src/flamenco/runtime/tests/test_dump_block.c b/src/flamenco/runtime/tests/test_dump_block.c index 537d3a4fed..a3c33db653 100644 --- a/src/flamenco/runtime/tests/test_dump_block.c +++ b/src/flamenco/runtime/tests/test_dump_block.c @@ -237,7 +237,7 @@ register_vote_account_from_funk( fd_funk_t * funk, } /* Account must be initialized correctly */ - if( FD_UNLIKELY( !fd_vote_state_versions_is_correct_and_initialized( acc ) ) ) { + if( FD_UNLIKELY( !fd_vote_state_versions_is_correct_and_initialized( acc->meta ) ) ) { return; } @@ -271,7 +271,7 @@ register_stake_delegation_from_funk( fd_funk_t * funk, /* Stake state must exist and be initialized correctly */ fd_stake_state_v2_t stake_state; - if( FD_UNLIKELY( fd_stake_get_state( acc, &stake_state ) || !fd_stake_state_v2_is_stake( &stake_state ) ) ) { + if( FD_UNLIKELY( fd_stake_get_state( acc->meta, &stake_state ) || !fd_stake_state_v2_is_stake( &stake_state ) ) ) { return; } diff --git a/src/flamenco/stakes/fd_stake_delegations.c b/src/flamenco/stakes/fd_stake_delegations.c index 045dfe129b..5becd54cdc 100644 --- a/src/flamenco/stakes/fd_stake_delegations.c +++ b/src/flamenco/stakes/fd_stake_delegations.c @@ -369,7 +369,7 @@ fd_stake_delegations_refresh( fd_stake_delegations_t * stake_delegations, } fd_stake_state_v2_t stake_state; - err = fd_stake_get_state( acct_rec, &stake_state ); + err = fd_stake_get_state( acct_rec->meta, &stake_state ); if( FD_UNLIKELY( err ) ) { fd_stake_delegation_map_idx_remove( stake_delegation_map, &stake_delegation->stake_account, ULONG_MAX, stake_delegation_pool ); fd_stake_delegation_pool_idx_release( stake_delegation_pool, i ); diff --git a/src/flamenco/stakes/fd_stakes.c b/src/flamenco/stakes/fd_stakes.c index 0304d3927b..dd28a93855 100644 --- a/src/flamenco/stakes/fd_stakes.c +++ b/src/flamenco/stakes/fd_stakes.c @@ -192,7 +192,7 @@ fd_stakes_update_stake_delegation( fd_pubkey_t const * pubkey, stake_account->meta = (fd_account_meta_t *)meta; fd_stake_state_v2_t stake_state; - int err = fd_stake_get_state( stake_account, &stake_state ); + int err = fd_stake_get_state( stake_account->meta, &stake_state ); if( FD_UNLIKELY( err!=0 ) ) { fd_stake_delegations_remove( stake_delegations_delta, pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); @@ -242,11 +242,7 @@ fd_stakes_update_vote_state( fd_pubkey_t const * pubkey, return; } - fd_txn_account_t vote_account[1]; - vote_account->data = (uchar *)fd_account_data( meta ); - vote_account->meta = (fd_account_meta_t *)meta; - - if( !fd_vote_state_versions_is_correct_and_initialized( vote_account ) ) { + if( !fd_vote_state_versions_is_correct_and_initialized( meta ) ) { fd_vote_states_remove( vote_states, pubkey ); fd_bank_vote_states_end_locking_modify( bank ); return; From ab43921a9b0970fc2afd56ae758aceaeb31b49ac Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Tue, 25 Nov 2025 21:18:40 +0000 Subject: [PATCH 27/32] wip --- src/flamenco/runtime/fd_executor.c | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index b0c17722d6..562901ef33 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -615,35 +615,32 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, total size of accounts and their owners are accumulated: duplicate owners should be avoided. https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L496-L517 */ - fd_txn_account_t owner_account[1]; - err = fd_txn_account_init_from_funk_readonly( owner_account, - (fd_pubkey_t const *)program_meta->owner, - runtime->funk, - &xid ); + + fd_pubkey_t const * owner_pubkey = (fd_pubkey_t const *)program_meta->owner; + fd_account_meta_t const * owner_account = fd_funk_get_acc_meta_readonly( runtime->funk, &xid, owner_pubkey, NULL, &err, NULL ); if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L520 */ return FD_RUNTIME_TXN_ERR_PROGRAM_ACCOUNT_NOT_FOUND; } - /* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L502-L510 */ - if( FD_UNLIKELY( memcmp( fd_txn_account_get_owner( owner_account ), fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) || + if( FD_UNLIKELY( memcmp( owner_account->owner, fd_solana_native_loader_id.key, sizeof(fd_pubkey_t) ) || ( !FD_FEATURE_ACTIVE_BANK( bank, remove_accounts_executable_flag_checks ) && - !fd_txn_account_is_executable( owner_account ) ) ) ) { + !owner_account->executable ) ) ) { return FD_RUNTIME_TXN_ERR_INVALID_PROGRAM_FOR_EXECUTION; } /* Count the owner's data in the loaded account size for program accounts. However, it is important to not double count repeated owners. https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L511-L517 */ - err = accumulate_and_check_loaded_account_data_size( fd_txn_account_get_data_len( owner_account ), + err = accumulate_and_check_loaded_account_data_size( owner_account->dlen, requested_loaded_accounts_data_size, &txn_out->details.loaded_accounts_data_size ); if( FD_UNLIKELY( err!=FD_RUNTIME_EXECUTE_SUCCESS ) ) { return err; } - fd_memcpy( validated_loaders[ validated_loaders_cnt++ ].key, owner_account->pubkey, sizeof(fd_pubkey_t) ); + fd_memcpy( validated_loaders[ validated_loaders_cnt++ ].key, owner_pubkey, sizeof(fd_pubkey_t) ); } return FD_RUNTIME_EXECUTE_SUCCESS; @@ -727,20 +724,23 @@ fd_collect_loaded_account( fd_runtime_t * runtime, } /* Load the programdata account from Funk to read the programdata length */ - fd_txn_account_t programdata_account[1]; fd_funk_txn_xid_t xid = { .ul = { fd_bank_slot_get( bank ), bank->idx } }; - err = fd_txn_account_init_from_funk_readonly( programdata_account, - &loader_state->inner.program.programdata_address, - runtime->funk, - &xid ); + + fd_account_meta_t const * programdata_meta = fd_funk_get_acc_meta_readonly( + runtime->funk, + &xid, + &loader_state->inner.program.programdata_address, + NULL, + &err, + NULL ); + if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) { return FD_RUNTIME_EXECUTE_SUCCESS; } /* Try to accumulate the programdata's data size https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L625-L630 */ - ulong programdata_size_delta = fd_ulong_sat_add( FD_TRANSACTION_ACCOUNT_BASE_SIZE, - fd_txn_account_get_data_len( programdata_account ) ); + ulong programdata_size_delta = fd_ulong_sat_add( FD_TRANSACTION_ACCOUNT_BASE_SIZE, programdata_meta->dlen ); err = fd_increase_calculated_data_size( txn_out, programdata_size_delta ); if( FD_UNLIKELY( err!=FD_RUNTIME_EXECUTE_SUCCESS ) ) { return err; From 57fe6bcd251209707296633300014b39a84f5e89 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Tue, 25 Nov 2025 21:35:51 +0000 Subject: [PATCH 28/32] wip --- src/flamenco/stakes/fd_stakes.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/flamenco/stakes/fd_stakes.c b/src/flamenco/stakes/fd_stakes.c index dd28a93855..b1d390b3c9 100644 --- a/src/flamenco/stakes/fd_stakes.c +++ b/src/flamenco/stakes/fd_stakes.c @@ -187,12 +187,8 @@ fd_stakes_update_stake_delegation( fd_pubkey_t const * pubkey, return; } - fd_txn_account_t stake_account[1]; - stake_account->data = (uchar *)fd_account_data( meta ); - stake_account->meta = (fd_account_meta_t *)meta; - fd_stake_state_v2_t stake_state; - int err = fd_stake_get_state( stake_account->meta, &stake_state ); + int err = fd_stake_get_state( meta, &stake_state ); if( FD_UNLIKELY( err!=0 ) ) { fd_stake_delegations_remove( stake_delegations_delta, pubkey ); fd_bank_stake_delegations_delta_end_locking_modify( bank ); From 633fb3da678b6c121096b3768a9f38c67eeccfc5 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Tue, 25 Nov 2025 22:22:32 +0000 Subject: [PATCH 29/32] wip --- src/flamenco/runtime/fd_runtime.c | 23 +++++++++++----------- src/flamenco/stakes/fd_stake_delegations.c | 14 +++++-------- 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 627fd9d67e..ac8b4b5111 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1016,8 +1016,8 @@ fd_runtime_finalize_account( fd_funk_t * funk, fd_account_meta_t * meta, fd_funk_rec_t * prev_rec ) { - uchar const * record_data = (uchar *)meta; - ulong record_sz = fd_account_meta_get_record_sz( meta ); + uchar const * record_data = (uchar *)meta; + ulong record_sz = fd_account_meta_get_record_sz( meta ); int err = FD_FUNK_SUCCESS; @@ -1069,7 +1069,8 @@ fd_runtime_finalize_account( fd_funk_t * funk, TODO: remove this when solcap v2 is here. */ static void -fd_runtime_buffer_solcap_account_update( fd_txn_account_t * account, +fd_runtime_buffer_solcap_account_update( fd_pubkey_t const * pubkey, + fd_account_meta_t const * meta, fd_bank_t * bank, fd_capture_ctx_t * capture_ctx ) { @@ -1079,12 +1080,11 @@ fd_runtime_buffer_solcap_account_update( fd_txn_account_t * account, } /* Get account data */ - fd_account_meta_t const * meta = fd_txn_account_get_meta( account ); - void const * data = fd_txn_account_get_data( account ); + void const * data = fd_account_data( meta ); /* Calculate account hash using lthash */ fd_lthash_value_t lthash[1]; - fd_hashes_account_lthash( account->pubkey, meta, data, lthash ); + fd_hashes_account_lthash( pubkey, meta, data, lthash ); /* Calculate message size */ if( FD_UNLIKELY( capture_ctx->account_updates_len >= FD_CAPTURE_CTX_MAX_ACCOUNT_UPDATES ) ) { @@ -1094,15 +1094,14 @@ fd_runtime_buffer_solcap_account_update( fd_txn_account_t * account, /* Write the message to the buffer */ fd_capture_ctx_account_update_msg_t * account_update_msg = (fd_capture_ctx_account_update_msg_t *)(capture_ctx->account_updates_buffer_ptr); - account_update_msg->pubkey = *account->pubkey; + account_update_msg->pubkey = *pubkey; account_update_msg->data_sz = meta->dlen; account_update_msg->bank_idx = bank->idx; fd_solana_account_meta_init( &account_update_msg->info, - fd_txn_account_get_lamports ( account ), - fd_txn_account_get_owner ( account ), - fd_txn_account_is_executable( account ) - ); + meta->lamports, + meta->owner, + meta->executable ); memcpy( account_update_msg->hash.uc, lthash->bytes, sizeof(fd_hash_t) ); capture_ctx->account_updates_buffer_ptr += sizeof(fd_capture_ctx_account_update_msg_t); @@ -1179,7 +1178,7 @@ fd_runtime_save_account( fd_funk_t * funk, account->data = fd_account_data( meta ); account->is_mutable = 1; - fd_runtime_buffer_solcap_account_update( account, bank, capture_ctx ); + fd_runtime_buffer_solcap_account_update( pubkey, meta, bank, capture_ctx ); /* Save the new version of the account to Funk */ fd_runtime_finalize_account( funk, xid, pubkey, meta, funk_prev_rec ); diff --git a/src/flamenco/stakes/fd_stake_delegations.c b/src/flamenco/stakes/fd_stake_delegations.c index 5becd54cdc..806ae51d28 100644 --- a/src/flamenco/stakes/fd_stake_delegations.c +++ b/src/flamenco/stakes/fd_stake_delegations.c @@ -1,6 +1,7 @@ #include "fd_stake_delegations.h" #include "../../funk/fd_funk_base.h" #include "../runtime/fd_txn_account.h" +#include "../runtime/fd_acc_mgr.h" #include "../runtime/program/fd_stake_program.h" #define POOL_NAME fd_stake_delegation_pool @@ -355,21 +356,16 @@ fd_stake_delegations_refresh( fd_stake_delegations_t * stake_delegations, continue; } - fd_txn_account_t acct_rec[1]; - int err = fd_txn_account_init_from_funk_readonly( - acct_rec, - &stake_delegation->stake_account, - funk, - xid ); - - if( FD_UNLIKELY( err || fd_txn_account_get_lamports( acct_rec )==0UL ) ) { + int err = 0; + fd_account_meta_t const * meta = fd_funk_get_acc_meta_readonly( funk, xid, &stake_delegation->stake_account, NULL, &err, NULL ); + if( FD_UNLIKELY( err || meta->lamports==0UL ) ) { fd_stake_delegation_map_idx_remove( stake_delegation_map, &stake_delegation->stake_account, ULONG_MAX, stake_delegation_pool ); fd_stake_delegation_pool_idx_release( stake_delegation_pool, i ); continue; } fd_stake_state_v2_t stake_state; - err = fd_stake_get_state( acct_rec->meta, &stake_state ); + err = fd_stake_get_state( meta, &stake_state ); if( FD_UNLIKELY( err ) ) { fd_stake_delegation_map_idx_remove( stake_delegation_map, &stake_delegation->stake_account, ULONG_MAX, stake_delegation_pool ); fd_stake_delegation_pool_idx_release( stake_delegation_pool, i ); From 2b9ce696e9fb3e1776f38ffad4554b7562631f4a Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Wed, 26 Nov 2025 20:07:25 +0000 Subject: [PATCH 30/32] wip --- src/flamenco/runtime/fd_runtime.c | 26 +++++++++++++++++++++++ src/flamenco/runtime/fd_runtime_helpers.h | 8 +++++++ src/flamenco/runtime/fd_txn_account.c | 24 --------------------- src/flamenco/runtime/fd_txn_account.h | 7 ------ 4 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index ac8b4b5111..cbe3bbb62e 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -22,6 +22,7 @@ #include "program/fd_stake_program.h" #include "program/fd_builtin_programs.h" +#include "program/fd_program_util.h" #include "sysvar/fd_sysvar_clock.h" #include "sysvar/fd_sysvar_last_restart_slot.h" @@ -1934,3 +1935,28 @@ fd_runtime_account_check_fee_payer_writable( fd_txn_in_t const * txn_in, (void) txn_out; return fd_txn_is_writable( TXN( txn_in->txn ), idx ); } + + +int +fd_account_meta_checked_sub_lamports( fd_account_meta_t * meta, ulong lamports ) { + ulong balance_post = 0UL; + int err = fd_ulong_checked_sub( meta->lamports, + lamports, + &balance_post ); + if( FD_UNLIKELY( err ) ) { + return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW; + } + + meta->lamports = balance_post; + return FD_EXECUTOR_INSTR_SUCCESS; +} + +void +fd_account_meta_resize( fd_account_meta_t * meta, + ulong dlen ) { + ulong old_sz = meta->dlen; + ulong new_sz = dlen; + ulong memset_sz = fd_ulong_sat_sub( new_sz, old_sz ); + fd_memset( fd_account_data( meta ) + old_sz, 0, memset_sz ); + meta->dlen = (uint)dlen; +} diff --git a/src/flamenco/runtime/fd_runtime_helpers.h b/src/flamenco/runtime/fd_runtime_helpers.h index d51e9f4364..a45d948d42 100644 --- a/src/flamenco/runtime/fd_runtime_helpers.h +++ b/src/flamenco/runtime/fd_runtime_helpers.h @@ -220,6 +220,14 @@ fd_runtime_account_check_fee_payer_writable( fd_txn_in_t const * txn_in, fd_txn_out_t * txn_out, ushort idx ); +int +fd_account_meta_checked_sub_lamports( fd_account_meta_t * meta, + ulong lamports ); + +void +fd_account_meta_resize( fd_account_meta_t * meta, + ulong dlen ); + FD_PROTOTYPES_END #endif /* HEADER_fd_src_flamenco_runtime_fd_runtime_helpers_h */ diff --git a/src/flamenco/runtime/fd_txn_account.c b/src/flamenco/runtime/fd_txn_account.c index c40dc5e314..25d8f7a477 100644 --- a/src/flamenco/runtime/fd_txn_account.c +++ b/src/flamenco/runtime/fd_txn_account.c @@ -328,20 +328,6 @@ fd_txn_account_checked_add_lamports( fd_txn_account_t * acct, ulong lamports ) { return FD_EXECUTOR_INSTR_SUCCESS; } -int -fd_account_meta_checked_sub_lamports( fd_account_meta_t * meta, ulong lamports ) { - ulong balance_post = 0UL; - int err = fd_ulong_checked_sub( meta->lamports, - lamports, - &balance_post ); - if( FD_UNLIKELY( err ) ) { - return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW; - } - - meta->lamports = balance_post; - return FD_EXECUTOR_INSTR_SUCCESS; -} - int fd_txn_account_checked_sub_lamports( fd_txn_account_t * acct, ulong lamports ) { ulong balance_post = 0UL; @@ -403,16 +389,6 @@ fd_txn_account_clear_owner( fd_txn_account_t * acct ) { fd_memset( acct->meta->owner, 0, sizeof(fd_pubkey_t) ); } -void -fd_account_meta_resize( fd_account_meta_t * meta, - ulong dlen ) { - ulong old_sz = meta->dlen; - ulong new_sz = dlen; - ulong memset_sz = fd_ulong_sat_sub( new_sz, old_sz ); - fd_memset( fd_account_data( meta ) + old_sz, 0, memset_sz ); - meta->dlen = (uint)dlen; -} - void fd_txn_account_resize( fd_txn_account_t * acct, ulong dlen ) { diff --git a/src/flamenco/runtime/fd_txn_account.h b/src/flamenco/runtime/fd_txn_account.h index b95e86fad4..5a48a20825 100644 --- a/src/flamenco/runtime/fd_txn_account.h +++ b/src/flamenco/runtime/fd_txn_account.h @@ -203,13 +203,6 @@ fd_txn_account_set_readonly( fd_txn_account_t * acct ); void fd_txn_account_set_mutable( fd_txn_account_t * acct ); -int -fd_account_meta_checked_sub_lamports( fd_account_meta_t * meta, ulong lamports ); - -void -fd_account_meta_resize( fd_account_meta_t * meta, - ulong dlen ); - FD_PROTOTYPES_END #endif /* HEADER_fd_src_flamenco_runtime_fd_txn_account_h */ From 8d6f9008b7119d63ce5bfc1734dfb9d1e98a849c Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Wed, 26 Nov 2025 20:13:45 +0000 Subject: [PATCH 31/32] wip --- src/flamenco/runtime/fd_executor.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 08dbec934a..f37fb5fd70 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -462,7 +462,6 @@ load_transaction_account( fd_runtime_t * runtime, fd_txn_out_t * txn_out, fd_pubkey_t const * pubkey, fd_account_meta_t * meta, - uchar is_writable, uchar unknown_acc, ulong txn_idx ) { @@ -491,10 +490,6 @@ load_transaction_account( fd_runtime_t * runtime, ulong base_account_size = FD_FEATURE_ACTIVE_BANK( bank, formalize_loaded_transaction_data_size ) ? FD_TRANSACTION_ACCOUNT_BASE_SIZE : 0UL; /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L828-L835 */ - if( is_writable ) { - /* TODO:FIXME: DO WE REALLY NEED THIS */ - runtime->accounts.starting_lamports[txn_idx] = meta->lamports; - } return fd_ulong_sat_add( base_account_size, meta->dlen ); } @@ -529,7 +524,6 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, fd_account_meta_t * meta = txn_out->accounts.metas[i]; uchar unknown_acc = !!(fd_runtime_get_account_at_index( txn_in, txn_out, i, fd_runtime_account_check_exists ) || meta->lamports==0UL); - uchar is_writable = !!(fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, i )); /* Collect the fee payer account separately (since it was already) loaded during fee payer validation. @@ -551,7 +545,7 @@ fd_executor_load_transaction_accounts_old( fd_runtime_t * runtime, } /* https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L733-L740 */ - ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, &txn_out->accounts.keys[i], meta, is_writable, unknown_acc, i ); + ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, &txn_out->accounts.keys[i], meta, unknown_acc, i ); int err = accumulate_and_check_loaded_account_data_size( loaded_acc_size, requested_loaded_accounts_data_size, &txn_out->details.loaded_accounts_data_size ); @@ -796,7 +790,6 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, uchar unknown_acc = !!(fd_runtime_get_account_at_index( txn_in, txn_out, i, fd_runtime_account_check_exists ) || meta->lamports==0UL); - uchar is_writable = !!(fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, i )); /* Collect the fee payer account separately (since it was already) loaded during fee payer validation. @@ -826,7 +819,7 @@ fd_executor_load_transaction_accounts_simd_186( fd_runtime_t * runtime, /* Load and collect any remaining accounts https://github.com/anza-xyz/agave/blob/v2.3.1/svm/src/account_loader.rs#L652-L659 */ - ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, &txn_out->accounts.keys[i], meta, is_writable, unknown_acc, i ); + ulong loaded_acc_size = load_transaction_account( runtime, bank, txn_in, txn_out, &txn_out->accounts.keys[i], meta, unknown_acc, i ); int err = fd_collect_loaded_account( runtime, txn_out, From bcbaa2da5bad5ff896d4b22d26a641d09d368cd1 Mon Sep 17 00:00:00 2001 From: Ishan Bhatt Date: Wed, 26 Nov 2025 20:25:24 +0000 Subject: [PATCH 32/32] wip --- src/flamenco/runtime/fd_executor.c | 3 +-- src/flamenco/runtime/fd_runtime.c | 5 ----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index f37fb5fd70..4e213dee5f 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -1182,7 +1182,6 @@ fd_txn_ctx_push( fd_runtime_t * runtime, } ulong refcnt = runtime->accounts.refcnt[idx]; - /* https://github.com/anza-xyz/agave/blob/v2.2.12/transaction-context/src/lib.rs#L401-L402 */ if( FD_UNLIKELY( refcnt!=0UL ) ) { return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_FAILED; @@ -1519,7 +1518,7 @@ fd_executor_setup_txn_account( fd_runtime_t * runtime, runtime->accounts.starting_lamports[idx] = account_meta->lamports; runtime->accounts.starting_dlen[idx] = account_meta->dlen; runtime->accounts.refcnt[idx] = 0UL; - txn_out->accounts.metas[ idx ] = account_meta; + txn_out->accounts.metas[idx] = account_meta; } static void diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index cbe3bbb62e..f6e9859dc6 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1173,11 +1173,6 @@ fd_runtime_save_account( fd_funk_t * funk, /* Publish account update to replay tile for solcap writing TODO: write in the exec tile with solcap v2 */ - fd_txn_account_t account[1]; - memcpy( account->pubkey, pubkey, sizeof(fd_pubkey_t) ); - account->meta = meta; - account->data = fd_account_data( meta ); - account->is_mutable = 1; fd_runtime_buffer_solcap_account_update( pubkey, meta, bank, capture_ctx );