Skip to content

Commit 2cfee67

Browse files
committed
fix: ix bugs on pyth lazer oracle crank
1 parent bbf4c0b commit 2cfee67

File tree

2 files changed

+17
-52
lines changed

2 files changed

+17
-52
lines changed

programs/drift/src/instructions/pyth_lazer_oracle.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use crate::state::pyth_lazer_oracle::{
77
use crate::validate;
88
use anchor_lang::prelude::*;
99
use pyth_lazer_solana_contract::protocol::message::SolanaMessage;
10-
use pyth_lazer_solana_contract::protocol::payload::{PayloadData, PayloadPropertyValue};
10+
use pyth_lazer_solana_contract::protocol::payload::{
11+
PayloadData, PayloadPropertyValue, TimestampUs,
12+
};
1113
use pyth_lazer_solana_contract::protocol::router::Price;
1214
use pyth_lazer_solana_contract::Storage;
1315
use solana_program::sysvar::instructions::load_current_index_checked;
@@ -76,23 +78,26 @@ pub fn handle_update_pyth_lazer_oracle<'c: 'info, 'info>(
7678
let mut best_bid_price: Option<Price> = None;
7779
let mut best_ask_price: Option<Price> = None;
7880
let mut exponent: Option<i16> = None;
79-
let mut feed_update_timestamp: Option<TimestampUs> = None;
81+
let mut feed_update_timestamp: Option<u64> = None;
8082

8183
for property in &payload_data.properties {
8284
match property {
8385
PayloadPropertyValue::BestBidPrice(price) => best_bid_price = *price,
8486
PayloadPropertyValue::BestAskPrice(price) => best_ask_price = *price,
8587
PayloadPropertyValue::Exponent(exp) => exponent = Some(*exp),
86-
PayloadPropertyValue::FeedUpdateTimestamp(timestamp) => {
87-
feed_update_timestamp = *timestamp
88-
}
88+
PayloadPropertyValue::FeedUpdateTimestamp(timestamp) => match timestamp {
89+
Some(timestamp) => match *timestamp {
90+
TimestampUs(ts) => feed_update_timestamp = Some(ts),
91+
},
92+
None => return Err(ErrorCode::InvalidPythLazerMessage.into()),
93+
},
8994
_ => {}
9095
}
9196
}
9297

9398
match feed_update_timestamp {
9499
Some(timestamp) => {
95-
if timestamp > current_timestamp {
100+
if current_timestamp >= timestamp {
96101
msg!(
97102
"Skipping lazer price update. current ts {} >= feed_update_timestamp {}",
98103
current_timestamp,
@@ -102,6 +107,7 @@ pub fn handle_update_pyth_lazer_oracle<'c: 'info, 'info>(
102107
}
103108
}
104109
None => {
110+
msg!("Skipping lazer price update. feed_update_timestamp is None",);
105111
return Err(ErrorCode::InvalidPythLazerMessage.into());
106112
}
107113
}
@@ -124,15 +130,15 @@ pub fn handle_update_pyth_lazer_oracle<'c: 'info, 'info>(
124130

125131
pyth_lazer_oracle.price = price;
126132
pyth_lazer_oracle.posted_slot = Clock::get()?.slot;
127-
pyth_lazer_oracle.publish_time = feed_update_timestamp;
133+
pyth_lazer_oracle.publish_time = feed_update_timestamp.unwrap();
128134
pyth_lazer_oracle.exponent = exponent.cast::<i32>()?;
129135
pyth_lazer_oracle.conf = conf.cast::<u64>()?;
130136
msg!("Price updated to {}", price);
131137

132138
msg!(
133139
"Posting new lazer update. current ts {} < feed_update_timestamp {}",
134140
current_timestamp,
135-
feed_update_timestamp
141+
feed_update_timestamp.unwrap()
136142
);
137143
}
138144

sdk/src/pyth/pythLazerSubscriber.ts

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ export class PythLazerSubscriber {
2828
private pythLazerClient?: PythLazerClient;
2929
feedIdChunkToPriceMessage: Map<string, string> = new Map();
3030
feedIdToPrice: Map<number, number> = new Map();
31+
/** Map of feed IDs to whether the price is stale
32+
* Not used right now. Want to implement this so we know we can use staleness checks on the client if we want to in the future.
33+
*/
3134
feedIdToIsStale: Map<number, boolean> = new Map();
3235
feedIdHashToFeedIds: Map<string, number[]> = new Map();
3336
subscriptionIdsToFeedIdsHash: Map<number, string> = new Map();
@@ -359,48 +362,4 @@ export class PythLazerSubscriber {
359362
}
360363
return this.feedIdToPrice.get(feedId);
361364
}
362-
363-
/**
364-
* Returns whether the current price for a feed ID is stale (carried forward from an earlier update).
365-
* Use feedUpdateTimestamp vs timestampUs: if feedUpdateTimestamp < timestampUs, the price is stale.
366-
* @param feedId - The Pyth Lazer feed ID to check
367-
* @returns true if price is carried forward (e.g. market closed, no new data), false if fresh, undefined if no data
368-
*/
369-
isFeedIdStale(feedId: number): boolean | undefined {
370-
return this.feedIdToIsStale.get(feedId);
371-
}
372-
373-
/**
374-
* Returns whether the current price for a market is stale (carried forward from an earlier update).
375-
* Use feedUpdateTimestamp vs timestampUs: if feedUpdateTimestamp < timestampUs, the price is stale.
376-
* @param marketIndex - The market index to check
377-
* @returns true if price is carried forward (e.g. market closed, no new data), false if fresh, undefined if no data
378-
*/
379-
isPriceStaleForMarket(marketIndex: number): boolean | undefined {
380-
const feedId = this.marketIndextoPriceFeedId.get(marketIndex);
381-
if (feedId === undefined) {
382-
return undefined;
383-
}
384-
return this.feedIdToIsStale.get(feedId);
385-
}
386-
387-
/**
388-
* Gets the current price and staleness for a market index.
389-
* @param marketIndex - The market index to get the price for
390-
* @returns Object with price and isStale, or undefined if no price available
391-
*/
392-
getPriceWithStaleness(
393-
marketIndex: number
394-
): { price: number; isStale: boolean } | undefined {
395-
const feedId = this.marketIndextoPriceFeedId.get(marketIndex);
396-
if (feedId === undefined) {
397-
return undefined;
398-
}
399-
const price = this.feedIdToPrice.get(feedId);
400-
if (price === undefined) {
401-
return undefined;
402-
}
403-
const isStale = this.feedIdToIsStale.get(feedId) ?? false;
404-
return { price, isStale };
405-
}
406365
}

0 commit comments

Comments
 (0)