casper_types/chainspec/
fee_handling.rs

1#[cfg(feature = "datasize")]
2use datasize::DataSize;
3use serde::{Deserialize, Serialize};
4
5use crate::bytesrepr::{self, FromBytes, ToBytes};
6
7const FEE_HANDLING_PROPOSER_TAG: u8 = 0;
8const FEE_HANDLING_ACCUMULATE_TAG: u8 = 1;
9const FEE_HANDLING_BURN_TAG: u8 = 2;
10const FEE_HANDLING_NONE_TAG: u8 = 3;
11
12/// Defines how fees are handled in the system.
13#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
14#[serde(tag = "type", rename_all = "snake_case")]
15#[cfg_attr(feature = "datasize", derive(DataSize))]
16pub enum FeeHandling {
17    /// Transaction fees are paid to the block proposer.
18    ///
19    /// This is the default option for public chains.
20    PayToProposer,
21    /// Transaction fees are accumulated in a special purse and then distributed during end of era
22    /// processing evenly among all administrator accounts.
23    ///
24    /// This setting is applicable for some private chains (but not all).
25    Accumulate,
26    /// Burn the fees.
27    Burn,
28    /// No fees.
29    // in 1.x the (implicit) default was PayToProposer
30    // FeeHandling::PayToProposer
31    // in 2.x the default is NoFee as there are no fees.
32    #[default]
33    NoFee,
34}
35
36impl FeeHandling {
37    /// Is the Accumulate variant selected?
38    pub fn is_accumulate(&self) -> bool {
39        matches!(self, FeeHandling::Accumulate)
40    }
41
42    /// Returns true if configured for no fees.
43    pub fn is_no_fee(&self) -> bool {
44        matches!(self, FeeHandling::NoFee)
45    }
46}
47
48impl ToBytes for FeeHandling {
49    fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
50        match self {
51            FeeHandling::PayToProposer => Ok(vec![FEE_HANDLING_PROPOSER_TAG]),
52            FeeHandling::Accumulate => Ok(vec![FEE_HANDLING_ACCUMULATE_TAG]),
53            FeeHandling::Burn => Ok(vec![FEE_HANDLING_BURN_TAG]),
54            FeeHandling::NoFee => Ok(vec![FEE_HANDLING_NONE_TAG]),
55        }
56    }
57
58    fn serialized_length(&self) -> usize {
59        1
60    }
61}
62
63impl FromBytes for FeeHandling {
64    fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
65        let (tag, rem) = u8::from_bytes(bytes)?;
66        match tag {
67            FEE_HANDLING_PROPOSER_TAG => Ok((FeeHandling::PayToProposer, rem)),
68            FEE_HANDLING_ACCUMULATE_TAG => Ok((FeeHandling::Accumulate, rem)),
69            FEE_HANDLING_BURN_TAG => Ok((FeeHandling::Burn, rem)),
70            FEE_HANDLING_NONE_TAG => Ok((FeeHandling::NoFee, rem)),
71            _ => Err(bytesrepr::Error::Formatting),
72        }
73    }
74}
75
76#[cfg(test)]
77mod tests {
78    use super::*;
79
80    #[test]
81    fn bytesrepr_roundtrip_for_refund() {
82        let fee_config = FeeHandling::PayToProposer;
83        bytesrepr::test_serialization_roundtrip(&fee_config);
84    }
85
86    #[test]
87    fn bytesrepr_roundtrip_for_accumulate() {
88        let fee_config = FeeHandling::Accumulate;
89        bytesrepr::test_serialization_roundtrip(&fee_config);
90    }
91
92    #[test]
93    fn bytesrepr_roundtrip_for_burn() {
94        let fee_config = FeeHandling::Burn;
95        bytesrepr::test_serialization_roundtrip(&fee_config);
96    }
97
98    #[test]
99    fn bytesrepr_roundtrip_for_no_fee() {
100        let fee_config = FeeHandling::NoFee;
101        bytesrepr::test_serialization_roundtrip(&fee_config);
102    }
103}