solana_validator_optimizer/
priority_fee.rs1use serde::Serialize;
2
3const MICRO_LAMPORTS_PER_LAMPORT: u64 = 1_000_000;
4
5#[derive(Debug, Clone, Serialize)]
6pub struct PriorityFeeAdvice {
7 pub compute_units: u64,
8 pub micro_lamports_per_compute_unit: u64,
9 pub estimated_priority_fee_lamports: u64,
10 pub estimated_priority_fee_sol: f64,
11 pub risk_level: String,
12 pub recommendation: String,
13}
14
15pub fn advise_priority_fee(
16 compute_units: u64,
17 micro_lamports_per_compute_unit: u64,
18) -> PriorityFeeAdvice {
19 let estimated_priority_fee_lamports =
20 compute_units.saturating_mul(micro_lamports_per_compute_unit) / MICRO_LAMPORTS_PER_LAMPORT;
21
22 let estimated_priority_fee_sol = estimated_priority_fee_lamports as f64 / 1_000_000_000_f64;
23
24 let (risk_level, recommendation) = classify_fee(
25 compute_units,
26 micro_lamports_per_compute_unit,
27 estimated_priority_fee_lamports,
28 );
29
30 PriorityFeeAdvice {
31 compute_units,
32 micro_lamports_per_compute_unit,
33 estimated_priority_fee_lamports,
34 estimated_priority_fee_sol,
35 risk_level,
36 recommendation,
37 }
38}
39
40fn classify_fee(
41 compute_units: u64,
42 micro_lamports_per_compute_unit: u64,
43 estimated_priority_fee_lamports: u64,
44) -> (String, String) {
45 if compute_units == 0 {
46 return (
47 "Invalid".to_string(),
48 "Compute units must be greater than zero.".to_string(),
49 );
50 }
51
52 if micro_lamports_per_compute_unit == 0 {
53 return (
54 "Low".to_string(),
55 "No priority fee is configured. This may be acceptable during low network activity but can reduce transaction landing reliability during congestion.".to_string(),
56 );
57 }
58
59 if estimated_priority_fee_lamports < 100 {
60 return (
61 "Low".to_string(),
62 "Priority fee is very low. Consider increasing compute unit price for production marketplace, reward, or high-frequency transaction flows.".to_string(),
63 );
64 }
65
66 if estimated_priority_fee_lamports <= 5_000 {
67 return (
68 "Normal".to_string(),
69 "Priority fee appears reasonable for moderate load. Monitor transaction landing rate and RPC latency in production.".to_string(),
70 );
71 }
72
73 if estimated_priority_fee_lamports <= 50_000 {
74 return (
75 "Elevated".to_string(),
76 "Priority fee is elevated. This may improve landing probability during congestion but should be monitored for cost impact.".to_string(),
77 );
78 }
79
80 (
81 "High".to_string(),
82 "Priority fee is high. Verify that this is intentional and justified by congestion, latency-sensitive flows, or high-value transactions.".to_string(),
83 )
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89
90 #[test]
91 fn calculates_priority_fee_in_lamports() {
92 let advice = advise_priority_fee(250_000, 1_000);
93 assert_eq!(advice.estimated_priority_fee_lamports, 250);
94 }
95
96 #[test]
97 fn detects_zero_compute_units() {
98 let advice = advise_priority_fee(0, 1_000);
99 assert_eq!(advice.risk_level, "Invalid");
100 }
101
102 #[test]
103 fn detects_zero_priority_fee() {
104 let advice = advise_priority_fee(250_000, 0);
105 assert_eq!(advice.risk_level, "Low");
106 }
107}