dubp_common/
currency_params.rs

1//  Copyright (C) 2020  Éloïs SANCHEZ.
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU Affero General Public License as
5// published by the Free Software Foundation, either version 3 of the
6// License, or (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11// GNU Affero General Public License for more details.
12//
13// You should have received a copy of the GNU Affero General Public License
14// along with this program.  If not, see <https://www.gnu.org/licenses/>.
15
16//! DUBP protocol currency parameters
17
18mod genesis_block_params;
19
20pub use genesis_block_params::{BlockV10Parameters, GenesisBlockParams, ParseParamsError};
21
22use crate::*;
23
24/// Default value for sig_renew_period parameter
25pub static DEFAULT_SIG_RENEW_PERIOD: &u64 = &5_259_600;
26/// Default value for ms_period parameter
27pub static DEFAULT_MS_PERIOD: &u64 = &5_259_600;
28/// Default value for tx_window parameter
29pub static DEFAULT_TX_WINDOW: &u64 = &604_800;
30/// Default maximum roolback length
31pub static DEFAULT_FORK_WINDOW_SIZE: &usize = &100;
32
33#[derive(Clone, Debug, Default, Deserialize, Serialize)]
34/// Currency name and parameters in genesis block
35pub struct CurrencyNameAndGenesisBlockParams {
36    pub currency_name: CurrencyName,
37    #[serde(rename = "currency_parameters")]
38    pub genesis_block_params: GenesisBlockParams,
39}
40
41#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Serialize)]
42/// Currency parameters
43pub struct CurrencyParameters {
44    /// Protocol version
45    pub protocol_version: usize,
46    /// UD target growth rate (see Relative Theorie of Money)
47    pub c: f64,
48    /// Duration between the creation of two UD (in seconds)
49    pub dt: u64,
50    /// Amount of the initial UD
51    pub ud0: usize,
52    /// Minimum duration between the writing of 2 certifications from the same issuer (in seconds)
53    pub sig_period: u64,
54    /// Minimum duration between two renewals of the same certification
55    pub sig_renew_period: u64,
56    /// Maximum number of active certifications at the same time (for the same issuer)
57    pub sig_stock: usize,
58    /// Maximum retention period of a pending certification
59    pub sig_window: u64,
60    /// Time to expiry of written certification
61    pub sig_validity: u64,
62    /// Minimum number of certifications required to become a member
63    pub sig_qty: usize,
64    /// Maximum retention period of a pending identity
65    pub idty_window: u64,
66    /// Maximum retention period of a pending membership
67    pub ms_window: u64,
68    /// Maximum retention period of a pending transaction
69    pub tx_window: u64,
70    /// Percentage of referring members who must be within step_max steps of each member
71    pub x_percent: f64,
72    /// Time to expiry of written membership
73    pub ms_validity: u64,
74    /// Minimum duration between the writing of 2 memberships from the same issuer (in seconds)
75    pub ms_period: u64,
76    /// For a member to respect the distance rule,
77    /// there must exist for more than x_percent % of the referring members
78    /// a path of less than step_max steps from the referring member to the evaluated member.
79    pub step_max: usize,
80    /// Number of blocks used for calculating median time.
81    pub median_time_blocks: usize,
82    /// The average time for writing 1 block (wished time)
83    pub avg_gen_time: u64,
84    /// The number of blocks required to evaluate again PoWMin value
85    pub dt_diff_eval: usize,
86    /// The percent of previous issuers to reach for personalized difficulty
87    pub percent_rot: f64,
88    /// Time of first UD.
89    pub ud_time0: u64,
90    /// Time of first reevaluation of the UD.
91    pub ud_reeval_time0: u64,
92    /// Time period between two re-evaluation of the UD.
93    pub dt_reeval: u64,
94    /// Maximum roolback length
95    pub fork_window_size: usize,
96}
97
98impl Default for CurrencyParameters {
99    fn default() -> Self {
100        Self::from((&CurrencyName::default(), BlockV10Parameters::default()))
101    }
102}
103
104impl From<CurrencyNameAndGenesisBlockParams> for CurrencyParameters {
105    fn from(currency_name_and_genesis_block_params: CurrencyNameAndGenesisBlockParams) -> Self {
106        match currency_name_and_genesis_block_params.genesis_block_params {
107            GenesisBlockParams::V10(genesis_params_v10) => CurrencyParameters::from((
108                &currency_name_and_genesis_block_params.currency_name,
109                genesis_params_v10,
110            )),
111        }
112    }
113}
114
115impl From<(&CurrencyName, BlockV10Parameters)> for CurrencyParameters {
116    fn from(source: (&CurrencyName, BlockV10Parameters)) -> CurrencyParameters {
117        let (currency_name, block_params) = source;
118        let sig_renew_period = match currency_name.0.as_str() {
119            "g1" => 5_259_600,
120            "g1-test" => 5_259_600 / 5,
121            _ => *DEFAULT_SIG_RENEW_PERIOD,
122        };
123        let ms_period = match currency_name.0.as_str() {
124            "g1" => 5_259_600,
125            "g1-test" => 5_259_600 / 5,
126            _ => *DEFAULT_MS_PERIOD,
127        };
128        let tx_window = match currency_name.0.as_str() {
129            "g1" => 604_800,
130            "g1-test" => 604_800,
131            _ => *DEFAULT_TX_WINDOW,
132        };
133        let fork_window_size = match currency_name.0.as_str() {
134            "g1" => 100,
135            "g1-test" => 100,
136            _ => *DEFAULT_FORK_WINDOW_SIZE,
137        };
138        CurrencyParameters {
139            protocol_version: 10,
140            c: block_params.c,
141            dt: block_params.dt,
142            ud0: block_params.ud0,
143            sig_period: block_params.sig_period,
144            sig_renew_period,
145            sig_stock: block_params.sig_stock,
146            sig_window: block_params.sig_window,
147            sig_validity: block_params.sig_validity,
148            sig_qty: block_params.sig_qty,
149            idty_window: block_params.idty_window,
150            ms_window: block_params.ms_window,
151            tx_window,
152            x_percent: block_params.x_percent,
153            ms_validity: block_params.ms_validity,
154            ms_period,
155            step_max: block_params.step_max,
156            median_time_blocks: block_params.median_time_blocks,
157            avg_gen_time: block_params.avg_gen_time,
158            dt_diff_eval: block_params.dt_diff_eval,
159            percent_rot: block_params.percent_rot,
160            ud_time0: block_params.ud_time0,
161            ud_reeval_time0: block_params.ud_reeval_time0,
162            dt_reeval: block_params.dt_reeval,
163            fork_window_size,
164        }
165    }
166}
167
168impl CurrencyParameters {
169    /// Get max value of connectivity (=1/x_percent)
170    pub fn max_connectivity(&self) -> f64 {
171        1.0 / self.x_percent
172    }
173}
174
175#[cfg(test)]
176mod tests {
177    use super::*;
178
179    #[test]
180    fn test_currency_params() {
181        let genesis_params = BlockV10Parameters {
182            c: 0.0488,
183            dt: 86_400,
184            ud0: 1_000,
185            sig_period: 432_000,
186            sig_stock: 100,
187            sig_window: 5_259_600,
188            sig_validity: 63_115_200,
189            sig_qty: 5,
190            idty_window: 5_259_600,
191            ms_window: 5_259_600,
192            x_percent: 0.8,
193            ms_validity: 31557600,
194            step_max: 5,
195            median_time_blocks: 24,
196            avg_gen_time: 300,
197            dt_diff_eval: 12,
198            percent_rot: 0.67,
199            ud_time0: 1_488_970_800,
200            ud_reeval_time0: 1_490_094_000,
201            dt_reeval: 15_778_800,
202        };
203
204        let currency_params_g1 =
205            CurrencyParameters::from((&CurrencyName("g1".to_owned()), genesis_params));
206
207        assert_eq!(
208            CurrencyParameters {
209                protocol_version: 10,
210                c: 0.0488,
211                dt: 86_400,
212                ud0: 1_000,
213                sig_period: 432_000,
214                sig_renew_period: 5_259_600,
215                sig_stock: 100,
216                sig_window: 5_259_600,
217                sig_validity: 63_115_200,
218                sig_qty: 5,
219                idty_window: 5_259_600,
220                ms_window: 5_259_600,
221                tx_window: 604_800,
222                x_percent: 0.8,
223                ms_validity: 31557600,
224                ms_period: 5_259_600,
225                step_max: 5,
226                median_time_blocks: 24,
227                avg_gen_time: 300,
228                dt_diff_eval: 12,
229                percent_rot: 0.67,
230                ud_time0: 1_488_970_800,
231                ud_reeval_time0: 1_490_094_000,
232                dt_reeval: 15_778_800,
233                fork_window_size: 100,
234            },
235            currency_params_g1,
236        );
237
238        let currency_params_gt =
239            CurrencyParameters::from((&CurrencyName("g1-test".to_owned()), genesis_params));
240
241        assert_eq!(
242            CurrencyParameters {
243                protocol_version: 10,
244                c: 0.0488,
245                dt: 86_400,
246                ud0: 1_000,
247                sig_period: 432_000,
248                sig_renew_period: 5_259_600 / 5,
249                sig_stock: 100,
250                sig_window: 5_259_600,
251                sig_validity: 63_115_200,
252                sig_qty: 5,
253                idty_window: 5_259_600,
254                ms_window: 5_259_600,
255                tx_window: 604_800,
256                x_percent: 0.8,
257                ms_validity: 31557600,
258                ms_period: 5_259_600 / 5,
259                step_max: 5,
260                median_time_blocks: 24,
261                avg_gen_time: 300,
262                dt_diff_eval: 12,
263                percent_rot: 0.67,
264                ud_time0: 1_488_970_800,
265                ud_reeval_time0: 1_490_094_000,
266                dt_reeval: 15_778_800,
267                fork_window_size: 100,
268            },
269            currency_params_gt,
270        );
271
272        let currency_params_default =
273            CurrencyParameters::from((&CurrencyName(DEFAULT_CURRENCY.to_owned()), genesis_params));
274
275        assert_eq!(
276            CurrencyParameters {
277                protocol_version: 10,
278                c: 0.0488,
279                dt: 86_400,
280                ud0: 1_000,
281                sig_period: 432_000,
282                sig_renew_period: *DEFAULT_SIG_RENEW_PERIOD,
283                sig_stock: 100,
284                sig_window: 5_259_600,
285                sig_validity: 63_115_200,
286                sig_qty: 5,
287                idty_window: 5_259_600,
288                ms_window: 5_259_600,
289                tx_window: *DEFAULT_TX_WINDOW,
290                x_percent: 0.8,
291                ms_validity: 31557600,
292                ms_period: *DEFAULT_MS_PERIOD,
293                step_max: 5,
294                median_time_blocks: 24,
295                avg_gen_time: 300,
296                dt_diff_eval: 12,
297                percent_rot: 0.67,
298                ud_time0: 1_488_970_800,
299                ud_reeval_time0: 1_490_094_000,
300                dt_reeval: 15_778_800,
301                fork_window_size: *DEFAULT_FORK_WINDOW_SIZE,
302            },
303            currency_params_default,
304        );
305    }
306}