1use num::rational::Ratio;
6
7#[derive(Debug, Clone, PartialEq, PartialOrd)]
9pub struct ProtocolParameters {
10 fee_per_byte: u64,
12
13 fee_constant: u64,
15
16 price_mem: f64,
18
19 price_cpu: f64,
21
22 collateral_coefficient: f64,
24
25 referenced_scripts_base_fee_per_byte: u64,
27
28 referenced_scripts_fee_multiplier: Ratio<u64>,
33
34 referenced_scripts_fee_step_size: u64,
39
40 plutus_v3_cost_model: PlutusV3CostModel,
42
43 start_time: u64,
45
46 first_shelley_slot: u64,
48}
49
50type PlutusV3CostModel = Vec<i64>;
51
52impl Default for ProtocolParameters {
55 fn default() -> Self {
56 Self {
57 fee_per_byte: 0,
58 fee_constant: 0,
59 price_mem: 0.0,
60 price_cpu: 0.0,
61 collateral_coefficient: 0.0,
62 referenced_scripts_base_fee_per_byte: 0,
63 referenced_scripts_fee_multiplier: Ratio::ONE,
64 referenced_scripts_fee_step_size: 0,
65 plutus_v3_cost_model: vec![],
66 start_time: 0,
67 first_shelley_slot: 0,
68 }
69 }
70}
71
72impl ProtocolParameters {
73 pub fn mainnet() -> Self {
78 Self::default()
79 .with_fee_per_byte(44)
80 .with_fee_constant(155381)
81 .with_collateral_coefficient(1.5)
82 .with_referenced_scripts_base_fee_per_byte(15)
83 .with_referenced_scripts_fee_multiplier(Ratio::new(12, 10))
84 .with_referenced_scripts_fee_step_size(25000)
85 .with_execution_price_mem(0.0577)
86 .with_execution_price_cpu(7.21e-05)
87 .with_start_time(1506203091)
88 .with_first_shelley_slot(4492800)
89 .with_plutus_v3_cost_model(vec![
90 100788, 420, 1, 1, 1000, 173, 0, 1, 1000, 59957, 4, 1, 11183, 32, 201305, 8356, 4,
91 16000, 100, 16000, 100, 16000, 100, 16000, 100, 16000, 100, 16000, 100, 100, 100,
92 16000, 100, 94375, 32, 132994, 32, 61462, 4, 72010, 178, 0, 1, 22151, 32, 91189,
93 769, 4, 2, 85848, 123203, 7305, -900, 1716, 549, 57, 85848, 0, 1, 1, 1000, 42921,
94 4, 2, 24548, 29498, 38, 1, 898148, 27279, 1, 51775, 558, 1, 39184, 1000, 60594, 1,
95 141895, 32, 83150, 32, 15299, 32, 76049, 1, 13169, 4, 22100, 10, 28999, 74, 1,
96 28999, 74, 1, 43285, 552, 1, 44749, 541, 1, 33852, 32, 68246, 32, 72362, 32, 7243,
97 32, 7391, 32, 11546, 32, 85848, 123203, 7305, -900, 1716, 549, 57, 85848, 0, 1,
98 90434, 519, 0, 1, 74433, 32, 85848, 123203, 7305, -900, 1716, 549, 57, 85848, 0, 1,
99 1, 85848, 123203, 7305, -900, 1716, 549, 57, 85848, 0, 1, 955506, 213312, 0, 2,
100 270652, 22588, 4, 1457325, 64566, 4, 20467, 1, 4, 0, 141992, 32, 100788, 420, 1, 1,
101 81663, 32, 59498, 32, 20142, 32, 24588, 32, 20744, 32, 25933, 32, 24623, 32,
102 43053543, 10, 53384111, 14333, 10, 43574283, 26308, 10, 16000, 100, 16000, 100,
103 962335, 18, 2780678, 6, 442008, 1, 52538055, 3756, 18, 267929, 18, 76433006, 8868,
104 18, 52948122, 18, 1995836, 36, 3227919, 12, 901022, 1, 166917843, 4307, 36, 284546,
105 36, 158221314, 26549, 36, 74698472, 36, 333849714, 1, 254006273, 72, 2174038, 72,
106 2261318, 64571, 4, 207616, 8310, 4, 1293828, 28716, 63, 0, 1, 1006041, 43623, 251,
107 0, 1, 100181, 726, 719, 0, 1, 100181, 726, 719, 0, 1, 100181, 726, 719, 0, 1,
108 107878, 680, 0, 1, 95336, 1, 281145, 18848, 0, 1, 180194, 159, 1, 1, 158519, 8942,
109 0, 1, 159378, 8813, 0, 1, 107490, 3298, 1, 106057, 655, 1, 1964219, 24520, 3,
110 ])
111 }
112
113 pub fn preprod() -> Self {
118 Self::mainnet()
119 .with_start_time(1654041600)
120 .with_first_shelley_slot(86400)
121 }
122
123 pub fn preview() -> Self {
130 Self::mainnet()
131 .with_start_time(1666656000)
132 .with_first_shelley_slot(0)
133 }
134
135 pub fn posix_to_slot(&self, posix: std::time::Duration) -> u64 {
137 let delta = posix.as_secs() - self.start_time;
138
139 let byron_duration = 20 * self.first_shelley_slot;
140 let since_shelley_duration = delta - byron_duration;
141
142 self.first_shelley_slot + since_shelley_duration
143 }
144
145 pub fn with_fee_per_byte(mut self, fee_per_byte: u64) -> Self {
147 self.fee_per_byte = fee_per_byte;
148 self
149 }
150
151 pub fn with_fee_constant(mut self, fee_constant: u64) -> Self {
153 self.fee_constant = fee_constant;
154 self
155 }
156
157 pub fn with_collateral_coefficient(mut self, collateral_coefficient: f64) -> Self {
159 self.collateral_coefficient = collateral_coefficient;
160 self
161 }
162
163 pub fn with_referenced_scripts_base_fee_per_byte(
165 mut self,
166 referenced_scripts_base_fee_per_byte: u64,
167 ) -> Self {
168 self.referenced_scripts_base_fee_per_byte = referenced_scripts_base_fee_per_byte;
169 self
170 }
171
172 pub fn with_referenced_scripts_fee_multiplier(
174 mut self,
175 referenced_scripts_fee_multiplier: Ratio<u64>,
176 ) -> Self {
177 self.referenced_scripts_fee_multiplier = referenced_scripts_fee_multiplier;
178 self
179 }
180
181 pub fn with_referenced_scripts_fee_step_size(
183 mut self,
184 referenced_scripts_fee_step_size: u64,
185 ) -> Self {
186 self.referenced_scripts_fee_step_size = referenced_scripts_fee_step_size;
187 self
188 }
189
190 pub fn with_execution_price_mem(mut self, price_mem: f64) -> Self {
192 self.price_mem = price_mem;
193 self
194 }
195
196 pub fn with_execution_price_cpu(mut self, price_cpu: f64) -> Self {
198 self.price_cpu = price_cpu;
199 self
200 }
201
202 pub fn with_start_time(mut self, start_time: u64) -> Self {
204 self.start_time = start_time;
205 self
206 }
207
208 pub fn with_first_shelley_slot(mut self, first_shelley_slot: u64) -> Self {
210 self.first_shelley_slot = first_shelley_slot;
211 self
212 }
213
214 pub fn with_plutus_v3_cost_model(mut self, cost_model: PlutusV3CostModel) -> Self {
216 self.plutus_v3_cost_model = cost_model;
217 self
218 }
219}
220
221impl ProtocolParameters {
224 pub fn base_fee(&self, size: u64) -> u64 {
226 size * self.fee_per_byte + self.fee_constant
227 }
228
229 pub fn referenced_scripts_fee(&self, mut size: u64) -> u64 {
231 let mut cost: Ratio<u64> = Ratio::ZERO;
232 let mut fee_per_byte: Ratio<u64> = Ratio::from(self.referenced_scripts_base_fee_per_byte);
233
234 loop {
235 if size < self.referenced_scripts_fee_step_size {
236 return (cost + fee_per_byte * size).floor().to_integer();
237 }
238
239 cost += fee_per_byte * self.referenced_scripts_fee_step_size;
240 fee_per_byte *= self.referenced_scripts_fee_multiplier;
241 size -= self.referenced_scripts_fee_step_size;
242 }
243 }
244
245 pub fn minimum_collateral(&self, base_fee: u64) -> u64 {
247 (base_fee as f64 * self.collateral_coefficient).ceil() as u64
248 }
249
250 pub fn price_mem(&self, execution_units: u64) -> u64 {
252 (self.price_mem * execution_units as f64).ceil() as u64
253 }
254
255 pub fn price_cpu(&self, execution_units: u64) -> u64 {
257 (self.price_cpu * execution_units as f64).ceil() as u64
258 }
259
260 pub fn plutus_v3_cost_model(&self) -> &PlutusV3CostModel {
261 &self.plutus_v3_cost_model
262 }
263}
264
265impl From<&ProtocolParameters> for uplc::tx::SlotConfig {
268 fn from(params: &ProtocolParameters) -> Self {
269 let byron_slot_length = 20; Self {
271 slot_length: 1000, zero_slot: params.first_shelley_slot,
273 zero_time: (params.start_time + byron_slot_length * params.first_shelley_slot) * 1000,
274 }
275 }
276}
277
278