whisky_pallas/wrapper/transaction_body/
protocol_param_update.rs

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)>, // RationalNumber
69        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)>, // unit interval
89    ) -> 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}