Skip to main content

solana_fee/
lib.rs

1#![cfg(feature = "agave-unstable-api")]
2use {solana_fee_structure::FeeDetails, solana_svm_transaction::svm_message::SVMStaticMessage};
3
4/// Bools indicating the activation of features relevant
5/// to the fee calculation.
6// DEVELOPER NOTE:
7// This struct may become empty at some point. It is preferable to keep it
8// instead of removing, since fees will naturally be changed via feature-gates
9// in the future. Keeping this struct will help keep things organized.
10#[derive(Copy, Clone)]
11pub struct FeeFeatures {}
12
13/// Calculate fee for `SanitizedMessage`
14pub fn calculate_fee(
15    message: &impl SVMStaticMessage,
16    lamports_per_signature: u64,
17    prioritization_fee: u64,
18    fee_features: FeeFeatures,
19) -> u64 {
20    calculate_fee_details(
21        message,
22        lamports_per_signature,
23        prioritization_fee,
24        fee_features,
25    )
26    .total_fee()
27}
28
29pub fn calculate_fee_details(
30    message: &impl SVMStaticMessage,
31    lamports_per_signature: u64,
32    prioritization_fee: u64,
33    _fee_features: FeeFeatures,
34) -> FeeDetails {
35    FeeDetails::new(
36        calculate_signature_fee(SignatureCounts::from(message), lamports_per_signature),
37        prioritization_fee,
38    )
39}
40
41/// Calculate fees from signatures.
42pub fn calculate_signature_fee(
43    SignatureCounts {
44        num_transaction_signatures,
45        num_ed25519_signatures,
46        num_secp256k1_signatures,
47        num_secp256r1_signatures,
48    }: SignatureCounts,
49    lamports_per_signature: u64,
50) -> u64 {
51    let signature_count = num_transaction_signatures
52        .saturating_add(num_ed25519_signatures)
53        .saturating_add(num_secp256k1_signatures)
54        .saturating_add(num_secp256r1_signatures);
55    signature_count.saturating_mul(lamports_per_signature)
56}
57
58pub struct SignatureCounts {
59    pub num_transaction_signatures: u64,
60    pub num_ed25519_signatures: u64,
61    pub num_secp256k1_signatures: u64,
62    pub num_secp256r1_signatures: u64,
63}
64
65impl<Tx: SVMStaticMessage> From<&Tx> for SignatureCounts {
66    fn from(message: &Tx) -> Self {
67        Self {
68            num_transaction_signatures: message.num_transaction_signatures(),
69            num_ed25519_signatures: message.num_ed25519_signatures(),
70            num_secp256k1_signatures: message.num_secp256k1_signatures(),
71            num_secp256r1_signatures: message.num_secp256r1_signatures(),
72        }
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn test_calculate_signature_fee() {
82        const LAMPORTS_PER_SIGNATURE: u64 = 5_000;
83
84        // Impossible case - 0 signatures.
85        assert_eq!(
86            calculate_signature_fee(
87                SignatureCounts {
88                    num_transaction_signatures: 0,
89                    num_ed25519_signatures: 0,
90                    num_secp256k1_signatures: 0,
91                    num_secp256r1_signatures: 0,
92                },
93                LAMPORTS_PER_SIGNATURE,
94            ),
95            0
96        );
97
98        // Simple signature
99        assert_eq!(
100            calculate_signature_fee(
101                SignatureCounts {
102                    num_transaction_signatures: 1,
103                    num_ed25519_signatures: 0,
104                    num_secp256k1_signatures: 0,
105                    num_secp256r1_signatures: 0,
106                },
107                LAMPORTS_PER_SIGNATURE,
108            ),
109            LAMPORTS_PER_SIGNATURE
110        );
111
112        // Pre-compile signatures.
113        assert_eq!(
114            calculate_signature_fee(
115                SignatureCounts {
116                    num_transaction_signatures: 1,
117                    num_ed25519_signatures: 2,
118                    num_secp256k1_signatures: 3,
119                    num_secp256r1_signatures: 4,
120                },
121                LAMPORTS_PER_SIGNATURE,
122            ),
123            10 * LAMPORTS_PER_SIGNATURE
124        );
125    }
126}