solana_sysvar/
fees.rs

1//! Current cluster fees.
2//!
3//! The _fees sysvar_ provides access to the [`Fees`] type, which contains the
4//! current [`FeeCalculator`].
5//!
6//! [`Fees`] implements [`Sysvar::get`] and can be loaded efficiently without
7//! passing the sysvar account ID to the program.
8//!
9//! This sysvar is deprecated and will not be available in the future.
10//! Transaction fees should be determined with the [`getFeeForMessage`] RPC
11//! method. For additional context see the [Comprehensive Compute Fees
12//! proposal][ccf].
13//!
14//! [`getFeeForMessage`]: https://solana.com/docs/rpc/http/getfeeformessage
15//! [ccf]: https://docs.solanalabs.com/proposals/comprehensive-compute-fees
16//!
17//! See also the Solana [documentation on the fees sysvar][sdoc].
18//!
19//! [sdoc]: https://docs.solanalabs.com/runtime/sysvars#fees
20
21#![allow(deprecated)]
22
23#[cfg(feature = "bincode")]
24use crate::SysvarSerialize;
25#[cfg(feature = "serde")]
26use serde_derive::{Deserialize, Serialize};
27pub use solana_sdk_ids::sysvar::fees::{check_id, id, ID};
28use {
29    crate::{impl_sysvar_get, Sysvar},
30    solana_fee_calculator::FeeCalculator,
31    solana_sdk_macro::CloneZeroed,
32    solana_sysvar_id::impl_deprecated_sysvar_id,
33};
34
35impl_deprecated_sysvar_id!(Fees);
36
37/// Transaction fees.
38#[deprecated(
39    since = "1.9.0",
40    note = "Please do not use, will no longer be available in the future"
41)]
42#[repr(C)]
43#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
44#[derive(Debug, CloneZeroed, Default, PartialEq, Eq)]
45pub struct Fees {
46    pub fee_calculator: FeeCalculator,
47}
48
49impl Fees {
50    pub fn new(fee_calculator: &FeeCalculator) -> Self {
51        #[allow(deprecated)]
52        Self {
53            fee_calculator: *fee_calculator,
54        }
55    }
56}
57
58impl Sysvar for Fees {
59    impl_sysvar_get!(sol_get_fees_sysvar);
60}
61
62#[cfg(feature = "bincode")]
63impl SysvarSerialize for Fees {}
64
65#[cfg(test)]
66mod tests {
67    use {super::*, serial_test::serial};
68
69    #[test]
70    fn test_clone() {
71        let fees = Fees {
72            fee_calculator: FeeCalculator {
73                lamports_per_signature: 1,
74            },
75        };
76        let cloned_fees = fees.clone();
77        assert_eq!(cloned_fees, fees);
78    }
79
80    struct MockFeesSyscall;
81    impl crate::program_stubs::SyscallStubs for MockFeesSyscall {
82        fn sol_get_fees_sysvar(&self, var_addr: *mut u8) -> u64 {
83            let fees = Fees {
84                fee_calculator: FeeCalculator {
85                    lamports_per_signature: 42,
86                },
87            };
88            unsafe {
89                std::ptr::copy_nonoverlapping(
90                    &fees as *const _ as *const u8,
91                    var_addr,
92                    core::mem::size_of::<Fees>(),
93                );
94            }
95            solana_program_entrypoint::SUCCESS
96        }
97    }
98
99    #[test]
100    #[serial]
101    fn test_fees_get_deprecated_syscall_path() {
102        let _ = crate::program_stubs::set_syscall_stubs(Box::new(MockFeesSyscall));
103        let got = Fees::get().unwrap();
104        assert_eq!(got.fee_calculator.lamports_per_signature, 42);
105    }
106
107    struct FailFeesSyscall;
108    impl crate::program_stubs::SyscallStubs for FailFeesSyscall {
109        fn sol_get_fees_sysvar(&self, _var_addr: *mut u8) -> u64 {
110            9999
111        }
112    }
113
114    #[test]
115    #[serial]
116    fn test_fees_get_deprecated_non_success_maps_to_unsupported() {
117        let prev = crate::program_stubs::set_syscall_stubs(Box::new(FailFeesSyscall));
118        let got = Fees::get();
119        assert_eq!(
120            got,
121            Err(solana_program_error::ProgramError::UnsupportedSysvar)
122        );
123        let _ = crate::program_stubs::set_syscall_stubs(prev);
124    }
125}