1use std::net::{Ipv4Addr, Ipv6Addr};
2
3use cardano_serialization_lib as csl;
4
5use whisky_common::*;
6
7use super::to_bignum;
8
9pub fn to_csl_drep(drep: &DRep) -> Result<csl::DRep, WError> {
10 match drep {
11 DRep::DRepId(drep_id) => {
12 Ok(csl::DRep::from_bech32(drep_id)
13 .map_err(WError::from_err("to_csl_drep - drep_id"))?)
14 }
15 DRep::AlwaysAbstain => Ok(csl::DRep::new_always_abstain()),
16 DRep::AlwaysNoConfidence => Ok(csl::DRep::new_always_no_confidence()),
17 }
18}
19
20pub fn to_csl_anchor(anchor: &Anchor) -> Result<csl::Anchor, WError> {
21 Ok(csl::Anchor::new(
22 &csl::URL::new(anchor.anchor_url.clone())
23 .map_err(WError::from_err("to_csl_anchor - invalid anchor url"))?,
24 &csl::AnchorDataHash::from_hex(&anchor.anchor_data_hash)
25 .map_err(WError::from_err("to_csl_anchor - invalid anchor data hash"))?,
26 ))
27}
28
29pub fn to_csl_cert(cert: CertificateType) -> Result<csl::Certificate, WError> {
30 match cert {
31 CertificateType::RegisterPool(reg_pool_cert) => to_register_pool_cert(reg_pool_cert),
32 CertificateType::RegisterStake(reg_stake_cert) => to_register_stake_cert(reg_stake_cert),
33 CertificateType::DeregisterStake(dereg_stake_cert) => {
34 to_deregister_stake_cert(dereg_stake_cert)
35 }
36 CertificateType::DelegateStake(deleg_stake_cert) => {
37 to_delegate_stake_cert(deleg_stake_cert)
38 }
39 CertificateType::RetirePool(retire_pool_cert) => to_retire_pool_cert(retire_pool_cert),
40 CertificateType::VoteDelegation(vote_deleg_cert) => {
41 to_vote_delegation_cert(vote_deleg_cert)
42 }
43 CertificateType::StakeAndVoteDelegation(stake_and_vote_deleg_cert) => {
44 to_stake_and_vote_delegation_cert(stake_and_vote_deleg_cert)
45 }
46 CertificateType::StakeRegistrationAndDelegation(stake_reg_and_deleg_cert) => {
47 to_stake_registration_and_delegation_cert(stake_reg_and_deleg_cert)
48 }
49 CertificateType::VoteRegistrationAndDelegation(vote_reg_and_deleg_cert) => {
50 to_vote_registration_and_delgation_cert(vote_reg_and_deleg_cert)
51 }
52 CertificateType::StakeVoteRegistrationAndDelegation(stake_vote_reg_and_deleg_cert) => {
53 to_stake_vote_registration_and_delegation_cert(stake_vote_reg_and_deleg_cert)
54 }
55 CertificateType::CommitteeHotAuth(committee_hot_auth_cert) => {
56 to_committee_hot_auth_cert(committee_hot_auth_cert)
57 }
58 CertificateType::CommitteeColdResign(committee_cold_resign_cert) => {
59 to_commitee_cold_resign_cert(committee_cold_resign_cert)
60 }
61 CertificateType::DRepRegistration(drep_registration_cert) => {
62 to_drep_registration_cert(drep_registration_cert)
63 }
64 CertificateType::DRepDeregistration(drep_deregistration_cert) => {
65 to_drep_deregistration_cert(drep_deregistration_cert)
66 }
67 CertificateType::DRepUpdate(drep_update_cert) => to_drep_update_cert(drep_update_cert),
68 }
69}
70
71fn to_register_pool_cert(register_pool: RegisterPool) -> Result<csl::Certificate, WError> {
72 let mut relays = csl::Relays::new();
73 for relay in register_pool.pool_params.relays {
74 match relay {
75 Relay::SingleHostAddr(single_host_address_relay) => {
76 let ipv4_bytes: Option<csl::Ipv4> =
77 single_host_address_relay.ipv4.map(|ipv4_str| {
78 let addr: Ipv4Addr = ipv4_str.parse().expect("ipv4 address parse failed");
79 csl::Ipv4::new(addr.octets().to_vec()).unwrap()
80 });
81
82 let ipv6_bytes: Option<csl::Ipv6> =
83 single_host_address_relay.ipv6.map(|ipv6_str| {
84 let addr: Ipv6Addr = ipv6_str.parse().expect("ipv6 address parse failed");
85 csl::Ipv6::new(addr.octets().to_vec()).unwrap()
86 });
87 relays.add(&csl::Relay::new_single_host_addr(
88 &csl::SingleHostAddr::new(
89 single_host_address_relay.port,
90 ipv4_bytes,
91 ipv6_bytes,
92 ),
93 ));
94 }
95 Relay::SingleHostName(single_host_name_relay) => relays.add(
96 &csl::Relay::new_single_host_name(&csl::SingleHostName::new(
97 single_host_name_relay.port,
98 &csl::DNSRecordAorAAAA::new(single_host_name_relay.domain_name).map_err(
99 WError::from_err("to_register_pool_cert - invalid domain name - single"),
100 )?,
101 )),
102 ),
103 Relay::MultiHostName(multi_host_name_relay) => {
104 relays.add(&csl::Relay::new_multi_host_name(&csl::MultiHostName::new(
105 &csl::DNSRecordSRV::new(multi_host_name_relay.domain_name).map_err(
106 WError::from_err("to_register_pool_cert - invalid domain name - multi"),
107 )?,
108 )))
109 }
110 }
111 }
112
113 let mut pool_owners = csl::Ed25519KeyHashes::new();
114 for owner in register_pool.pool_params.owners {
115 pool_owners.add(
116 &csl::Ed25519KeyHash::from_hex(&owner).map_err(WError::from_err(
117 "to_register_pool_cert - invalid pool owner",
118 ))?,
119 );
120 }
121 Ok(csl::Certificate::new_pool_registration(
122 &csl::PoolRegistration::new(&csl::PoolParams::new(
123 &csl::Ed25519KeyHash::from_hex(®ister_pool.pool_params.operator).map_err(
124 WError::from_err("to_register_pool_cert - invalid pool operator"),
125 )?,
126 &csl::VRFKeyHash::from_hex(®ister_pool.pool_params.vrf_key_hash).map_err(
127 WError::from_err("to_register_pool_cert - invalid pool vrf key hash"),
128 )?,
129 &csl::BigNum::from_str(®ister_pool.pool_params.pledge).map_err(WError::from_err(
130 "to_register_pool_cert - invalid pool pledge",
131 ))?,
132 &csl::BigNum::from_str(®ister_pool.pool_params.cost).map_err(WError::from_err(
133 "to_register_pool_cert - invalid pool cost",
134 ))?,
135 &csl::UnitInterval::new(
136 &csl::BigNum::from_str(®ister_pool.pool_params.margin.0.to_string()).map_err(
137 WError::from_err("to_register_pool_cert - invalid pool margin - 0"),
138 )?,
139 &csl::BigNum::from_str(®ister_pool.pool_params.margin.1.to_string()).map_err(
140 WError::from_err("to_register_pool_cert - invalid pool margin - 1"),
141 )?,
142 ),
143 &csl::RewardAddress::from_address(
144 &csl::Address::from_bech32(®ister_pool.pool_params.reward_address).map_err(
145 WError::from_err("to_register_pool_cert - invalid pool reward address"),
146 )?,
147 )
148 .ok_or_else(WError::from_opt(
149 "to_register_pool_cert - invalid pool reward address",
150 "Invalid reward address",
151 ))?,
152 &pool_owners,
153 &relays,
154 register_pool.pool_params.metadata.map(|data| {
155 csl::PoolMetadata::new(
156 &csl::URL::new(data.url).unwrap(),
157 &csl::PoolMetadataHash::from_hex(&data.hash).unwrap(),
158 )
159 }),
160 )),
161 ))
162}
163
164fn to_register_stake_cert(register_stake: RegisterStake) -> Result<csl::Certificate, WError> {
165 Ok(csl::Certificate::new_stake_registration(
166 &csl::StakeRegistration::new(
167 &csl::Address::from_bech32(®ister_stake.stake_key_address)
168 .map_err(WError::from_err(
169 "to_register_stake_cert - invalid stake key address",
170 ))?
171 .payment_cred()
172 .unwrap(),
173 ),
174 ))
175}
176
177fn to_delegate_stake_cert(delegate_stake: DelegateStake) -> Result<csl::Certificate, WError> {
178 Ok(csl::Certificate::new_stake_delegation(
179 &csl::StakeDelegation::new(
180 &csl::Address::from_bech32(&delegate_stake.stake_key_address)
181 .map_err(WError::from_err(
182 "to_delegate_stake_cert - invalid stake key address",
183 ))?
184 .payment_cred()
185 .unwrap(),
186 &csl::Ed25519KeyHash::from_hex(&delegate_stake.pool_id)
187 .map_err(WError::from_err("to_delegate_stake_cert - invalid pool id"))?,
188 ),
189 ))
190}
191
192fn to_deregister_stake_cert(deregister_stake: DeregisterStake) -> Result<csl::Certificate, WError> {
193 Ok(csl::Certificate::new_stake_deregistration(
194 &csl::StakeDeregistration::new(
195 &csl::Address::from_bech32(&deregister_stake.stake_key_address)
196 .map_err(WError::from_err(
197 "to_deregister_stake_cert - invalid stake key address",
198 ))?
199 .payment_cred()
200 .unwrap(),
201 ),
202 ))
203}
204
205fn to_retire_pool_cert(retire_pool: RetirePool) -> Result<csl::Certificate, WError> {
206 Ok(csl::Certificate::new_pool_retirement(
207 &csl::PoolRetirement::new(
208 &csl::Ed25519KeyHash::from_hex(&retire_pool.pool_id)
209 .map_err(WError::from_err("to_retire_pool_cert - invalid pool id"))?,
210 retire_pool.epoch,
211 ),
212 ))
213}
214
215fn to_vote_delegation_cert(vote_delegation: VoteDelegation) -> Result<csl::Certificate, WError> {
216 Ok(csl::Certificate::new_vote_delegation(
217 &csl::VoteDelegation::new(
218 &csl::Address::from_bech32(&vote_delegation.stake_key_address)
219 .map_err(WError::from_err(
220 "to_vote_delegation_cert - invalid stake key address",
221 ))?
222 .payment_cred()
223 .unwrap(),
224 &to_csl_drep(&vote_delegation.drep)?,
225 ),
226 ))
227}
228
229fn to_stake_and_vote_delegation_cert(
230 stake_and_vote_delegation: StakeAndVoteDelegation,
231) -> Result<csl::Certificate, WError> {
232 Ok(csl::Certificate::new_stake_and_vote_delegation(
233 &csl::StakeAndVoteDelegation::new(
234 &csl::Address::from_bech32(&stake_and_vote_delegation.stake_key_address)
235 .map_err(WError::from_err(
236 "to_stake_and_vote_delegation_cert - invalid stake key address",
237 ))?
238 .payment_cred()
239 .unwrap(),
240 &csl::Ed25519KeyHash::from_hex(&stake_and_vote_delegation.pool_key_hash).map_err(
241 WError::from_err("to_stake_and_vote_delegation_cert - invalid pool key hash"),
242 )?,
243 &to_csl_drep(&stake_and_vote_delegation.drep)?,
244 ),
245 ))
246}
247
248fn to_stake_registration_and_delegation_cert(
249 stake_registration_and_delegation: StakeRegistrationAndDelegation,
250) -> Result<csl::Certificate, WError> {
251 Ok(csl::Certificate::new_stake_registration_and_delegation(
252 &csl::StakeRegistrationAndDelegation::new(
253 &csl::Address::from_bech32(&stake_registration_and_delegation.stake_key_address)
254 .map_err(WError::from_err(
255 "to_stake_registration_and_delegation_cert - invalid stake key address",
256 ))?
257 .payment_cred()
258 .ok_or_else(WError::from_opt(
259 "to_stake_registration_and_delegation_cert - invalid stake key address",
260 "Invalid stake key address",
261 ))?,
262 &csl::Ed25519KeyHash::from_hex(&stake_registration_and_delegation.pool_key_hash)
263 .map_err(WError::from_err(
264 "to_stake_registration_and_delegation_cert - invalid pool key hash",
265 ))?,
266 &to_bignum(stake_registration_and_delegation.coin).map_err(WError::add_err_trace(
267 "to_stake_registration_and_delegation_cert",
268 ))?,
269 ),
270 ))
271}
272
273fn to_vote_registration_and_delgation_cert(
274 vote_registration_and_delgation: VoteRegistrationAndDelegation,
275) -> Result<csl::Certificate, WError> {
276 Ok(csl::Certificate::new_vote_registration_and_delegation(
277 &csl::VoteRegistrationAndDelegation::new(
278 &csl::Address::from_bech32(&vote_registration_and_delgation.stake_key_address)
279 .map_err(WError::from_err(
280 "to_vote_registration_and_delgation_cert - invalid stake key address",
281 ))?
282 .payment_cred()
283 .ok_or_else(WError::from_opt(
284 "to_vote_registration_and_delgation_cert - invalid stake key address",
285 "Invalid stake key address",
286 ))?,
287 &to_csl_drep(&vote_registration_and_delgation.drep).map_err(WError::add_err_trace(
288 "to_vote_registration_and_delgation_cert - invalid drep",
289 ))?,
290 &to_bignum(vote_registration_and_delgation.coin).map_err(WError::add_err_trace(
291 "to_vote_registration_and_delgation_cert - invalid coin",
292 ))?,
293 ),
294 ))
295}
296
297fn to_stake_vote_registration_and_delegation_cert(
298 stake_vote_registration_and_delegation: StakeVoteRegistrationAndDelegation,
299) -> Result<csl::Certificate, WError> {
300 Ok(
301 csl::Certificate::new_stake_vote_registration_and_delegation(
302 &csl::StakeVoteRegistrationAndDelegation::new(
303 &csl::Address::from_bech32(
304 &stake_vote_registration_and_delegation.stake_key_address,
305 )
306 .map_err(WError::from_err(
307 "to_stake_vote_registration_and_delegation_cert - invalid stake key address",
308 ))?
309 .payment_cred()
310 .ok_or_else(WError::from_opt(
311 "to_stake_vote_registration_and_delegation_cert - invalid stake key address",
312 "Invalid stake key address",
313 ))?,
314 &csl::Ed25519KeyHash::from_hex(
315 &stake_vote_registration_and_delegation.pool_key_hash,
316 )
317 .map_err(WError::from_err(
318 "to_stake_vote_registration_and_delegation_cert - invalid pool key hash",
319 ))?,
320 &to_csl_drep(&stake_vote_registration_and_delegation.drep).map_err(
321 WError::add_err_trace(
322 "to_stake_vote_registration_and_delegation_cert - invalid drep",
323 ),
324 )?,
325 &to_bignum(stake_vote_registration_and_delegation.coin).map_err(
326 WError::add_err_trace(
327 "to_stake_vote_registration_and_delegation_cert - invalid coin",
328 ),
329 )?,
330 ),
331 ),
332 )
333}
334
335fn to_committee_hot_auth_cert(
336 committee_hot_auth: CommitteeHotAuth,
337) -> Result<csl::Certificate, WError> {
338 Ok(csl::Certificate::new_committee_hot_auth(
339 &csl::CommitteeHotAuth::new(
340 &csl::Address::from_bech32(&committee_hot_auth.committee_cold_key_address)
341 .map_err(WError::from_err(
342 "to_committee_hot_auth_cert - invalid committee cold key address",
343 ))?
344 .payment_cred()
345 .ok_or_else(WError::from_opt(
346 "to_committee_hot_auth_cert - invalid committee cold key address",
347 "Invalid committee cold key address",
348 ))?,
349 &csl::Address::from_bech32(&committee_hot_auth.committee_hot_key_address)
350 .map_err(WError::from_err(
351 "to_committee_hot_auth_cert - invalid committee hot key address",
352 ))?
353 .payment_cred()
354 .ok_or_else(WError::from_opt(
355 "to_committee_hot_auth_cert - invalid committee hot key address",
356 "Invalid committee hot key address",
357 ))?,
358 ),
359 ))
360}
361
362fn to_commitee_cold_resign_cert(
363 committee_cold_resign: CommitteeColdResign,
364) -> Result<csl::Certificate, WError> {
365 let committee_cold_key =
366 &csl::Address::from_bech32(&committee_cold_resign.committee_cold_key_address)
367 .map_err(WError::from_err(
368 "to_commitee_cold_resign_cert - invalid committee cold key address",
369 ))?
370 .payment_cred()
371 .ok_or_else(WError::from_opt(
372 "to_commitee_cold_resign_cert - invalid committee cold key address",
373 "Invalid committee cold key address",
374 ))?;
375 match committee_cold_resign.anchor {
376 Some(anchor) => Ok(csl::Certificate::new_committee_cold_resign(
377 &csl::CommitteeColdResign::new_with_anchor(
378 committee_cold_key,
379 &to_csl_anchor(&anchor).map_err(WError::add_err_trace(
380 "to_commitee_cold_resign_cert - invalid anchor",
381 ))?,
382 ),
383 )),
384 None => Ok(csl::Certificate::new_committee_cold_resign(
385 &csl::CommitteeColdResign::new(committee_cold_key),
386 )),
387 }
388}
389
390fn to_drep_registration_cert(
391 drep_registration: DRepRegistration,
392) -> Result<csl::Certificate, WError> {
393 let drep = csl::DRep::from_bech32(&drep_registration.drep_id).map_err(WError::from_err(
394 "to_drep_registration_cert - invalid drep id",
395 ))?;
396 let drep_credential = if drep.to_script_hash().is_some() {
397 csl::Credential::from_scripthash(&drep.to_script_hash().unwrap())
398 } else if drep.to_key_hash().is_some() {
399 csl::Credential::from_keyhash(&drep.to_key_hash().unwrap())
400 } else {
401 return Err(WError::new(
402 "to_drep_registration_cert - invalid drep id",
403 "Error occured when deserializing DrepId to either script hash or key hash",
404 ));
405 };
406
407 match drep_registration.anchor {
408 Some(anchor) => Ok(csl::Certificate::new_drep_registration(
409 &csl::DRepRegistration::new_with_anchor(
410 &drep_credential,
411 &to_bignum(drep_registration.coin).map_err(WError::add_err_trace(
412 "to_drep_registration_cert - invalid coin",
413 ))?,
414 &to_csl_anchor(&anchor).map_err(WError::add_err_trace(
415 "to_drep_registration_cert - invalid anchor",
416 ))?,
417 ),
418 )),
419 None => Ok(csl::Certificate::new_drep_registration(
420 &csl::DRepRegistration::new(
421 &drep_credential,
422 &to_bignum(drep_registration.coin).map_err(WError::add_err_trace(
423 "to_drep_registration_cert - invalid coin",
424 ))?,
425 ),
426 )),
427 }
428}
429
430fn to_drep_deregistration_cert(
431 drep_deregistration: DRepDeregistration,
432) -> Result<csl::Certificate, WError> {
433 let drep = csl::DRep::from_bech32(&drep_deregistration.drep_id).map_err(WError::from_err(
434 "to_drep_deregistration_cert - invalid drep id",
435 ))?;
436 let drep_credential = if drep.to_script_hash().is_some() {
437 csl::Credential::from_scripthash(&drep.to_script_hash().unwrap())
438 } else if drep.to_key_hash().is_some() {
439 csl::Credential::from_keyhash(&drep.to_key_hash().unwrap())
440 } else {
441 return Err(WError::new(
442 "to_drep_deregistration_cert - invalid drep id",
443 "Error occured when deserializing DrepId to either script hash or key hash",
444 ));
445 };
446
447 Ok(csl::Certificate::new_drep_deregistration(
448 &csl::DRepDeregistration::new(
449 &drep_credential,
450 &to_bignum(drep_deregistration.coin).map_err(WError::add_err_trace(
451 "to_drep_deregistration_cert - invalid coin",
452 ))?,
453 ),
454 ))
455}
456
457fn to_drep_update_cert(drep_update: DRepUpdate) -> Result<csl::Certificate, WError> {
458 let drep = csl::DRep::from_bech32(&drep_update.drep_id)
459 .map_err(WError::from_err("to_drep_update_cert - invalid drep id"))?;
460 let drep_credential = if drep.to_script_hash().is_some() {
461 csl::Credential::from_scripthash(&drep.to_script_hash().unwrap())
462 } else if drep.to_key_hash().is_some() {
463 csl::Credential::from_keyhash(&drep.to_key_hash().unwrap())
464 } else {
465 return Err(WError::new(
466 "to_drep_update_cert - invalid drep id",
467 "Error occured when deserializing DrepId to either script hash or key hash",
468 ));
469 };
470 match drep_update.anchor {
471 Some(anchor) => Ok(csl::Certificate::new_drep_update(
472 &csl::DRepUpdate::new_with_anchor(&drep_credential, &to_csl_anchor(&anchor)?),
473 )),
474 None => Ok(csl::Certificate::new_drep_update(&csl::DRepUpdate::new(
475 &drep_credential,
476 ))),
477 }
478}