Skip to main content

dpp/balances/total_credits_balance/
mod.rs

1use crate::balances::credits::{Creditable, MAX_CREDITS};
2use crate::fee::{Credits, SignedCredits};
3use crate::ProtocolError;
4use std::fmt;
5
6/// The outcome of verifying credits
7#[derive(Copy, Clone, Debug)]
8pub struct TotalCreditsBalance {
9    /// all the credits in platform
10    pub total_credits_in_platform: Credits,
11    /// all the credits in distribution pools
12    pub total_in_pools: SignedCredits,
13    /// all the credits in identity balances
14    pub total_identity_balances: SignedCredits,
15    /// all the credits in specialized balances
16    pub total_specialized_balances: SignedCredits,
17    /// all the credits in addresses
18    pub total_in_addresses: SignedCredits,
19    /// all the credits inside shielded credit pools
20    pub total_in_shielded_balances: SignedCredits,
21}
22
23impl fmt::Display for TotalCreditsBalance {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        writeln!(f, "TotalCreditsBalance {{")?;
26        writeln!(
27            f,
28            "    total_credits_in_platform: {},",
29            self.total_credits_in_platform
30        )?;
31        writeln!(f, "    total_in_pools: {},", self.total_in_pools)?;
32        writeln!(
33            f,
34            "    total_identity_balances: {},",
35            self.total_identity_balances
36        )?;
37        writeln!(
38            f,
39            "    total_specialized_balances: {},",
40            self.total_specialized_balances
41        )?;
42        writeln!(
43            f,
44            "    total_addresses_balances: {},",
45            self.total_in_addresses
46        )?;
47        writeln!(
48            f,
49            "    total_in_shielded_balances: {}",
50            self.total_in_shielded_balances
51        )?;
52        write!(f, "}}")
53    }
54}
55
56impl TotalCreditsBalance {
57    /// Is the outcome okay? basically do the values match up
58    /// Errors in case of overflow
59    pub fn ok(&self) -> Result<bool, ProtocolError> {
60        let TotalCreditsBalance {
61            total_credits_in_platform,
62            total_in_pools,
63            total_identity_balances,
64            total_specialized_balances,
65            total_in_addresses,
66            total_in_shielded_balances,
67        } = *self;
68
69        if total_in_pools < 0 {
70            return Err(ProtocolError::CriticalCorruptedCreditsCodeExecution(
71                "Credits in distribution pools are less than 0".to_string(),
72            ));
73        }
74
75        if total_identity_balances < 0 {
76            return Err(ProtocolError::CriticalCorruptedCreditsCodeExecution(
77                "Credits of identity balances are less than 0".to_string(),
78            ));
79        }
80
81        if total_specialized_balances < 0 {
82            return Err(ProtocolError::CriticalCorruptedCreditsCodeExecution(
83                "Credits of specialized balances are less than 0".to_string(),
84            ));
85        }
86
87        if total_in_addresses < 0 {
88            return Err(ProtocolError::CriticalCorruptedCreditsCodeExecution(
89                "Credits of addresses are less than 0".to_string(),
90            ));
91        }
92
93        if total_in_shielded_balances < 0 {
94            return Err(ProtocolError::CriticalCorruptedCreditsCodeExecution(
95                "Credits inside shielded balances are less than 0".to_string(),
96            ));
97        }
98
99        if total_credits_in_platform > MAX_CREDITS {
100            return Err(ProtocolError::CriticalCorruptedCreditsCodeExecution(
101                "Total credits in platform more than max credits size".to_string(),
102            ));
103        }
104
105        let total_from_trees = (total_in_pools)
106            .checked_add(total_identity_balances)
107            .and_then(|partial_sum| partial_sum.checked_add(total_specialized_balances))
108            .and_then(|partial_sum| partial_sum.checked_add(total_in_addresses))
109            .and_then(|partial_sum| partial_sum.checked_add(total_in_shielded_balances))
110            .ok_or(ProtocolError::CriticalCorruptedCreditsCodeExecution(
111                "Overflow of total credits".to_string(),
112            ))?;
113
114        Ok(total_credits_in_platform.to_signed()? == total_from_trees)
115    }
116
117    /// Get the total in all trees
118    pub fn total_in_trees(&self) -> Result<Credits, ProtocolError> {
119        let TotalCreditsBalance {
120            total_in_pools,
121            total_identity_balances,
122            total_specialized_balances,
123            total_in_addresses,
124            total_in_shielded_balances,
125            ..
126        } = *self;
127
128        let total_in_trees = total_in_pools
129            .checked_add(total_identity_balances)
130            .and_then(|partial_sum| partial_sum.checked_add(total_specialized_balances))
131            .and_then(|partial_sum| partial_sum.checked_add(total_in_addresses))
132            .and_then(|partial_sum| partial_sum.checked_add(total_in_shielded_balances))
133            .ok_or(ProtocolError::CriticalCorruptedCreditsCodeExecution(
134                "Overflow of total credits".to_string(),
135            ))?;
136
137        Ok(total_in_trees.to_unsigned())
138    }
139}