@@ -84,121 +84,66 @@ fd_exec_txn_ctx_delete( void * mem ) {
84
84
}
85
85
86
86
int
87
- fd_exec_txn_ctx_get_account_view_idx ( fd_exec_txn_ctx_t * ctx ,
88
- uchar idx ,
89
- fd_txn_account_t * * account ) {
87
+ fd_exec_txn_ctx_get_account_at_index ( fd_exec_txn_ctx_t * ctx ,
88
+ uchar idx ,
89
+ fd_txn_account_t * * account ,
90
+ fd_txn_account_condition_fn_t * condition ) {
90
91
if ( FD_UNLIKELY ( idx >=ctx -> accounts_cnt ) ) {
91
92
return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
92
93
}
93
94
94
95
fd_txn_account_t * txn_account = & ctx -> accounts [idx ];
95
96
* account = txn_account ;
96
97
97
- if ( FD_UNLIKELY ( !fd_acc_exists ( txn_account -> const_meta ) ) ) {
98
- return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
98
+ if ( condition != NULL ) {
99
+ if ( FD_UNLIKELY ( !condition ( ctx , idx , * account ) ) )
100
+ return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
99
101
}
100
102
101
103
return FD_ACC_MGR_SUCCESS ;
102
104
}
103
105
104
106
int
105
- fd_exec_txn_ctx_get_account_view ( fd_exec_txn_ctx_t * ctx ,
106
- fd_pubkey_t const * pubkey ,
107
- fd_txn_account_t * * account ) {
108
- for ( ulong i = 0 ; i < ctx -> accounts_cnt ; i ++ ) {
109
- if ( memcmp ( pubkey -> uc , ctx -> account_keys [i ].uc , sizeof (fd_pubkey_t ) )== 0 ) {
110
- // TODO: check if readable???
111
- fd_txn_account_t * txn_account = & ctx -> accounts [i ];
112
- * account = txn_account ;
113
-
114
- if ( FD_UNLIKELY ( !fd_acc_exists ( txn_account -> const_meta ) ) ) {
115
- return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
116
- }
117
-
118
- return FD_ACC_MGR_SUCCESS ;
119
- }
107
+ fd_exec_txn_ctx_get_account_with_key ( fd_exec_txn_ctx_t * ctx ,
108
+ fd_pubkey_t const * pubkey ,
109
+ fd_txn_account_t * * account ,
110
+ fd_txn_account_condition_fn_t * condition ) {
111
+ int index = fd_exec_txn_ctx_find_index_of_account ( ctx , pubkey );
112
+ if ( FD_UNLIKELY ( index == -1 ) ) {
113
+ return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
120
114
}
121
115
122
- return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
116
+ return fd_exec_txn_ctx_get_account_at_index ( ctx ,
117
+ (uchar )index ,
118
+ account ,
119
+ condition );
123
120
}
124
121
125
122
int
126
- fd_exec_txn_ctx_get_account_executable_view ( fd_exec_txn_ctx_t * ctx ,
127
- fd_pubkey_t const * pubkey ,
128
- fd_txn_account_t * * account ) {
123
+ fd_exec_txn_ctx_get_executable_account ( fd_exec_txn_ctx_t * ctx ,
124
+ fd_pubkey_t const * pubkey ,
125
+ fd_txn_account_t * * account ,
126
+ fd_txn_account_condition_fn_t * condition ) {
129
127
/* First try to fetch the executable account from the existing borrowed accounts.
130
128
If the pubkey is in the account keys, then we want to re-use that
131
129
borrowed account since it reflects changes from prior instructions. Referencing the
132
130
read-only executable accounts list is incorrect behavior when the program
133
131
data account is written to in a prior instruction (e.g. program upgrade + invoke within the same txn) */
134
- int err = fd_exec_txn_ctx_get_account_view ( ctx , pubkey , account );
132
+ int err = fd_exec_txn_ctx_get_account_with_key ( ctx , pubkey , account , condition );
135
133
if ( FD_UNLIKELY ( err == FD_ACC_MGR_SUCCESS ) ) {
136
134
return FD_ACC_MGR_SUCCESS ;
137
135
}
138
136
139
137
for ( ulong i = 0 ; i < ctx -> executable_cnt ; i ++ ) {
140
138
if ( memcmp ( pubkey -> uc , ctx -> executable_accounts [i ].pubkey -> uc , sizeof (fd_pubkey_t ) )== 0 ) {
141
- // TODO: check if readable???
142
139
fd_txn_account_t * txn_account = & ctx -> executable_accounts [i ];
143
140
* account = txn_account ;
144
141
145
- if ( FD_UNLIKELY ( !fd_acc_exists ( txn_account -> const_meta ) ) )
146
- return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
147
-
148
- return FD_ACC_MGR_SUCCESS ;
149
- }
150
- }
151
-
152
- return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
153
- }
154
-
155
- int
156
- fd_exec_txn_ctx_get_account_modify_fee_payer ( fd_exec_txn_ctx_t * ctx ,
157
- fd_txn_account_t * * account ) {
158
-
159
- * account = & ctx -> accounts [ FD_FEE_PAYER_TXN_IDX ];
160
-
161
- if ( FD_UNLIKELY ( !fd_txn_is_writable ( ctx -> txn_descriptor , FD_FEE_PAYER_TXN_IDX ) ) ) {
162
- return FD_ACC_MGR_ERR_WRITE_FAILED ;
163
- }
164
- return FD_ACC_MGR_SUCCESS ;
165
- }
166
-
167
- int
168
- fd_exec_txn_ctx_get_account_modify_idx ( fd_exec_txn_ctx_t * ctx ,
169
- uchar idx ,
170
- ulong min_data_sz ,
171
- fd_txn_account_t * * account ) {
172
- if ( idx >= ctx -> accounts_cnt ) {
173
- return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
174
- }
175
-
176
- fd_txn_account_t * txn_account = & ctx -> accounts [idx ];
177
- if ( FD_UNLIKELY ( !fd_txn_account_is_writable_idx ( ctx , (int )idx ) ) ) {
178
- return FD_ACC_MGR_ERR_WRITE_FAILED ;
179
- }
180
-
181
- if ( min_data_sz > txn_account -> const_meta -> dlen ) {
182
- fd_txn_account_resize ( txn_account , min_data_sz );
183
- }
184
-
185
- * account = txn_account ;
186
- return FD_ACC_MGR_SUCCESS ;
187
- }
188
-
189
- int
190
- fd_exec_txn_ctx_get_account_modify ( fd_exec_txn_ctx_t * ctx ,
191
- fd_pubkey_t const * pubkey ,
192
- ulong min_data_sz ,
193
- fd_txn_account_t * * account ) {
194
- for ( ulong i = 0 ; i < ctx -> accounts_cnt ; i ++ ) {
195
- if ( memcmp ( pubkey -> uc , ctx -> account_keys [i ].uc , sizeof (fd_pubkey_t ) )== 0 ) {
196
- // TODO: check if writable???
197
- fd_txn_account_t * txn_account = & ctx -> accounts [i ];
198
- if ( min_data_sz > txn_account -> const_meta -> dlen ) {
199
- fd_txn_account_resize ( txn_account , min_data_sz );
142
+ if ( condition != NULL ) {
143
+ if ( FD_UNLIKELY ( !condition ( ctx , (int )i , * account ) ) )
144
+ return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
200
145
}
201
- * account = txn_account ;
146
+
202
147
return FD_ACC_MGR_SUCCESS ;
203
148
}
204
149
}
@@ -336,7 +281,7 @@ fd_txn_account_is_demotion( fd_exec_txn_ctx_t const * txn_ctx, int idx )
336
281
337
282
https://github.com/anza-xyz/agave/blob/v2.1.11/sdk/program/src/message/sanitized.rs#L38-L47 */
338
283
int
339
- fd_txn_account_is_writable_idx ( fd_exec_txn_ctx_t const * txn_ctx , int idx ) {
284
+ fd_exec_txn_ctx_account_is_writable_idx ( fd_exec_txn_ctx_t const * txn_ctx , int idx ) {
340
285
341
286
/* https://github.com/anza-xyz/agave/blob/v2.1.11/sdk/program/src/message/sanitized.rs#L43 */
342
287
if ( !fd_txn_is_writable ( txn_ctx -> txn_descriptor , idx ) ) {
@@ -360,3 +305,30 @@ fd_txn_account_is_writable_idx( fd_exec_txn_ctx_t const * txn_ctx, int idx ) {
360
305
361
306
return 1 ;
362
307
}
308
+
309
+ /* Account pre-condition filtering functions */
310
+
311
+ int
312
+ fd_txn_account_exists ( fd_exec_txn_ctx_t const * ctx ,
313
+ int idx ,
314
+ fd_txn_account_t * acc ) {
315
+ (void ) ctx ;
316
+ (void ) idx ;
317
+ return fd_acc_exists ( acc -> const_meta );
318
+ }
319
+
320
+ int
321
+ fd_txn_account_is_writable ( fd_exec_txn_ctx_t const * ctx ,
322
+ int idx ,
323
+ fd_txn_account_t * acc ) {
324
+ (void ) acc ;
325
+ return fd_exec_txn_ctx_account_is_writable_idx ( ctx , idx );
326
+ }
327
+
328
+ int
329
+ fd_txn_account_fee_payer_writable ( fd_exec_txn_ctx_t const * ctx ,
330
+ int idx ,
331
+ fd_txn_account_t * acc ) {
332
+ (void ) acc ;
333
+ return fd_txn_is_writable ( ctx -> txn_descriptor , idx );
334
+ }
0 commit comments