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}
20
21impl fmt::Display for TotalCreditsBalance {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        writeln!(f, "TotalCreditsBalance {{")?;
24        writeln!(
25            f,
26            "    total_credits_in_platform: {},",
27            self.total_credits_in_platform
28        )?;
29        writeln!(f, "    total_in_pools: {},", self.total_in_pools)?;
30        writeln!(
31            f,
32            "    total_identity_balances: {},",
33            self.total_identity_balances
34        )?;
35        writeln!(
36            f,
37            "    total_specialized_balances: {}",
38            self.total_specialized_balances
39        )?;
40        writeln!(
41            f,
42            "    total_addresses_balances: {}",
43            self.total_in_addresses
44        )?;
45        write!(f, "}}")
46    }
47}
48
49impl TotalCreditsBalance {
50    /// Is the outcome okay? basically do the values match up
51    /// Errors in case of overflow
52    pub fn ok(&self) -> Result<bool, ProtocolError> {
53        let TotalCreditsBalance {
54            total_credits_in_platform,
55            total_in_pools,
56            total_identity_balances,
57            total_specialized_balances,
58            total_in_addresses,
59        } = *self;
60
61        if total_in_pools < 0 {
62            return Err(ProtocolError::CriticalCorruptedCreditsCodeExecution(
63                "Credits in distribution pools are less than 0".to_string(),
64            ));
65        }
66
67        if total_identity_balances < 0 {
68            return Err(ProtocolError::CriticalCorruptedCreditsCodeExecution(
69                "Credits of identity balances are less than 0".to_string(),
70            ));
71        }
72
73        if total_specialized_balances < 0 {
74            return Err(ProtocolError::CriticalCorruptedCreditsCodeExecution(
75                "Credits of specialized balances are less than 0".to_string(),
76            ));
77        }
78
79        if total_in_addresses < 0 {
80            return Err(ProtocolError::CriticalCorruptedCreditsCodeExecution(
81                "Credits of addresses are less than 0".to_string(),
82            ));
83        }
84
85        if total_credits_in_platform > MAX_CREDITS {
86            return Err(ProtocolError::CriticalCorruptedCreditsCodeExecution(
87                "Total credits in platform more than max credits size".to_string(),
88            ));
89        }
90
91        let total_from_trees = (total_in_pools)
92            .checked_add(total_identity_balances)
93            .and_then(|partial_sum| partial_sum.checked_add(total_specialized_balances))
94            .and_then(|partial_sum| partial_sum.checked_add(total_in_addresses))
95            .ok_or(ProtocolError::CriticalCorruptedCreditsCodeExecution(
96                "Overflow of total credits".to_string(),
97            ))?;
98
99        Ok(total_credits_in_platform.to_signed()? == total_from_trees)
100    }
101
102    /// Get the total in all trees
103    pub fn total_in_trees(&self) -> Result<Credits, ProtocolError> {
104        let TotalCreditsBalance {
105            total_in_pools,
106            total_identity_balances,
107            total_specialized_balances,
108            total_in_addresses,
109            ..
110        } = *self;
111
112        let total_in_trees = total_in_pools
113            .checked_add(total_identity_balances)
114            .and_then(|partial_sum| partial_sum.checked_add(total_specialized_balances))
115            .and_then(|partial_sum| partial_sum.checked_add(total_in_addresses))
116            .ok_or(ProtocolError::CriticalCorruptedCreditsCodeExecution(
117                "Overflow of total credits".to_string(),
118            ))?;
119
120        Ok(total_in_trees.to_unsigned())
121    }
122}