saito_core/core/consensus/
burnfee.rs1use std::cmp::max;
2
3use log::debug;
4
5use crate::core::defs::{Currency, Timestamp};
6
7pub struct BurnFee {}
26
27impl BurnFee {
28 pub fn return_routing_work_needed_to_produce_block_in_nolan(
39 burn_fee_previous_block: Currency,
40 current_block_timestamp_in_ms: Timestamp,
41 previous_block_timestamp_in_ms: Timestamp,
42 heartbeat: Timestamp,
43 ) -> Currency {
44 if previous_block_timestamp_in_ms >= current_block_timestamp_in_ms {
47 return 10_000_000_000_000_000_000;
48 }
49
50 let elapsed_time = max(
51 current_block_timestamp_in_ms - previous_block_timestamp_in_ms,
52 1,
53 );
54
55 if elapsed_time >= (2 * heartbeat) {
56 return 0;
57 }
58
59 let elapsed_time_float = elapsed_time as f64;
61 let burn_fee_previous_block_as_float: f64 = burn_fee_previous_block as f64 / 100_000_000.0;
62 let work_needed_float: f64 = burn_fee_previous_block_as_float / elapsed_time_float;
63
64 (work_needed_float * 100_000_000.0).round() as Currency
66 }
67
68 pub fn calculate_burnfee_for_block(
77 burn_fee_previous_block: Currency,
78 current_block_timestamp_in_ms: Timestamp,
79 previous_block_timestamp_in_ms: Timestamp,
80 heartbeat: Timestamp,
81 ) -> Currency {
82 debug!("calculate burnfee : previous block burn fee = {:?} current timestamp = {:?} prev block timestamp : {:?}",
83 burn_fee_previous_block, current_block_timestamp_in_ms, previous_block_timestamp_in_ms);
84 if previous_block_timestamp_in_ms >= current_block_timestamp_in_ms {
86 return 10_000_000_000_000_000_000;
87 }
88 let timestamp_difference = max(
89 1,
90 current_block_timestamp_in_ms - previous_block_timestamp_in_ms,
91 );
92
93 if burn_fee_previous_block == 0 {
95 return 50_000_000;
96 }
97
98 let burn_fee_previous_block_as_float: f64 = burn_fee_previous_block as f64 / 100_000_000.0;
99
100 let res0 = heartbeat as f64 / timestamp_difference as f64;
101 let res1 = res0.sqrt();
102 let res2: f64 = burn_fee_previous_block_as_float * res1;
103 let new_burnfee: Currency = (res2 * 100_000_000.0).round() as Currency;
104
105 new_burnfee
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use crate::core::defs::Currency;
112
113 use super::*;
114
115 #[test]
116 fn burnfee_return_work_needed_test() {
117 assert_eq!(
119 BurnFee::return_routing_work_needed_to_produce_block_in_nolan(10, 2 * 2_000, 0, 1_000),
120 0
121 );
122
123 assert_eq!(
125 BurnFee::return_routing_work_needed_to_produce_block_in_nolan(
126 10_0000_0000,
127 0,
128 0,
129 1_000
130 ),
131 10_000_000_000_000_000_000,
132 );
133 }
134
135 #[test]
136 fn burnfee_burn_fee_adjustment_test() {
137 let mut new_start_burnfee =
139 BurnFee::calculate_burnfee_for_block(100_000_000, 1_000, 0, 1_000);
140 assert_eq!(new_start_burnfee, 100_000_000);
141
142 new_start_burnfee = BurnFee::calculate_burnfee_for_block(100_000_000, 1_000 / 10, 0, 1_000);
144 assert_eq!(
145 new_start_burnfee,
146 (100_000_000.0 * 10f64.sqrt()).round() as Currency
147 );
148 }
149
150 #[test]
151 fn burnfee_slr_match() {
152 let burn_fee_previous_block = 50000000;
153 let current_block_timestamp: Timestamp = 1658821423;
154 let previous_block_timestamp: Timestamp = 1658821412;
155
156 let burnfee = BurnFee::calculate_burnfee_for_block(
157 burn_fee_previous_block,
158 current_block_timestamp,
159 previous_block_timestamp,
160 100,
161 );
162 assert_eq!(burnfee, 150755672);
163 }
164}