dpp/balances/total_credits_balance/
mod.rs1use crate::balances::credits::{Creditable, MAX_CREDITS};
2use crate::fee::{Credits, SignedCredits};
3use crate::ProtocolError;
4use std::fmt;
5
6#[derive(Copy, Clone, Debug)]
8pub struct TotalCreditsBalance {
9 pub total_credits_in_platform: Credits,
11 pub total_in_pools: SignedCredits,
13 pub total_identity_balances: SignedCredits,
15 pub total_specialized_balances: SignedCredits,
17 pub total_in_addresses: SignedCredits,
19 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 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 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}