Skip to content

Commit fd24d11

Browse files
flamenco: refactor txn_ctx/instr_ctx account getters API
1 parent 898a6aa commit fd24d11

21 files changed

+449
-328
lines changed

src/flamenco/runtime/context/fd_exec_instr_ctx.c

+55-23
Original file line numberDiff line numberDiff line change
@@ -81,54 +81,86 @@ 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,
98+
fd_txn_account_t * txn_account,
8799
fd_borrowed_account_t * account ) {
88100
/* TODO this is slightly wrong. Agave returns NotEnoughAccountKeys when the account index is
89101
out of bounds in the transaction context and MissingAccount when the account index is out of
90102
bounds in the instruction context. */
91103

92-
/* Return a NotEnoughAccountKeys error if the idx is out of bounds.
93-
https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L603 */
94-
if( FD_UNLIKELY( idx >= ctx->instr->acct_cnt ) ) {
95-
return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
96-
}
97-
98-
fd_txn_account_t * instr_account = ctx->instr->accounts[idx];
99-
100104
/* Return an AccountBorrowFailed error if the write is not acquirable.
101105
https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L605 */
102-
int acquire_result = fd_txn_account_acquire_write( instr_account );
106+
int acquire_result = fd_txn_account_acquire_write( txn_account );
103107
if( FD_UNLIKELY( !acquire_result ) ) {
104108
return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_FAILED;
105109
}
106110

107111
/* Create a BorrowedAccount upon success.
108112
https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L606 */
109-
fd_borrowed_account_init( account, instr_account, ctx, (int)idx );
113+
fd_borrowed_account_init( account, txn_account, ctx, (ushort)idx );
110114
return FD_EXECUTOR_INSTR_SUCCESS;
111115
}
112116

