From 533520a59a5988bc3fa279b4c81281b0a46d01d7 Mon Sep 17 00:00:00 2001 From: Ali Behjati Date: Fri, 1 Dec 2023 20:39:53 +0100 Subject: [PATCH] fix: use both latest publisher and aggregate slot for dynamic pricing (#99) --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/agent/solana/exporter.rs | 54 +++++++++++++++++++----------------- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cd7f4fa..64f3a00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2731,7 +2731,7 @@ dependencies = [ [[package]] name = "pyth-agent" -version = "2.4.1" +version = "2.4.2" dependencies = [ "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 3794c18..3176c83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pyth-agent" -version = "2.4.1" +version = "2.4.2" edition = "2021" [[bin]] diff --git a/src/agent/solana/exporter.rs b/src/agent/solana/exporter.rs index 2b660dd..bc8d2e5 100644 --- a/src/agent/solana/exporter.rs +++ b/src/agent/solana/exporter.rs @@ -746,38 +746,40 @@ impl Exporter { // used instead of the publishers latest update to avoid overpaying. let oldest_slot = result .values() + .filter(|account| account.min_pub != 255) // Only consider live price accounts .flat_map(|account| { account .comp .iter() .find(|c| c.publisher == publish_keypair.pubkey()) - .map(|c| c.latest.pub_slot) + .map(|c| c.latest.pub_slot.max(account.agg.pub_slot)) }) - .min() - .ok_or(anyhow!("No price accounts"))?; - - let slot_gap = network_state.current_slot.saturating_sub(oldest_slot); - - // Set the dynamic price exponentially based on the slot gap. If the max slot gap is - // 25, on this number (or more) the maximum unit price is paid, and then on slot 24 it - // is half of that and gets halved each lower slot. Given that we have max total - // compute price of 10**12 and 250k compute units in one tx (12 updates) these are the - // estimated prices based on slot gaps: - // 25 (or more): 4_000_000 - // 20 : 125_000 - // 18 : 31_250 - // 15 : 3_906 - // 13 : 976 - // 10 : 122 - let exponential_price = maximum_unit_price - >> self - .config - .maximum_slot_gap_for_dynamic_compute_unit_price - .saturating_sub(slot_gap); - - compute_unit_price_micro_lamports = compute_unit_price_micro_lamports - .map(|price| price.max(exponential_price)) - .or(Some(exponential_price)); + .min(); + + if let Some(oldest_slot) = oldest_slot { + let slot_gap = network_state.current_slot.saturating_sub(oldest_slot); + + // Set the dynamic price exponentially based on the slot gap. If the max slot gap is + // 25, on this number (or more) the maximum unit price is paid, and then on slot 24 it + // is half of that and gets halved each lower slot. Given that we have max total + // compute price of 10**12 and 250k compute units in one tx (12 updates) these are the + // estimated prices based on slot gaps: + // 25 (or more): 4_000_000 + // 20 : 125_000 + // 18 : 31_250 + // 15 : 3_906 + // 13 : 976 + // 10 : 122 + let exponential_price = maximum_unit_price + >> self + .config + .maximum_slot_gap_for_dynamic_compute_unit_price + .saturating_sub(slot_gap); + + compute_unit_price_micro_lamports = compute_unit_price_micro_lamports + .map(|price| price.max(exponential_price)) + .or(Some(exponential_price)); + } } if let Some(compute_unit_price_micro_lamports) = compute_unit_price_micro_lamports {