casper_storage/data_access_layer/
fee.rs

1use std::collections::BTreeSet;
2use thiserror::Error;
3
4use crate::system::{
5    runtime_native::{Config as NativeRuntimeConfig, TransferConfig},
6    transfer::TransferError,
7};
8use casper_types::{
9    account::AccountHash, execution::Effects, BlockTime, Digest, FeeHandling, ProtocolVersion,
10    Transfer,
11};
12
13use crate::tracking_copy::TrackingCopyError;
14
15/// Fee request.
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct FeeRequest {
18    config: NativeRuntimeConfig,
19    state_hash: Digest,
20    protocol_version: ProtocolVersion,
21    block_time: BlockTime,
22}
23
24impl FeeRequest {
25    /// Ctor.
26    pub fn new(
27        config: NativeRuntimeConfig,
28        state_hash: Digest,
29        protocol_version: ProtocolVersion,
30        block_time: BlockTime,
31    ) -> Self {
32        FeeRequest {
33            config,
34            state_hash,
35            protocol_version,
36            block_time,
37        }
38    }
39
40    /// Returns config.
41    pub fn config(&self) -> &NativeRuntimeConfig {
42        &self.config
43    }
44
45    /// Returns state_hash.
46    pub fn state_hash(&self) -> Digest {
47        self.state_hash
48    }
49
50    /// Returns protocol_version.
51    pub fn protocol_version(&self) -> ProtocolVersion {
52        self.protocol_version
53    }
54
55    /// Returns fee handling setting.
56    pub fn fee_handling(&self) -> &FeeHandling {
57        self.config.fee_handling()
58    }
59
60    /// Returns block time.
61    pub fn block_time(&self) -> BlockTime {
62        self.block_time
63    }
64
65    /// Returns administrative accounts, if any.
66    pub fn administrative_accounts(&self) -> Option<&BTreeSet<AccountHash>> {
67        match self.config.transfer_config() {
68            TransferConfig::Administered {
69                administrative_accounts,
70                ..
71            } => Some(administrative_accounts),
72            TransferConfig::Unadministered => None,
73        }
74    }
75
76    /// Should we attempt to distribute fees?
77    pub fn should_distribute_fees(&self) -> bool {
78        // we only distribute if chainspec FeeHandling == Accumulate
79        // and if there are administrative accounts to receive the fees.
80        // the various public networks do not use this option.
81        if !self.fee_handling().is_accumulate() {
82            return false;
83        }
84
85        matches!(
86            self.config.transfer_config(),
87            TransferConfig::Administered { .. }
88        )
89    }
90}
91
92/// Fee error.
93#[derive(Clone, Error, Debug)]
94pub enum FeeError {
95    /// No fees distributed error.
96    #[error("Undistributed fees")]
97    NoFeesDistributed,
98    /// Tracking copy error.
99    #[error(transparent)]
100    TrackingCopy(TrackingCopyError),
101    /// Registry entry not found.
102    #[error("Registry entry not found: {0}")]
103    RegistryEntryNotFound(String),
104    /// Transfer error.
105    #[error(transparent)]
106    Transfer(TransferError),
107    /// Named keys not found.
108    #[error("Named keys not found")]
109    NamedKeysNotFound,
110    /// Administrative accounts not found.
111    #[error("Administrative accounts not found")]
112    AdministrativeAccountsNotFound,
113}
114
115/// Fee result.
116#[derive(Debug, Clone)]
117pub enum FeeResult {
118    /// Root not found in global state.
119    RootNotFound,
120    /// Failure result.
121    Failure(FeeError),
122    /// Success result.
123    Success {
124        /// List of transfers that happened during execution.
125        transfers: Vec<Transfer>,
126        /// State hash after fee distribution outcome is committed to the global state.
127        post_state_hash: Digest,
128        /// Effects of the fee distribution process.
129        effects: Effects,
130    },
131}
132
133impl FeeResult {
134    /// Returns true if successful, else false.
135    pub fn is_success(&self) -> bool {
136        matches!(self, FeeResult::Success { .. })
137    }
138}