1
1
#[ cfg( feature = "pythnet" ) ]
2
2
use {
3
3
crate :: accounts:: {
4
+ PriceAccountV2 ,
5
+ PythAccount ,
4
6
PythOracleSerialize ,
5
7
UPD_PRICE_WRITE_SEED ,
6
8
} ,
14
16
crate :: {
15
17
accounts:: {
16
18
PriceAccount ,
17
- PriceAccountV2 ,
18
19
PriceInfo ,
19
- PythAccount ,
20
20
} ,
21
21
deserialize:: {
22
22
load,
@@ -160,7 +160,10 @@ pub fn upd_price(
160
160
}
161
161
162
162
// Try to update the aggregate
163
+ #[ allow( unused_variables) ]
163
164
let mut aggregate_updated = false ;
165
+
166
+ #[ allow( unused_assignments) ]
164
167
if clock. slot > latest_aggregate_price. pub_slot_ {
165
168
unsafe {
166
169
aggregate_updated = c_upd_aggregate (
@@ -171,20 +174,39 @@ pub fn upd_price(
171
174
}
172
175
}
173
176
177
+ // TWAP message will be stored here if:
178
+ // * price_account is V2
179
+ // * accumulator accounts were passed
180
+ #[ cfg( feature = "pythnet" ) ]
181
+ let mut maybe_twap_msg = None ;
174
182
175
- let account_len = price_account. try_data_len ( ) ?;
176
- if account_len >= PriceAccountV2 :: MINIMUM_SIZE {
177
- let mut price_data =
183
+ // Feature-gated PriceAccountV2-specific processing, used only on pythnet/pythtest. May populate
184
+ // maybe_twap_msg for later use in accumulator message cross-call.
185
+ //
186
+ // NOTE: This is done here specifically in order to keep price
187
+ // account data available for borrowing as v1 for remaining v1 processing.
188
+ #[ cfg( feature = "pythnet" ) ]
189
+ if price_account. try_data_len ( ) ? >= PriceAccountV2 :: MINIMUM_SIZE {
190
+ let mut price_data_v2 =
178
191
load_checked :: < PriceAccountV2 > ( price_account, cmd_args. header . version ) ?;
179
192
180
193
if aggregate_updated {
181
- price_data. update_price_cumulative ( ) ?;
194
+ // Update PriceCumulative on aggregation. This is done
195
+ // here, because PriceCumulative must update
196
+ // regardless of accumulator accounts being passed.
197
+ price_data_v2. update_price_cumulative ( ) ?;
198
+ }
199
+
200
+ // Populate the TWAP message if accumulator will be used
201
+ if maybe_accumulator_accounts. is_some ( ) {
202
+ maybe_twap_msg = Some ( price_data_v2. as_twap_message ( price_account. key ) ) ;
182
203
}
183
204
}
184
205
206
+ // Reload as V1 for remaining V1-compatible processing
185
207
let mut price_data = load_checked :: < PriceAccount > ( price_account, cmd_args. header . version ) ?;
186
208
187
-
209
+ // Feature-gated accumulator-specific code, used only on pythnet/pythtest
188
210
#[ cfg( feature = "pythnet" ) ]
189
211
{
190
212
// We want to send a message every time the aggregate price updates. However, during the migration,
@@ -194,6 +216,7 @@ pub fn upd_price(
194
216
if aggregate_updated {
195
217
price_data. message_sent_ = 0 ;
196
218
}
219
+
197
220
if let Some ( accumulator_accounts) = maybe_accumulator_accounts {
198
221
if price_data. message_sent_ == 0 {
199
222
// Check that the oracle PDA is correctly configured for the program we are calling.
@@ -225,10 +248,16 @@ pub fn upd_price(
225
248
is_writable: true ,
226
249
} ,
227
250
] ;
228
- let message = vec ! [ price_data
251
+
252
+ let mut message = vec ! [ price_data
229
253
. as_price_feed_message( price_account. key)
230
254
. to_bytes( ) ] ;
231
255
256
+ // Append a TWAP message if available
257
+ if let Some ( twap_msg) = maybe_twap_msg {
258
+ message. push ( twap_msg. to_bytes ( ) ) ;
259
+ }
260
+
232
261
// anchor discriminator for "global:put_all"
233
262
let discriminator: [ u8 ; 8 ] = [ 212 , 225 , 193 , 91 , 151 , 238 , 20 , 93 ] ;
234
263
let create_inputs_ix = Instruction :: new_with_borsh (
0 commit comments