1#![cfg(feature = "agave-unstable-api")]
2use {
3 agave_feature_set::FeatureSet, solana_fee_structure::FeeDetails,
4 solana_svm_transaction::svm_message::SVMStaticMessage,
5};
6
7#[derive(Copy, Clone)]
14pub struct FeeFeatures {}
15
16impl From<&FeatureSet> for FeeFeatures {
17 fn from(_feature_set: &FeatureSet) -> Self {
18 Self {}
19 }
20}
21
22pub fn calculate_fee(
24 message: &impl SVMStaticMessage,
25 lamports_per_signature: u64,
26 prioritization_fee: u64,
27 fee_features: FeeFeatures,
28) -> u64 {
29 calculate_fee_details(
30 message,
31 lamports_per_signature,
32 prioritization_fee,
33 fee_features,
34 )
35 .total_fee()
36}
37
38pub fn calculate_fee_details(
39 message: &impl SVMStaticMessage,
40 lamports_per_signature: u64,
41 prioritization_fee: u64,
42 _fee_features: FeeFeatures,
43) -> FeeDetails {
44 FeeDetails::new(
45 calculate_signature_fee(SignatureCounts::from(message), lamports_per_signature),
46 prioritization_fee,
47 )
48}
49
50pub fn calculate_signature_fee(
52 SignatureCounts {
53 num_transaction_signatures,
54 num_ed25519_signatures,
55 num_secp256k1_signatures,
56 num_secp256r1_signatures,
57 }: SignatureCounts,
58 lamports_per_signature: u64,
59) -> u64 {
60 let signature_count = num_transaction_signatures
61 .saturating_add(num_ed25519_signatures)
62 .saturating_add(num_secp256k1_signatures)
63 .saturating_add(num_secp256r1_signatures);
64 signature_count.saturating_mul(lamports_per_signature)
65}
66
67pub struct SignatureCounts {
68 pub num_transaction_signatures: u64,
69 pub num_ed25519_signatures: u64,
70 pub num_secp256k1_signatures: u64,
71 pub num_secp256r1_signatures: u64,
72}
73
74impl<Tx: SVMStaticMessage> From<&Tx> for SignatureCounts {
75 fn from(message: &Tx) -> Self {
76 Self {
77 num_transaction_signatures: message.num_transaction_signatures(),
78 num_ed25519_signatures: message.num_ed25519_signatures(),
79 num_secp256k1_signatures: message.num_secp256k1_signatures(),
80 num_secp256r1_signatures: message.num_secp256r1_signatures(),
81 }
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn test_calculate_signature_fee() {
91 const LAMPORTS_PER_SIGNATURE: u64 = 5_000;
92
93 assert_eq!(
95 calculate_signature_fee(
96 SignatureCounts {
97 num_transaction_signatures: 0,
98 num_ed25519_signatures: 0,
99 num_secp256k1_signatures: 0,
100 num_secp256r1_signatures: 0,
101 },
102 LAMPORTS_PER_SIGNATURE,
103 ),
104 0
105 );
106
107 assert_eq!(
109 calculate_signature_fee(
110 SignatureCounts {
111 num_transaction_signatures: 1,
112 num_ed25519_signatures: 0,
113 num_secp256k1_signatures: 0,
114 num_secp256r1_signatures: 0,
115 },
116 LAMPORTS_PER_SIGNATURE,
117 ),
118 LAMPORTS_PER_SIGNATURE
119 );
120
121 assert_eq!(
123 calculate_signature_fee(
124 SignatureCounts {
125 num_transaction_signatures: 1,
126 num_ed25519_signatures: 2,
127 num_secp256k1_signatures: 3,
128 num_secp256r1_signatures: 4,
129 },
130 LAMPORTS_PER_SIGNATURE,
131 ),
132 10 * LAMPORTS_PER_SIGNATURE
133 );
134 }
135}