diff --git a/src/discof/bank/fd_bank_tile.c b/src/discof/bank/fd_bank_tile.c index e5c2101040f..11ce731f530 100644 --- a/src/discof/bank/fd_bank_tile.c +++ b/src/discof/bank/fd_bank_tile.c @@ -46,6 +46,8 @@ typedef struct { fd_banks_t * banks; fd_spad_t * exec_spad; + fd_writable_acc_buf_t writable_acc_arr[ FD_RUNTIME_MAX_WRITABLE_ACCOUNTS_PER_TRANSACTION ]; + fd_exec_txn_ctx_t txn_ctx[1]; struct { @@ -62,11 +64,11 @@ FD_FN_PURE static inline ulong scratch_footprint( fd_topo_tile_t const * tile ) { (void)tile; ulong l = FD_LAYOUT_INIT; - l = FD_LAYOUT_APPEND( l, alignof( fd_bank_ctx_t ), sizeof( fd_bank_ctx_t ) ); - l = FD_LAYOUT_APPEND( l, FD_BLAKE3_ALIGN, FD_BLAKE3_FOOTPRINT ); - l = FD_LAYOUT_APPEND( l, FD_BMTREE_COMMIT_ALIGN, FD_BMTREE_COMMIT_FOOTPRINT(0) ); - l = FD_LAYOUT_APPEND( l, FD_SPAD_ALIGN, FD_SPAD_FOOTPRINT( FD_RUNTIME_TRANSACTION_EXECUTION_FOOTPRINT_DEFAULT ) ); - l = FD_LAYOUT_APPEND( l, fd_txncache_align(), fd_txncache_footprint( tile->bank.max_live_slots ) ); + l = FD_LAYOUT_APPEND( l, alignof(fd_bank_ctx_t), sizeof(fd_bank_ctx_t) ); + l = FD_LAYOUT_APPEND( l, FD_BLAKE3_ALIGN, FD_BLAKE3_FOOTPRINT ); + l = FD_LAYOUT_APPEND( l, FD_BMTREE_COMMIT_ALIGN, FD_BMTREE_COMMIT_FOOTPRINT(0) ); + l = FD_LAYOUT_APPEND( l, FD_SPAD_ALIGN, FD_SPAD_FOOTPRINT( FD_RUNTIME_TRANSACTION_EXECUTION_FOOTPRINT_DEFAULT ) ); + l = FD_LAYOUT_APPEND( l, fd_txncache_align(), fd_txncache_footprint( tile->bank.max_live_slots ) ); return FD_LAYOUT_FINI( l, scratch_align() ); } @@ -161,7 +163,7 @@ handle_microblock( fd_bank_ctx_t * ctx, txn->flags &= ~FD_TXN_P_FLAGS_SANITIZE_SUCCESS; - int err = fd_runtime_prepare_and_execute_txn( ctx->banks, ctx->_bank_idx, txn_ctx, txn, ctx->exec_spad, NULL, 0 ); + int err = fd_runtime_prepare_and_execute_txn( ctx->banks, ctx->_bank_idx, txn_ctx, txn, ctx->exec_spad, ctx->writable_acc_arr, NULL, 0 ); if( FD_UNLIKELY( !(txn_ctx->flags & FD_TXN_P_FLAGS_SANITIZE_SUCCESS ) ) ) { ctx->metrics.txn_result[ fd_bank_err_from_runtime_err( err ) ]++; continue; @@ -235,14 +237,14 @@ handle_microblock( fd_bank_ctx_t * ctx, fork and diverge, so the link from here til PoH mixin must be completely reliable with nothing dropped. - fd_runtime_finalize_txn checks if the transaction fits into the + fd_runtime_commit_txn checks if the transaction fits into the block with the cost tracker. If it doesn't fit, flags is set to zero. A key invariant of the leader pipeline is that pack ensures all transactions must fit already, so it is a fatal error if that happens. We cannot reject the transaction here as there would be no way to undo the partially applied changes to the bank in finalize anyway. */ - fd_runtime_finalize_txn( ctx->txn_ctx->funk, txn_ctx->status_cache, txn_ctx->xid, txn_ctx, bank, NULL ); + fd_runtime_commit_txn( ctx->txn_ctx->funk, txn_ctx->status_cache, txn_ctx->xid, txn_ctx, bank, NULL ); FD_TEST( txn->flags ); } @@ -304,6 +306,7 @@ handle_bundle( fd_bank_ctx_t * ctx, ulong sz, ulong begin_tspub, fd_stem_context_t * stem ) { + uchar * dst = (uchar *)fd_chunk_to_laddr( ctx->out_mem, ctx->out_chunk ); fd_txn_p_t * txns = (fd_txn_p_t *)dst; @@ -326,7 +329,7 @@ handle_bundle( fd_bank_ctx_t * ctx, fd_exec_txn_ctx_t txn_ctx[ 1 ]; // TODO ... bank manager ? txn->flags &= ~(FD_TXN_P_FLAGS_SANITIZE_SUCCESS | FD_TXN_P_FLAGS_EXECUTE_SUCCESS); - int err = fd_runtime_prepare_and_execute_txn( NULL, ULONG_MAX, txn_ctx, txn, NULL, NULL, 0 ); /* TODO ... */ + int err = fd_runtime_prepare_and_execute_txn( NULL, ULONG_MAX, txn_ctx, txn, NULL, NULL, NULL, 0 ); /* TODO ... */ transaction_err[ i ] = err; if( FD_UNLIKELY( err ) ) { @@ -493,11 +496,11 @@ unprivileged_init( fd_topo_t * topo, void * scratch = fd_topo_obj_laddr( topo, tile->tile_obj_id ); FD_SCRATCH_ALLOC_INIT( l, scratch ); - fd_bank_ctx_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof( fd_bank_ctx_t ), sizeof( fd_bank_ctx_t ) ); - void * blake3 = FD_SCRATCH_ALLOC_APPEND( l, FD_BLAKE3_ALIGN, FD_BLAKE3_FOOTPRINT ); - void * bmtree = FD_SCRATCH_ALLOC_APPEND( l, FD_BMTREE_COMMIT_ALIGN, FD_BMTREE_COMMIT_FOOTPRINT(0) ); - void * exec_spad = FD_SCRATCH_ALLOC_APPEND( l, FD_SPAD_ALIGN, FD_SPAD_FOOTPRINT( FD_RUNTIME_TRANSACTION_EXECUTION_FOOTPRINT_DEFAULT ) ); - void * _txncache = FD_SCRATCH_ALLOC_APPEND( l, fd_txncache_align(), fd_txncache_footprint( tile->bank.max_live_slots ) ); + fd_bank_ctx_t * ctx = FD_SCRATCH_ALLOC_APPEND( l, alignof( fd_bank_ctx_t ), sizeof( fd_bank_ctx_t ) ); + void * blake3 = FD_SCRATCH_ALLOC_APPEND( l, FD_BLAKE3_ALIGN, FD_BLAKE3_FOOTPRINT ); + void * bmtree = FD_SCRATCH_ALLOC_APPEND( l, FD_BMTREE_COMMIT_ALIGN, FD_BMTREE_COMMIT_FOOTPRINT(0) ); + void * exec_spad = FD_SCRATCH_ALLOC_APPEND( l, FD_SPAD_ALIGN, FD_SPAD_FOOTPRINT( FD_RUNTIME_TRANSACTION_EXECUTION_FOOTPRINT_DEFAULT ) ); + void * _txncache = FD_SCRATCH_ALLOC_APPEND( l, fd_txncache_align(), fd_txncache_footprint( tile->bank.max_live_slots ) ); #define NONNULL( x ) (__extension__({ \ __typeof__((x)) __x = (x); \ diff --git a/src/discof/exec/fd_exec_tile.c b/src/discof/exec/fd_exec_tile.c index d43a9a41f50..8fe2bbacd24 100644 --- a/src/discof/exec/fd_exec_tile.c +++ b/src/discof/exec/fd_exec_tile.c @@ -58,11 +58,16 @@ typedef struct fd_exec_tile_ctx { /* A transaction can be executed as long as there is a valid handle to a funk_txn and a bank. These are queried from fd_banks_t and - fd_funk_t. - TODO: These should probably be made read-only handles. */ + fd_funk_t. */ fd_banks_t * banks; fd_funk_t funk[ 1 ]; + /* An array for writable accounts. This is a staging buffer for + transactions. The buffer is sized to be large enough to hold all + writable accounts for a transaction with 10MiB for each account + and up to 64 writable accounts. */ + fd_writable_acc_buf_t writable_accounts_arr[ FD_RUNTIME_MAX_WRITABLE_ACCOUNTS_PER_TRANSACTION ]; + fd_txncache_t * txncache; fd_vote_tracker_t * vote_tracker; @@ -121,6 +126,7 @@ during_frag( fd_exec_tile_ctx_t * ctx, ctx->txn_ctx, &txn->txn, ctx->exec_spad, + ctx->writable_accounts_arr, ctx->capture_ctx, 1 ); } else { @@ -172,7 +178,7 @@ after_frag( fd_exec_tile_ctx_t * ctx, } if( FD_LIKELY( ctx->txn_ctx->flags & FD_TXN_P_FLAGS_EXECUTE_SUCCESS ) ) { - fd_runtime_finalize_txn( + fd_runtime_commit_txn( ctx->funk, ctx->txncache, &xid, diff --git a/src/flamenco/runtime/Local.mk b/src/flamenco/runtime/Local.mk index 6d9d6d8b6db..23ed0dfe3c8 100644 --- a/src/flamenco/runtime/Local.mk +++ b/src/flamenco/runtime/Local.mk @@ -39,8 +39,6 @@ $(call add-objs, tests/fd_dump_pb,fd_flamenco) $(call add-hdrs,fd_txn_account.h) $(call add-objs,fd_txn_account,fd_flamenco) -$(call make-unit-test,test_txn_account,test_txn_account,fd_flamenco fd_funk fd_ballet fd_util) -$(call run-unit-test,test_txn_account,) $(call add-hdrs,fd_bank.h) $(call add-objs,fd_bank,fd_flamenco) diff --git a/src/flamenco/runtime/context/fd_exec_txn_ctx.h b/src/flamenco/runtime/context/fd_exec_txn_ctx.h index 7c7233d3317..1c05ce56a6b 100644 --- a/src/flamenco/runtime/context/fd_exec_txn_ctx.h +++ b/src/flamenco/runtime/context/fd_exec_txn_ctx.h @@ -10,6 +10,7 @@ #include "../../../funk/fd_funk.h" #include "../fd_compute_budget_details.h" #include "../../../disco/pack/fd_microblock.h" +#include "../fd_runtime_const.h" /* Return data for syscalls */ @@ -21,6 +22,12 @@ struct fd_txn_return_data { typedef struct fd_txn_return_data fd_txn_return_data_t; +/* TODO:FIXME: magic number for alignment*/ +struct __attribute__((aligned(8UL))) fd_writable_acc_buf { + uchar mem[ FD_RUNTIME_ACC_SZ_MAX ]; +}; +typedef struct fd_writable_acc_buf fd_writable_acc_buf_t; + /* fd_exec_txn_ctx_t is the context needed to execute a transaction. */ /* An entry in the instruction trace */ @@ -63,6 +70,8 @@ struct fd_exec_txn_ctx { fd_spad_t * spad; /* Sized out to handle the worst case footprint of single transaction execution. */ fd_wksp_t * spad_wksp; /* Workspace for the spad. */ + fd_writable_acc_buf_t * writable_accounts_arr; + fd_compute_budget_details_t compute_budget_details; /* Compute budget details */ /* Fields below here are not guaranteed to be local joins in txn execution. */ diff --git a/src/flamenco/runtime/fd_executor.c b/src/flamenco/runtime/fd_executor.c index 9b0afcf0486..8eb981a3240 100644 --- a/src/flamenco/runtime/fd_executor.c +++ b/src/flamenco/runtime/fd_executor.c @@ -952,11 +952,11 @@ fd_executor_create_rollback_fee_payer_account( fd_exec_txn_ctx_t * txn_ctx, ulong data_len = fd_txn_account_get_data_len( &txn_ctx->accounts[FD_FEE_PAYER_TXN_IDX] ); void * fee_payer_data = fd_spad_alloc( txn_ctx->spad, FD_ACCOUNT_REC_ALIGN, sizeof(fd_account_meta_t) + data_len ); fd_memcpy( fee_payer_data, (uchar *)meta, sizeof(fd_account_meta_t) + data_len ); - if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new( + if( FD_UNLIKELY( !fd_txn_account_new( txn_ctx->rollback_fee_payer_account, fee_payer_key, (fd_account_meta_t *)fee_payer_data, - 1 ), txn_ctx->spad_wksp ) ) ) { + 1 ) ) ) { FD_LOG_CRIT(( "Failed to join txn account" )); } @@ -1420,7 +1420,6 @@ fd_executor_setup_txn_account( fd_exec_txn_ctx_t * txn_ctx, int is_writable = fd_exec_txn_ctx_account_is_writable_idx( txn_ctx, idx ) || idx==FD_FEE_PAYER_TXN_IDX; fd_account_meta_t * account_meta = NULL; - fd_wksp_t * data_wksp = NULL; if( is_writable ) { /* If the account is writable or a fee payer, then we need to create @@ -1428,7 +1427,7 @@ fd_executor_setup_txn_account( fd_exec_txn_ctx_t * txn_ctx, copy the account data into the staging area; otherwise, we need to initialize a new metadata. */ - uchar * new_raw_data = fd_spad_alloc( txn_ctx->spad, FD_ACCOUNT_REC_ALIGN, FD_ACC_TOT_SZ_MAX ); + uchar * new_raw_data = txn_ctx->writable_accounts_arr[idx].mem; ulong dlen = !!meta ? meta->dlen : 0UL; if( FD_LIKELY( meta ) ) { @@ -1440,7 +1439,6 @@ fd_executor_setup_txn_account( fd_exec_txn_ctx_t * txn_ctx, } account_meta = (fd_account_meta_t *)new_raw_data; - data_wksp = txn_ctx->spad_wksp; } else { /* If the account is not writable, then we can simply initialize @@ -1450,20 +1448,18 @@ fd_executor_setup_txn_account( fd_exec_txn_ctx_t * txn_ctx, if( FD_LIKELY( err==FD_ACC_MGR_SUCCESS ) ) { account_meta = (fd_account_meta_t *)meta; - data_wksp = fd_funk_wksp( txn_ctx->funk ); } else { uchar * mem = fd_spad_alloc( txn_ctx->spad, FD_TXN_ACCOUNT_ALIGN, sizeof(fd_account_meta_t) ); account_meta = (fd_account_meta_t *)mem; - data_wksp = txn_ctx->spad_wksp; fd_account_meta_init( account_meta ); } } - if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new( + if( FD_UNLIKELY( !fd_txn_account_new( txn_account, acc, account_meta, - is_writable ), data_wksp ) ) ) { + is_writable ) ) ) { FD_LOG_CRIT(( "Failed to join txn account" )); } diff --git a/src/flamenco/runtime/fd_runtime.c b/src/flamenco/runtime/fd_runtime.c index 1594e4082e8..8b8938537a7 100644 --- a/src/flamenco/runtime/fd_runtime.c +++ b/src/flamenco/runtime/fd_runtime.c @@ -1033,14 +1033,8 @@ fd_runtime_save_account( fd_funk_t * funk, fd_funk_txn_xid_t const * xid, fd_txn_account_t * account, fd_bank_t * bank, - fd_wksp_t * acc_data_wksp, fd_capture_ctx_t * capture_ctx ) { - /* Join the transaction account */ - if( FD_UNLIKELY( !fd_txn_account_join( account, acc_data_wksp ) ) ) { - FD_LOG_CRIT(( "fd_runtime_save_account: failed to join account" )); - } - /* Look up the previous version of the account from Funk */ FD_TXN_ACCOUNT_DECL( previous_account_version ); int err = fd_txn_account_init_from_funk_readonly( previous_account_version, account->pubkey, funk, xid ); @@ -1071,18 +1065,14 @@ fd_runtime_save_account( fd_funk_t * funk, fd_runtime_finalize_account( funk, xid, account ); } -/* fd_runtime_finalize_txn is a helper used by the non-tpool transaction - executor to finalize borrowed account changes back into funk. It also - handles txncache insertion and updates to the vote/stake cache. - TODO: This function should probably be moved to fd_executor.c. */ void -fd_runtime_finalize_txn( fd_funk_t * funk, - fd_txncache_t * txncache, - fd_funk_txn_xid_t const * xid, - fd_exec_txn_ctx_t * txn_ctx, - fd_bank_t * bank, - fd_capture_ctx_t * capture_ctx ) { +fd_runtime_commit_txn( fd_funk_t * funk, + fd_txncache_t * txncache, + fd_funk_txn_xid_t const * xid, + fd_exec_txn_ctx_t * txn_ctx, + fd_bank_t * bank, + fd_capture_ctx_t * capture_ctx ) { /* Collect fees */ FD_ATOMIC_FETCH_AND_ADD( fd_bank_txn_count_modify( bank ), 1UL ); @@ -1107,12 +1097,12 @@ fd_runtime_finalize_txn( fd_funk_t * funk, We should always rollback the nonce account first. Note that the nonce account may be the fee payer (case 2). */ if( txn_ctx->nonce_account_idx_in_txn!=ULONG_MAX ) { - fd_runtime_save_account( funk, xid, txn_ctx->rollback_nonce_account, bank, txn_ctx->spad_wksp, capture_ctx ); + fd_runtime_save_account( funk, xid, txn_ctx->rollback_nonce_account, bank, 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_ctx->nonce_account_idx_in_txn!=FD_FEE_PAYER_TXN_IDX ) ) { - fd_runtime_save_account( funk, xid, txn_ctx->rollback_fee_payer_account, bank, txn_ctx->spad_wksp, capture_ctx ); + fd_runtime_save_account( funk, xid, txn_ctx->rollback_fee_payer_account, bank, capture_ctx ); } } else { @@ -1125,10 +1115,7 @@ fd_runtime_finalize_txn( fd_funk_t * funk, continue; } - fd_txn_account_t * acc_rec = fd_txn_account_join( &txn_ctx->accounts[i], txn_ctx->spad_wksp ); - if( FD_UNLIKELY( !acc_rec ) ) { - FD_LOG_CRIT(( "fd_runtime_finalize_txn: failed to join account at idx %u", i )); - } + fd_txn_account_t * acc_rec = &txn_ctx->accounts[i]; if( dirty_vote_acc && 0==memcmp( fd_txn_account_get_owner( acc_rec ), &fd_solana_vote_program_id, sizeof(fd_pubkey_t) ) ) { fd_vote_store_account( acc_rec, bank ); @@ -1142,7 +1129,7 @@ fd_runtime_finalize_txn( fd_funk_t * funk, cache updates have been applied. */ fd_executor_reclaim_account( txn_ctx, &txn_ctx->accounts[i] ); - fd_runtime_save_account( funk, xid, &txn_ctx->accounts[i], bank, txn_ctx->spad_wksp, capture_ctx ); + fd_runtime_save_account( funk, xid, &txn_ctx->accounts[i], bank, capture_ctx ); } /* We need to queue any existing program accounts that may have @@ -1196,13 +1183,14 @@ fd_runtime_finalize_txn( fd_funk_t * funk, } int -fd_runtime_prepare_and_execute_txn( fd_banks_t * banks, - ulong bank_idx, - fd_exec_txn_ctx_t * txn_ctx, - fd_txn_p_t * txn, - fd_spad_t * exec_spad, - fd_capture_ctx_t * capture_ctx, - uchar do_sigverify ) { +fd_runtime_prepare_and_execute_txn( fd_banks_t * banks, + ulong bank_idx, + fd_exec_txn_ctx_t * txn_ctx, + fd_txn_p_t * txn, + fd_spad_t * exec_spad, + fd_writable_acc_buf_t * writable_accounts_arr, + fd_capture_ctx_t * capture_ctx, + uchar do_sigverify ) { FD_SPAD_FRAME_BEGIN( exec_spad ) { int exec_res = 0; @@ -1222,6 +1210,7 @@ fd_runtime_prepare_and_execute_txn( fd_banks_t * banks, txn_ctx->xid[0] = (fd_funk_txn_xid_t){ .ul = { slot, slot } }; txn_ctx->capture_ctx = capture_ctx; txn_ctx->txn = *txn; + txn_ctx->writable_accounts_arr = writable_accounts_arr; txn_ctx->flags = FD_TXN_P_FLAGS_SANITIZE_SUCCESS; fd_exec_txn_ctx_setup_basic( txn_ctx ); diff --git a/src/flamenco/runtime/fd_runtime.h b/src/flamenco/runtime/fd_runtime.h index dccfe81ef40..5b9d10d1c3b 100644 --- a/src/flamenco/runtime/fd_runtime.h +++ b/src/flamenco/runtime/fd_runtime.h @@ -451,21 +451,22 @@ fd_runtime_pre_execute_check( fd_exec_txn_ctx_t * txn_ctx ); transaction. */ int -fd_runtime_prepare_and_execute_txn( fd_banks_t * banks, - ulong bank_idx, - fd_exec_txn_ctx_t * txn_ctx, - fd_txn_p_t * txn, - fd_spad_t * exec_spad, - fd_capture_ctx_t * capture_ctx, - uchar do_sigverify ); +fd_runtime_prepare_and_execute_txn( fd_banks_t * banks, + ulong bank_idx, + fd_exec_txn_ctx_t * txn_ctx, + fd_txn_p_t * txn, + fd_spad_t * exec_spad, + fd_writable_acc_buf_t * writable_accounts_arr, + fd_capture_ctx_t * capture_ctx, + uchar do_sigverify ); void -fd_runtime_finalize_txn( fd_funk_t * funk, - fd_txncache_t * txncache, - fd_funk_txn_xid_t const * xid, - fd_exec_txn_ctx_t * txn_ctx, - fd_bank_t * bank, - fd_capture_ctx_t * capture_ctx ); +fd_runtime_commit_txn( fd_funk_t * funk, + fd_txncache_t * txncache, + fd_funk_txn_xid_t const * xid, + fd_exec_txn_ctx_t * txn_ctx, + fd_bank_t * bank, + fd_capture_ctx_t * capture_ctx ); /* Epoch Boundary *************************************************************/ diff --git a/src/flamenco/runtime/fd_txn_account.c b/src/flamenco/runtime/fd_txn_account.c index 4569df61492..99058e126b1 100644 --- a/src/flamenco/runtime/fd_txn_account.c +++ b/src/flamenco/runtime/fd_txn_account.c @@ -1,7 +1,7 @@ #include "fd_txn_account.h" #include "fd_runtime.h" -void * +fd_txn_account_t * fd_txn_account_new( void * mem, fd_pubkey_t const * pubkey, fd_account_meta_t * meta, @@ -30,27 +30,12 @@ fd_txn_account_new( void * mem, fd_memcpy( txn_account->pubkey, pubkey, sizeof(fd_pubkey_t) ); - fd_wksp_t * wksp = fd_wksp_containing( meta ); - txn_account->magic = FD_TXN_ACCOUNT_MAGIC; - txn_account->starting_dlen = meta->dlen; txn_account->starting_lamports = meta->lamports; uchar * data = (uchar *)meta + sizeof(fd_account_meta_t); - txn_account->meta_gaddr = fd_wksp_gaddr( wksp, meta ); - if( FD_UNLIKELY( !txn_account->meta_gaddr ) ) { - FD_LOG_WARNING(( "meta_gaddr is 0" )); - return NULL; - } - - txn_account->data_gaddr = fd_wksp_gaddr( wksp, data ); - if( FD_UNLIKELY( !txn_account->data_gaddr ) ) { - FD_LOG_WARNING(( "data_gaddr is 0" )); - return NULL; - } - txn_account->meta = meta; txn_account->data = data; txn_account->is_mutable = is_mutable; @@ -58,93 +43,6 @@ fd_txn_account_new( void * mem, return mem; } -fd_txn_account_t * -fd_txn_account_join( void * mem, fd_wksp_t * data_wksp ) { - if( FD_UNLIKELY( !mem ) ) { - FD_LOG_WARNING(( "NULL mem" )); - return NULL; - } - - if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, alignof(fd_txn_account_t) ) ) ) { - FD_LOG_WARNING(( "misaligned mem" )); - return NULL; - } - - if( FD_UNLIKELY( !data_wksp ) ) { - FD_LOG_WARNING(( "NULL data_wksp" )); - return NULL; - } - - fd_txn_account_t * txn_account = (fd_txn_account_t *)mem; - - if( FD_UNLIKELY( txn_account->magic != FD_TXN_ACCOUNT_MAGIC ) ) { - FD_LOG_WARNING(( "wrong magic" )); - return NULL; - } - - if( FD_UNLIKELY( txn_account->meta_gaddr==0UL ) ) { - FD_LOG_WARNING(( "`meta gaddr is 0" )); - return NULL; - } - - txn_account->meta = fd_wksp_laddr( data_wksp, txn_account->meta_gaddr ); - if( FD_UNLIKELY( !txn_account->meta ) ) { - FD_LOG_WARNING(( "meta is NULL" )); - return NULL; - } - - txn_account->data = fd_wksp_laddr( data_wksp, txn_account->data_gaddr ); - if( FD_UNLIKELY( !txn_account->data && txn_account->meta->dlen ) ) { - FD_LOG_WARNING(( "data is NULL" )); - return NULL; - } - - return txn_account; -} - -void * -fd_txn_account_leave( fd_txn_account_t * acct ) { - - if( FD_UNLIKELY( !acct ) ) { - FD_LOG_WARNING(( "NULL acct" )); - return NULL; - } - - if( FD_UNLIKELY( acct->magic != FD_TXN_ACCOUNT_MAGIC ) ) { - FD_LOG_WARNING(( "wrong magic" )); - return NULL; - } - - acct->meta = NULL; - acct->data = NULL; - - return acct; -} - -void * -fd_txn_account_delete( void * mem ) { - if( FD_UNLIKELY( !mem ) ) { - FD_LOG_WARNING(( "NULL mem" )); - return NULL; - } - - if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, alignof(fd_txn_account_t) ) ) ) { - FD_LOG_WARNING(( "misaligned mem" )); - return NULL; - } - - fd_txn_account_t * txn_account = (fd_txn_account_t *)mem; - - if( FD_UNLIKELY( txn_account->magic != FD_TXN_ACCOUNT_MAGIC ) ) { - FD_LOG_WARNING(( "wrong magic" )); - return NULL; - } - - txn_account->magic = 0UL; - - return mem; -} - /* Factory constructors from funk */ int @@ -166,11 +64,11 @@ fd_txn_account_init_from_funk_readonly( fd_txn_account_t * acct, return err; } - if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new( + if( FD_UNLIKELY( !fd_txn_account_new( acct, pubkey, (fd_account_meta_t *)meta, - 0 ), fd_funk_wksp( funk ) ) ) ) { + 0 ) ) ) { FD_LOG_CRIT(( "Failed to join txn account" )); } @@ -206,11 +104,11 @@ fd_txn_account_init_from_funk_mutable( fd_txn_account_t * acct, prepared_rec field so that any created records can be published with fd_txn_account_mutable_fini. */ - if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new( + if( FD_UNLIKELY( !fd_txn_account_new( acct, pubkey, (fd_account_meta_t *)meta, - 1 ), fd_funk_wksp( funk ) ) ) ) { + 1 ) ) ) { FD_LOG_CRIT(( "Failed to join txn account" )); } diff --git a/src/flamenco/runtime/fd_txn_account.h b/src/flamenco/runtime/fd_txn_account.h index 85a89eb4e6b..33f9108080f 100644 --- a/src/flamenco/runtime/fd_txn_account.h +++ b/src/flamenco/runtime/fd_txn_account.h @@ -64,40 +64,12 @@ FD_PROTOTYPES_BEGIN After a successful call to fd_txn_account_new, the object will now own the account's metadata and data. */ -void * +fd_txn_account_t * fd_txn_account_new( void * mem, fd_pubkey_t const * pubkey, fd_account_meta_t * meta, int is_mutable ); -/* fd_txn_account_join joins a thread with an indepedent address space - to the memory region allocated by fd_txn_account_new. There can be - only ONE valid join per fd_txn_account_t object. If a _join is called - from one thread, it is implied that the object is no longer valid - on other threads. - - TODO: When the new db is introduced, the wksp argument should be - removed in favor of using offsets into other data structures. */ - -fd_txn_account_t * -fd_txn_account_join( void * mem, fd_wksp_t * data_wksp ); - -/* fd_txn_account_leave leaves a current local join and returns a - pointer to the underlying shared memory region. The fd_txn_account_t - will still own the account's metadata and data. */ - -void * -fd_txn_account_leave( fd_txn_account_t * acct ); - -/* fd_txn_account_delete removes the memory layout for the - fd_txn_account_t object. It returns a pointer to the underlying - shared struct. Any attempts to join after a call to - fd_txn_account_delete will fail. The account's metadata and data - will be owned by the caller after the delete is called. */ - -void * -fd_txn_account_delete( void * mem ); - /* Factory constructors from funk. TODO: These need to be removed when a new db is introduced and either replaced with a new factory constructor or removed entirely in favor diff --git a/src/flamenco/runtime/program/fd_system_program_nonce.c b/src/flamenco/runtime/program/fd_system_program_nonce.c index 156160874a4..a2472e7e611 100644 --- a/src/flamenco/runtime/program/fd_system_program_nonce.c +++ b/src/flamenco/runtime/program/fd_system_program_nonce.c @@ -1030,11 +1030,11 @@ fd_check_transaction_age( fd_exec_txn_ctx_t * txn_ctx ) { } 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( + if( FD_UNLIKELY( !fd_txn_account_new( txn_ctx->rollback_nonce_account, &txn_ctx->account_keys[ instr_accts[ 0UL ] ], (fd_account_meta_t *)borrowed_account_data, - 1 ), txn_ctx->spad_wksp ) ) ) { + 1 ) ) ) { FD_LOG_CRIT(( "Failed to join txn account" )); } diff --git a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c index 7bf04251136..1ce04b53c78 100644 --- a/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c +++ b/src/flamenco/runtime/sysvar/fd_sysvar_instructions.c @@ -62,7 +62,7 @@ fd_sysvar_instructions_serialize_account( fd_exec_txn_ctx_t * txn_ctx, if( !fd_txn_account_is_mutable( rec ) ) { uchar * mem = fd_spad_alloc( txn_ctx->spad, FD_TXN_ACCOUNT_ALIGN, sizeof(fd_account_meta_t) + serialized_sz ); 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 ), txn_ctx->spad_wksp ); + fd_txn_account_t * acc = fd_txn_account_new( rec, &fd_sysvar_instructions_id, meta, 1 ); if( FD_UNLIKELY( !acc ) ) { FD_LOG_CRIT(( "Failed to join txn account" )); } diff --git a/src/flamenco/runtime/test_txn_account.c b/src/flamenco/runtime/test_txn_account.c deleted file mode 100644 index 4527798b690..00000000000 --- a/src/flamenco/runtime/test_txn_account.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "fd_txn_account.h" -#include "fd_acc_mgr.h" - -int -main( int argc, char ** argv ) { - fd_boot( &argc, &argv ); - - char * _page_sz = "gigantic"; - ulong numa_idx = fd_shmem_numa_idx( 0 ); - fd_wksp_t * wksp = fd_wksp_new_anonymous( fd_cstr_to_shmem_page_sz( _page_sz ), - 1UL, - fd_shmem_cpu_idx( numa_idx ), - "wksp", - 0UL ); - void * tx_acc_mem = fd_wksp_alloc_laddr( wksp, FD_TXN_ACCOUNT_ALIGN, FD_TXN_ACCOUNT_FOOTPRINT, 1UL ); - FD_TEST( tx_acc_mem ); - - fd_pubkey_t pubkey = { .ul = { 9, 10 } }; - - uchar * data = fd_wksp_alloc_laddr( wksp, 1UL, 1000UL, 1UL ); - uchar * data2 = fd_wksp_alloc_laddr( wksp, 1UL, 1000UL, 1UL ); - fd_account_meta_t * meta = (fd_account_meta_t *)data; - fd_account_meta_init( meta ); - meta->dlen = 100UL; - uchar * acc_data = fd_account_meta_get_data( meta ); - - FD_TEST( !fd_txn_account_new( NULL, &pubkey, meta, 0 ) ); - FD_TEST( !fd_txn_account_new( tx_acc_mem, NULL, meta, 0 ) ); - FD_TEST( !fd_txn_account_new( tx_acc_mem, &pubkey, NULL, 0 ) ); - - uchar * new_tx_account = fd_txn_account_new( tx_acc_mem, &pubkey, meta, 0 ); - FD_TEST( new_tx_account ); - - FD_TEST( !fd_txn_account_join( NULL, wksp ) ); - FD_TEST( !fd_txn_account_join( data2, wksp ) ); - FD_TEST( !fd_txn_account_join( tx_acc_mem, NULL ) ); - fd_txn_account_t * txn_account = fd_txn_account_join( tx_acc_mem, wksp ); - FD_TEST( txn_account ); - - /* TODO: These tests do not enforce that the account is read-only - because the current impl calls FD_LOG_CRIT when the account is - not mutable but the caller calls a mutator. */ - - uchar null_hash[32] = { 0 }; - - FD_TEST( !fd_txn_account_is_mutable( txn_account ) ); - FD_TEST( fd_txn_account_is_readonly( txn_account ) ); - FD_TEST( fd_txn_account_get_data_len( txn_account ) == 100UL ); - FD_TEST( fd_txn_account_get_lamports( txn_account ) == 0UL ); - FD_TEST( fd_txn_account_get_rent_epoch( txn_account ) == ULONG_MAX ); - FD_TEST( !memcmp( fd_txn_account_get_owner( txn_account ), null_hash, sizeof(null_hash) ) ); - FD_TEST( fd_txn_account_get_meta( txn_account ) == meta ); - FD_TEST( fd_txn_account_get_data( txn_account ) == acc_data ); - - FD_TEST( fd_txn_account_leave( txn_account ) ); - - FD_TEST( fd_txn_account_join( fd_txn_account_leave( txn_account ), wksp ) ); - FD_TEST( !fd_txn_account_leave( NULL ) ); - - uchar * deleted_tx_account = fd_txn_account_delete( fd_txn_account_leave( txn_account ) ); - FD_TEST( deleted_tx_account ); - FD_TEST( !fd_txn_account_join( deleted_tx_account, wksp ) ); - FD_TEST( !fd_txn_account_delete( NULL ) ); - - /* Repeat similar tests with a mutable account */ - - meta->dlen = 101UL; - txn_account = fd_txn_account_join( fd_txn_account_new( tx_acc_mem, &pubkey, meta, 1 ), wksp ); - FD_TEST( txn_account ); - - FD_TEST( fd_txn_account_is_mutable( txn_account ) ); - FD_TEST( !fd_txn_account_is_readonly( txn_account ) ); - FD_TEST( fd_txn_account_get_data_len( txn_account ) == 101UL ); - FD_TEST( fd_txn_account_get_lamports( txn_account ) == 0UL ); - - fd_txn_account_set_lamports( txn_account, 1000UL ); - FD_TEST( fd_txn_account_get_lamports( txn_account ) == 1000UL ); - - FD_TEST( fd_txn_account_get_rent_epoch( txn_account ) == ULONG_MAX ); - - fd_txn_account_set_data_len( txn_account, 102UL ); - FD_TEST( fd_txn_account_get_data_len( txn_account ) == 102UL ); - FD_TEST( fd_txn_account_delete( fd_txn_account_leave( txn_account ) ) ); - - FD_LOG_NOTICE(( "pass" )); - - fd_halt(); - return 0; -} diff --git a/src/flamenco/runtime/tests/fd_block_harness.c b/src/flamenco/runtime/tests/fd_block_harness.c index f325bb2c6d3..4e50cd04b5d 100644 --- a/src/flamenco/runtime/tests/fd_block_harness.c +++ b/src/flamenco/runtime/tests/fd_block_harness.c @@ -491,8 +491,8 @@ fd_runtime_fuzz_block_ctx_exec( fd_solfuzz_runner_t * runner, break; } - /* Finalize the transaction */ - fd_runtime_finalize_txn( + /* Commit the transaction */ + fd_runtime_commit_txn( slot_ctx->funk, NULL, slot_ctx->xid, diff --git a/src/flamenco/runtime/tests/fd_instr_harness.c b/src/flamenco/runtime/tests/fd_instr_harness.c index 7235d903efa..6a435d68192 100644 --- a/src/flamenco/runtime/tests/fd_instr_harness.c +++ b/src/flamenco/runtime/tests/fd_instr_harness.c @@ -148,7 +148,7 @@ fd_runtime_fuzz_instr_ctx_create( fd_solfuzz_runner_t * runner, ulong dlen = fd_txn_account_get_data_len( acc ); fd_account_meta_t * meta = (fd_account_meta_t *)data; fd_memcpy( data, fd_txn_account_get_meta( acc ), sizeof(fd_account_meta_t)+dlen ); - if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new( acc, acc_key, meta, 0 ), txn_ctx->spad_wksp ) ) ) { + if( FD_UNLIKELY( !fd_txn_account_new( acc, acc_key, meta, 0 ) ) ) { FD_LOG_CRIT(( "Failed to join and new a txn account" )); } } @@ -173,11 +173,7 @@ fd_runtime_fuzz_instr_ctx_create( fd_solfuzz_runner_t * runner, fd_account_meta_t * meta = fd_spad_alloc( txn_ctx->spad, alignof(fd_account_meta_t), sizeof(fd_account_meta_t) ); fd_account_meta_init( meta ); - if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new( - program_acc, - program_key, - meta, - 1 ), txn_ctx->spad_wksp ) ) ) { + if( FD_UNLIKELY( !fd_txn_account_new( program_acc, program_key, meta, 1 ) ) ) { FD_LOG_CRIT(( "Failed to join and new a txn account" )); } @@ -199,7 +195,7 @@ fd_runtime_fuzz_instr_ctx_create( fd_solfuzz_runner_t * runner, uchar * mem = fd_spad_alloc( txn_ctx->spad, FD_TXN_ACCOUNT_ALIGN, sizeof(fd_account_meta_t) ); fd_account_meta_t * meta = (fd_account_meta_t *)mem; memset( meta, 0, sizeof(fd_account_meta_t) ); - if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new( acc, acc_key, meta, 0 ), txn_ctx->spad_wksp ) ) ) { + if( FD_UNLIKELY( !fd_txn_account_new( acc, acc_key, meta, 0 ) ) ) { FD_LOG_CRIT(( "Failed to join and new a txn account" )); } continue; diff --git a/src/flamenco/runtime/tests/fd_txn_harness.c b/src/flamenco/runtime/tests/fd_txn_harness.c index 3c22189bb55..b9049dcbabc 100644 --- a/src/flamenco/runtime/tests/fd_txn_harness.c +++ b/src/flamenco/runtime/tests/fd_txn_harness.c @@ -347,12 +347,13 @@ fd_runtime_fuzz_txn_ctx_exec( fd_solfuzz_runner_t * runner, int * exec_res ) { /* Setup the spad for account allocation */ - uchar * txn_ctx_mem = fd_spad_alloc( runner->spad, FD_EXEC_TXN_CTX_ALIGN, FD_EXEC_TXN_CTX_FOOTPRINT ); - fd_exec_txn_ctx_t * txn_ctx = fd_exec_txn_ctx_join( fd_exec_txn_ctx_new( txn_ctx_mem ), runner->spad, fd_wksp_containing( runner->spad ) ); - txn_ctx->flags = FD_TXN_P_FLAGS_SANITIZE_SUCCESS; - *txn_ctx->funk = *slot_ctx->funk; - txn_ctx->bank_hash_cmp = NULL; - txn_ctx->fuzz_config.enable_vm_tracing = runner->enable_vm_tracing; + uchar * txn_ctx_mem = fd_spad_alloc( runner->spad, FD_EXEC_TXN_CTX_ALIGN, FD_EXEC_TXN_CTX_FOOTPRINT ); + fd_writable_acc_buf_t * writable_acc_arr = fd_spad_alloc( runner->spad, alignof(fd_writable_acc_buf_t), sizeof(fd_writable_acc_buf_t) * FD_RUNTIME_MAX_WRITABLE_ACCOUNTS_PER_TRANSACTION ); + fd_exec_txn_ctx_t * txn_ctx = fd_exec_txn_ctx_join( fd_exec_txn_ctx_new( txn_ctx_mem ), runner->spad, fd_wksp_containing( runner->spad ) ); + txn_ctx->flags = FD_TXN_P_FLAGS_SANITIZE_SUCCESS; + *txn_ctx->funk = *slot_ctx->funk; + txn_ctx->bank_hash_cmp = NULL; + txn_ctx->fuzz_config.enable_vm_tracing = runner->enable_vm_tracing; *exec_res = fd_runtime_prepare_and_execute_txn( slot_ctx->banks, @@ -360,6 +361,7 @@ fd_runtime_fuzz_txn_ctx_exec( fd_solfuzz_runner_t * runner, txn_ctx, txn, runner->spad, + writable_acc_arr, NULL, 0 );