1use std::collections::BTreeMap;
2
3use pallas::ledger::primitives::conway::{
4 CostModels as PallasCostModels, DRepVotingThresholds as PallasDRepVotingThresholds,
5 ExUnitPrices as PallasExUnitPrices, ExUnits as PallasExUnits,
6 PoolVotingThresholds as PallasPoolVotingThresholds,
7};
8use pallas::ledger::primitives::{
9 conway::ProtocolParamUpdate as PallasProtocolParamUpdate, Fragment, RationalNumber,
10};
11#[derive(Debug, PartialEq, Eq, Clone)]
12pub struct CostModels {
13 pub plutus_v1: Option<Vec<i64>>,
14 pub plutus_v2: Option<Vec<i64>>,
15 pub plutus_v3: Option<Vec<i64>>,
16}
17
18#[derive(Debug, PartialEq, Eq, Clone)]
19pub struct PoolVotingThresholds {
20 pub motion_no_confidence: (u64, u64),
21 pub committee_normal: (u64, u64),
22 pub committee_no_confidence: (u64, u64),
23 pub hard_fork_initiation: (u64, u64),
24 pub security_voting_threshold: (u64, u64),
25}
26
27#[derive(Debug, PartialEq, Eq, Clone)]
28pub struct DRepVotingThresholds {
29 pub motion_no_confidence: (u64, u64),
30 pub committee_normal: (u64, u64),
31 pub committee_no_confidence: (u64, u64),
32 pub update_constitution: (u64, u64),
33 pub hard_fork_initiation: (u64, u64),
34 pub pp_network_group: (u64, u64),
35 pub pp_economic_group: (u64, u64),
36 pub pp_technical_group: (u64, u64),
37 pub pp_governance_group: (u64, u64),
38 pub treasury_withdrawal: (u64, u64),
39}
40
41#[derive(Debug, PartialEq, Eq, Clone)]
42pub struct ExUnitPrices {
43 pub mem_price: (u64, u64),
44 pub step_price: (u64, u64),
45}
46#[derive(Debug, PartialEq, Eq, Clone)]
47pub struct ExUnits {
48 pub mem: u64,
49 pub steps: u64,
50}
51
52#[derive(Debug, PartialEq, Eq, Clone)]
53pub struct ProtocolParamUpdate {
54 pub inner: PallasProtocolParamUpdate,
55}
56
57impl ProtocolParamUpdate {
58 pub fn new(
59 minfee_a: Option<u64>,
60 minfee_b: Option<u64>,
61 max_block_body_size: Option<u64>,
62 max_transaction_size: Option<u64>,
63 max_block_header_size: Option<u64>,
64 key_deposit: Option<u64>,
65 pool_deposit: Option<u64>,
66 maximum_epoch: Option<u64>,
67 desired_number_of_stake_pools: Option<u64>,
68 pool_pledge_influence: Option<(u64, u64)>, expansion_rate: Option<(u64, u64)>,
70 treasury_growth_rate: Option<(u64, u64)>,
71 min_pool_cost: Option<u64>,
72 ada_per_utxo_byte: Option<u64>,
73 cost_models_for_script_languages: Option<CostModels>,
74 execution_costs: Option<ExUnitPrices>,
75 max_tx_ex_units: Option<ExUnits>,
76 max_block_ex_units: Option<ExUnits>,
77 max_value_size: Option<u64>,
78 collateral_percentage: Option<u64>,
79 max_collateral_inputs: Option<u64>,
80 pool_voting_thresholds: Option<PoolVotingThresholds>,
81 drep_voting_thresholds: Option<DRepVotingThresholds>,
82 min_committee_size: Option<u64>,
83 committee_term_limit: Option<u64>,
84 governance_action_validity_period: Option<u64>,
85 governance_action_deposit: Option<u64>,
86 drep_deposit: Option<u64>,
87 drep_inactivity_period: Option<u64>,
88 minfee_refscript_cost_per_byte: Option<(u64, u64)>, ) -> Result<Self, String> {
90 Ok(Self {
91 inner: PallasProtocolParamUpdate {
92 minfee_a,
93 minfee_b,
94 max_block_body_size,
95 max_transaction_size,
96 max_block_header_size,
97 key_deposit,
98 pool_deposit,
99 maximum_epoch,
100 desired_number_of_stake_pools,
101 pool_pledge_influence: Self::parse_rational_number(pool_pledge_influence),
102 expansion_rate: Self::parse_rational_number(expansion_rate),
103 treasury_growth_rate: Self::parse_rational_number(treasury_growth_rate),
104 min_pool_cost,
105 ada_per_utxo_byte,
106 cost_models_for_script_languages: Self::parse_cost_models(
107 cost_models_for_script_languages,
108 ),
109 execution_costs: Self::parse_ex_unit_prices(execution_costs),
110 max_tx_ex_units: Self::parse_ex_units(max_tx_ex_units),
111 max_block_ex_units: Self::parse_ex_units(max_block_ex_units),
112 max_value_size,
113 collateral_percentage,
114 max_collateral_inputs,
115 pool_voting_thresholds: Self::parse_pool_voting_thresholds(pool_voting_thresholds),
116 drep_voting_thresholds: Self::parse_drep_voting_thresholds(drep_voting_thresholds),
117 min_committee_size,
118 committee_term_limit,
119 governance_action_validity_period,
120 governance_action_deposit,
121 drep_deposit,
122 drep_inactivity_period,
123 minfee_refscript_cost_per_byte: Self::parse_rational_number(
124 minfee_refscript_cost_per_byte,
125 ),
126 },
127 })
128 }
129
130 pub fn encode(&self) -> String {
131 hex::encode(
132 self.inner
133 .encode_fragment()
134 .expect("encoding failed at ProtocolParameterUpdate"),
135 )
136 }
137
138 pub fn decode_bytes(bytes: &[u8]) -> Result<Self, String> {
139 let inner = PallasProtocolParamUpdate::decode_fragment(&bytes)
140 .map_err(|e| format!("Fragment decode error: {}", e.to_string()))?;
141 Ok(Self { inner })
142 }
143
144 fn parse_rational_number(tuple: Option<(u64, u64)>) -> Option<RationalNumber> {
145 match tuple {
146 Some((numerator, denominator)) => Some(RationalNumber {
147 numerator,
148 denominator,
149 }),
150 None => None,
151 }
152 }
153
154 fn parse_cost_models(cost_models: Option<CostModels>) -> Option<PallasCostModels> {
155 match cost_models {
156 Some(models) => Some(PallasCostModels {
157 plutus_v1: models.plutus_v1,
158 plutus_v2: models.plutus_v2,
159 plutus_v3: models.plutus_v3,
160 unknown: BTreeMap::new(),
161 }),
162 None => None,
163 }
164 }
165
166 fn parse_ex_unit_prices(tuple: Option<ExUnitPrices>) -> Option<PallasExUnitPrices> {
167 match tuple {
168 Some(prices) => Some(PallasExUnitPrices {
169 mem_price: Self::parse_rational_number(Some(prices.mem_price))?,
170 step_price: Self::parse_rational_number(Some(prices.step_price))?,
171 }),
172 None => None,
173 }
174 }
175
176 fn parse_ex_units(ex_units: Option<ExUnits>) -> Option<PallasExUnits> {
177 match ex_units {
178 Some(units) => Some(pallas::ledger::primitives::conway::ExUnits {
179 mem: units.mem,
180 steps: units.steps,
181 }),
182 None => None,
183 }
184 }
185
186 fn parse_pool_voting_thresholds(
187 tuple: Option<PoolVotingThresholds>,
188 ) -> Option<PallasPoolVotingThresholds> {
189 match tuple {
190 Some(thresholds) => Some(PallasPoolVotingThresholds {
191 motion_no_confidence: Self::parse_rational_number(Some(
192 thresholds.motion_no_confidence,
193 ))?,
194 committee_normal: Self::parse_rational_number(Some(thresholds.committee_normal))?,
195 committee_no_confidence: Self::parse_rational_number(Some(
196 thresholds.committee_no_confidence,
197 ))?,
198 hard_fork_initiation: Self::parse_rational_number(Some(
199 thresholds.hard_fork_initiation,
200 ))?,
201 security_voting_threshold: Self::parse_rational_number(Some(
202 thresholds.security_voting_threshold,
203 ))?,
204 }),
205 None => None,
206 }
207 }
208
209 fn parse_drep_voting_thresholds(
210 tuple: Option<DRepVotingThresholds>,
211 ) -> Option<PallasDRepVotingThresholds> {
212 match tuple {
213 Some(thresholds) => Some(PallasDRepVotingThresholds {
214 motion_no_confidence: Self::parse_rational_number(Some(
215 thresholds.motion_no_confidence,
216 ))?,
217 committee_normal: Self::parse_rational_number(Some(thresholds.committee_normal))?,
218 committee_no_confidence: Self::parse_rational_number(Some(
219 thresholds.committee_no_confidence,
220 ))?,
221 update_constitution: Self::parse_rational_number(Some(
222 thresholds.update_constitution,
223 ))?,
224 hard_fork_initiation: Self::parse_rational_number(Some(
225 thresholds.hard_fork_initiation,
226 ))?,
227 pp_network_group: Self::parse_rational_number(Some(thresholds.pp_network_group))?,
228 pp_economic_group: Self::parse_rational_number(Some(thresholds.pp_economic_group))?,
229 pp_technical_group: Self::parse_rational_number(Some(
230 thresholds.pp_technical_group,
231 ))?,
232 pp_governance_group: Self::parse_rational_number(Some(
233 thresholds.pp_governance_group,
234 ))?,
235 treasury_withdrawal: Self::parse_rational_number(Some(
236 thresholds.treasury_withdrawal,
237 ))?,
238 }),
239 None => None,
240 }
241 }
242}