Skip to content

Commit

Permalink
refactor: improve price cap configuration (#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
ali-bahjati authored Dec 13, 2023
1 parent 533520a commit c76ccc4
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 28 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pyth-agent"
version = "2.4.2"
version = "2.4.3"
edition = "2021"

[[bin]]
Expand Down
11 changes: 2 additions & 9 deletions config/config.sample.pythnet.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,8 @@ exporter.compute_unit_limit = 20000
# during periods of high network congestion.
exporter.dynamic_compute_unit_pricing_enabled = true

# Maximum slot gap between the current slot and the oldest slot amongst all the accounts in
# the batch. This is used to calculate the dynamic price per compute unit. When the slot gap
# reaches this number we will use the maximum total_compute_fee for the transaction.
exporter.maximum_slot_gap_for_dynamic_compute_unit_price = 40

# The interval with which to poll account information. We are adding it as an extra
# layer of protection to ensure we get the latest account information if there are
# any issues with the ws subscription.
oracle.poll_interval_duration = "5s"
# Price per compute unit offered for update_price transactions
exporter.compute_unit_price_micro_lamports = 1000

# Configuration for the JRPC API
[pythd_adapter]
Expand Down
8 changes: 4 additions & 4 deletions config/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ key_store.mapping_key = "RelevantOracleMappingAddress"
# calculated based on the network previous prioritization fees.
# exporter.dynamic_compute_unit_pricing_enabled = false

# Maximum total compute unit fee paid for a single transaction. Defaults to 0.001 SOL. This
# is a safety measure while using dynamic compute price to prevent the exporter from paying
# too much for a single transaction. The default is 10**12 micro lamports (0.001 SOL).
# exporter.maximum_total_compute_fee_micro_lamports = 1000000000000
# Maximum compute unit price offered for update_price transactions. Defaults to
# 1 million microlamports. This is a safety measure while using dynamic compute
# price to prevent the exporter from paying too much for a single transaction.
# exporter.maximum_compute_unit_price_micro_lamports = 1000000

# Maximum slot gap between the current slot and the oldest slot amongst all the accounts in
# the batch. This is used to calculate the dynamic price per compute unit. When the slot gap
Expand Down
24 changes: 12 additions & 12 deletions src/agent/solana/exporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ pub struct Config {
/// Maximum total compute unit fee paid for a single transaction. Defaults to 0.001 SOL. This
/// is a safety measure while using dynamic compute price to prevent the exporter from paying
/// too much for a single transaction
pub maximum_total_compute_fee_micro_lamports: u64,
pub maximum_compute_unit_price_micro_lamports: u64,
/// Maximum slot gap between the current slot and the oldest slot amongst all the accounts in
/// the batch. This is used to calculate the dynamic price per compute unit. When the slot gap
/// reaches this number we will use the maximum total_compute_fee for the transaction.
Expand All @@ -156,12 +156,12 @@ impl Default for Config {
compute_unit_limit: 40000,
compute_unit_price_micro_lamports: None,
dynamic_compute_unit_pricing_enabled: false,
// Maximum total compute unit fee paid for a single transaction (0.00003 SOL)
maximum_total_compute_fee_micro_lamports: 30_000_000_000,
// Maximum compute unit price (as a cap on the dynamic price)
maximum_compute_unit_price_micro_lamports: 1_000_000,
// A publisher update is not included if it is 25 slots behind the current slot.
// Due to the delay in the network (until a block gets confirmed) we add 5 slots
// to make sure we do not overpay.
maximum_slot_gap_for_dynamic_compute_unit_price: 30,
// Due to the delay in the network (until a block gets confirmed) and potential
// ws issues we add 15 slots to make sure we do not overpay.
maximum_slot_gap_for_dynamic_compute_unit_price: 40,
}
}
}
Expand Down Expand Up @@ -710,17 +710,14 @@ impl Exporter {
// keep the uptime high during congestion whereas without it we would publish price after a
// large gap and then we can publish it again after the next large gap.
if self.config.dynamic_compute_unit_pricing_enabled {
let maximum_unit_price =
self.config.maximum_total_compute_fee_micro_lamports / total_compute_limit as u64;

// Use the estimated previous price if it is higher
// than the current price.
if let Some(estimated_recent_price) = self.recent_compute_unit_price_micro_lamports {
// Get the estimated compute unit price and wrap it so it stays below the maximum
// total compute unit fee. We additionally divide such price by 2 to create an
// exponential decay. This will make sure that a spike doesn't get propagated
// forever.
let estimated_price = (estimated_recent_price >> 1).min(maximum_unit_price);
let estimated_price = estimated_recent_price >> 1;

compute_unit_price_micro_lamports = compute_unit_price_micro_lamports
.map(|price| price.max(estimated_price))
Expand Down Expand Up @@ -770,7 +767,7 @@ impl Exporter {
// 15 : 3_906
// 13 : 976
// 10 : 122
let exponential_price = maximum_unit_price
let exponential_price = self.config.maximum_compute_unit_price_micro_lamports
>> self
.config
.maximum_slot_gap_for_dynamic_compute_unit_price
Expand All @@ -782,7 +779,10 @@ impl Exporter {
}
}

if let Some(compute_unit_price_micro_lamports) = compute_unit_price_micro_lamports {
if let Some(mut compute_unit_price_micro_lamports) = compute_unit_price_micro_lamports {
compute_unit_price_micro_lamports = compute_unit_price_micro_lamports
.min(self.config.maximum_compute_unit_price_micro_lamports);

debug!(self.logger, "setting compute unit price"; "unit_price" => compute_unit_price_micro_lamports);
instructions.push(ComputeBudgetInstruction::set_compute_unit_price(
compute_unit_price_micro_lamports,
Expand Down
2 changes: 1 addition & 1 deletion src/agent/solana/oracle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ impl Default for Config {
fn default() -> Self {
Self {
commitment: CommitmentLevel::Confirmed,
poll_interval_duration: Duration::from_secs(2 * 60),
poll_interval_duration: Duration::from_secs(5),
subscriber_enabled: true,
updates_channel_capacity: 10000,
data_channel_capacity: 10000,
Expand Down

0 comments on commit c76ccc4

Please sign in to comment.