Skip to content

Commit caca5c3

Browse files
account for try_borrow_mut
1 parent 1e9971b commit caca5c3

File tree

7 files changed

+71
-35
lines changed

7 files changed

+71
-35
lines changed

src/flamenco/runtime/context/fd_exec_txn_ctx.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ fd_exec_txn_ctx_get_account_at_index( fd_exec_txn_ctx_t * ctx,
9696
*account = txn_account;
9797

9898
if( FD_LIKELY( condition != NULL ) ) {
99-
if( FD_UNLIKELY( !condition( ctx, idx, *account ) ) ) {
99+
if( FD_UNLIKELY( !condition( *account, ctx, idx ) ) ) {
100100
return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT;
101101
}
102102
}
@@ -141,7 +141,7 @@ fd_exec_txn_ctx_get_executable_account( fd_exec_txn_ctx_t * ctx,
141141
*account = txn_account;
142142

143143
if( FD_LIKELY( condition != NULL ) ) {
144-
if( FD_UNLIKELY( !condition( ctx, (int)i, *account ) ) ) {
144+
if( FD_UNLIKELY( !condition( *account, ctx, (int)i ) ) ) {
145145
return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT;
146146
}
147147
}
@@ -311,26 +311,35 @@ fd_exec_txn_ctx_account_is_writable_idx( fd_exec_txn_ctx_t const * txn_ctx, int
311311
/* Account pre-condition filtering functions */
312312

313313
int
314-
fd_txn_account_exists( fd_exec_txn_ctx_t const * ctx,
315-
int idx,
316-
fd_txn_account_t * acc ) {
314+
fd_txn_account_check_exists( fd_txn_account_t * acc,
315+
fd_exec_txn_ctx_t const * ctx,
316+
int idx ) {
317317
(void) ctx;
318318
(void) idx;
319319
return fd_acc_exists( acc->const_meta );
320320
}
321321

322322
int
323-
fd_txn_account_is_writable( fd_exec_txn_ctx_t const * ctx,
324-
int idx,
325-
fd_txn_account_t * acc ) {
323+
fd_txn_account_check_is_writable( fd_txn_account_t * acc,
324+
fd_exec_txn_ctx_t const * ctx,
325+
int idx ) {
326326
(void) acc;
327327
return fd_exec_txn_ctx_account_is_writable_idx( ctx, idx );
328328
}
329329

330330
int
331-
fd_txn_account_fee_payer_writable( fd_exec_txn_ctx_t const * ctx,
332-
int idx,
333-
fd_txn_account_t * acc ) {
331+
fd_txn_account_check_fee_payer_writable( fd_txn_account_t * acc,
332+
fd_exec_txn_ctx_t const * ctx,
333+
int idx ) {
334334
(void) acc;
335335
return fd_txn_is_writable( ctx->txn_descriptor, idx );
336336
}
337+
338+
int
339+
fd_txn_account_check_borrow_mut( fd_txn_account_t * acc,
340+
fd_exec_txn_ctx_t const * ctx,
341+
int idx ) {
342+
(void) ctx;
343+
(void) idx;
344+
return fd_txn_account_is_mutable( acc ) && fd_txn_account_acquire_write( acc );
345+
}

src/flamenco/runtime/context/fd_exec_txn_ctx.h

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,9 @@ fd_exec_txn_ctx_find_index_of_account( fd_exec_txn_ctx_t const * ctx,
255255
return -1;
256256
}
257257

258-
typedef int fd_txn_account_condition_fn_t ( fd_exec_txn_ctx_t const * ctx,
259-
int idx,
260-
fd_txn_account_t * acc );
258+
typedef int fd_txn_account_condition_fn_t ( fd_txn_account_t * acc,
259+
fd_exec_txn_ctx_t const * ctx,
260+
int idx );
261261

262262
/* Mirrors Agave function solana_sdk::transaction_context::get_account_at_index
263263
@@ -315,14 +315,14 @@ fd_exec_txn_ctx_account_is_writable_idx( fd_exec_txn_ctx_t const * ctx, int idx
315315
when obtaining accounts from the transaction context. Passed as a function pointer. */
316316

317317
int
318-
fd_txn_account_exists( fd_exec_txn_ctx_t const * ctx,
319-
int idx,
320-
fd_txn_account_t * acc );
318+
fd_txn_account_check_exists( fd_txn_account_t * acc,
319+
fd_exec_txn_ctx_t const * ctx,
320+
int idx );
321321

322322
int
323-
fd_txn_account_is_writable( fd_exec_txn_ctx_t const * ctx,
324-
int idx,
325-
fd_txn_account_t * acc );
323+
fd_txn_account_check_is_writable( fd_txn_account_t * acc,
324+
fd_exec_txn_ctx_t const * ctx,
325+
int idx );
326326

327327
/* The fee payer is a valid modifiable account if it is passed in as writable
328328
in the message via a valid signature. We ignore if the account has been
@@ -331,9 +331,25 @@ fd_txn_account_is_writable( fd_exec_txn_ctx_t const * ctx,
331331
doesn't have a writable signature. */
332332

333333
int
334-
fd_txn_account_fee_payer_writable( fd_exec_txn_ctx_t const * ctx,
335-
int idx,
336-
fd_txn_account_t * acc );
334+
fd_txn_account_check_fee_payer_writable( fd_txn_account_t * acc,
335+
fd_exec_txn_ctx_t const * ctx,
336+
int idx );
337+
338+
/* Checks if the account is mutable and borrows the account mutably.
339+
340+
The borrow is an acquired write on the account object.
341+
The caller is responsible for releasing the write via
342+
fd_txn_account_release_write.
343+
344+
TODO: Agave doesn't need to check if the account is mutable
345+
because it uses Writable/Readable traits for accounts. We
346+
should have a similar concept to abstract away fd_txn_account_t's
347+
const_meta and meta fields. */
348+
349+
int
350+
fd_txn_account_check_borrow_mut( fd_txn_account_t * acc,
351+
fd_exec_txn_ctx_t const * ctx,
352+
int idx );
337353

338354
FD_PROTOTYPES_END
339355

src/flamenco/runtime/fd_executor.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ fd_executor_load_transaction_accounts( fd_exec_txn_ctx_t * txn_ctx ) {
444444
/* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L429-L443 */
445445
for( ulong i=0UL; i<txn_ctx->accounts_cnt; i++ ) {
446446
fd_txn_account_t * acct = &txn_ctx->accounts[i];
447-
uchar unknown_acc = !!(fd_exec_txn_ctx_get_account_at_index( txn_ctx, (uchar)i, &acct, fd_txn_account_exists ) ||
447+
uchar unknown_acc = !!(fd_exec_txn_ctx_get_account_at_index( txn_ctx, (uchar)i, &acct, fd_txn_account_check_exists ) ||
448448
acct->const_meta->info.lamports==0UL);
449449
ulong acc_size = unknown_acc ? 0UL : acct->const_meta->dlen;
450450
uchar is_writable = !!( fd_exec_txn_ctx_account_is_writable_idx( txn_ctx, (int)i ) );
@@ -496,7 +496,7 @@ fd_executor_load_transaction_accounts( fd_exec_txn_ctx_t * txn_ctx ) {
496496
int err = fd_exec_txn_ctx_get_account_at_index( txn_ctx,
497497
instr->program_id,
498498
&program_account,
499-
fd_txn_account_exists );
499+
fd_txn_account_check_exists );
500500
if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS || program_account->const_meta->info.lamports==0UL ) ) {
501501
return FD_RUNTIME_TXN_ERR_PROGRAM_ACCOUNT_NOT_FOUND;
502502
}
@@ -793,7 +793,7 @@ fd_executor_validate_transaction_fee_payer( fd_exec_txn_ctx_t * txn_ctx ) {
793793
err = fd_exec_txn_ctx_get_account_at_index( txn_ctx,
794794
FD_FEE_PAYER_TXN_IDX,
795795
&fee_payer_rec,
796-
fd_txn_account_fee_payer_writable );
796+
fd_txn_account_check_fee_payer_writable );
797797
if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) {
798798
return FD_RUNTIME_TXN_ERR_ACCOUNT_NOT_FOUND;
799799
}
@@ -1388,11 +1388,13 @@ fd_execute_txn( fd_execute_txn_task_info_t * task_info ) {
13881388
#ifdef VLOG
13891389
FD_LOG_WARNING(( "Start of transaction for %d for %s", i, FD_BASE58_ENC_64_ALLOCA( sig ) ));
13901390
#endif
1391+
txn_ctx->current_instr_idx = i;
13911392

13921393
if ( FD_UNLIKELY( use_sysvar_instructions ) ) {
13931394
ret = fd_sysvar_instructions_update_current_instr_idx( txn_ctx, i );
13941395
if( ret != FD_ACC_MGR_SUCCESS ) {
13951396
FD_LOG_WARNING(( "sysvar instructions failed to update instruction index" ));
1397+
txn_ctx->instr_err_idx = i;
13961398
return FD_RUNTIME_TXN_ERR_INSTRUCTION_ERROR;
13971399
}
13981400
}
@@ -1402,7 +1404,6 @@ fd_execute_txn( fd_execute_txn_task_info_t * task_info ) {
14021404
fd_dump_instr_to_protobuf(txn_ctx, &txn_ctx->instr_infos[i], i);
14031405
}
14041406

1405-
txn_ctx->current_instr_idx = i;
14061407
int instr_exec_result = fd_execute_instr( txn_ctx, &txn_ctx->instr_infos[i] );
14071408
#ifdef VLOG
14081409
FD_LOG_WARNING(( "fd_execute_instr result (%d) for %s", exec_result, FD_BASE58_ENC_64_ALLOCA( sig ) ));

src/flamenco/runtime/fd_txn_account.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ fd_txn_account_is_executable( fd_txn_account_t const * acct ) {
6565
return !!acct->const_meta->info.executable;
6666
}
6767

68+
static inline int
69+
fd_txn_account_is_mutable( fd_txn_account_t const * acct ) {
70+
/* A txn account is mutable if meta is non NULL */
71+
return acct->meta != NULL;
72+
}
73+
6874
/* Setters */
6975

7076
static inline void
@@ -144,7 +150,9 @@ fd_txn_account_acquire_read_is_safe( fd_txn_account_t const * acct ) {
144150

145151
/* fd_txn_account_acquire_write acquires write/exclusive access.
146152
Causes all other write or read acquire attempts will fail. Returns 1
147-
on success, 0 on failure. */
153+
on success, 0 on failure.
154+
155+
Mirrors a try_borrow_mut() call in Agave. */
148156
static inline int
149157
fd_txn_account_acquire_write( fd_txn_account_t * acct ) {
150158
if( FD_UNLIKELY( !fd_txn_account_acquire_write_is_safe( acct ) ) ) {
@@ -164,7 +172,7 @@ fd_txn_account_release_write( fd_txn_account_t * acct ) {
164172
}
165173

166174
static inline void
167-
fd_txn_account_release_write_private(fd_txn_account_t * acct ) {
175+
fd_txn_account_release_write_private( fd_txn_account_t * acct ) {
168176
/* Only release if it is not yet released */
169177
if( !fd_txn_account_acquire_write_is_safe( acct ) ) {
170178
fd_txn_account_release_write( acct );

src/flamenco/runtime/program/fd_bpf_loader_program.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ read_bpf_upgradeable_loader_state_for_program( fd_exec_txn_ctx_t *
133133
int err = fd_exec_txn_ctx_get_account_at_index( txn_ctx,
134134
program_id,
135135
&rec,
136-
fd_txn_account_exists );
136+
fd_txn_account_check_exists );
137137
if( FD_UNLIKELY( err ) ) {
138138
*opt_err = err;
139139
return NULL;
@@ -1928,7 +1928,7 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * ctx ) {
19281928
err = fd_exec_txn_ctx_get_executable_account( ctx->txn_ctx,
19291929
programdata_pubkey,
19301930
&program_data_account,
1931-
fd_txn_account_exists );
1931+
fd_txn_account_check_exists );
19321932
if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) {
19331933
if( FD_FEATURE_ACTIVE( ctx->txn_ctx->slot, ctx->txn_ctx->features, remove_accounts_executable_flag_checks ) ) {
19341934
return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_PROGRAM_ID;

src/flamenco/runtime/sysvar/fd_sysvar_instructions.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ fd_sysvar_instructions_serialize_account( fd_exec_txn_ctx_t * txn_ctx,
4242
int err = fd_exec_txn_ctx_get_account_with_key( txn_ctx,
4343
&fd_sysvar_instructions_id,
4444
&rec,
45-
fd_txn_account_exists );
45+
fd_txn_account_check_exists );
4646
if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS && rec==NULL ) ) {
4747
/* The way we use this, this should NEVER hit since the borrowed accounts should be set up
4848
before this is called, and this is only called if the sysvar instructions account is in
@@ -139,7 +139,7 @@ fd_sysvar_instructions_update_current_instr_idx( fd_exec_txn_ctx_t * txn_ctx,
139139
int err = fd_exec_txn_ctx_get_account_with_key( txn_ctx,
140140
&fd_sysvar_instructions_id,
141141
&rec,
142-
NULL );
142+
fd_txn_account_check_borrow_mut );
143143
if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) {
144144
/* https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/message_processor.rs#L40 */
145145
return FD_RUNTIME_TXN_ERR_INVALID_ACCOUNT_INDEX;
@@ -150,5 +150,7 @@ fd_sysvar_instructions_update_current_instr_idx( fd_exec_txn_ctx_t * txn_ctx,
150150
uchar * serialized_current_instr_idx = rec->data + (rec->meta->dlen - sizeof(ushort));
151151
FD_STORE( ushort, serialized_current_instr_idx, current_instr_idx );
152152

153+
fd_txn_account_release_write( rec );
154+
153155
return FD_EXECUTOR_INSTR_SUCCESS;
154156
}

src/flamenco/runtime/tests/fd_exec_instr_test.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,7 +2293,7 @@ __wrap_fd_execute_instr( fd_exec_txn_ctx_t * txn_ctx,
22932293
if( fd_exec_txn_ctx_get_account_at_index( txn_ctx,
22942294
idx_in_txn,
22952295
&acct,
2296-
fd_txn_account_exists ) ) {
2296+
fd_txn_account_check_exists ) ) {
22972297
break;
22982298
}
22992299
if( acct->meta == NULL ){
@@ -2305,7 +2305,7 @@ __wrap_fd_execute_instr( fd_exec_txn_ctx_t * txn_ctx,
23052305
idx_in_txn,
23062306
/* Do not reallocate if data is not going to be modified */
23072307
&acct,
2308-
fd_txn_account_is_writable );
2308+
fd_txn_account_check_is_writable );
23092309
if( err ) break;
23102310

23112311
/* resize manually

0 commit comments

Comments
 (0)