@@ -13,20 +13,25 @@ pub mod processor;
1313pub mod instruction;
1414
1515use std:: mem:: size_of;
16+ use borsh:: { BorshSerialize , BorshDeserialize } ;
1617use bytemuck:: {
1718 cast_slice, from_bytes, try_cast_slice,
1819 Pod , PodCastError , Zeroable ,
1920} ;
2021
22+ #[ cfg( target_arch = "bpf" ) ]
23+ use solana_program:: { clock:: Clock , sysvar:: Sysvar } ;
24+
2125solana_program:: declare_id!( "PythC11111111111111111111111111111111111111" ) ;
2226
23- pub const MAGIC : u32 = 0xa1b2c3d4 ;
24- pub const VERSION_2 : u32 = 2 ;
25- pub const VERSION : u32 = VERSION_2 ;
26- pub const MAP_TABLE_SIZE : usize = 640 ;
27- pub const PROD_ACCT_SIZE : usize = 512 ;
28- pub const PROD_HDR_SIZE : usize = 48 ;
29- pub const PROD_ATTR_SIZE : usize = PROD_ACCT_SIZE - PROD_HDR_SIZE ;
27+ pub const MAGIC : u32 = 0xa1b2c3d4 ;
28+ pub const VERSION_2 : u32 = 2 ;
29+ pub const VERSION : u32 = VERSION_2 ;
30+ pub const MAP_TABLE_SIZE : usize = 640 ;
31+ pub const PROD_ACCT_SIZE : usize = 512 ;
32+ pub const PROD_HDR_SIZE : usize = 48 ;
33+ pub const PROD_ATTR_SIZE : usize = PROD_ACCT_SIZE - PROD_HDR_SIZE ;
34+ pub const MAX_SLOT_DIFFERENCE : u64 = 25 ;
3035
3136/// The type of Pyth account determines what data it contains
3237#[ derive( Copy , Clone ) ]
@@ -40,7 +45,7 @@ pub enum AccountType
4045}
4146
4247/// The current status of a price feed.
43- #[ derive( Copy , Clone , PartialEq ) ]
48+ #[ derive( Copy , Clone , PartialEq , BorshSerialize , BorshDeserialize , Debug ) ]
4449#[ repr( C ) ]
4550pub enum PriceStatus
4651{
@@ -146,11 +151,15 @@ unsafe impl Pod for Product {}
146151#[ repr( C ) ]
147152pub struct PriceInfo
148153{
149- /// the current price
154+ /// the current price.
155+ /// For the aggregate price use price.get_current_price() whenever possible. It has more checks to make sure price is valid.
150156 pub price : i64 ,
151- /// confidence interval around the price
157+ /// confidence interval around the price.
158+ /// For the aggregate confidence use price.get_current_price() whenever possible. It has more checks to make sure price is valid.
152159 pub conf : u64 ,
153- /// status of price (Trading is valid)
160+ /// status of price (Trading is valid).
161+ /// For the aggregate status use price.get_current_status() whenever possible.
162+ /// Price data can sometimes go stale and the function handles the status in such cases.
154163 pub status : PriceStatus ,
155164 /// notification of any corporate action
156165 pub corp_act : CorpAction ,
@@ -180,9 +189,9 @@ pub struct Ema
180189 /// The current value of the EMA
181190 pub val : i64 ,
182191 /// numerator state for next update
183- numer : i64 ,
192+ pub numer : i64 ,
184193 /// denominator state for next update
185- denom : i64
194+ pub denom : i64
186195}
187196
188197/// Price accounts represent a continuously-updating price feed for a product.
@@ -243,13 +252,26 @@ unsafe impl Zeroable for Price {}
243252unsafe impl Pod for Price { }
244253
245254impl Price {
255+ /**
256+ * Get the current status of the aggregate price.
257+ * If this lib is used on-chain it will mark price status as unknown if price has not been updated for a while.
258+ */
259+ pub fn get_current_price_status ( & self ) -> PriceStatus {
260+ #[ cfg( target_arch = "bpf" ) ]
261+ if matches ! ( self . agg. status, PriceStatus :: Trading ) &&
262+ Clock :: get ( ) . unwrap ( ) . slot - self . agg . pub_slot > MAX_SLOT_DIFFERENCE {
263+ return PriceStatus :: Unknown ;
264+ }
265+ self . agg . status
266+ }
267+
246268 /**
247269 * Get the current price and confidence interval as fixed-point numbers of the form a * 10^e.
248270 * Returns a struct containing the current price, confidence interval, and the exponent for both
249271 * numbers. Returns `None` if price information is currently unavailable for any reason.
250272 */
251273 pub fn get_current_price ( & self ) -> Option < PriceConf > {
252- if !matches ! ( self . agg . status , PriceStatus :: Trading ) {
274+ if !matches ! ( self . get_current_price_status ( ) , PriceStatus :: Trading ) {
253275 None
254276 } else {
255277 Some ( PriceConf {
@@ -394,6 +416,7 @@ pub fn load_price(data: &[u8]) -> Result<&Price, PythError> {
394416 return Ok ( pyth_price) ;
395417}
396418
419+
397420pub struct AttributeIter < ' a > {
398421 attrs : & ' a [ u8 ] ,
399422}
0 commit comments