Skip to content

Commit a114adf

Browse files
clean up and polishing
1 parent c8b03c6 commit a114adf

10 files changed

+137
-91
lines changed

src/flamenco/runtime/context/fd_exec_instr_ctx.c

+24-17
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@ fd_exec_instr_ctx_delete( void * mem ) {
8181
return mem;
8282
}
8383

84+
int
85+
fd_exec_instr_ctx_find_idx_of_instr_account( fd_exec_instr_ctx_t const * ctx,
86+
fd_pubkey_t const * pubkey ) {
87+
for( int i = 0; i < ctx->instr->acct_cnt; i++ ) {
88+
if( memcmp( pubkey->uc, ctx->instr->acct_pubkeys[i].uc, sizeof(fd_pubkey_t) )==0 ) {
89+
return i;
90+
}
91+
}
92+
return -1;
93+
}
94+
8495
int
8596
fd_exec_instr_ctx_try_borrow_account( fd_exec_instr_ctx_t const * ctx,
8697
ulong idx,
@@ -105,8 +116,8 @@ fd_exec_instr_ctx_try_borrow_account( fd_exec_instr_ctx_t const * ctx,
105116

106117
int
107118
fd_exec_instr_ctx_try_borrow_instr_account( fd_exec_instr_ctx_t const * ctx,
108-
ulong idx,
109-
fd_borrowed_account_t * account ) {
119+
ulong idx,
120+
fd_borrowed_account_t * account ) {
110121
/* Return a NotEnoughAccountKeys error if the idx is out of bounds.
111122
https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L603 */
112123
if( FD_UNLIKELY( idx >= ctx->instr->acct_cnt ) ) {
@@ -115,30 +126,26 @@ fd_exec_instr_ctx_try_borrow_instr_account( fd_exec_instr_ctx_t const * ctx,
115126

116127
fd_txn_account_t * instr_account = ctx->instr->accounts[idx];
117128

118-
return fd_exec_instr_ctx_try_borrow_account( ctx, idx, instr_account, account );
129+
return fd_exec_instr_ctx_try_borrow_account( ctx,
130+
idx,
131+
instr_account,
132+
account );
119133
}
120134

121135
int
122136
fd_exec_instr_ctx_try_borrow_instr_account_with_key( fd_exec_instr_ctx_t * ctx,
123-
fd_pubkey_t const * pubkey,
124-
fd_borrowed_account_t * account ) {
137+
fd_pubkey_t const * pubkey,
138+
fd_borrowed_account_t * account ) {
125139
for( ulong i = 0; i < ctx->instr->acct_cnt; i++ ) {
126140
if( memcmp( pubkey->uc, ctx->instr->acct_pubkeys[i].uc, sizeof(fd_pubkey_t) )==0 ) {
127141
return fd_exec_instr_ctx_try_borrow_instr_account( ctx, i, account );
128142
}
129143
}
130-
return FD_EXECUTOR_INSTR_ERR_MISSING_ACC;
131-
}
132144

133-
int
134-
fd_exec_instr_ctx_find_idx_of_instr_account( fd_exec_instr_ctx_t const * ctx,
135-
fd_pubkey_t const * pubkey ) {
136-
for( int i = 0; i < ctx->instr->acct_cnt; i++ ) {
137-
if( memcmp( pubkey->uc, ctx->instr->acct_pubkeys[i].uc, sizeof(fd_pubkey_t) )==0 ) {
138-
return i;
139-
}
140-
}
141-
return -1;
145+
/* Return a NotEnoughAccountKeys error if the account is not found
146+
in the instruction context to match the error code returned by
147+
fd_exec_instr_ctx_try_borrow_instr_account. */
148+
return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
142149
}
143150

144151
int
@@ -147,7 +154,7 @@ fd_exec_instr_ctx_try_borrow_last_program_account( fd_exec_instr_ctx_t const * c
147154
fd_txn_account_t * program_account = NULL;
148155
fd_exec_txn_ctx_get_account_at_index( ctx->txn_ctx,
149156
ctx->instr->program_id,
150-
&program_account,
157+
&program_account,
151158
NULL );
152159

153160
return fd_exec_instr_ctx_try_borrow_account( ctx,

src/flamenco/runtime/context/fd_exec_instr_ctx.h

+14-14
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ struct __attribute__((aligned(8UL))) fd_exec_instr_ctx {
4040

4141
/* Be careful when using this macro. There may be places where the error
4242
will need to be handled differently. */
43-
#define FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, idx, acc ) do { \
44-
int err = fd_exec_instr_ctx_try_borrow_instr_account( ctx, idx, acc ); \
45-
if( FD_UNLIKELY( err ) ) return err; \
43+
#define FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, idx, acc ) do { \
44+
int err = fd_exec_instr_ctx_try_borrow_instr_account( ctx, idx, acc ); \
45+
if( FD_UNLIKELY( err ) ) return err; \
4646
} while (0)
4747

4848
FD_PROTOTYPES_BEGIN
@@ -80,6 +80,17 @@ fd_exec_instr_ctx_check_num_insn_accounts( fd_exec_instr_ctx_t * ctx,
8080
return FD_EXECUTOR_INSTR_SUCCESS;
8181
}
8282

83+
/* Mirrors Agave function solana_sdk::transaction_context::InstructionContext::find_index_of_instruction_account.
84+
85+
Returns the index of the the instruction account given the account pubkey
86+
or -1 if the account is not found.
87+
88+
https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L524-L538 */
89+
90+
int
91+
fd_exec_instr_ctx_find_idx_of_instr_account( fd_exec_instr_ctx_t const * ctx,
92+
fd_pubkey_t const * pubkey );
93+
8394
/* Mirrors Agave function solana_sdk::transaction_context::InstructionContext::try_borrow_account.
8495
8596
Borrows an account from the instruction context with a given account index.
@@ -100,17 +111,6 @@ fd_exec_instr_ctx_try_borrow_instr_account_with_key( fd_exec_instr_ctx_t * ctx
100111
fd_pubkey_t const * pubkey,
101112
fd_borrowed_account_t * account );
102113

103-
/* Mirrors Agave function solana_sdk::transaction_context::InstructionContext::find_index_of_instruction_account.
104-
105-
Returns the index of the the instruction account given the account pubkey
106-
or -1 if the account is not found.
107-
108-
https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L524-L538 */
109-
110-
int
111-
fd_exec_instr_ctx_find_idx_of_instr_account( fd_exec_instr_ctx_t const * ctx,
112-
fd_pubkey_t const * pubkey );
113-
114114
/* Mirrors Agave function solana_sdk::transaction_context::InstructionContext::try_borrow_last_program_account
115115
116116
Borrows the instruction's program account. Since there is only one program account per

src/flamenco/runtime/context/fd_exec_txn_ctx.c

+29-2
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ fd_exec_txn_ctx_get_account_at_index( fd_exec_txn_ctx_t * ctx,
9898
*account = txn_account;
9999

100100
if( condition != NULL ) {
101-
if( FD_UNLIKELY( !condition( ctx, idx, *account ) ) )
101+
if( FD_UNLIKELY( !condition( ctx, idx, *account ) ) )
102102
return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT;
103103
}
104104

@@ -146,7 +146,7 @@ fd_exec_txn_ctx_get_executable_account( fd_exec_txn_ctx_t * ctx,
146146
*account = txn_account;
147147

148148
if( condition != NULL ) {
149-
if( FD_UNLIKELY( !condition( ctx, (int)i, *account ) ) )
149+
if( FD_UNLIKELY( !condition( ctx, (int)i, *account ) ) )
150150
return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT;
151151
}
152152

@@ -310,3 +310,30 @@ fd_exec_txn_ctx_account_is_writable_idx( fd_exec_txn_ctx_t const * txn_ctx, int
310310

311311
return 1;
312312
}
313+
314+
/* Account pre-condition filtering functions */
315+
316+
int
317+
fd_txn_account_exists( fd_exec_txn_ctx_t * ctx,
318+
int idx,
319+
fd_txn_account_t * acc ) {
320+
(void) ctx;
321+
(void) idx;
322+
return fd_acc_exists( acc->const_meta );
323+
}
324+
325+
int
326+
fd_txn_account_is_writable( fd_exec_txn_ctx_t * ctx,
327+
int idx,
328+
fd_txn_account_t * acc ) {
329+
(void) acc;
330+
return fd_exec_txn_ctx_account_is_writable_idx( ctx, idx );
331+
}
332+
333+
int
334+
fd_txn_account_fee_payer_writable( fd_exec_txn_ctx_t * ctx,
335+
int idx,
336+
fd_txn_account_t * acc ) {
337+
(void) acc;
338+
return fd_txn_is_writable( ctx->txn_descriptor, idx );
339+
}

src/flamenco/runtime/context/fd_exec_txn_ctx.h

+25-20
Original file line numberDiff line numberDiff line change
@@ -248,15 +248,19 @@ fd_exec_txn_ctx_find_index_of_account( fd_exec_txn_ctx_t * ctx,
248248

249249
/* Mirrors Agave function solana_sdk::transaction_context::get_account_at_index
250250
251+
Takes a function pointer to a condition function to check pre-conditions on the
252+
obtained account. If the condition function is NULL, the account is returned without
253+
any pre-condition checks.
254+
251255
https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L223-L230 */
252256

253257
int
254258
fd_exec_txn_ctx_get_account_at_index( fd_exec_txn_ctx_t * ctx,
255259
uchar idx,
256260
fd_txn_account_t * * account,
257-
int (*condition)( fd_exec_txn_ctx_t * ctx,
258-
int idx,
259-
fd_txn_account_t * acc) );
261+
int (*condition) ( fd_exec_txn_ctx_t * ctx,
262+
int idx,
263+
fd_txn_account_t * acc) );
260264

261265
int
262266
fd_exec_txn_ctx_get_account_with_key( fd_exec_txn_ctx_t * ctx,
@@ -289,34 +293,35 @@ fd_exec_txn_ctx_reset_return_data( fd_exec_txn_ctx_t * txn_ctx );
289293
2. If the account is the program id AND the upgradeable loader account is in
290294
the set of transaction accounts. */
291295
/* https://github.com/anza-xyz/agave/blob/v2.1.1/sdk/program/src/message/versions/v0/loaded.rs#L137-L150 */
296+
292297
int
293298
fd_exec_txn_ctx_account_is_writable_idx( fd_exec_txn_ctx_t const * txn_ctx, int idx );
294299

295-
/* Conditional filter functions */
296-
static inline int
300+
/* Account pre-condition filtering functions
301+
302+
Used to filter accounts based on pre-conditions such as existence, is_writable, etc.
303+
when obtaining accounts from the transaction context. Passed as a function pointer. */
304+
305+
int
297306
fd_txn_account_exists( fd_exec_txn_ctx_t * ctx,
298307
int idx,
299-
fd_txn_account_t * acc ) {
300-
(void) ctx;
301-
(void) idx;
302-
return fd_acc_exists( acc->const_meta );
303-
}
308+
fd_txn_account_t * acc );
304309

305-
static inline int
310+
int
306311
fd_txn_account_is_writable( fd_exec_txn_ctx_t * ctx,
307312
int idx,
308-
fd_txn_account_t * acc ) {
309-
(void) acc;
310-
return fd_exec_txn_ctx_account_is_writable_idx( ctx, idx );
311-
}
313+
fd_txn_account_t * acc );
312314

313-
static inline int
315+
/* The fee payer is a valid modifiable account if it is passed in as writable
316+
in the message via a valid signature. We ignore if the account has been
317+
demoted or not (see fd_exec_txn_ctx_account_is_writable_idx) for more details.
318+
Agave and Firedancer will reject the fee payer if the transaction message
319+
doesn't have a writable signature. */
320+
321+
int
314322
fd_txn_account_fee_payer_writable( fd_exec_txn_ctx_t * ctx,
315323
int idx,
316-
fd_txn_account_t * acc ) {
317-
(void) acc;
318-
return fd_txn_is_writable( ctx->txn_descriptor, idx );
319-
}
324+
fd_txn_account_t * acc );
320325

321326
FD_PROTOTYPES_END
322327

src/flamenco/runtime/fd_executor.c

+10-9
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_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 ) );
@@ -493,7 +493,10 @@ fd_executor_load_transaction_accounts( fd_exec_txn_ctx_t * txn_ctx ) {
493493
/* Mimicking `load_account()` here with 0-lamport check as well.
494494
https://github.com/anza-xyz/agave/blob/v2.2.0/svm/src/account_loader.rs#L455-L462 */
495495
fd_txn_account_t * program_account = NULL;
496-
int err = fd_exec_txn_ctx_get_account_at_index( txn_ctx, instr->program_id, &program_account, &fd_txn_account_exists );
496+
int err = fd_exec_txn_ctx_get_account_at_index( txn_ctx,
497+
instr->program_id,
498+
&program_account,
499+
&fd_txn_account_exists );
497500
if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS || program_account->const_meta->info.lamports==0UL ) ) {
498501
return FD_RUNTIME_TXN_ERR_PROGRAM_ACCOUNT_NOT_FOUND;
499502
}
@@ -785,14 +788,12 @@ fd_executor_validate_transaction_fee_payer( fd_exec_txn_ctx_t * txn_ctx ) {
785788
return err;
786789
}
787790

788-
/* The fee payer is a valid modifiable account if it is passed in as writable
789-
in the message via a valid signature. We ignore if the account has been
790-
demoted or not (see fd_txn_account_is_writable_idx) for more details.
791-
Agave and Firedancer will reject the fee payer if the transaction message
792-
doesn't have a writable signature.
793-
https://github.com/anza-xyz/agave/blob/16de8b75ebcd57022409b422de557dd37b1de8db/svm/src/transaction_processor.rs#L431-L436 */
791+
/* https://github.com/anza-xyz/agave/blob/16de8b75ebcd57022409b422de557dd37b1de8db/svm/src/transaction_processor.rs#L431-L436 */
794792
fd_txn_account_t * fee_payer_rec = NULL;
795-
err = fd_exec_txn_ctx_get_account_at_index( txn_ctx, FD_FEE_PAYER_TXN_IDX, &fee_payer_rec, &fd_txn_account_fee_payer_writable );
793+
err = fd_exec_txn_ctx_get_account_at_index( txn_ctx,
794+
FD_FEE_PAYER_TXN_IDX,
795+
&fee_payer_rec,
796+
fd_txn_account_fee_payer_writable );
796797
if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) {
797798
return FD_RUNTIME_TXN_ERR_ACCOUNT_NOT_FOUND;
798799
}