113117
int
114-
fd_exec_instr_ctx_try_borrow_account_with_key( fd_exec_instr_ctx_t * ctx,
115-
fd_pubkey_t const * pubkey,
116-
fd_borrowed_account_t * account ) {
117-
for( ulong i = 0; i < ctx->instr->acct_cnt; i++ ) {
118-
if( memcmp( pubkey->uc, ctx->instr->acct_pubkeys[i].uc, sizeof(fd_pubkey_t) )==0 ) {
119-
return fd_exec_instr_ctx_try_borrow_account( ctx, i, account );
120-
}
118+
fd_exec_instr_ctx_try_borrow_instr_account( fd_exec_instr_ctx_t const * ctx,
119+
ulong idx,
120+
fd_borrowed_account_t * account ) {
121+
/* Return a NotEnoughAccountKeys error if the idx is out of bounds.
122+
https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L603 */
123+
if( FD_UNLIKELY( idx>=ctx->instr->acct_cnt ) ) {
124+
return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
121125
}
122-
return FD_EXECUTOR_INSTR_ERR_MISSING_ACC;
126+
127+
fd_txn_account_t * instr_account = ctx->instr->accounts[idx];
128+
129+
return fd_exec_instr_ctx_try_borrow_account( ctx,
130+
idx,
131+
instr_account,
132+
account );
123133
}
124134

125135
int
126-
fd_exec_instr_ctx_find_idx_of_instr_account( fd_exec_instr_ctx_t const * ctx,
127-
fd_pubkey_t const * pubkey ) {
128-
for( int i = 0; i < ctx->instr->acct_cnt; i++ ) {
136+
fd_exec_instr_ctx_try_borrow_instr_account_with_key( fd_exec_instr_ctx_t const * ctx,
137+
fd_pubkey_t const * pubkey,
138+
fd_borrowed_account_t * account ) {
139+
for( ulong i=0; i<ctx->instr->acct_cnt; i++ ) {
129140
if( memcmp( pubkey->uc, ctx->instr->acct_pubkeys[i].uc, sizeof(fd_pubkey_t) )==0 ) {
130-
return i;
141+
return fd_exec_instr_ctx_try_borrow_instr_account( ctx, i, account );
131142
}
132143
}
133-
return -1;
144+
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;
149+
}
150+
151+
int
152+
fd_exec_instr_ctx_try_borrow_last_program_account( fd_exec_instr_ctx_t const * ctx,
153+
fd_borrowed_account_t * account ) {
154+
fd_txn_account_t * program_account = NULL;
155+
fd_exec_txn_ctx_get_account_at_index( ctx->txn_ctx,
156+
ctx->instr->program_id,
157+
&program_account,
158+
NULL );
159+
160+
/* The index_in_instruction for a borrowed program account is invalid,
161+
so it is set to a sentinel value of USHORT_MAX. */
162+
return fd_exec_instr_ctx_try_borrow_account( ctx,
163+
USHORT_MAX,
164+
program_account,
165+
account );
134166
}

src/flamenco/runtime/context/fd_exec_instr_ctx.h

+38-15
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ struct __attribute__((aligned(8UL))) fd_exec_instr_ctx {
4141
/* Be careful when using this macro. There may be places where the error
4242
will need to be handled differently. */
4343
#define FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, idx, acc ) do { \
44-
int err = fd_exec_instr_ctx_try_borrow_account( ctx, idx, acc ); \
44+
int err = fd_exec_instr_ctx_try_borrow_instr_account( ctx, idx, acc ); \
4545
if( FD_UNLIKELY( err ) ) return err; \
4646
} while (0)
4747

@@ -71,45 +71,68 @@ fd_exec_instr_ctx_delete( void * mem );
7171
7272
https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L490 */
7373
static inline int
74-
fd_exec_instr_ctx_check_num_insn_accounts( fd_exec_instr_ctx_t * ctx,
75-
uint expected_accounts ) {
74+
fd_exec_instr_ctx_check_num_insn_accounts( fd_exec_instr_ctx_t const * ctx,
75+
uint expected_accounts ) {
7676

7777
if( FD_UNLIKELY( ctx->instr->acct_cnt<expected_accounts ) ) {
7878
return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
7979
}
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+
94+
/* Mirrors Agave function solana_sdk::transaction_context::InstructionContext::get_number_of_program_accounts.
95+
96+
Strictly returns 1, as we only support one program account per instruction.
97+
98+
https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L480-L482 */
99+
100+
static inline ushort
101+
fd_exec_instr_ctx_get_number_of_program_accounts( fd_exec_instr_ctx_t const * ctx ) {
102+
(void) ctx;
103+
return 1U;
104+
}
105+
83106
/* Mirrors Agave function solana_sdk::transaction_context::InstructionContext::try_borrow_account.
84107
85108
Borrows an account from the instruction context with a given account index.
86109
87110
https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L594 */
88111

89112
int
90-
fd_exec_instr_ctx_try_borrow_account( fd_exec_instr_ctx_t const * ctx,
91-
ulong idx,
92-
fd_borrowed_account_t * account );
113+
fd_exec_instr_ctx_try_borrow_instr_account( fd_exec_instr_ctx_t const * ctx,
114+
ulong idx,
115+
fd_borrowed_account_t * account );
93116

94117
/* A wrapper around fd_exec_instr_ctx_try_borrow_account that accepts an account pubkey.
95118
96119
Borrows an account from the instruction context with a given pubkey. */
97120

98121
int
99-
fd_exec_instr_ctx_try_borrow_account_with_key( fd_exec_instr_ctx_t * ctx,
100-
fd_pubkey_t const * pubkey,
101-
fd_borrowed_account_t * account );
122+
fd_exec_instr_ctx_try_borrow_instr_account_with_key( fd_exec_instr_ctx_t const * ctx,
123+
fd_pubkey_t const * pubkey,
124+
fd_borrowed_account_t * account );
102125

103-
/* Mirrors Agave function solana_sdk::transaction_context::InstructionContext::find_index_of_instruction_account.
126+
/* Mirrors Agave function solana_sdk::transaction_context::InstructionContext::try_borrow_last_program_account
104127
105-
Returns the index of the the instruction account given the account pubkey
106-
or -1 if the account is not found.
128+
Borrows the instruction's program account. Since there is only one program account per
129+
instruction, this function simply borrows the instruction's only program account, despite the name.
107130
108-
https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L524-L538 */
131+
https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L616 */
109132

110133
int
111-
fd_exec_instr_ctx_find_idx_of_instr_account( fd_exec_instr_ctx_t const * ctx,
112-
fd_pubkey_t const * pubkey );
134+
fd_exec_instr_ctx_try_borrow_last_program_account( fd_exec_instr_ctx_t const * ctx,
135+
fd_borrowed_account_t * account );
113136

114137
FD_PROTOTYPES_END
115138

0 commit comments

Comments
 (0)