diff --git a/program/c/src/oracle/upd_aggregate.h b/program/c/src/oracle/upd_aggregate.h index 9668a073..21ae8e45 100644 --- a/program/c/src/oracle/upd_aggregate.h +++ b/program/c/src/oracle/upd_aggregate.h @@ -134,14 +134,6 @@ static inline void upd_twap( // update aggregate price static inline bool upd_aggregate( pc_price_t *ptr, uint64_t slot, int64_t timestamp ) { - // only re-compute aggregate in next slot - if ( slot <= ptr->agg_.pub_slot_ ) { - return false; - } - - // get number of slots from last published valid price - int64_t agg_diff = ( int64_t )slot - ( int64_t )( ptr->last_slot_ ); - // Update the value of the previous price, if it had TRADING status. if ( ptr->agg_.status_ == PC_STATUS_TRADING ) { ptr->prev_slot_ = ptr->agg_.pub_slot_; @@ -224,7 +216,6 @@ static inline bool upd_aggregate( pc_price_t *ptr, uint64_t slot, int64_t timest ptr->agg_.price_ = agg_price; ptr->agg_.conf_ = (uint64_t)agg_conf; - upd_twap( ptr, agg_diff ); return true; } diff --git a/program/rust/src/processor/upd_price.rs b/program/rust/src/processor/upd_price.rs index 55446b0c..4af6e89a 100644 --- a/program/rust/src/processor/upd_price.rs +++ b/program/rust/src/processor/upd_price.rs @@ -177,21 +177,32 @@ pub fn upd_price( // Try to update the aggregate #[allow(unused_variables)] - let mut aggregate_updated = false; - - // NOTE: c_upd_aggregate must use a raw pointer to price - // data. Solana's `.borrow_*` methods require exclusive - // access, i.e. no other borrow can exist for the account. - #[allow(unused_assignments)] - if clock.slot > latest_aggregate_price.pub_slot_ { - unsafe { - aggregate_updated = c_upd_aggregate( + let aggregate_updated = if clock.slot > latest_aggregate_price.pub_slot_ { + let updated = unsafe { + // NOTE: c_upd_aggregate must use a raw pointer to price + // data. Solana's `.borrow_*` methods require exclusive + // access, i.e. no other borrow can exist for the account. + c_upd_aggregate( price_account.try_borrow_mut_data()?.as_mut_ptr(), clock.slot, clock.unix_timestamp, - ); + ) + }; + + // If the aggregate was successfully updated, calculate the difference and update TWAP. + if updated { + let agg_diff = (clock.slot as i64) + - load_checked::(price_account, cmd_args.header.version)?.prev_slot_ + as i64; + // Encapsulate TWAP update logic in a function to minimize unsafe block scope. + unsafe { + c_upd_twap(price_account.try_borrow_mut_data()?.as_mut_ptr(), agg_diff); + } } - } + updated + } else { + false + }; // Reload price data as a struct after c_upd_aggregate() borrow is dropped let mut price_data = load_checked::(price_account, cmd_args.header.version)?; diff --git a/program/rust/src/tests/test_upd_aggregate.rs b/program/rust/src/tests/test_upd_aggregate.rs index a2f643fb..c9e962cf 100644 --- a/program/rust/src/tests/test_upd_aggregate.rs +++ b/program/rust/src/tests/test_upd_aggregate.rs @@ -100,8 +100,6 @@ fn test_upd_aggregate() { assert_eq!(price_data.agg_.price_, 100); assert_eq!(price_data.agg_.conf_, 10); - assert_eq!(price_data.twap_.val_, 100); - assert_eq!(price_data.twac_.val_, 10); assert_eq!(price_data.num_qt_, 1); assert_eq!(price_data.timestamp_, 1); assert_eq!(price_data.prev_slot_, 0); @@ -134,8 +132,6 @@ fn test_upd_aggregate() { assert_eq!(price_data.agg_.price_, 145); assert_eq!(price_data.agg_.conf_, 55); - assert_eq!(price_data.twap_.val_, 106); - assert_eq!(price_data.twac_.val_, 16); assert_eq!(price_data.num_qt_, 2); assert_eq!(price_data.timestamp_, 2); assert_eq!(price_data.prev_slot_, 1000); @@ -169,8 +165,6 @@ fn test_upd_aggregate() { assert_eq!(price_data.agg_.price_, 200); assert_eq!(price_data.agg_.conf_, 90); - assert_eq!(price_data.twap_.val_, 114); - assert_eq!(price_data.twac_.val_, 23); assert_eq!(price_data.num_qt_, 3); assert_eq!(price_data.timestamp_, 3); assert_eq!(price_data.prev_slot_, 1000); @@ -205,8 +199,6 @@ fn test_upd_aggregate() { assert_eq!(price_data.agg_.price_, 245); assert_eq!(price_data.agg_.conf_, 85); - assert_eq!(price_data.twap_.val_, 125); - assert_eq!(price_data.twac_.val_, 28); assert_eq!(price_data.num_qt_, 4); assert_eq!(price_data.timestamp_, 4); assert_eq!(price_data.last_slot_, 1001);