data_anchor_client/fees/
fee_strategy.rs1use anchor_lang::prelude::Pubkey;
2use solana_client::nonblocking::rpc_client::RpcClient;
3use tracing::Instrument;
4
5use super::Lamports;
6use crate::{ChainError, DataAnchorClientResult, Fee, Priority, TransactionType};
7
8#[derive(Debug, Clone, Copy)]
10pub enum FeeStrategy {
11 Fixed(Fee),
13 BasedOnRecentFees(Priority),
15}
16
17impl Default for FeeStrategy {
18 fn default() -> Self {
19 Self::BasedOnRecentFees(Priority::default())
20 }
21}
22
23impl From<Fee> for FeeStrategy {
24 fn from(fee: Fee) -> Self {
25 Self::Fixed(fee)
26 }
27}
28
29impl From<Priority> for FeeStrategy {
30 fn from(priority: Priority) -> Self {
31 Self::BasedOnRecentFees(priority)
32 }
33}
34
35impl FeeStrategy {
36 pub(crate) async fn convert_fee_strategy_to_fixed(
38 &self,
39 rpc_client: &RpcClient,
40 mutating_accounts: &[Pubkey],
41 tx_type: TransactionType,
42 ) -> DataAnchorClientResult<Fee> {
43 let priority = match self {
44 FeeStrategy::Fixed(fee) => {
45 return Ok(*fee);
47 }
48 FeeStrategy::BasedOnRecentFees(priority) => priority,
49 };
50
51 let mut fee_retries = 5;
52
53 while fee_retries > 0 {
54 let res = priority
55 .get_priority_fee_estimate(rpc_client, mutating_accounts)
56 .in_current_span()
57 .await;
58
59 match res {
60 Ok(fee) => {
61 return Ok(Fee {
62 prioritization_fee_rate: fee,
63 num_signatures: tx_type.num_signatures(),
64 compute_unit_limit: tx_type.compute_unit_limit(),
65 price_per_signature: Lamports(5000),
66 blob_account_size: 0,
67 });
68 }
69 Err(e) => {
70 fee_retries -= 1;
71 if fee_retries == 0 {
72 return Err(e);
73 }
74 }
75 }
76 }
77
78 Err(ChainError::ConversionError("Fee strategy conversion failed after retries").into())
79 }
80}