1use crate::fee::epoch::{EpochIndex, SignedCreditsPerEpoch, PERPETUAL_STORAGE_ERAS};
40use rust_decimal::prelude::*;
41use rust_decimal::Decimal;
42use rust_decimal_macros::dec;
43use std::cmp::Ordering;
44
45use crate::balances::credits::Credits;
46use crate::ProtocolError;
47use std::ops::Mul;
48
49#[rustfmt::skip]
53pub const FEE_DISTRIBUTION_TABLE: [Decimal; PERPETUAL_STORAGE_ERAS as usize] = [
54 dec!(0.05000), dec!(0.04800), dec!(0.04600), dec!(0.04400), dec!(0.04200),
55 dec!(0.04000), dec!(0.03850), dec!(0.03700), dec!(0.03550), dec!(0.03400),
56 dec!(0.03250), dec!(0.03100), dec!(0.02950), dec!(0.02850), dec!(0.02750),
57 dec!(0.02650), dec!(0.02550), dec!(0.02450), dec!(0.02350), dec!(0.02250),
58 dec!(0.02150), dec!(0.02050), dec!(0.01950), dec!(0.01875), dec!(0.01800),
59 dec!(0.01725), dec!(0.01650), dec!(0.01575), dec!(0.01500), dec!(0.01425),
60 dec!(0.01350), dec!(0.01275), dec!(0.01200), dec!(0.01125), dec!(0.01050),
61 dec!(0.00975), dec!(0.00900), dec!(0.00825), dec!(0.00750), dec!(0.00675),
62 dec!(0.00600), dec!(0.00525), dec!(0.00475), dec!(0.00425), dec!(0.00375),
63 dec!(0.00325), dec!(0.00275), dec!(0.00225), dec!(0.00175), dec!(0.00125),
64];
65
66type DistributionAmount = Credits;
67type DistributionLeftovers = Credits;
68
69pub fn distribute_storage_fee_to_epochs_collection(
71 credits_per_epochs: &mut SignedCreditsPerEpoch,
72 storage_fee: Credits,
73 start_epoch_index: EpochIndex,
74 epochs_per_era: u16,
75) -> Result<DistributionLeftovers, ProtocolError> {
76 distribution_storage_fee_to_epochs_map(
77 storage_fee,
78 start_epoch_index,
79 |epoch_index, epoch_fee_share| {
80 let epoch_credits = credits_per_epochs.entry(epoch_index).or_default();
81
82 *epoch_credits = epoch_credits
83 .checked_add_unsigned(epoch_fee_share)
84 .ok_or_else(|| {
85 ProtocolError::Overflow(
86 "updated epoch credits are not fitting to credits max size",
87 )
88 })?;
89
90 Ok(())
91 },
92 epochs_per_era,
93 )
94}
95
96pub fn subtract_refunds_from_epoch_credits_collection(
99 credits_per_epochs: &mut SignedCreditsPerEpoch,
100 storage_fee: Credits,
101 start_epoch_index: EpochIndex,
102 current_epoch_index: EpochIndex,
103 epochs_per_era: u16,
104) -> Result<(), ProtocolError> {
105 let leftovers = refund_storage_fee_to_epochs_map(
106 storage_fee,
107 start_epoch_index,
108 current_epoch_index + 1,
109 |epoch_index, epoch_fee_share| {
110 let epoch_credits = credits_per_epochs.entry(epoch_index).or_default();
111
112 *epoch_credits = epoch_credits
113 .checked_sub_unsigned(epoch_fee_share)
114 .ok_or_else(|| {
115 ProtocolError::Overflow(
116 "updated epoch credits are not fitting to credits min size",
117 )
118 })?;
119
120 Ok(())
121 },
122 epochs_per_era,
123 )?;
124
125 if leftovers > 0 {
127 let epoch_credits = credits_per_epochs.entry(current_epoch_index).or_default();
128
129 *epoch_credits = epoch_credits
130 .checked_sub_unsigned(leftovers)
131 .ok_or_else(|| {
132 ProtocolError::Overflow("updated epoch credits are not fitting to credits min size")
133 })?;
134 }
135
136 Ok(())
137}
138
139pub fn calculate_storage_fee_refund_amount_and_leftovers(
141 storage_fee: Credits,
142 start_epoch_index: EpochIndex,
143 current_epoch_index: EpochIndex,
144 epochs_per_era: u16,
145) -> Result<(DistributionAmount, DistributionLeftovers), ProtocolError> {
146 let mut skipped_amount = 0;
147
148 let leftovers = distribution_storage_fee_to_epochs_map(
149 storage_fee,
150 start_epoch_index,
151 |epoch_index, epoch_fee_share| {
152 if epoch_index < current_epoch_index + 1 {
153 skipped_amount += epoch_fee_share;
154 }
155
156 Ok(())
157 },
158 epochs_per_era,
159 )?;
160
161 Ok((storage_fee - skipped_amount - leftovers, leftovers))
162}
163
164fn original_removed_credits_multiplier_from(
165 start_epoch_index: EpochIndex,
166 start_repayment_from_epoch_index: EpochIndex,
167 epochs_per_era: u16,
168) -> Decimal {
169 let paid_epochs = start_repayment_from_epoch_index - start_epoch_index;
170
171 let current_era = (paid_epochs / epochs_per_era) as usize;
172
173 let ratio_used: Decimal =
174 FEE_DISTRIBUTION_TABLE
175 .iter()
176 .enumerate()
177 .filter_map(|(era, epoch_multiplier)| match era.cmp(¤t_era) {
178 Ordering::Less => None,
179 Ordering::Equal => {
180 let amount_epochs_left_in_era = epochs_per_era - paid_epochs % epochs_per_era;
181 Some(epoch_multiplier.mul(
182 Decimal::from(amount_epochs_left_in_era) / Decimal::from(epochs_per_era),
183 ))
184 }
185 Ordering::Greater => Some(*epoch_multiplier),
186 })
187 .sum();
188
189 dec!(1) / ratio_used
190}
191
192fn restore_original_removed_credits_amount(
197 refund_amount: Decimal,
198 start_epoch_index: EpochIndex,
199 start_repayment_from_epoch_index: EpochIndex,
200 epochs_per_era: u16,
201) -> Result<Decimal, ProtocolError> {
202 let multiplier = original_removed_credits_multiplier_from(
203 start_epoch_index,
204 start_repayment_from_epoch_index,
205 epochs_per_era,
206 );
207
208 refund_amount
209 .checked_mul(multiplier)
210 .ok_or(ProtocolError::Overflow(
211 "overflow when multiplying with the multiplier (this should be impossible)",
212 ))
213}
214
215fn distribution_storage_fee_to_epochs_map<F>(
218 storage_fee: Credits,
219 start_epoch_index: EpochIndex,
220 mut map_function: F,
221 epochs_per_era: u16,
222) -> Result<DistributionLeftovers, ProtocolError>
223where
224 F: FnMut(EpochIndex, Credits) -> Result<(), ProtocolError>,
225{
226 if storage_fee == 0 {
227 return Ok(0);
228 }
229
230 let storage_fee_dec: Decimal = storage_fee.into();
231
232 let mut distribution_leftover_credits = storage_fee;
233
234 let epochs_per_era_dec = Decimal::from(epochs_per_era);
235
236 for era in 0..PERPETUAL_STORAGE_ERAS {
237 let distribution_for_that_era_ratio = FEE_DISTRIBUTION_TABLE[era as usize];
238
239 let era_fee_share = storage_fee_dec * distribution_for_that_era_ratio;
240
241 let epoch_fee_share_dec = era_fee_share / epochs_per_era_dec;
242
243 let epoch_fee_share: Credits = epoch_fee_share_dec
244 .floor()
245 .to_u64()
246 .ok_or_else(|| ProtocolError::Overflow("storage fees are not fitting in a u64"))?;
247
248 let era_start_epoch_index = start_epoch_index + epochs_per_era * era;
249
250 for epoch_index in era_start_epoch_index..era_start_epoch_index + epochs_per_era {
251 map_function(epoch_index, epoch_fee_share)?;
253
254 distribution_leftover_credits = distribution_leftover_credits
255 .checked_sub(epoch_fee_share)
256 .ok_or(ProtocolError::Overflow(
257 "leftovers bigger than initial value",
258 ))?;
259 }
260 }
261
262 Ok(distribution_leftover_credits)
263}
264
265fn refund_storage_fee_to_epochs_map<F>(
269 storage_fee: Credits,
270 start_epoch_index: EpochIndex,
271 skip_until_epoch_index: EpochIndex,
272 mut map_function: F,
273 epochs_per_era: u16,
274) -> Result<DistributionLeftovers, ProtocolError>
275where
276 F: FnMut(EpochIndex, Credits) -> Result<(), ProtocolError>,
277{
278 if storage_fee == 0 {
279 return Ok(0);
280 }
281
282 let storage_fee_dec: Decimal = storage_fee.into();
283
284 let mut distribution_leftover_credits = storage_fee;
285
286 let epochs_per_era_dec = Decimal::from(epochs_per_era);
287
288 let start_era: u16 = (skip_until_epoch_index - start_epoch_index) / epochs_per_era;
289
290 let estimated_storage_fee_dec = restore_original_removed_credits_amount(
295 storage_fee_dec,
296 start_epoch_index,
297 skip_until_epoch_index,
298 epochs_per_era,
299 )?;
300
301 for era in start_era..PERPETUAL_STORAGE_ERAS {
302 let distribution_for_that_era_ratio = FEE_DISTRIBUTION_TABLE[era as usize];
303
304 let estimated_era_fee_share = estimated_storage_fee_dec * distribution_for_that_era_ratio;
305
306 let estimated_epoch_fee_share_dec = estimated_era_fee_share / epochs_per_era_dec;
307
308 let estimated_epoch_fee_share: Credits = estimated_epoch_fee_share_dec
309 .floor()
310 .to_u64()
311 .ok_or_else(|| ProtocolError::Overflow("storage fees are not fitting in a u64"))?;
312
313 let era_start_epoch_index = if era == start_era {
314 skip_until_epoch_index
315 } else {
316 start_epoch_index + epochs_per_era * era
317 };
318
319 let era_end_epoch_index = start_epoch_index + ((era + 1) * epochs_per_era);
320
321 for epoch_index in era_start_epoch_index..era_end_epoch_index {
322 map_function(epoch_index, estimated_epoch_fee_share)?;
323
324 distribution_leftover_credits = distribution_leftover_credits
325 .checked_sub(estimated_epoch_fee_share)
326 .ok_or(ProtocolError::Overflow(
327 "leftovers bigger than initial value",
328 ))?;
329 }
330 }
331 Ok(distribution_leftover_credits)
332}
333
334#[cfg(test)]
335mod tests {
336 use super::*;
337 use crate::fee::epoch::GENESIS_EPOCH_INDEX;
338 use rust_decimal::Decimal;
339 use rust_decimal_macros::dec;
340
341 mod original_removed_credits_multiplier_from {
342 use super::*;
343
344 #[test]
345 fn should_create_multiplier_for_epochs_since_the_beginning() {
346 let epoch_0_cost = dec!(0.05000) / dec!(20.0);
348 let multiplier_should_be = dec!(1.0) / (dec!(1.0) - epoch_0_cost);
349
350 let multiplier = original_removed_credits_multiplier_from(0, 1, 20);
351
352 assert_eq!(multiplier_should_be, multiplier);
353 }
354
355 #[test]
356 fn should_create_multiplier_for_epochs_since_24_and_repaid_since_43() {
357 let epoch_0_cost = dec!(19.0) * dec!(0.05000) / dec!(20.0);
359
360 let multiplier_should_be = dec!(1.0) / (dec!(1.0) - epoch_0_cost);
361
362 let multiplier = original_removed_credits_multiplier_from(24, 43, 20);
363
364 assert_eq!(multiplier_should_be, multiplier);
365 }
366 }
367
368 mod fee_distribution_table {
369 use super::*;
370
371 #[test]
372 fn should_have_sum_of_1() {
373 assert_eq!(FEE_DISTRIBUTION_TABLE.iter().sum::<Decimal>(), dec!(1.0),);
374 }
375
376 #[test]
377 fn should_distribute_value() {
378 let value = Decimal::from(i64::MAX);
379
380 let calculated_value: Decimal = FEE_DISTRIBUTION_TABLE
381 .into_iter()
382 .map(|ratio| value * ratio)
383 .sum();
384
385 assert_eq!(calculated_value, value);
386 }
387 }
388
389 mod distribution_storage_fee_to_epochs_map {
390 use super::*;
391
392 #[test]
393 fn should_distribute_nothing_if_storage_fees_are_zero() {
394 let mut calls = 0;
395
396 let leftovers = distribution_storage_fee_to_epochs_map(
397 0,
398 GENESIS_EPOCH_INDEX,
399 |_, _| {
400 calls += 1;
401
402 Ok(())
403 },
404 20,
405 )
406 .expect("should distribute storage fee");
407
408 assert_eq!(calls, 0);
409 assert_eq!(leftovers, 0);
410 }
411
412 #[test]
413 fn should_call_function_for_each_epoch_for_50_eras_sequentially() {
414 let mut calls = 0;
415
416 let mut previous_epoch_index = -1;
417
418 let leftovers = distribution_storage_fee_to_epochs_map(
419 100000,
420 GENESIS_EPOCH_INDEX,
421 |epoch_index, _| {
422 assert_eq!(epoch_index as i32, previous_epoch_index + 1);
423 previous_epoch_index = epoch_index as i32;
424
425 calls += 1;
426
427 Ok(())
428 },
429 20,
430 )
431 .expect("should distribute storage fee");
432
433 assert_eq!(calls, 1000); assert_eq!(leftovers, 360);
435 }
436 }
437
438 mod distribute_storage_fee_to_epochs_collection {
439 use super::*;
440 use crate::balances::credits::{Creditable, MAX_CREDITS};
441 use crate::fee::SignedCredits;
442
443 #[test]
444 fn should_distribute_max_credits_value_without_overflow() {
445 let storage_fee = MAX_CREDITS;
446
447 let mut credits_per_epochs = SignedCreditsPerEpoch::default();
448
449 let leftovers = distribute_storage_fee_to_epochs_collection(
450 &mut credits_per_epochs,
451 storage_fee,
452 GENESIS_EPOCH_INDEX,
453 20,
454 )
455 .expect("should distribute storage fee");
456
457 assert_eq!(leftovers, 507);
459 }
460
461 #[test]
462 fn should_deterministically_distribute_fees() {
463 let storage_fee = 1000000;
464 let current_epoch_index = 42;
465
466 let mut credits_per_epochs = SignedCreditsPerEpoch::default();
467
468 let leftovers = distribute_storage_fee_to_epochs_collection(
469 &mut credits_per_epochs,
470 storage_fee,
471 current_epoch_index,
472 20,
473 )
474 .expect("should distribute storage fee");
475
476 assert_eq!(leftovers, 180);
478
479 #[rustfmt::skip]
481 let reference_fees: [SignedCredits; 1000] = [
482 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500,
483 2500, 2500, 2500, 2500, 2500, 2500, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
484 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2300, 2300,
485 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300, 2300,
486 2300, 2300, 2300, 2300, 2200, 2200, 2200, 2200, 2200, 2200, 2200, 2200, 2200, 2200,
487 2200, 2200, 2200, 2200, 2200, 2200, 2200, 2200, 2200, 2200, 2100, 2100, 2100, 2100,
488 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100, 2100,
489 2100, 2100, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000,
490 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 1925, 1925, 1925, 1925, 1925, 1925,
491 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925, 1925,
492 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850, 1850,
493 1850, 1850, 1850, 1850, 1850, 1850, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775,
494 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1775, 1700, 1700,
495 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700, 1700,
496 1700, 1700, 1700, 1700, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625,
497 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1625, 1550, 1550, 1550, 1550,
498 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550,
499 1550, 1550, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475,
500 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1475, 1425, 1425, 1425, 1425, 1425, 1425,
501 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425,
502 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375, 1375,
503 1375, 1375, 1375, 1375, 1375, 1375, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325,
504 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1275, 1275,
505 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275, 1275,
506 1275, 1275, 1275, 1275, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225,
507 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1175, 1175, 1175, 1175,
508 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175, 1175,
509 1175, 1175, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125,
510 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1075, 1075, 1075, 1075, 1075, 1075,
511 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075,
512 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025, 1025,
513 1025, 1025, 1025, 1025, 1025, 1025, 975, 975, 975, 975, 975, 975, 975, 975, 975,
514 975, 975, 975, 975, 975, 975, 975, 975, 975, 975, 975, 937, 937, 937, 937, 937,
515 937, 937, 937, 937, 937, 937, 937, 937, 937, 937, 937, 937, 937, 937, 937, 900,
516 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900,
517 900, 900, 900, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862, 862,
518 862, 862, 862, 862, 862, 862, 862, 825, 825, 825, 825, 825, 825, 825, 825, 825,
519 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, 825, 787, 787, 787, 787, 787,
520 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 787, 750,
521 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, 750,
522 750, 750, 750, 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 712, 712,
523 712, 712, 712, 712, 712, 712, 712, 675, 675, 675, 675, 675, 675, 675, 675, 675,
524 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 675, 637, 637, 637, 637, 637,
525 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 637, 600,
526 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
527 600, 600, 600, 562, 562, 562, 562, 562, 562, 562, 562, 562, 562, 562, 562, 562,
528 562, 562, 562, 562, 562, 562, 562, 525, 525, 525, 525, 525, 525, 525, 525, 525,
529 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 487, 487, 487, 487, 487,
530 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, 450,
531 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, 450,
532 450, 450, 450, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
533 412, 412, 412, 412, 412, 412, 412, 375, 375, 375, 375, 375, 375, 375, 375, 375,
534 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 337, 337, 337, 337, 337,
535 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 337, 300,
536 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
537 300, 300, 300, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
538 262, 262, 262, 262, 262, 262, 262, 237, 237, 237, 237, 237, 237, 237, 237, 237,
539 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 212, 212, 212, 212, 212,
540 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 187,
541 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
542 187, 187, 187, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162,
543 162, 162, 162, 162, 162, 162, 162, 137, 137, 137, 137, 137, 137, 137, 137, 137,
544 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 112, 112, 112, 112, 112,
545 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 87,
546 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 62,
547 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62
548 ];
549
550 assert_eq!(
551 credits_per_epochs.clone().into_values().collect::<Vec<_>>(),
552 reference_fees
553 );
554
555 let total_distributed: SignedCredits = credits_per_epochs.values().sum();
556
557 assert_eq!(total_distributed.to_unsigned() + leftovers, storage_fee);
558
559 let leftovers = distribute_storage_fee_to_epochs_collection(
566 &mut credits_per_epochs,
567 storage_fee,
568 current_epoch_index,
569 20,
570 )
571 .expect("should distribute storage fee");
572
573 assert_eq!(
575 credits_per_epochs.into_values().collect::<Vec<_>>(),
576 reference_fees
577 .into_iter()
578 .map(|val| val * 2)
579 .collect::<Vec<_>>()
580 );
581
582 assert_eq!(leftovers, 180);
583 }
584 }
585
586 mod subtract_refunds_from_epoch_credits_collection {
587 use super::*;
588 use crate::balances::credits::Creditable;
589 use crate::fee::SignedCredits;
590
591 #[test]
592 fn should_deduct_refunds_from_collection_since_specific_epoch_start_at_genesis() {
593 let start_epoch_index: EpochIndex = GENESIS_EPOCH_INDEX;
599 const REFUNDED_EPOCH_INDEX: EpochIndex = 42;
600 let original_storage_fee = 1200005;
601
602 let (refund_amount, leftovers) = calculate_storage_fee_refund_amount_and_leftovers(
603 original_storage_fee,
604 start_epoch_index,
605 REFUNDED_EPOCH_INDEX,
606 20,
607 )
608 .expect("should distribute storage fee");
609
610 assert_eq!(refund_amount, 1074120);
611 assert_eq!(leftovers, 5);
612
613 let mut credits_per_epochs = SignedCreditsPerEpoch::default();
614
615 subtract_refunds_from_epoch_credits_collection(
616 &mut credits_per_epochs,
617 refund_amount,
618 start_epoch_index,
619 REFUNDED_EPOCH_INDEX,
620 20,
621 )
622 .expect("should distribute storage fee");
623
624 #[rustfmt::skip]
628 let reference_fees: [SignedCredits;
629 (1000 - REFUNDED_EPOCH_INDEX - 1) as usize] = [-2760, -2760, -2760,
630 -2760, -2760, -2760, -2760, -2760, -2760, -2760, -2760, -2760, -2760, -2760, -2760,
631 -2760, -2760, -2640, -2640, -2640, -2640, -2640, -2640, -2640, -2640, -2640, -2640,
632 -2640, -2640, -2640, -2640, -2640, -2640, -2640, -2640, -2640, -2640, -2520, -2520,
633 -2520, -2520, -2520, -2520, -2520, -2520, -2520, -2520, -2520, -2520, -2520, -2520,
634 -2520, -2520, -2520, -2520, -2520, -2520, -2400, -2400, -2400, -2400, -2400, -2400,
635 -2400, -2400, -2400, -2400, -2400, -2400, -2400, -2400, -2400, -2400, -2400, -2400,
636 -2400, -2400, -2310, -2310, -2310, -2310, -2310, -2310, -2310, -2310, -2310, -2310,
637 -2310, -2310, -2310, -2310, -2310, -2310, -2310, -2310, -2310, -2310, -2220, -2220,
638 -2220, -2220, -2220, -2220, -2220, -2220, -2220, -2220, -2220, -2220, -2220, -2220,
639 -2220, -2220, -2220, -2220, -2220, -2220, -2130, -2130, -2130, -2130, -2130, -2130,
640 -2130, -2130, -2130, -2130, -2130, -2130, -2130, -2130, -2130, -2130, -2130, -2130,
641 -2130, -2130, -2040, -2040, -2040, -2040, -2040, -2040, -2040, -2040, -2040, -2040,
642 -2040, -2040, -2040, -2040, -2040, -2040, -2040, -2040, -2040, -2040, -1950, -1950,
643 -1950, -1950, -1950, -1950, -1950, -1950, -1950, -1950, -1950, -1950, -1950, -1950,
644 -1950, -1950, -1950, -1950, -1950, -1950, -1860, -1860, -1860, -1860, -1860, -1860,
645 -1860, -1860, -1860, -1860, -1860, -1860, -1860, -1860, -1860, -1860, -1860, -1860,
646 -1860, -1860, -1770, -1770, -1770, -1770, -1770, -1770, -1770, -1770, -1770, -1770,
647 -1770, -1770, -1770, -1770, -1770, -1770, -1770, -1770, -1770, -1770, -1710, -1710,
648 -1710, -1710, -1710, -1710, -1710, -1710, -1710, -1710, -1710, -1710, -1710, -1710,
649 -1710, -1710, -1710, -1710, -1710, -1710, -1650, -1650, -1650, -1650, -1650, -1650,
650 -1650, -1650, -1650, -1650, -1650, -1650, -1650, -1650, -1650, -1650, -1650, -1650,
651 -1650, -1650, -1590, -1590, -1590, -1590, -1590, -1590, -1590, -1590, -1590, -1590,
652 -1590, -1590, -1590, -1590, -1590, -1590, -1590, -1590, -1590, -1590, -1530, -1530,
653 -1530, -1530, -1530, -1530, -1530, -1530, -1530, -1530, -1530, -1530, -1530, -1530,
654 -1530, -1530, -1530, -1530, -1530, -1530, -1470, -1470, -1470, -1470, -1470, -1470,
655 -1470, -1470, -1470, -1470, -1470, -1470, -1470, -1470, -1470, -1470, -1470, -1470,
656 -1470, -1470, -1410, -1410, -1410, -1410, -1410, -1410, -1410, -1410, -1410, -1410,
657 -1410, -1410, -1410, -1410, -1410, -1410, -1410, -1410, -1410, -1410, -1350, -1350,
658 -1350, -1350, -1350, -1350, -1350, -1350, -1350, -1350, -1350, -1350, -1350, -1350,
659 -1350, -1350, -1350, -1350, -1350, -1350, -1290, -1290, -1290, -1290, -1290, -1290,
660 -1290, -1290, -1290, -1290, -1290, -1290, -1290, -1290, -1290, -1290, -1290, -1290,
661 -1290, -1290, -1230, -1230, -1230, -1230, -1230, -1230, -1230, -1230, -1230, -1230,
662 -1230, -1230, -1230, -1230, -1230, -1230, -1230, -1230, -1230, -1230, -1170, -1170,
663 -1170, -1170, -1170, -1170, -1170, -1170, -1170, -1170, -1170, -1170, -1170, -1170,
664 -1170, -1170, -1170, -1170, -1170, -1170, -1125, -1125, -1125, -1125, -1125, -1125,
665 -1125, -1125, -1125, -1125, -1125, -1125, -1125, -1125, -1125, -1125, -1125, -1125,
666 -1125, -1125, -1080, -1080, -1080, -1080, -1080, -1080, -1080, -1080, -1080, -1080,
667 -1080, -1080, -1080, -1080, -1080, -1080, -1080, -1080, -1080, -1080, -1035, -1035,
668 -1035, -1035, -1035, -1035, -1035, -1035, -1035, -1035, -1035, -1035, -1035, -1035,
669 -1035, -1035, -1035, -1035, -1035, -1035, -990, -990, -990, -990, -990, -990, -990,
670 -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -990, -945,
671 -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945, -945,
672 -945, -945, -945, -945, -945, -900, -900, -900, -900, -900, -900, -900, -900, -900,
673 -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -900, -855, -855, -855,
674 -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855, -855,
675 -855, -855, -855, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810, -810,
676 -810, -810, -810, -810, -810, -810, -810, -810, -810, -765, -765, -765, -765, -765,
677 -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765, -765,
678 -765, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, -720,
679 -720, -720, -720, -720, -720, -720, -720, -675, -675, -675, -675, -675, -675, -675,
680 -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -675, -630,
681 -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630, -630,
682 -630, -630, -630, -630, -630, -585, -585, -585, -585, -585, -585, -585, -585, -585,
683 -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -585, -540, -540, -540,
684 -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, -540,
685 -540, -540, -540, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495, -495,
686 -495, -495, -495, -495, -495, -495, -495, -495, -495, -450, -450, -450, -450, -450,
687 -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450, -450,
688 -450, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405, -405,
689 -405, -405, -405, -405, -405, -405, -405, -360, -360, -360, -360, -360, -360, -360,
690 -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -360, -315,
691 -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315, -315,
692 -315, -315, -315, -315, -315, -285, -285, -285, -285, -285, -285, -285, -285, -285,
693 -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -285, -255, -255, -255,
694 -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255,
695 -255, -255, -255, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225, -225,
696 -225, -225, -225, -225, -225, -225, -225, -225, -225, -195, -195, -195, -195, -195,
697 -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195, -195,
698 -195, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165, -165,
699 -165, -165, -165, -165, -165, -165, -165, -135, -135, -135, -135, -135, -135, -135,
700 -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -135, -105,
701 -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, -105,
702 -105, -105, -105, -105, -105, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75, -75,
703 -75, -75, -75, -75, -75, -75, -75, -75, -75];
704
705 assert_eq!(
706 credits_per_epochs.clone().into_values().collect::<Vec<_>>(),
707 reference_fees
708 );
709
710 let total_distributed: SignedCredits = credits_per_epochs.values().sum();
711
712 assert_eq!(total_distributed.to_unsigned(), refund_amount);
713 }
714
715 #[test]
716 fn should_deduct_refunds_from_collection_start_epoch_doesnt_matter_check() {
717 for start_epoch_index in 0..150 {
718 let current_epoch_index_where_refund_occurred: EpochIndex = start_epoch_index + 14;
719
720 let original_storage_fee = 3405507;
721 let (refund_amount, leftovers) = calculate_storage_fee_refund_amount_and_leftovers(
722 original_storage_fee,
723 start_epoch_index,
724 current_epoch_index_where_refund_occurred,
725 20,
726 )
727 .expect("should distribute storage fee");
728
729 assert_eq!(refund_amount, 3277305);
730 assert_eq!(leftovers, 507);
731
732 let multiplier = original_removed_credits_multiplier_from(
733 start_epoch_index,
734 current_epoch_index_where_refund_occurred + 1,
735 20,
736 );
737
738 assert!(
743 (Decimal::from(refund_amount) * multiplier)
744 .abs_sub(&Decimal::from(original_storage_fee - leftovers))
745 < dec!(100)
746 );
747
748 assert!(
750 (Decimal::from(refund_amount) * multiplier)
751 < Decimal::from(original_storage_fee - leftovers)
752 );
753
754 let mut credits_per_epochs = SignedCreditsPerEpoch::default();
755
756 subtract_refunds_from_epoch_credits_collection(
757 &mut credits_per_epochs,
758 refund_amount,
759 start_epoch_index,
760 current_epoch_index_where_refund_occurred,
761 20,
762 )
763 .expect("should distribute storage fee");
764 #[rustfmt::skip]
768 let reference_fees: Vec<SignedCredits> =
769 vec![-525, -8512, -8512, -8512, -8512, -8512, -8171, -8171, -8171, -8171, -8171, -8171,
770 -8171, -8171, -8171, -8171, -8171, -8171, -8171, -8171, -8171, -8171, -8171,
771 -8171, -8171, -8171, -7831, -7831, -7831, -7831, -7831, -7831, -7831, -7831,
772 -7831, -7831, -7831, -7831, -7831, -7831, -7831, -7831, -7831, -7831, -7831,
773 -7831, -7490, -7490, -7490, -7490, -7490, -7490, -7490, -7490, -7490, -7490,
774 -7490, -7490, -7490, -7490, -7490, -7490, -7490, -7490, -7490, -7490, -7150,
775 -7150, -7150, -7150, -7150, -7150, -7150, -7150, -7150, -7150, -7150, -7150,
776 -7150, -7150, -7150, -7150, -7150, -7150, -7150, -7150, -6809, -6809, -6809,
777 -6809, -6809, -6809, -6809, -6809, -6809, -6809, -6809, -6809, -6809, -6809,
778 -6809, -6809, -6809, -6809, -6809, -6809, -6554, -6554, -6554, -6554, -6554,
779 -6554, -6554, -6554, -6554, -6554, -6554, -6554, -6554, -6554, -6554, -6554,
780 -6554, -6554, -6554, -6554, -6299, -6299, -6299, -6299, -6299, -6299, -6299,
781 -6299, -6299, -6299, -6299, -6299, -6299, -6299, -6299, -6299, -6299, -6299,
782 -6299, -6299, -6043, -6043, -6043, -6043, -6043, -6043, -6043, -6043, -6043,
783 -6043, -6043, -6043, -6043, -6043, -6043, -6043, -6043, -6043, -6043, -6043,
784 -5788, -5788, -5788, -5788, -5788, -5788, -5788, -5788, -5788, -5788, -5788,
785 -5788, -5788, -5788, -5788, -5788, -5788, -5788, -5788, -5788, -5533, -5533,
786 -5533, -5533, -5533, -5533, -5533, -5533, -5533, -5533, -5533, -5533, -5533,
787 -5533, -5533, -5533, -5533, -5533, -5533, -5533, -5277, -5277, -5277, -5277,
788 -5277, -5277, -5277, -5277, -5277, -5277, -5277, -5277, -5277, -5277, -5277,
789 -5277, -5277, -5277, -5277, -5277, -5022, -5022, -5022, -5022, -5022, -5022,
790 -5022, -5022, -5022, -5022, -5022, -5022, -5022, -5022, -5022, -5022, -5022,
791 -5022, -5022, -5022, -4852, -4852, -4852, -4852, -4852, -4852, -4852, -4852,
792 -4852, -4852, -4852, -4852, -4852, -4852, -4852, -4852, -4852, -4852, -4852,
793 -4852, -4681, -4681, -4681, -4681, -4681, -4681, -4681, -4681, -4681, -4681,
794 -4681, -4681, -4681, -4681, -4681, -4681, -4681, -4681, -4681, -4681, -4511,
795 -4511, -4511, -4511, -4511, -4511, -4511, -4511, -4511, -4511, -4511, -4511,
796 -4511, -4511, -4511, -4511, -4511, -4511, -4511, -4511, -4341, -4341, -4341,
797 -4341, -4341, -4341, -4341, -4341, -4341, -4341, -4341, -4341, -4341, -4341,
798 -4341, -4341, -4341, -4341, -4341, -4341, -4171, -4171, -4171, -4171, -4171,
799 -4171, -4171, -4171, -4171, -4171, -4171, -4171, -4171, -4171, -4171, -4171,
800 -4171, -4171, -4171, -4171, -4000, -4000, -4000, -4000, -4000, -4000, -4000,
801 -4000, -4000, -4000, -4000, -4000, -4000, -4000, -4000, -4000, -4000, -4000,
802 -4000, -4000, -3830, -3830, -3830, -3830, -3830, -3830, -3830, -3830, -3830,
803 -3830, -3830, -3830, -3830, -3830, -3830, -3830, -3830, -3830, -3830, -3830,
804 -3660, -3660, -3660, -3660, -3660, -3660, -3660, -3660, -3660, -3660, -3660,
805 -3660, -3660, -3660, -3660, -3660, -3660, -3660, -3660, -3660, -3490, -3490,
806 -3490, -3490, -3490, -3490, -3490, -3490, -3490, -3490, -3490, -3490, -3490,
807 -3490, -3490, -3490, -3490, -3490, -3490, -3490, -3319, -3319, -3319, -3319,
808 -3319, -3319, -3319, -3319, -3319, -3319, -3319, -3319, -3319, -3319, -3319,
809 -3319, -3319, -3319, -3319, -3319, -3192, -3192, -3192, -3192, -3192, -3192,
810 -3192, -3192, -3192, -3192, -3192, -3192, -3192, -3192, -3192, -3192, -3192,
811 -3192, -3192, -3192, -3064, -3064, -3064, -3064, -3064, -3064, -3064, -3064,
812 -3064, -3064, -3064, -3064, -3064, -3064, -3064, -3064, -3064, -3064, -3064,
813 -3064, -2936, -2936, -2936, -2936, -2936, -2936, -2936, -2936, -2936, -2936,
814 -2936, -2936, -2936, -2936, -2936, -2936, -2936, -2936, -2936, -2936, -2809,
815 -2809, -2809, -2809, -2809, -2809, -2809, -2809, -2809, -2809, -2809, -2809,
816 -2809, -2809, -2809, -2809, -2809, -2809, -2809, -2809, -2681, -2681, -2681,
817 -2681, -2681, -2681, -2681, -2681, -2681, -2681, -2681, -2681, -2681, -2681,
818 -2681, -2681, -2681, -2681, -2681, -2681, -2553, -2553, -2553, -2553, -2553,
819 -2553, -2553, -2553, -2553, -2553, -2553, -2553, -2553, -2553, -2553, -2553,
820 -2553, -2553, -2553, -2553, -2426, -2426, -2426, -2426, -2426, -2426, -2426,
821 -2426, -2426, -2426, -2426, -2426, -2426, -2426, -2426, -2426, -2426, -2426,
822 -2426, -2426, -2298, -2298, -2298, -2298, -2298, -2298, -2298, -2298, -2298,
823 -2298, -2298, -2298, -2298, -2298, -2298, -2298, -2298, -2298, -2298, -2298,
824 -2170, -2170, -2170, -2170, -2170, -2170, -2170, -2170, -2170, -2170, -2170,
825 -2170, -2170, -2170, -2170, -2170, -2170, -2170, -2170, -2170, -2042, -2042,
826 -2042, -2042, -2042, -2042, -2042, -2042, -2042, -2042, -2042, -2042, -2042,
827 -2042, -2042, -2042, -2042, -2042, -2042, -2042, -1915, -1915, -1915, -1915,
828 -1915, -1915, -1915, -1915, -1915, -1915, -1915, -1915, -1915, -1915, -1915,
829 -1915, -1915, -1915, -1915, -1915, -1787, -1787, -1787, -1787, -1787, -1787,
830 -1787, -1787, -1787, -1787, -1787, -1787, -1787, -1787, -1787, -1787, -1787,
831 -1787, -1787, -1787, -1659, -1659, -1659, -1659, -1659, -1659, -1659, -1659,
832 -1659, -1659, -1659, -1659, -1659, -1659, -1659, -1659, -1659, -1659, -1659,
833 -1659, -1532, -1532, -1532, -1532, -1532, -1532, -1532, -1532, -1532, -1532,
834 -1532, -1532, -1532, -1532, -1532, -1532, -1532, -1532, -1532, -1532, -1404,
835 -1404, -1404, -1404, -1404, -1404, -1404, -1404, -1404, -1404, -1404, -1404,
836 -1404, -1404, -1404, -1404, -1404, -1404, -1404, -1404, -1276, -1276, -1276,
837 -1276, -1276, -1276, -1276, -1276, -1276, -1276, -1276, -1276, -1276, -1276,
838 -1276, -1276, -1276, -1276, -1276, -1276, -1149, -1149, -1149, -1149, -1149,
839 -1149, -1149, -1149, -1149, -1149, -1149, -1149, -1149, -1149, -1149, -1149,
840 -1149, -1149, -1149, -1149, -1021, -1021, -1021, -1021, -1021, -1021, -1021,
841 -1021, -1021, -1021, -1021, -1021, -1021, -1021, -1021, -1021, -1021, -1021,
842 -1021, -1021, -893, -893, -893, -893, -893, -893, -893, -893, -893, -893,
843 -893, -893, -893, -893, -893, -893, -893, -893, -893, -893, -808, -808, -808,
844 -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808, -808,
845 -808, -808, -808, -808, -723, -723, -723, -723, -723, -723, -723, -723, -723,
846 -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, -638, -638,
847 -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638, -638,
848 -638, -638, -638, -638, -638, -553, -553, -553, -553, -553, -553, -553, -553,
849 -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -553, -468,
850 -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468, -468,
851 -468, -468, -468, -468, -468, -468, -383, -383, -383, -383, -383, -383, -383,
852 -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383, -383,
853 -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, -297,
854 -297, -297, -297, -297, -297, -297, -297, -212, -212, -212, -212, -212, -212,
855 -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212,
856 -212];
857
858 assert_eq!(
859 credits_per_epochs.clone().into_values().collect::<Vec<_>>(),
860 reference_fees
861 );
862
863 let total_distributed: SignedCredits = credits_per_epochs.values().sum();
864
865 assert_eq!(total_distributed.to_unsigned(), refund_amount);
866 }
867 }
868
869 #[test]
870 fn should_deduct_refunds_from_two_collection_since_specific_epoch() {
871 const CURRENT_EPOCH_INDEX_WHERE_REFUND_OCCURRED: EpochIndex = 42;
872 let mut credits_per_epochs = SignedCreditsPerEpoch::default();
873
874 let first_start_epoch_index: EpochIndex = GENESIS_EPOCH_INDEX;
882
883 let first_original_storage_fee = 1200005;
884 let (first_refund_amount, leftovers) =
885 calculate_storage_fee_refund_amount_and_leftovers(
886 first_original_storage_fee,
887 first_start_epoch_index,
888 CURRENT_EPOCH_INDEX_WHERE_REFUND_OCCURRED,
889 20,
890 )
891 .expect("should distribute storage fee");
892
893 assert_eq!(first_refund_amount, 1074120);
894 assert_eq!(leftovers, 5);
895
896 subtract_refunds_from_epoch_credits_collection(
897 &mut credits_per_epochs,
898 first_refund_amount,
899 first_start_epoch_index,
900 CURRENT_EPOCH_INDEX_WHERE_REFUND_OCCURRED,
901 20,
902 )
903 .expect("should distribute storage fee");
904
905 const SECOND_START_EPOCH_INDEX: EpochIndex = 28;
912
913 let second_original_storage_fee = 3405507;
914 let (second_refund_amount, leftovers) =
915 calculate_storage_fee_refund_amount_and_leftovers(
916 second_original_storage_fee,
917 SECOND_START_EPOCH_INDEX,
918 CURRENT_EPOCH_INDEX_WHERE_REFUND_OCCURRED,
919 20,
920 )
921 .expect("should distribute storage fee");
922
923 assert_eq!(second_refund_amount, 3277305);
924 assert_eq!(leftovers, 507);
925
926 let multiplier = original_removed_credits_multiplier_from(
927 SECOND_START_EPOCH_INDEX,
928 CURRENT_EPOCH_INDEX_WHERE_REFUND_OCCURRED + 1,
929 20,
930 );
931
932 assert!(
937 (Decimal::from(second_refund_amount) * multiplier)
938 .abs_sub(&Decimal::from(second_original_storage_fee - leftovers))
939 < dec!(100)
940 );
941
942 assert!(
944 (Decimal::from(second_refund_amount) * multiplier)
945 < Decimal::from(second_original_storage_fee - leftovers)
946 );
947
948 subtract_refunds_from_epoch_credits_collection(
949 &mut credits_per_epochs,
950 second_refund_amount,
951 SECOND_START_EPOCH_INDEX,
952 CURRENT_EPOCH_INDEX_WHERE_REFUND_OCCURRED,
953 20,
954 )
955 .expect("should distribute storage fee");
956 #[rustfmt::skip]
960 let reference_fees: [SignedCredits;
961 (SECOND_START_EPOCH_INDEX + 1000 - CURRENT_EPOCH_INDEX_WHERE_REFUND_OCCURRED) as usize] =
962 [-525, -11272, -11272, -11272, -11272, -11272, -10931, -10931, -10931, -10931,
963 -10931, -10931, -10931, -10931, -10931, -10931, -10931, -10931, -10811, -10811,
964 -10811, -10811, -10811, -10811, -10811, -10811, -10471, -10471, -10471, -10471,
965 -10471, -10471, -10471, -10471, -10471, -10471, -10471, -10471, -10351, -10351,
966 -10351, -10351, -10351, -10351, -10351, -10351, -10010, -10010, -10010, -10010,
967 -10010, -10010, -10010, -10010, -10010, -10010, -10010, -10010, -9890, -9890,
968 -9890, -9890, -9890, -9890, -9890, -9890, -9550, -9550, -9550, -9550, -9550,
969 -9550, -9550, -9550, -9550, -9550, -9550, -9550, -9460, -9460, -9460, -9460,
970 -9460, -9460, -9460, -9460, -9119, -9119, -9119, -9119, -9119, -9119, -9119,
971 -9119, -9119, -9119, -9119, -9119, -9029, -9029, -9029, -9029, -9029, -9029,
972 -9029, -9029, -8774, -8774, -8774, -8774, -8774, -8774, -8774, -8774, -8774,
973 -8774, -8774, -8774, -8684, -8684, -8684, -8684, -8684, -8684, -8684, -8684,
974 -8429, -8429, -8429, -8429, -8429, -8429, -8429, -8429, -8429, -8429, -8429,
975 -8429, -8339, -8339, -8339, -8339, -8339, -8339, -8339, -8339, -8083, -8083,
976 -8083, -8083, -8083, -8083, -8083, -8083, -8083, -8083, -8083, -8083, -7993,
977 -7993, -7993, -7993, -7993, -7993, -7993, -7993, -7738, -7738, -7738, -7738,
978 -7738, -7738, -7738, -7738, -7738, -7738, -7738, -7738, -7648, -7648, -7648,
979 -7648, -7648, -7648, -7648, -7648, -7393, -7393, -7393, -7393, -7393, -7393,
980 -7393, -7393, -7393, -7393, -7393, -7393, -7303, -7303, -7303, -7303, -7303,
981 -7303, -7303, -7303, -7047, -7047, -7047, -7047, -7047, -7047, -7047, -7047,
982 -7047, -7047, -7047, -7047, -6987, -6987, -6987, -6987, -6987, -6987, -6987,
983 -6987, -6732, -6732, -6732, -6732, -6732, -6732, -6732, -6732, -6732, -6732,
984 -6732, -6732, -6672, -6672, -6672, -6672, -6672, -6672, -6672, -6672, -6502,
985 -6502, -6502, -6502, -6502, -6502, -6502, -6502, -6502, -6502, -6502, -6502,
986 -6442, -6442, -6442, -6442, -6442, -6442, -6442, -6442, -6271, -6271, -6271,
987 -6271, -6271, -6271, -6271, -6271, -6271, -6271, -6271, -6271, -6211, -6211,
988 -6211, -6211, -6211, -6211, -6211, -6211, -6041, -6041, -6041, -6041, -6041,
989 -6041, -6041, -6041, -6041, -6041, -6041, -6041, -5981, -5981, -5981, -5981,
990 -5981, -5981, -5981, -5981, -5811, -5811, -5811, -5811, -5811, -5811, -5811,
991 -5811, -5811, -5811, -5811, -5811, -5751, -5751, -5751, -5751, -5751, -5751,
992 -5751, -5751, -5581, -5581, -5581, -5581, -5581, -5581, -5581, -5581, -5581,
993 -5581, -5581, -5581, -5521, -5521, -5521, -5521, -5521, -5521, -5521, -5521,
994 -5350, -5350, -5350, -5350, -5350, -5350, -5350, -5350, -5350, -5350, -5350,
995 -5350, -5290, -5290, -5290, -5290, -5290, -5290, -5290, -5290, -5120, -5120,
996 -5120, -5120, -5120, -5120, -5120, -5120, -5120, -5120, -5120, -5120, -5060,
997 -5060, -5060, -5060, -5060, -5060, -5060, -5060, -4890, -4890, -4890, -4890,
998 -4890, -4890, -4890, -4890, -4890, -4890, -4890, -4890, -4830, -4830, -4830,
999 -4830, -4830, -4830, -4830, -4830, -4660, -4660, -4660, -4660, -4660, -4660,
1000 -4660, -4660, -4660, -4660, -4660, -4660, -4615, -4615, -4615, -4615, -4615,
1001 -4615, -4615, -4615, -4444, -4444, -4444, -4444, -4444, -4444, -4444, -4444,
1002 -4444, -4444, -4444, -4444, -4399, -4399, -4399, -4399, -4399, -4399, -4399,
1003 -4399, -4272, -4272, -4272, -4272, -4272, -4272, -4272, -4272, -4272, -4272,
1004 -4272, -4272, -4227, -4227, -4227, -4227, -4227, -4227, -4227, -4227, -4099,
1005 -4099, -4099, -4099, -4099, -4099, -4099, -4099, -4099, -4099, -4099, -4099,
1006 -4054, -4054, -4054, -4054, -4054, -4054, -4054, -4054, -3926, -3926, -3926,
1007 -3926, -3926, -3926, -3926, -3926, -3926, -3926, -3926, -3926, -3881, -3881,
1008 -3881, -3881, -3881, -3881, -3881, -3881, -3754, -3754, -3754, -3754, -3754,
1009 -3754, -3754, -3754, -3754, -3754, -3754, -3754, -3709, -3709, -3709, -3709,
1010 -3709, -3709, -3709, -3709, -3581, -3581, -3581, -3581, -3581, -3581, -3581,
1011 -3581, -3581, -3581, -3581, -3581, -3536, -3536, -3536, -3536, -3536, -3536,
1012 -3536, -3536, -3408, -3408, -3408, -3408, -3408, -3408, -3408, -3408, -3408,
1013 -3408, -3408, -3408, -3363, -3363, -3363, -3363, -3363, -3363, -3363, -3363,
1014 -3236, -3236, -3236, -3236, -3236, -3236, -3236, -3236, -3236, -3236, -3236,
1015 -3236, -3191, -3191, -3191, -3191, -3191, -3191, -3191, -3191, -3063, -3063,
1016 -3063, -3063, -3063, -3063, -3063, -3063, -3063, -3063, -3063, -3063, -3018,
1017 -3018, -3018, -3018, -3018, -3018, -3018, -3018, -2890, -2890, -2890, -2890,
1018 -2890, -2890, -2890, -2890, -2890, -2890, -2890, -2890, -2845, -2845, -2845,
1019 -2845, -2845, -2845, -2845, -2845, -2717, -2717, -2717, -2717, -2717, -2717,
1020 -2717, -2717, -2717, -2717, -2717, -2717, -2672, -2672, -2672, -2672, -2672,
1021 -2672, -2672, -2672, -2545, -2545, -2545, -2545, -2545, -2545, -2545, -2545,
1022 -2545, -2545, -2545, -2545, -2500, -2500, -2500, -2500, -2500, -2500, -2500,
1023 -2500, -2372, -2372, -2372, -2372, -2372, -2372, -2372, -2372, -2372, -2372,
1024 -2372, -2372, -2327, -2327, -2327, -2327, -2327, -2327, -2327, -2327, -2199,
1025 -2199, -2199, -2199, -2199, -2199, -2199, -2199, -2199, -2199, -2199, -2199,
1026 -2154, -2154, -2154, -2154, -2154, -2154, -2154, -2154, -2027, -2027, -2027,
1027 -2027, -2027, -2027, -2027, -2027, -2027, -2027, -2027, -2027, -1982, -1982,
1028 -1982, -1982, -1982, -1982, -1982, -1982, -1854, -1854, -1854, -1854, -1854,
1029 -1854, -1854, -1854, -1854, -1854, -1854, -1854, -1809, -1809, -1809, -1809,
1030 -1809, -1809, -1809, -1809, -1681, -1681, -1681, -1681, -1681, -1681, -1681,
1031 -1681, -1681, -1681, -1681, -1681, -1636, -1636, -1636, -1636, -1636, -1636,
1032 -1636, -1636, -1509, -1509, -1509, -1509, -1509, -1509, -1509, -1509, -1509,
1033 -1509, -1509, -1509, -1464, -1464, -1464, -1464, -1464, -1464, -1464, -1464,
1034 -1336, -1336, -1336, -1336, -1336, -1336, -1336, -1336, -1336, -1336, -1336,
1035 -1336, -1306, -1306, -1306, -1306, -1306, -1306, -1306, -1306, -1178, -1178,
1036 -1178, -1178, -1178, -1178, -1178, -1178, -1178, -1178, -1178, -1178, -1148,
1037 -1148, -1148, -1148, -1148, -1148, -1148, -1148, -1063, -1063, -1063, -1063,
1038 -1063, -1063, -1063, -1063, -1063, -1063, -1063, -1063, -1033, -1033, -1033,
1039 -1033, -1033, -1033, -1033, -1033, -948, -948, -948, -948, -948, -948, -948,
1040 -948, -948, -948, -948, -948, -918, -918, -918, -918, -918, -918, -918, -918,
1041 -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -833, -803,
1042 -803, -803, -803, -803, -803, -803, -803, -718, -718, -718, -718, -718, -718,
1043 -718, -718, -718, -718, -718, -718, -688, -688, -688, -688, -688, -688, -688,
1044 -688, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603, -603,
1045 -573, -573, -573, -573, -573, -573, -573, -573, -488, -488, -488, -488, -488,
1046 -488, -488, -488, -488, -488, -488, -488, -458, -458, -458, -458, -458, -458,
1047 -458, -458, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372, -372,
1048 -372, -297, -297, -297, -297, -297, -297, -297, -297, -212, -212, -212, -212,
1049 -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212, -212,
1050 -212, -212, -212];
1051
1052 assert_eq!(
1053 credits_per_epochs.clone().into_values().collect::<Vec<_>>(),
1054 reference_fees
1055 );
1056
1057 let total_distributed: SignedCredits = credits_per_epochs.values().sum();
1058
1059 assert_eq!(
1060 total_distributed.to_unsigned(),
1061 first_refund_amount + second_refund_amount
1062 );
1063 }
1064 }
1065
1066 mod calculate_storage_fee_refund_amount_and_leftovers {
1067 use super::*;
1068
1069 #[test]
1070 fn should_calculate_amount_and_leftovers() {
1071 let storage_fee = 10000;
1072
1073 let (amount, leftovers) = calculate_storage_fee_refund_amount_and_leftovers(
1074 storage_fee,
1075 GENESIS_EPOCH_INDEX + 1,
1076 2,
1077 20,
1078 )
1079 .expect("should distribute storage fee");
1080
1081 let first_two_epochs_amount = 50;
1082
1083 assert_eq!(leftovers, 400);
1084 assert_eq!(amount, storage_fee - leftovers - first_two_epochs_amount);
1085 }
1086 }
1087}