Skip to content

Commit

Permalink
chore: Change to the new Pyth sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
Aursen committed Jul 24, 2024
1 parent cc67039 commit 1e0ec5f
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 156 deletions.
184 changes: 86 additions & 98 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ termcolor = "1.2.0"
cargo_metadata = "=0.18.1"
nom = "~7"
log = "0.4"
pyth-sdk-solana = { git = "https://github.com/AdrenaDEX/pyth-sdk-rs", branch = "fix-solana-deps" }
pyth-solana-receiver-sdk = "0.3.1"
tokio = "1.18.4"
futures = "0.3.26"
version = "3.0.0"
Expand Down
3 changes: 1 addition & 2 deletions plugin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ sablier-thread-program = { workspace = true, features = ["no-entrypoint"] }
sablier-webhook-program = { workspace = true, features = ["no-entrypoint"] }
sablier-utils.workspace = true
log.workspace = true
pyth-sdk-solana.workspace = true
pyth-solana-receiver-sdk.workspace = true
reqwest.workspace = true
solana-account-decoder.workspace = true
solana-client.workspace = true
Expand All @@ -42,7 +42,6 @@ solana-program.workspace = true
solana-sdk.workspace = true
tokio.workspace = true
futures.workspace = true
static-pubkey.workspace = true

[build-dependencies]
cargo_metadata.workspace = true
Expand Down
43 changes: 14 additions & 29 deletions plugin/src/events.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
use anchor_lang::{prelude::AccountInfo, AccountDeserialize, Discriminator};
use anchor_lang::{AccountDeserialize, Discriminator};
use bincode::deserialize;
use pyth_sdk_solana::{state::SolanaPriceAccount, PriceFeed};
use pyth_solana_receiver_sdk::price_update::{PriceFeedMessage, PriceUpdateV2};
use sablier_thread_program::state::{Thread, VersionedThread};
use sablier_webhook_program::state::Webhook;
use solana_geyser_plugin_interface::geyser_plugin_interface::{
GeyserPluginError, ReplicaAccountInfo,
};
use solana_program::{clock::Clock, pubkey::Pubkey, sysvar};
use static_pubkey::static_pubkey;

static PYTH_ORACLE_PROGRAM_ID_MAINNET: Pubkey =
static_pubkey!("FsJ3A3u2vn5cTVofAjvy6y5kwABJAqYWpe4975bi2epH");
static PYTH_ORACLE_PROGRAM_ID_DEVNET: Pubkey =
static_pubkey!("gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s");

#[derive(Debug)]
pub enum AccountUpdateEvent {
Clock { clock: Clock },
Thread { thread: VersionedThread },
PriceFeed { price_feed: PriceFeed },
PriceFeed { price_feed: PriceFeedMessage },
Webhook { webhook: Webhook },
}

Expand Down Expand Up @@ -57,26 +51,17 @@ impl TryFrom<&mut ReplicaAccountInfo<'_>> for AccountUpdateEvent {
}

