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}
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 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 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}