src/flamenco/runtime/fd_system_ids.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ extern const fd_pubkey_t fd_solana_stake_program_buffer_address;
6060
not be writable.
6161
6262
Whenever Agave changes the reserved account keys set, new feature-gated checks will need to be implemented in
63-
`fd_txn_account_is_writable_idx()`, and additional functions will need to be added here.
63+
`fd_exec_txn_ctx_account_is_writable_idx()`, and additional functions will need to be added here.
6464
6565
Instead of maintaining a map of sysvars and builtins, Agave recommends checking the sysvar owner account, or checking
6666
the reserved keys below.

src/flamenco/runtime/program/fd_bpf_loader_program.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,10 @@ read_bpf_upgradeable_loader_state_for_program( fd_exec_txn_ctx_t *
130130
uchar program_id,
131131
int * opt_err ) {
132132
fd_txn_account_t * rec = NULL;
133-
int err = fd_exec_txn_ctx_get_account_at_index( txn_ctx, program_id, &rec, &fd_txn_account_exists );
133+
int err = fd_exec_txn_ctx_get_account_at_index( txn_ctx,
134+
program_id,
135+
&rec,
136+
fd_txn_account_exists );
134137
if( FD_UNLIKELY( err ) ) {
135138
*opt_err = err;
136139
return NULL;
@@ -1897,7 +1900,6 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * ctx ) {
18971900
18981901
Every error that comes out of this block is mapped to an InvalidAccountData instruction error in Agave. */
18991902

1900-
/* use try_borrow_last_program_account */
19011903
fd_account_meta_t const * metadata = program_account.acct->const_meta;
19021904
uchar is_deprecated = !memcmp( metadata->info.owner, &fd_solana_bpf_loader_deprecated_program_id, sizeof(fd_pubkey_t) );
19031905

@@ -1923,7 +1925,10 @@ fd_bpf_loader_program_execute( fd_exec_instr_ctx_t * ctx ) {
19231925

19241926
fd_txn_account_t * program_data_account = NULL;
19251927
fd_pubkey_t * programdata_pubkey = (fd_pubkey_t *)&program_account_state->inner.program.programdata_address;
1926-
err = fd_exec_txn_ctx_get_executable_account( ctx->txn_ctx, programdata_pubkey, &program_data_account, &fd_txn_account_exists );
1928+
err = fd_exec_txn_ctx_get_executable_account( ctx->txn_ctx,
1929+
programdata_pubkey,
1930+
&program_data_account,
1931+
fd_txn_account_exists );
19271932
if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) {
19281933
return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
19291934
}

src/flamenco/runtime/program/fd_loader_v4_program.c

+4-7
Original file line numberDiff line numberDiff line change
@@ -774,17 +774,14 @@ fd_loader_v4_program_execute( fd_exec_instr_ctx_t * instr_ctx ) {
774774
}
775775
}
776776
} else {
777-
/* try borrow last program account */
778777
/* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/loader-v4/src/lib.rs#L489 */
779-
fd_txn_account_t * program = NULL;
780-
rc = fd_exec_txn_ctx_get_account_at_index( instr_ctx->txn_ctx, instr_ctx->instr->program_id, &program, &fd_txn_account_exists );
781-
if( FD_UNLIKELY( rc ) ) {
782-
return rc;
783-
}
778+
fd_guarded_borrowed_account_t program;
779+
rc = fd_exec_instr_ctx_try_borrow_last_program_account( instr_ctx, &program );
780+
if( FD_UNLIKELY( rc ) ) return rc;
784781

785782
/* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/loader-v4/src/lib.rs#L490 */
786783
fd_loader_v4_state_t state = {0};
787-
rc = fd_loader_v4_get_state( program, &state );
784+
rc = fd_loader_v4_get_state( program.acct, &state );
788785
if( FD_UNLIKELY( rc ) ) {
789786
return rc;
790787
}

src/flamenco/runtime/sysvar/fd_sysvar_instructions.c

+10-10
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ fd_sysvar_instructions_serialize_account( fd_exec_txn_ctx_t * txn_ctx,
3939
ulong serialized_sz = instructions_serialized_size( instrs, instrs_cnt );
4040

4141
fd_txn_account_t * rec = NULL;
42-
int err = fd_exec_txn_ctx_get_account_with_key( txn_ctx, &fd_sysvar_instructions_id, &rec, &fd_txn_account_exists );
42+
int err = fd_exec_txn_ctx_get_account_with_key( txn_ctx,
43+
&fd_sysvar_instructions_id,
44+
&rec,
45+
fd_txn_account_exists );
4346
if( FD_UNLIKELY( err != FD_ACC_MGR_SUCCESS && rec == NULL ) ) {
4447
/* The way we use this, this should NEVER hit since the borrowed accounts should be set up
4548
before this is called, and this is only called if the sysvar instructions account is in
@@ -131,15 +134,12 @@ fd_sysvar_instructions_update_current_instr_idx( fd_exec_txn_ctx_t * txn_ctx,
131134
ushort current_instr_idx ) {
132135
fd_txn_account_t * rec = NULL;
133136

134-
/* Find the index of the sysvar account.
135-
https://github.com/anza-xyz/agave/blob/v2.1.14/svm/src/message_processor.rs#L49-L51 */
136-
int index = fd_exec_txn_ctx_find_index_of_account( txn_ctx, &fd_sysvar_instructions_id );
137-
if( FD_UNLIKELY( index==-1 ) ) {
138-
return FD_ACC_MGR_ERR_READ_FAILED;
139-
}
140-
141-
/* https://github.com/anza-xyz/agave/blob/v2.1.14/svm/src/message_processor.rs#L53-L55 */
142-
int err = fd_exec_txn_ctx_get_account_at_index( txn_ctx, (uchar)index, &rec, NULL );
137+
/* Obtain the sysvar instruction account
138+
https://github.com/anza-xyz/agave/blob/v2.1.14/svm/src/message_processor.rs#L53-L55 */
139+
int err = fd_exec_txn_ctx_get_account_with_key( txn_ctx,
140+
&fd_sysvar_instructions_id,
141+
&rec,
142+
NULL );
143143
if( FD_UNLIKELY( err != FD_ACC_MGR_SUCCESS ) ) {
144144
return FD_ACC_MGR_ERR_READ_FAILED;
145145
}

0 commit comments

Comments
 (0)