// If the account belongs to Pyth, attempt to parse it.
if owner_pubkey.eq(&PYTH_ORACLE_PROGRAM_ID_MAINNET)
|| owner_pubkey.eq(&PYTH_ORACLE_PROGRAM_ID_DEVNET)
{
let data = &mut account_info.data.to_vec();
let acc_info = AccountInfo::new(
&account_pubkey,
false,
false,
&mut account_info.lamports,
data,
&owner_pubkey,
account_info.executable,
account_info.rent_epoch,
);
let price_feed = SolanaPriceAccount::account_info_to_feed(&acc_info).map_err(|_| {
GeyserPluginError::AccountsUpdateError {
msg: "Failed to parse Pyth price account".into(),
}
})?;
return Ok(AccountUpdateEvent::PriceFeed { price_feed });
if owner_pubkey.eq(&pyth_solana_receiver_sdk::ID) {
let price_account =
PriceUpdateV2::try_deserialize(&mut account_info.data).map_err(|_| {
GeyserPluginError::AccountsUpdateError {
msg: "Failed to parse Pyth price account".into(),
}
})?;

return Ok(AccountUpdateEvent::PriceFeed {
price_feed: price_account.price_message,
});
}

// If the account belongs to the webhook program, parse in
Expand Down
16 changes: 4 additions & 12 deletions plugin/src/observers/thread.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use chrono::DateTime;
use log::info;
use pyth_sdk_solana::PriceFeed;
use pyth_solana_receiver_sdk::price_update::PriceFeedMessage;
use sablier_cron::Schedule;
use sablier_thread_program::state::{Equality, Trigger, TriggerContext, VersionedThread};
use solana_geyser_plugin_interface::geyser_plugin_interface::{
Expand Down Expand Up @@ -165,29 +165,21 @@ impl ThreadObserver {
pub async fn observe_price_feed(
self: Arc<Self>,
account_pubkey: Pubkey,
price_feed: PriceFeed,
price_feed: PriceFeedMessage,
) -> PluginResult<()> {
let r_pyth_threads = self.pyth_threads.read().await;
if let Some(pyth_threads) = r_pyth_threads.get(&account_pubkey) {
for pyth_thread in pyth_threads {
match pyth_thread.equality {
Equality::GreaterThanOrEqual => {
if price_feed
.get_price_unchecked()
.price
.ge(&pyth_thread.limit)
{
if price_feed.price.ge(&pyth_thread.limit) {
let mut w_now_threads = self.now_threads.write().await;
w_now_threads.insert(pyth_thread.thread_pubkey);
drop(w_now_threads);
}
}
Equality::LessThanOrEqual => {
if price_feed
.get_price_unchecked()
.price
.le(&pyth_thread.limit)
{
if price_feed.price.le(&pyth_thread.limit) {
let mut w_now_threads = self.now_threads.write().await;
w_now_threads.insert(pyth_thread.thread_pubkey);
drop(w_now_threads);
Expand Down
2 changes: 1 addition & 1 deletion programs/thread/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ chrono = { workspace = true, features = ["alloc"] }
sablier-cron.workspace = true
sablier-network-program = { features = ["cpi"], workspace = true }
sablier-utils.workspace = true
pyth-sdk-solana.workspace = true
pyth-solana-receiver-sdk.workspace = true
version.workspace = true
24 changes: 14 additions & 10 deletions programs/thread/src/instructions/thread_kickoff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{

use anchor_lang::prelude::*;
use chrono::DateTime;
use pyth_sdk_solana::state::SolanaPriceAccount;
use pyth_solana_receiver_sdk::price_update::PriceUpdateV2;
use sablier_cron::Schedule;
use sablier_network_program::state::{Worker, WorkerAccount};
use sablier_utils::thread::Trigger;
Expand Down Expand Up @@ -195,7 +195,7 @@ pub fn handler(ctx: Context<ThreadKickoff>) -> Result<()> {
})
}
Trigger::Pyth {
price_feed: price_feed_pubkey,
feed_id,
equality,
limit,
} => {
Expand All @@ -205,17 +205,21 @@ pub fn handler(ctx: Context<ThreadKickoff>) -> Result<()> {
return Err(SablierError::TriggerConditionFailed.into());
}
Some(account_info) => {
require!(
price_feed_pubkey.eq(account_info.key),
require_keys_eq!(
*account_info.owner,
pyth_solana_receiver_sdk::ID,
SablierError::TriggerConditionFailed
);
const STALENESS_THRESHOLD: u64 = 60; // staleness threshold in seconds
let price_feed =
SolanaPriceAccount::account_info_to_feed(account_info).unwrap();
let current_timestamp = Clock::get()?.unix_timestamp;
let current_price = price_feed
.get_price_no_older_than(current_timestamp, STALENESS_THRESHOLD)
.unwrap();
let price_update =
PriceUpdateV2::try_deserialize(&mut account_info.data.borrow().as_ref())?;

let current_price = price_update.get_price_no_older_than(
&Clock::get()?,
STALENESS_THRESHOLD,
feed_id,
)?;

match equality {
Equality::GreaterThanOrEqual => {
require!(
Expand Down
1 change: 1 addition & 0 deletions utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ base64.workspace = true
serde = { workspace = true, features = ["derive"] }
static-pubkey.workspace = true
sablier-macros = { path = "./macros" }
pyth-solana-receiver-sdk.workspace = true
2 changes: 1 addition & 1 deletion utils/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use syn::{

mod space;

#[proc_macro_derive(MinSpace, attributes(max_len, raw_space, internal))]
#[proc_macro_derive(MinSpace, attributes(max_len, raw_space))]
pub fn derive_min_space(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);

Expand Down
6 changes: 4 additions & 2 deletions utils/src/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use anchor_lang::{
solana_program::{self, instruction::Instruction},
AnchorDeserialize,
};
use pyth_solana_receiver_sdk::price_update::FeedId;
use sablier_macros::MinSpace;
use serde::{Deserialize, Serialize};
use static_pubkey::static_pubkey;
Expand Down Expand Up @@ -84,8 +85,9 @@ pub enum Trigger {

/// Allows a thread to be kicked off according to a Pyth price feed movement.
Pyth {
/// The address of the price feed to monitor.
price_feed: Pubkey,
/// The price feed id to monitor.
#[raw_space(32)]
feed_id: FeedId, // TODO implement in the macro
/// The equality operator (gte or lte) used to compare prices.
equality: Equality,
/// The limit price to compare the Pyth feed to.
Expand Down

0 comments on commit 1e0ec5f

Please sign in to comment.