@@ -84,121 +84,72 @@ 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
+ int (* condition )( fd_exec_txn_ctx_t * ctx ,
91
+ int idx ,
92
+ fd_txn_account_t * acc ) ) {
90
93
if ( FD_UNLIKELY ( idx >=ctx -> accounts_cnt ) ) {
91
94
return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
92
95
}
93
96
94
97
fd_txn_account_t * txn_account = & ctx -> accounts [idx ];
95
98
* account = txn_account ;
96
99
97
- if ( FD_UNLIKELY ( !fd_acc_exists ( txn_account -> const_meta ) ) ) {
98
- return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
100
+ if ( condition != NULL ) {
101
+ if ( FD_UNLIKELY ( !condition ( ctx , idx , * account ) ) )
102
+ return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
99
103
}
100
104
101
105
return FD_ACC_MGR_SUCCESS ;
102
106
}
103
107
104
108
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
- }
109
+ fd_exec_txn_ctx_get_account_with_key ( fd_exec_txn_ctx_t * ctx ,
110
+ fd_pubkey_t const * pubkey ,
111
+ fd_txn_account_t * * account ,
112
+ int (* condition )( fd_exec_txn_ctx_t * ctx ,
113
+ int idx ,
114
+ fd_txn_account_t * acc ) ) {
115
+ int index = fd_exec_txn_ctx_find_index_of_account ( ctx , pubkey );
116
+ if ( FD_UNLIKELY ( index == -1 ) ) {
117
+ return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
120
118
}
121
119
122
- return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
120
+ return fd_exec_txn_ctx_get_account_at_index ( ctx ,
121
+ (uchar )index ,
122
+ account ,
123
+ condition );
123
124
}
124
125
125
126
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 ) {
127
+ fd_exec_txn_ctx_get_executable_account ( fd_exec_txn_ctx_t * ctx ,
128
+ fd_pubkey_t const * pubkey ,
129
+ fd_txn_account_t * * account ,
130
+ int (* condition )( fd_exec_txn_ctx_t * ctx ,
131
+ int idx ,
132
+ fd_txn_account_t * acc ) ) {
129
133
/* First try to fetch the executable account from the existing borrowed accounts.
130
134
If the pubkey is in the account keys, then we want to re-use that
131
135
borrowed account since it reflects changes from prior instructions. Referencing the
132
136
read-only executable accounts list is incorrect behavior when the program
133
137
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 );
138
+ int err = fd_exec_txn_ctx_get_account_with_key ( ctx , pubkey , account , condition );
135
139
if ( FD_UNLIKELY ( err == FD_ACC_MGR_SUCCESS ) ) {
136
140
return FD_ACC_MGR_SUCCESS ;
137
141
}
138
142
139
143
for ( ulong i = 0 ; i < ctx -> executable_cnt ; i ++ ) {
140
144
if ( memcmp ( pubkey -> uc , ctx -> executable_accounts [i ].pubkey -> uc , sizeof (fd_pubkey_t ) )== 0 ) {
141
- // TODO: check if readable???
142
145
fd_txn_account_t * txn_account = & ctx -> executable_accounts [i ];
143
146
* account = txn_account ;
144
147
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 );
148
+ if ( condition != NULL ) {
149
+ if ( FD_UNLIKELY ( !condition ( ctx , (int )i , * account ) ) )
150
+ return FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ;
200
151
}
201
- * account = txn_account ;
152
+
202
153
return FD_ACC_MGR_SUCCESS ;
203
154
}
204
155
}
@@ -335,7 +286,7 @@ fd_txn_account_is_demotion( fd_exec_txn_ctx_t const * txn_ctx, int idx )
335
286
336
287
https://github.com/anza-xyz/agave/blob/v2.1.11/sdk/program/src/message/sanitized.rs#L38-L47 */
337
288
int
338
- fd_txn_account_is_writable_idx ( fd_exec_txn_ctx_t const * txn_ctx , int idx ) {
289
+ fd_exec_txn_ctx_account_is_writable_idx ( fd_exec_txn_ctx_t const * txn_ctx , int idx ) {
339
290
340
291
/* https://github.com/anza-xyz/agave/blob/v2.1.11/sdk/program/src/message/sanitized.rs#L43 */
341
292
if ( !fd_txn_is_writable ( txn_ctx -> txn_descriptor , idx ) ) {
@@ -359,3 +310,30 @@ fd_txn_account_is_writable_idx( fd_exec_txn_ctx_t const * txn_ctx, int idx ) {
359
310
360
311
return 1 ;
361
312
}
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
+ }
0 commit comments