1use serde::{Deserialize, Serialize};
6
7use pallas_codec::minicbor::{self, Decode, Encode};
8use pallas_codec::utils::CborWrap;
9
10pub use crate::{
11 plutus_data::*, AddrKeyhash, AssetName, Bytes, Coin, CostModel, DnsName, Epoch, ExUnits,
12 GenesisDelegateHash, Genesishash, Hash, IPv4, IPv6, KeepRaw, KeyValuePairs, MaybeIndefArray,
13 Metadata, Metadatum, MetadatumLabel, NetworkId, NonEmptyKeyValuePairs, NonEmptySet, NonZeroInt,
14 Nonce, NonceVariant, Nullable, PlutusScript, PolicyId, PoolKeyhash, PoolMetadata,
15 PoolMetadataHash, Port, PositiveCoin, PositiveInterval, ProtocolVersion, RationalNumber, Relay,
16 RewardAccount, ScriptHash, Set, StakeCredential, TransactionIndex, TransactionInput,
17 UnitInterval, VrfCert, VrfKeyhash,
18};
19
20use crate::babbage;
21
22pub use crate::babbage::HeaderBody;
23
24pub use crate::babbage::OperationalCert;
25
26pub use crate::babbage::Header;
27
28pub type Multiasset<A> = NonEmptyKeyValuePairs<PolicyId, NonEmptyKeyValuePairs<AssetName, A>>;
29
30pub type Mint = Multiasset<NonZeroInt>;
31
32#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
33pub enum Value {
34 Coin(Coin),
35 Multiasset(Coin, Multiasset<PositiveCoin>),
36}
37
38impl<'b, C> minicbor::decode::Decode<'b, C> for Value {
39 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
40 match d.datatype()? {
41 minicbor::data::Type::U8 => Ok(Value::Coin(d.decode_with(ctx)?)),
42 minicbor::data::Type::U16 => Ok(Value::Coin(d.decode_with(ctx)?)),
43 minicbor::data::Type::U32 => Ok(Value::Coin(d.decode_with(ctx)?)),
44 minicbor::data::Type::U64 => Ok(Value::Coin(d.decode_with(ctx)?)),
45 minicbor::data::Type::Array => {
46 d.array()?;
47 let coin = d.decode_with(ctx)?;
48 let multiasset = d.decode_with(ctx)?;
49 Ok(Value::Multiasset(coin, multiasset))
50 }
51 _ => Err(minicbor::decode::Error::message(
52 "unknown cbor data type for Alonzo Value enum",
53 )),
54 }
55 }
56}
57
58impl<C> minicbor::encode::Encode<C> for Value {
59 fn encode<W: minicbor::encode::Write>(
60 &self,
61 e: &mut minicbor::Encoder<W>,
62 ctx: &mut C,
63 ) -> Result<(), minicbor::encode::Error<W::Error>> {
64 match self {
66 Value::Coin(coin) => {
67 e.encode_with(coin, ctx)?;
68 }
69 Value::Multiasset(coin, other) => {
70 e.array(2)?;
71 e.encode_with(coin, ctx)?;
72 e.encode_with(other, ctx)?;
73 }
74 };
75
76 Ok(())
77 }
78}
79
80pub use crate::alonzo::TransactionOutput as LegacyTransactionOutput;
81
82pub type Withdrawals = NonEmptyKeyValuePairs<RewardAccount, Coin>;
83
84pub type RequiredSigners = NonEmptySet<AddrKeyhash>;
85
86#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
87pub enum Certificate {
88 StakeRegistration(StakeCredential),
89 StakeDeregistration(StakeCredential),
90 StakeDelegation(StakeCredential, PoolKeyhash),
91 PoolRegistration {
92 operator: PoolKeyhash,
93 vrf_keyhash: VrfKeyhash,
94 pledge: Coin,
95 cost: Coin,
96 margin: UnitInterval,
97 reward_account: RewardAccount,
98 pool_owners: Set<AddrKeyhash>,
99 relays: Vec<Relay>,
100 pool_metadata: Nullable<PoolMetadata>,
101 },
102 PoolRetirement(PoolKeyhash, Epoch),
103
104 Reg(StakeCredential, Coin),
105 UnReg(StakeCredential, Coin),
106 VoteDeleg(StakeCredential, DRep),
107 StakeVoteDeleg(StakeCredential, PoolKeyhash, DRep),
108 StakeRegDeleg(StakeCredential, PoolKeyhash, Coin),
109 VoteRegDeleg(StakeCredential, DRep, Coin),
110 StakeVoteRegDeleg(StakeCredential, PoolKeyhash, DRep, Coin),
111
112 AuthCommitteeHot(CommitteeColdCredential, CommitteeHotCredential),
113 ResignCommitteeCold(CommitteeColdCredential, Nullable<Anchor>),
114 RegDRepCert(DRepCredential, Coin, Nullable<Anchor>),
115 UnRegDRepCert(DRepCredential, Coin),
116 UpdateDRepCert(DRepCredential, Nullable<Anchor>),
117}
118
119impl<'b, C> minicbor::decode::Decode<'b, C> for Certificate {
120 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
121 d.array()?;
122 let variant = d.u16()?;
123
124 match variant {
125 0 => {
126 let a = d.decode_with(ctx)?;
127 Ok(Certificate::StakeRegistration(a))
128 }
129 1 => {
130 let a = d.decode_with(ctx)?;
131 Ok(Certificate::StakeDeregistration(a))
132 }
133 2 => {
134 let a = d.decode_with(ctx)?;
135 let b = d.decode_with(ctx)?;
136 Ok(Certificate::StakeDelegation(a, b))
137 }
138 3 => {
139 let operator = d.decode_with(ctx)?;
140 let vrf_keyhash = d.decode_with(ctx)?;
141 let pledge = d.decode_with(ctx)?;
142 let cost = d.decode_with(ctx)?;
143 let margin = d.decode_with(ctx)?;
144 let reward_account = d.decode_with(ctx)?;
145 let pool_owners = d.decode_with(ctx)?;
146 let relays = d.decode_with(ctx)?;
147 let pool_metadata = d.decode_with(ctx)?;
148
149 Ok(Certificate::PoolRegistration {
150 operator,
151 vrf_keyhash,
152 pledge,
153 cost,
154 margin,
155 reward_account,
156 pool_owners,
157 relays,
158 pool_metadata,
159 })
160 }
161 4 => {
162 let a = d.decode_with(ctx)?;
163 let b = d.decode_with(ctx)?;
164 Ok(Certificate::PoolRetirement(a, b))
165 }
166
167 7 => {
168 let a = d.decode_with(ctx)?;
169 let b = d.decode_with(ctx)?;
170 Ok(Certificate::Reg(a, b))
171 }
172 8 => {
173 let a = d.decode_with(ctx)?;
174 let b = d.decode_with(ctx)?;
175 Ok(Certificate::UnReg(a, b))
176 }
177 9 => {
178 let a = d.decode_with(ctx)?;
179 let b = d.decode_with(ctx)?;
180 Ok(Certificate::VoteDeleg(a, b))
181 }
182 10 => {
183 let a = d.decode_with(ctx)?;
184 let b = d.decode_with(ctx)?;
185 let c = d.decode_with(ctx)?;
186 Ok(Certificate::StakeVoteDeleg(a, b, c))
187 }
188 11 => {
189 let a = d.decode_with(ctx)?;
190 let b = d.decode_with(ctx)?;
191 let c = d.decode_with(ctx)?;
192 Ok(Certificate::StakeRegDeleg(a, b, c))
193 }
194 12 => {
195 let a = d.decode_with(ctx)?;
196 let b = d.decode_with(ctx)?;
197 let c = d.decode_with(ctx)?;
198 Ok(Certificate::VoteRegDeleg(a, b, c))
199 }
200 13 => {
201 let a = d.decode_with(ctx)?;
202 let b = d.decode_with(ctx)?;
203 let c = d.decode_with(ctx)?;
204 let d = d.decode_with(ctx)?;
205 Ok(Certificate::StakeVoteRegDeleg(a, b, c, d))
206 }
207 14 => {
208 let a = d.decode_with(ctx)?;
209 let b = d.decode_with(ctx)?;
210 Ok(Certificate::AuthCommitteeHot(a, b))
211 }
212 15 => {
213 let a = d.decode_with(ctx)?;
214 let b = d.decode_with(ctx)?;
215 Ok(Certificate::ResignCommitteeCold(a, b))
216 }
217 16 => {
218 let a = d.decode_with(ctx)?;
219 let b = d.decode_with(ctx)?;
220 let c = d.decode_with(ctx)?;
221 Ok(Certificate::RegDRepCert(a, b, c))
222 }
223 17 => {
224 let a = d.decode_with(ctx)?;
225 let b = d.decode_with(ctx)?;
226 Ok(Certificate::UnRegDRepCert(a, b))
227 }
228 18 => {
229 let a = d.decode_with(ctx)?;
230 let b = d.decode_with(ctx)?;
231 Ok(Certificate::UpdateDRepCert(a, b))
232 }
233 _ => Err(minicbor::decode::Error::message(
234 "unknown variant id for certificate",
235 )),
236 }
237 }
238}
239
240impl<C> minicbor::encode::Encode<C> for Certificate {
241 fn encode<W: minicbor::encode::Write>(
242 &self,
243 e: &mut minicbor::Encoder<W>,
244 ctx: &mut C,
245 ) -> Result<(), minicbor::encode::Error<W::Error>> {
246 match self {
247 Certificate::StakeRegistration(a) => {
248 e.array(2)?;
249 e.u16(0)?;
250 e.encode_with(a, ctx)?;
251 }
252 Certificate::StakeDeregistration(a) => {
253 e.array(2)?;
254 e.u16(1)?;
255 e.encode_with(a, ctx)?;
256 }
257 Certificate::StakeDelegation(a, b) => {
258 e.array(3)?;
259 e.u16(2)?;
260 e.encode_with(a, ctx)?;
261 e.encode_with(b, ctx)?;
262 }
263 Certificate::PoolRegistration {
264 operator,
265 vrf_keyhash,
266 pledge,
267 cost,
268 margin,
269 reward_account,
270 pool_owners,
271 relays,
272 pool_metadata,
273 } => {
274 e.array(10)?;
275 e.u16(3)?;
276
277 e.encode_with(operator, ctx)?;
278 e.encode_with(vrf_keyhash, ctx)?;
279 e.encode_with(pledge, ctx)?;
280 e.encode_with(cost, ctx)?;
281 e.encode_with(margin, ctx)?;
282 e.encode_with(reward_account, ctx)?;
283 e.encode_with(pool_owners, ctx)?;
284 e.encode_with(relays, ctx)?;
285 e.encode_with(pool_metadata, ctx)?;
286 }
287 Certificate::PoolRetirement(a, b) => {
288 e.array(3)?;
289 e.u16(4)?;
290 e.encode_with(a, ctx)?;
291 e.encode_with(b, ctx)?;
292 }
293 Certificate::Reg(a, b) => {
295 e.array(3)?;
296 e.u16(7)?;
297 e.encode_with(a, ctx)?;
298 e.encode_with(b, ctx)?;
299 }
300 Certificate::UnReg(a, b) => {
301 e.array(3)?;
302 e.u16(8)?;
303 e.encode_with(a, ctx)?;
304 e.encode_with(b, ctx)?;
305 }
306 Certificate::VoteDeleg(a, b) => {
307 e.array(3)?;
308 e.u16(9)?;
309 e.encode_with(a, ctx)?;
310 e.encode_with(b, ctx)?;
311 }
312 Certificate::StakeVoteDeleg(a, b, c) => {
313 e.array(4)?;
314 e.u16(10)?;
315 e.encode_with(a, ctx)?;
316 e.encode_with(b, ctx)?;
317 e.encode_with(c, ctx)?;
318 }
319 Certificate::StakeRegDeleg(a, b, c) => {
320 e.array(4)?;
321 e.u16(11)?;
322 e.encode_with(a, ctx)?;
323 e.encode_with(b, ctx)?;
324 e.encode_with(c, ctx)?;
325 }
326 Certificate::VoteRegDeleg(a, b, c) => {
327 e.array(4)?;
328 e.u16(12)?;
329 e.encode_with(a, ctx)?;
330 e.encode_with(b, ctx)?;
331 e.encode_with(c, ctx)?;
332 }
333 Certificate::StakeVoteRegDeleg(a, b, c, d) => {
334 e.array(5)?;
335 e.u16(13)?;
336 e.encode_with(a, ctx)?;
337 e.encode_with(b, ctx)?;
338 e.encode_with(c, ctx)?;
339 e.encode_with(d, ctx)?;
340 }
341 Certificate::AuthCommitteeHot(a, b) => {
342 e.array(3)?;
343 e.u16(14)?;
344 e.encode_with(a, ctx)?;
345 e.encode_with(b, ctx)?;
346 }
347 Certificate::ResignCommitteeCold(a, b) => {
348 e.array(3)?;
349 e.u16(15)?;
350 e.encode_with(a, ctx)?;
351 e.encode_with(b, ctx)?;
352 }
353 Certificate::RegDRepCert(a, b, c) => {
354 e.array(4)?;
355 e.u16(16)?;
356 e.encode_with(a, ctx)?;
357 e.encode_with(b, ctx)?;
358 e.encode_with(c, ctx)?;
359 }
360 Certificate::UnRegDRepCert(a, b) => {
361 e.array(3)?;
362 e.u16(17)?;
363 e.encode_with(a, ctx)?;
364 e.encode_with(b, ctx)?;
365 }
366 Certificate::UpdateDRepCert(a, b) => {
367 e.array(3)?;
368 e.u16(18)?;
369 e.encode_with(a, ctx)?;
370 e.encode_with(b, ctx)?;
371 }
372 }
373
374 Ok(())
375 }
376}
377
378#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Eq, Ord, Clone)]
379pub enum DRep {
380 Key(AddrKeyhash),
381 Script(ScriptHash),
382 Abstain,
383 NoConfidence,
384}
385
386impl<'b, C> minicbor::decode::Decode<'b, C> for DRep {
387 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
388 d.array()?;
389 let variant = d.u16()?;
390
391 match variant {
392 0 => Ok(DRep::Key(d.decode_with(ctx)?)),
393 1 => Ok(DRep::Script(d.decode_with(ctx)?)),
394 2 => Ok(DRep::Abstain),
395 3 => Ok(DRep::NoConfidence),
396 _ => Err(minicbor::decode::Error::message(
397 "invalid variant id for DRep",
398 )),
399 }
400 }
401}
402
403impl<C> minicbor::encode::Encode<C> for DRep {
404 fn encode<W: minicbor::encode::Write>(
405 &self,
406 e: &mut minicbor::Encoder<W>,
407 ctx: &mut C,
408 ) -> Result<(), minicbor::encode::Error<W::Error>> {
409 match self {
410 DRep::Key(h) => {
411 e.array(2)?;
412 e.encode_with(0, ctx)?;
413 e.encode_with(h, ctx)?;
414
415 Ok(())
416 }
417 DRep::Script(h) => {
418 e.array(2)?;
419 e.encode_with(1, ctx)?;
420 e.encode_with(h, ctx)?;
421
422 Ok(())
423 }
424 DRep::Abstain => {
425 e.array(1)?;
426 e.encode_with(2, ctx)?;
427
428 Ok(())
429 }
430 DRep::NoConfidence => {
431 e.array(1)?;
432 e.encode_with(3, ctx)?;
433
434 Ok(())
435 }
436 }
437 }
438}
439
440pub type DRepCredential = StakeCredential;
441
442pub type CommitteeColdCredential = StakeCredential;
443
444pub type CommitteeHotCredential = StakeCredential;
445
446#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
447#[cbor(index_only)]
448pub enum Language {
449 #[n(0)]
450 PlutusV1,
451
452 #[n(1)]
453 PlutusV2,
454
455 #[n(2)]
456 PlutusV3,
457}
458
459#[deprecated(since = "0.31.0", note = "use `CostModels` instead")]
460pub type CostMdls = CostModels;
461
462#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
463#[cbor(map)]
464pub struct CostModels {
465 #[n(0)]
466 pub plutus_v1: Option<CostModel>,
467
468 #[n(1)]
469 pub plutus_v2: Option<CostModel>,
470
471 #[n(2)]
472 pub plutus_v3: Option<CostModel>,
473}
474
475#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
476#[cbor(map)]
477pub struct ProtocolParamUpdate {
478 #[n(0)]
479 pub minfee_a: Option<u64>,
480 #[n(1)]
481 pub minfee_b: Option<u64>,
482 #[n(2)]
483 pub max_block_body_size: Option<u64>,
484 #[n(3)]
485 pub max_transaction_size: Option<u64>,
486 #[n(4)]
487 pub max_block_header_size: Option<u64>,
488 #[n(5)]
489 pub key_deposit: Option<Coin>,
490 #[n(6)]
491 pub pool_deposit: Option<Coin>,
492 #[n(7)]
493 pub maximum_epoch: Option<Epoch>,
494 #[n(8)]
495 pub desired_number_of_stake_pools: Option<u64>,
496 #[n(9)]
497 pub pool_pledge_influence: Option<RationalNumber>,
498 #[n(10)]
499 pub expansion_rate: Option<UnitInterval>,
500 #[n(11)]
501 pub treasury_growth_rate: Option<UnitInterval>,
502
503 #[n(16)]
504 pub min_pool_cost: Option<Coin>,
505 #[n(17)]
506 pub ada_per_utxo_byte: Option<Coin>,
507 #[n(18)]
508 pub cost_models_for_script_languages: Option<CostModels>,
509 #[n(19)]
510 pub execution_costs: Option<ExUnitPrices>,
511 #[n(20)]
512 pub max_tx_ex_units: Option<ExUnits>,
513 #[n(21)]
514 pub max_block_ex_units: Option<ExUnits>,
515 #[n(22)]
516 pub max_value_size: Option<u64>,
517 #[n(23)]
518 pub collateral_percentage: Option<u64>,
519 #[n(24)]
520 pub max_collateral_inputs: Option<u64>,
521
522 #[n(25)]
523 pub pool_voting_thresholds: Option<PoolVotingThresholds>,
524 #[n(26)]
525 pub drep_voting_thresholds: Option<DRepVotingThresholds>,
526 #[n(27)]
527 pub min_committee_size: Option<u64>,
528 #[n(28)]
529 pub committee_term_limit: Option<Epoch>,
530 #[n(29)]
531 pub governance_action_validity_period: Option<Epoch>,
532 #[n(30)]
533 pub governance_action_deposit: Option<Coin>,
534 #[n(31)]
535 pub drep_deposit: Option<Coin>,
536 #[n(32)]
537 pub drep_inactivity_period: Option<Epoch>,
538 #[n(33)]
539 pub minfee_refscript_cost_per_byte: Option<UnitInterval>,
540}
541
542#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
543pub struct Update {
544 #[n(0)]
545 pub proposed_protocol_parameter_updates: KeyValuePairs<Genesishash, ProtocolParamUpdate>,
546
547 #[n(1)]
548 pub epoch: Epoch,
549}
550
551#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
552pub struct PoolVotingThresholds {
553 pub motion_no_confidence: UnitInterval,
554 pub committee_normal: UnitInterval,
555 pub committee_no_confidence: UnitInterval,
556 pub hard_fork_initiation: UnitInterval,
557 pub security_voting_threshold: UnitInterval,
558}
559
560impl<'b, C> minicbor::Decode<'b, C> for PoolVotingThresholds {
561 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
562 d.array()?;
563
564 Ok(Self {
565 motion_no_confidence: d.decode_with(ctx)?,
566 committee_normal: d.decode_with(ctx)?,
567 committee_no_confidence: d.decode_with(ctx)?,
568 hard_fork_initiation: d.decode_with(ctx)?,
569 security_voting_threshold: d.decode_with(ctx)?,
570 })
571 }
572}
573
574impl<C> minicbor::Encode<C> for PoolVotingThresholds {
575 fn encode<W: minicbor::encode::Write>(
576 &self,
577 e: &mut minicbor::Encoder<W>,
578 ctx: &mut C,
579 ) -> Result<(), minicbor::encode::Error<W::Error>> {
580 e.array(5)?;
581
582 e.encode_with(&self.motion_no_confidence, ctx)?;
583 e.encode_with(&self.committee_normal, ctx)?;
584 e.encode_with(&self.committee_no_confidence, ctx)?;
585 e.encode_with(&self.hard_fork_initiation, ctx)?;
586 e.encode_with(&self.security_voting_threshold, ctx)?;
587
588 Ok(())
589 }
590}
591
592#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
593pub struct DRepVotingThresholds {
594 pub motion_no_confidence: UnitInterval,
595 pub committee_normal: UnitInterval,
596 pub committee_no_confidence: UnitInterval,
597 pub update_constitution: UnitInterval,
598 pub hard_fork_initiation: UnitInterval,
599 pub pp_network_group: UnitInterval,
600 pub pp_economic_group: UnitInterval,
601 pub pp_technical_group: UnitInterval,
602 pub pp_governance_group: UnitInterval,
603 pub treasury_withdrawal: UnitInterval,
604}
605
606impl<'b, C> minicbor::Decode<'b, C> for DRepVotingThresholds {
607 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
608 d.array()?;
609
610 Ok(Self {
611 motion_no_confidence: d.decode_with(ctx)?,
612 committee_normal: d.decode_with(ctx)?,
613 committee_no_confidence: d.decode_with(ctx)?,
614 update_constitution: d.decode_with(ctx)?,
615 hard_fork_initiation: d.decode_with(ctx)?,
616 pp_network_group: d.decode_with(ctx)?,
617 pp_economic_group: d.decode_with(ctx)?,
618 pp_technical_group: d.decode_with(ctx)?,
619 pp_governance_group: d.decode_with(ctx)?,
620 treasury_withdrawal: d.decode_with(ctx)?,
621 })
622 }
623}
624
625impl<C> minicbor::Encode<C> for DRepVotingThresholds {
626 fn encode<W: minicbor::encode::Write>(
627 &self,
628 e: &mut minicbor::Encoder<W>,
629 ctx: &mut C,
630 ) -> Result<(), minicbor::encode::Error<W::Error>> {
631 e.array(10)?;
632
633 e.encode_with(&self.motion_no_confidence, ctx)?;
634 e.encode_with(&self.committee_normal, ctx)?;
635 e.encode_with(&self.committee_no_confidence, ctx)?;
636 e.encode_with(&self.update_constitution, ctx)?;
637 e.encode_with(&self.hard_fork_initiation, ctx)?;
638 e.encode_with(&self.pp_network_group, ctx)?;
639 e.encode_with(&self.pp_economic_group, ctx)?;
640 e.encode_with(&self.pp_technical_group, ctx)?;
641 e.encode_with(&self.pp_governance_group, ctx)?;
642 e.encode_with(&self.treasury_withdrawal, ctx)?;
643
644 Ok(())
645 }
646}
647
648#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
649#[cbor(map)]
650pub struct PseudoTransactionBody<T1> {
651 #[n(0)]
652 pub inputs: Set<TransactionInput>,
653
654 #[n(1)]
655 pub outputs: Vec<T1>,
656
657 #[n(2)]
658 pub fee: Coin,
659
660 #[n(3)]
661 pub ttl: Option<u64>,
662
663 #[n(4)]
664 pub certificates: Option<NonEmptySet<Certificate>>,
665
666 #[n(5)]
667 pub withdrawals: Option<NonEmptyKeyValuePairs<RewardAccount, Coin>>,
668
669 #[n(7)]
670 pub auxiliary_data_hash: Option<Bytes>,
671
672 #[n(8)]
673 pub validity_interval_start: Option<u64>,
674
675 #[n(9)]
676 pub mint: Option<Multiasset<NonZeroInt>>,
677
678 #[n(11)]
679 pub script_data_hash: Option<Hash<32>>,
680
681 #[n(13)]
682 pub collateral: Option<NonEmptySet<TransactionInput>>,
683
684 #[n(14)]
685 pub required_signers: Option<RequiredSigners>,
686
687 #[n(15)]
688 pub network_id: Option<NetworkId>,
689
690 #[n(16)]
691 pub collateral_return: Option<T1>,
692
693 #[n(17)]
694 pub total_collateral: Option<Coin>,
695
696 #[n(18)]
697 pub reference_inputs: Option<NonEmptySet<TransactionInput>>,
698
699 #[n(19)]
701 pub voting_procedures: Option<VotingProcedures>,
702
703 #[n(20)]
704 pub proposal_procedures: Option<NonEmptySet<ProposalProcedure>>,
705
706 #[n(21)]
707 pub treasury_value: Option<Coin>,
708
709 #[n(22)]
710 pub donation: Option<PositiveCoin>,
711}
712
713pub type TransactionBody = PseudoTransactionBody<TransactionOutput>;
714
715pub type MintedTransactionBody<'a> = PseudoTransactionBody<MintedTransactionOutput<'a>>;
716
717impl<'a> From<MintedTransactionBody<'a>> for TransactionBody {
718 fn from(value: MintedTransactionBody<'a>) -> Self {
719 Self {
720 inputs: value.inputs,
721 outputs: value.outputs.into_iter().map(|x| x.into()).collect(),
722 fee: value.fee,
723 ttl: value.ttl,
724 certificates: value.certificates,
725 withdrawals: value.withdrawals,
726 auxiliary_data_hash: value.auxiliary_data_hash,
727 validity_interval_start: value.validity_interval_start,
728 mint: value.mint,
729 script_data_hash: value.script_data_hash,
730 collateral: value.collateral,
731 required_signers: value.required_signers,
732 network_id: value.network_id,
733 collateral_return: value.collateral_return.map(|x| x.into()),
734 total_collateral: value.total_collateral,
735 reference_inputs: value.reference_inputs,
736 voting_procedures: value.voting_procedures,
737 proposal_procedures: value.proposal_procedures,
738 treasury_value: value.treasury_value,
739 donation: value.donation,
740 }
741 }
742}
743
744#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
745pub enum Vote {
746 No,
747 Yes,
748 Abstain,
749}
750
751impl<'b, C> minicbor::Decode<'b, C> for Vote {
752 fn decode(
753 d: &mut minicbor::Decoder<'b>,
754 _ctx: &mut C,
755 ) -> Result<Self, minicbor::decode::Error> {
756 match d.u8()? {
757 0 => Ok(Self::No),
758 1 => Ok(Self::Yes),
759 2 => Ok(Self::Abstain),
760 _ => Err(minicbor::decode::Error::message(
761 "invalid number for Vote kind",
762 )),
763 }
764 }
765}
766
767impl<C> minicbor::Encode<C> for Vote {
768 fn encode<W: minicbor::encode::Write>(
769 &self,
770 e: &mut minicbor::Encoder<W>,
771 _ctx: &mut C,
772 ) -> Result<(), minicbor::encode::Error<W::Error>> {
773 match &self {
774 Self::No => e.u8(0)?,
775 Self::Yes => e.u8(1)?,
776 Self::Abstain => e.u8(2)?,
777 };
778
779 Ok(())
780 }
781}
782
783pub type VotingProcedures =
784 NonEmptyKeyValuePairs<Voter, NonEmptyKeyValuePairs<GovActionId, VotingProcedure>>;
785
786#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
787pub struct VotingProcedure {
788 pub vote: Vote,
789 pub anchor: Nullable<Anchor>,
790}
791
792impl<'b, C> minicbor::Decode<'b, C> for VotingProcedure {
793 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
794 d.array()?;
795
796 Ok(Self {
797 vote: d.decode_with(ctx)?,
798 anchor: d.decode_with(ctx)?,
799 })
800 }
801}
802
803impl<C> minicbor::Encode<C> for VotingProcedure {
804 fn encode<W: minicbor::encode::Write>(
805 &self,
806 e: &mut minicbor::Encoder<W>,
807 ctx: &mut C,
808 ) -> Result<(), minicbor::encode::Error<W::Error>> {
809 e.array(2)?;
810
811 e.encode_with(&self.vote, ctx)?;
812 e.encode_with(&self.anchor, ctx)?;
813
814 Ok(())
815 }
816}
817
818#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
819pub struct ProposalProcedure {
820 pub deposit: Coin,
821 pub reward_account: RewardAccount,
822 pub gov_action: GovAction,
823 pub anchor: Anchor,
824}
825
826impl<'b, C> minicbor::Decode<'b, C> for ProposalProcedure {
827 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
828 d.array()?;
829
830 Ok(Self {
831 deposit: d.decode_with(ctx)?,
832 reward_account: d.decode_with(ctx)?,
833 gov_action: d.decode_with(ctx)?,
834 anchor: d.decode_with(ctx)?,
835 })
836 }
837}
838
839impl<C> minicbor::Encode<C> for ProposalProcedure {
840 fn encode<W: minicbor::encode::Write>(
841 &self,
842 e: &mut minicbor::Encoder<W>,
843 ctx: &mut C,
844 ) -> Result<(), minicbor::encode::Error<W::Error>> {
845 e.array(4)?;
846
847 e.encode_with(self.deposit, ctx)?;
848 e.encode_with(&self.reward_account, ctx)?;
849 e.encode_with(&self.gov_action, ctx)?;
850 e.encode_with(&self.anchor, ctx)?;
851
852 Ok(())
853 }
854}
855
856#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
857pub enum GovAction {
858 ParameterChange(
859 Nullable<GovActionId>,
860 Box<ProtocolParamUpdate>,
861 Nullable<ScriptHash>,
862 ),
863 HardForkInitiation(Nullable<GovActionId>, ProtocolVersion),
864 TreasuryWithdrawals(KeyValuePairs<RewardAccount, Coin>, Nullable<ScriptHash>),
865 NoConfidence(Nullable<GovActionId>),
866 UpdateCommittee(
867 Nullable<GovActionId>,
868 Set<CommitteeColdCredential>,
869 KeyValuePairs<CommitteeColdCredential, Epoch>,
870 UnitInterval,
871 ),
872 NewConstitution(Nullable<GovActionId>, Constitution),
873 Information,
874}
875
876impl<'b, C> minicbor::decode::Decode<'b, C> for GovAction {
877 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
878 d.array()?;
879 let variant = d.u16()?;
880
881 match variant {
882 0 => {
883 let a = d.decode_with(ctx)?;
884 let b = d.decode_with(ctx)?;
885 let c = d.decode_with(ctx)?;
886 Ok(GovAction::ParameterChange(a, b, c))
887 }
888 1 => {
889 let a = d.decode_with(ctx)?;
890 let b = d.decode_with(ctx)?;
891 Ok(GovAction::HardForkInitiation(a, b))
892 }
893 2 => {
894 let a = d.decode_with(ctx)?;
895 let b = d.decode_with(ctx)?;
896 Ok(GovAction::TreasuryWithdrawals(a, b))
897 }
898 3 => {
899 let a = d.decode_with(ctx)?;
900 Ok(GovAction::NoConfidence(a))
901 }
902 4 => {
903 let a = d.decode_with(ctx)?;
904 let b = d.decode_with(ctx)?;
905 let c = d.decode_with(ctx)?;
906 let d = d.decode_with(ctx)?;
907 Ok(GovAction::UpdateCommittee(a, b, c, d))
908 }
909 5 => {
910 let a = d.decode_with(ctx)?;
911 let b = d.decode_with(ctx)?;
912 Ok(GovAction::NewConstitution(a, b))
913 }
914 6 => Ok(GovAction::Information),
915 _ => Err(minicbor::decode::Error::message(
916 "unknown variant id for certificate",
917 )),
918 }
919 }
920}
921
922impl<C> minicbor::encode::Encode<C> for GovAction {
923 fn encode<W: minicbor::encode::Write>(
924 &self,
925 e: &mut minicbor::Encoder<W>,
926 ctx: &mut C,
927 ) -> Result<(), minicbor::encode::Error<W::Error>> {
928 match self {
929 GovAction::ParameterChange(a, b, c) => {
930 e.array(4)?;
931 e.u16(0)?;
932 e.encode_with(a, ctx)?;
933 e.encode_with(b, ctx)?;
934 e.encode_with(c, ctx)?;
935 }
936 GovAction::HardForkInitiation(a, b) => {
937 e.array(3)?;
938 e.u16(1)?;
939 e.encode_with(a, ctx)?;
940 e.encode_with(b, ctx)?;
941 }
942 GovAction::TreasuryWithdrawals(a, b) => {
943 e.array(3)?;
944 e.u16(2)?;
945 e.encode_with(a, ctx)?;
946 e.encode_with(b, ctx)?;
947 }
948 GovAction::NoConfidence(a) => {
949 e.array(2)?;
950 e.u16(3)?;
951 e.encode_with(a, ctx)?;
952 }
953 GovAction::UpdateCommittee(a, b, c, d) => {
954 e.array(5)?;
955 e.u16(4)?;
956 e.encode_with(a, ctx)?;
957 e.encode_with(b, ctx)?;
958 e.encode_with(c, ctx)?;
959 e.encode_with(d, ctx)?;
960 }
961 GovAction::NewConstitution(a, b) => {
962 e.array(3)?;
963 e.u16(5)?;
964 e.encode_with(a, ctx)?;
965 e.encode_with(b, ctx)?;
966 }
967 GovAction::Information => {
969 e.array(1)?;
970 e.u16(6)?;
971 }
972 }
973
974 Ok(())
975 }
976}
977
978#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
979pub struct Constitution {
980 pub anchor: Anchor,
981 pub guardrail_script: Nullable<ScriptHash>,
982}
983
984impl<'b, C> minicbor::Decode<'b, C> for Constitution {
985 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
986 d.array()?;
987
988 Ok(Self {
989 anchor: d.decode_with(ctx)?,
990 guardrail_script: d.decode_with(ctx)?,
991 })
992 }
993}
994
995impl<C> minicbor::Encode<C> for Constitution {
996 fn encode<W: minicbor::encode::Write>(
997 &self,
998 e: &mut minicbor::Encoder<W>,
999 ctx: &mut C,
1000 ) -> Result<(), minicbor::encode::Error<W::Error>> {
1001 e.array(2)?;
1002
1003 e.encode_with(&self.anchor, ctx)?;
1004 e.encode_with(&self.guardrail_script, ctx)?;
1005
1006 Ok(())
1007 }
1008}
1009
1010#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Eq, Ord, Clone)]
1011pub enum Voter {
1012 ConstitutionalCommitteeScript(ScriptHash),
1013 ConstitutionalCommitteeKey(AddrKeyhash),
1014 DRepScript(ScriptHash),
1015 DRepKey(AddrKeyhash),
1016 StakePoolKey(AddrKeyhash),
1017}
1018
1019impl<'b, C> minicbor::decode::Decode<'b, C> for Voter {
1020 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
1021 d.array()?;
1022 let variant = d.u16()?;
1023
1024 match variant {
1025 0 => Ok(Voter::ConstitutionalCommitteeKey(d.decode_with(ctx)?)),
1026 1 => Ok(Voter::ConstitutionalCommitteeScript(d.decode_with(ctx)?)),
1027 2 => Ok(Voter::DRepKey(d.decode_with(ctx)?)),
1028 3 => Ok(Voter::DRepScript(d.decode_with(ctx)?)),
1029 4 => Ok(Voter::StakePoolKey(d.decode_with(ctx)?)),
1030 _ => Err(minicbor::decode::Error::message(
1031 "invalid variant id for DRep",
1032 )),
1033 }
1034 }
1035}
1036
1037impl<C> minicbor::encode::Encode<C> for Voter {
1038 fn encode<W: minicbor::encode::Write>(
1039 &self,
1040 e: &mut minicbor::Encoder<W>,
1041 ctx: &mut C,
1042 ) -> Result<(), minicbor::encode::Error<W::Error>> {
1043 e.array(2)?;
1044
1045 match self {
1046 Voter::ConstitutionalCommitteeKey(h) => {
1047 e.encode_with(0, ctx)?;
1048 e.encode_with(h, ctx)?;
1049
1050 Ok(())
1051 }
1052 Voter::ConstitutionalCommitteeScript(h) => {
1053 e.encode_with(1, ctx)?;
1054 e.encode_with(h, ctx)?;
1055
1056 Ok(())
1057 }
1058 Voter::DRepKey(h) => {
1059 e.encode_with(2, ctx)?;
1060 e.encode_with(h, ctx)?;
1061
1062 Ok(())
1063 }
1064 Voter::DRepScript(h) => {
1065 e.encode_with(3, ctx)?;
1066 e.encode_with(h, ctx)?;
1067
1068 Ok(())
1069 }
1070 Voter::StakePoolKey(h) => {
1071 e.encode_with(4, ctx)?;
1072 e.encode_with(h, ctx)?;
1073
1074 Ok(())
1075 }
1076 }
1077 }
1078}
1079
1080#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Eq, Ord, Clone)]
1081pub struct Anchor {
1082 pub url: String,
1083 pub content_hash: Hash<32>,
1084}
1085
1086impl<'b, C> minicbor::Decode<'b, C> for Anchor {
1087 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
1088 d.array()?;
1089
1090 Ok(Self {
1091 url: d.decode_with(ctx)?,
1092 content_hash: d.decode_with(ctx)?,
1093 })
1094 }
1095}
1096
1097impl<C> minicbor::Encode<C> for Anchor {
1098 fn encode<W: minicbor::encode::Write>(
1099 &self,
1100 e: &mut minicbor::Encoder<W>,
1101 ctx: &mut C,
1102 ) -> Result<(), minicbor::encode::Error<W::Error>> {
1103 e.array(2)?;
1104
1105 e.encode_with(&self.url, ctx)?;
1106 e.encode_with(self.content_hash, ctx)?;
1107
1108 Ok(())
1109 }
1110}
1111
1112#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
1113pub struct GovActionId {
1114 pub transaction_id: Hash<32>,
1115 pub action_index: u32,
1116}
1117
1118impl<'b, C> minicbor::Decode<'b, C> for GovActionId {
1119 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
1120 d.array()?;
1121
1122 Ok(Self {
1123 transaction_id: d.decode_with(ctx)?,
1124 action_index: d.decode_with(ctx)?,
1125 })
1126 }
1127}
1128
1129impl<C> minicbor::Encode<C> for GovActionId {
1130 fn encode<W: minicbor::encode::Write>(
1131 &self,
1132 e: &mut minicbor::Encoder<W>,
1133 ctx: &mut C,
1134 ) -> Result<(), minicbor::encode::Error<W::Error>> {
1135 e.array(2)?;
1136
1137 e.encode_with(self.transaction_id, ctx)?;
1138 e.encode_with(self.action_index, ctx)?;
1139
1140 Ok(())
1141 }
1142}
1143
1144#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
1145pub enum PseudoTransactionOutput<T> {
1146 Legacy(LegacyTransactionOutput),
1147 PostAlonzo(T),
1148}
1149
1150impl<'b, C, T> minicbor::Decode<'b, C> for PseudoTransactionOutput<T>
1151where
1152 T: minicbor::Decode<'b, C>,
1153{
1154 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
1155 match d.datatype()? {
1156 minicbor::data::Type::Array | minicbor::data::Type::ArrayIndef => {
1157 Ok(PseudoTransactionOutput::Legacy(d.decode_with(ctx)?))
1158 }
1159 minicbor::data::Type::Map | minicbor::data::Type::MapIndef => {
1160 Ok(PseudoTransactionOutput::PostAlonzo(d.decode_with(ctx)?))
1161 }
1162 _ => Err(minicbor::decode::Error::message(
1163 "invalid type for transaction output struct",
1164 )),
1165 }
1166 }
1167}
1168
1169impl<C, T> minicbor::Encode<C> for PseudoTransactionOutput<T>
1170where
1171 T: minicbor::Encode<C>,
1172{
1173 fn encode<W: minicbor::encode::Write>(
1174 &self,
1175 e: &mut minicbor::Encoder<W>,
1176 ctx: &mut C,
1177 ) -> Result<(), minicbor::encode::Error<W::Error>> {
1178 match self {
1179 PseudoTransactionOutput::Legacy(x) => x.encode(e, ctx),
1180 PseudoTransactionOutput::PostAlonzo(x) => x.encode(e, ctx),
1181 }
1182 }
1183}
1184
1185pub type PostAlonzoTransactionOutput =
1186 crate::babbage::PseudoPostAlonzoTransactionOutput<Value, DatumOption, ScriptRef>;
1187
1188pub type TransactionOutput = PseudoTransactionOutput<PostAlonzoTransactionOutput>;
1189
1190pub type MintedTransactionOutput<'b> =
1191 PseudoTransactionOutput<MintedPostAlonzoTransactionOutput<'b>>;
1192
1193impl<'b> From<MintedTransactionOutput<'b>> for TransactionOutput {
1194 fn from(value: MintedTransactionOutput<'b>) -> Self {
1195 match value {
1196 PseudoTransactionOutput::Legacy(x) => Self::Legacy(x),
1197 PseudoTransactionOutput::PostAlonzo(x) => Self::PostAlonzo(x.into()),
1198 }
1199 }
1200}
1201
1202pub type MintedPostAlonzoTransactionOutput<'b> = crate::babbage::PseudoPostAlonzoTransactionOutput<
1203 Value,
1204 MintedDatumOption<'b>,
1205 MintedScriptRef<'b>,
1206>;
1207
1208impl<'b> From<MintedPostAlonzoTransactionOutput<'b>> for PostAlonzoTransactionOutput {
1209 fn from(value: MintedPostAlonzoTransactionOutput<'b>) -> Self {
1210 Self {
1211 address: value.address,
1212 value: value.value,
1213 datum_option: value.datum_option.map(|x| x.into()),
1214 script_ref: value.script_ref.map(|x| CborWrap(x.unwrap().into())),
1215 }
1216 }
1217}
1218
1219pub use crate::alonzo::VKeyWitness;
1220
1221pub use crate::alonzo::NativeScript;
1222
1223#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
1224pub struct ExUnitPrices {
1225 #[n(0)]
1226 pub mem_price: RationalNumber,
1227
1228 #[n(1)]
1229 pub step_price: RationalNumber,
1230}
1231
1232#[derive(
1233 Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy,
1234)]
1235#[cbor(index_only)]
1236pub enum RedeemerTag {
1237 #[n(0)]
1238 Spend,
1239 #[n(1)]
1240 Mint,
1241 #[n(2)]
1242 Cert,
1243 #[n(3)]
1244 Reward,
1245 #[n(4)]
1246 Vote,
1247 #[n(5)]
1248 Propose,
1249}
1250
1251#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
1252pub struct Redeemer {
1253 #[n(0)]
1254 pub tag: RedeemerTag,
1255
1256 #[n(1)]
1257 pub index: u32,
1258
1259 #[n(2)]
1260 pub data: PlutusData,
1261
1262 #[n(3)]
1263 pub ex_units: ExUnits,
1264}
1265
1266#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
1267pub struct RedeemersKey {
1268 #[n(0)]
1269 pub tag: RedeemerTag,
1270 #[n(1)]
1271 pub index: u32,
1272}
1273
1274#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
1275pub struct RedeemersValue {
1276 #[n(0)]
1277 pub data: PlutusData,
1278 #[n(1)]
1279 pub ex_units: ExUnits,
1280}
1281
1282#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
1283pub enum Redeemers {
1284 List(MaybeIndefArray<Redeemer>),
1285 Map(NonEmptyKeyValuePairs<RedeemersKey, RedeemersValue>),
1286}
1287
1288impl From<NonEmptyKeyValuePairs<RedeemersKey, RedeemersValue>> for Redeemers {
1289 fn from(value: NonEmptyKeyValuePairs<RedeemersKey, RedeemersValue>) -> Self {
1290 Redeemers::Map(value)
1291 }
1292}
1293
1294impl<'b, C> minicbor::Decode<'b, C> for Redeemers {
1295 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
1296 match d.datatype()? {
1297 minicbor::data::Type::Array | minicbor::data::Type::ArrayIndef => {
1298 Ok(Self::List(d.decode_with(ctx)?))
1299 }
1300 minicbor::data::Type::Map | minicbor::data::Type::MapIndef => {
1301 Ok(Self::Map(d.decode_with(ctx)?))
1302 }
1303 _ => Err(minicbor::decode::Error::message(
1304 "invalid type for redeemers struct",
1305 )),
1306 }
1307 }
1308}
1309
1310impl<C> minicbor::Encode<C> for Redeemers {
1311 fn encode<W: minicbor::encode::Write>(
1312 &self,
1313 e: &mut minicbor::Encoder<W>,
1314 ctx: &mut C,
1315 ) -> Result<(), minicbor::encode::Error<W::Error>> {
1316 match self {
1317 Self::List(x) => e.encode_with(x, ctx)?,
1318 Self::Map(x) => e.encode_with(x, ctx)?,
1319 };
1320
1321 Ok(())
1322 }
1323}
1324
1325pub use crate::alonzo::BootstrapWitness;
1326
1327#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
1328#[cbor(map)]
1329pub struct WitnessSet {
1330 #[n(0)]
1331 pub vkeywitness: Option<NonEmptySet<VKeyWitness>>,
1332
1333 #[n(1)]
1334 pub native_script: Option<NonEmptySet<NativeScript>>,
1335
1336 #[n(2)]
1337 pub bootstrap_witness: Option<NonEmptySet<BootstrapWitness>>,
1338
1339 #[n(3)]
1340 pub plutus_v1_script: Option<NonEmptySet<PlutusScript<1>>>,
1341
1342 #[n(4)]
1343 pub plutus_data: Option<NonEmptySet<PlutusData>>,
1344
1345 #[n(5)]
1346 pub redeemer: Option<Redeemers>,
1347
1348 #[n(6)]
1349 pub plutus_v2_script: Option<NonEmptySet<PlutusScript<2>>>,
1350
1351 #[n(7)]
1352 pub plutus_v3_script: Option<NonEmptySet<PlutusScript<3>>>,
1353}
1354
1355#[derive(Encode, Decode, Debug, PartialEq, Clone)]
1356#[cbor(map)]
1357pub struct MintedWitnessSet<'b> {
1358 #[n(0)]
1359 pub vkeywitness: Option<NonEmptySet<VKeyWitness>>,
1360
1361 #[n(1)]
1362 pub native_script: Option<NonEmptySet<KeepRaw<'b, NativeScript>>>,
1363
1364 #[n(2)]
1365 pub bootstrap_witness: Option<NonEmptySet<BootstrapWitness>>,
1366
1367 #[n(3)]
1368 pub plutus_v1_script: Option<NonEmptySet<PlutusScript<1>>>,
1369
1370 #[b(4)]
1371 pub plutus_data: Option<NonEmptySet<KeepRaw<'b, PlutusData>>>,
1372
1373 #[n(5)]
1374 pub redeemer: Option<KeepRaw<'b, Redeemers>>,
1375
1376 #[n(6)]
1377 pub plutus_v2_script: Option<NonEmptySet<PlutusScript<2>>>,
1378
1379 #[n(7)]
1380 pub plutus_v3_script: Option<NonEmptySet<PlutusScript<3>>>,
1381}
1382
1383impl<'b> From<MintedWitnessSet<'b>> for WitnessSet {
1384 fn from(x: MintedWitnessSet<'b>) -> Self {
1385 WitnessSet {
1386 vkeywitness: x.vkeywitness,
1387 native_script: x.native_script.map(Into::into),
1388 bootstrap_witness: x.bootstrap_witness,
1389 plutus_v1_script: x.plutus_v1_script,
1390 plutus_data: x.plutus_data.map(Into::into),
1391 redeemer: x.redeemer.map(|x| x.unwrap()),
1392 plutus_v2_script: x.plutus_v2_script,
1393 plutus_v3_script: x.plutus_v3_script,
1394 }
1395 }
1396}
1397
1398#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
1399#[cbor(map)]
1400pub struct PostAlonzoAuxiliaryData {
1401 #[n(0)]
1402 pub metadata: Option<Metadata>,
1403
1404 #[n(1)]
1405 pub native_scripts: Option<Vec<NativeScript>>,
1406
1407 #[n(2)]
1408 pub plutus_v1_scripts: Option<Vec<PlutusScript<1>>>,
1409
1410 #[n(3)]
1411 pub plutus_v2_scripts: Option<Vec<PlutusScript<2>>>,
1412
1413 #[n(4)]
1414 pub plutus_v3_scripts: Option<Vec<PlutusScript<3>>>,
1415}
1416
1417pub use crate::babbage::DatumHash;
1418
1419pub use crate::babbage::PseudoDatumOption;
1420
1421pub use crate::babbage::DatumOption;
1422
1423pub use crate::babbage::MintedDatumOption;
1424
1425#[deprecated(since = "0.31.0", note = "use `PlutusScript<1>` instead")]
1426pub type PlutusV1Script = PlutusScript<1>;
1427
1428#[deprecated(since = "0.31.0", note = "use `PlutusScript<2>` instead")]
1429pub type PlutusV2Script = PlutusScript<2>;
1430
1431#[deprecated(since = "0.31.0", note = "use `PlutusScript<3>` instead")]
1432pub type PlutusV3Script = PlutusScript<3>;
1433
1434#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
1436pub enum PseudoScript<T1> {
1437 NativeScript(T1),
1438 PlutusV1Script(PlutusScript<1>),
1439 PlutusV2Script(PlutusScript<2>),
1440 PlutusV3Script(PlutusScript<3>),
1441}
1442
1443pub type ScriptRef = PseudoScript<NativeScript>;
1445
1446pub type MintedScriptRef<'b> = PseudoScript<KeepRaw<'b, NativeScript>>;
1447
1448impl<'b> From<MintedScriptRef<'b>> for ScriptRef {
1449 fn from(value: MintedScriptRef<'b>) -> Self {
1450 match value {
1451 PseudoScript::NativeScript(x) => Self::NativeScript(x.unwrap()),
1452 PseudoScript::PlutusV1Script(x) => Self::PlutusV1Script(x),
1453 PseudoScript::PlutusV2Script(x) => Self::PlutusV2Script(x),
1454 PseudoScript::PlutusV3Script(x) => Self::PlutusV3Script(x),
1455 }
1456 }
1457}
1458
1459impl<'b> From<babbage::MintedScriptRef<'b>> for MintedScriptRef<'b> {
1461 fn from(value: babbage::MintedScriptRef<'b>) -> Self {
1462 match value {
1463 babbage::MintedScriptRef::NativeScript(x) => Self::NativeScript(x),
1464 babbage::MintedScriptRef::PlutusV1Script(x) => Self::PlutusV1Script(x),
1465 babbage::MintedScriptRef::PlutusV2Script(x) => Self::PlutusV2Script(x),
1466 }
1467 }
1468}
1469
1470impl<'b, C, T> minicbor::Decode<'b, C> for PseudoScript<T>
1471where
1472 T: minicbor::Decode<'b, ()>,
1473{
1474 fn decode(
1475 d: &mut minicbor::Decoder<'b>,
1476 _ctx: &mut C,
1477 ) -> Result<Self, minicbor::decode::Error> {
1478 d.array()?;
1479
1480 match d.u8()? {
1481 0 => Ok(Self::NativeScript(d.decode()?)),
1482 1 => Ok(Self::PlutusV1Script(d.decode()?)),
1483 2 => Ok(Self::PlutusV2Script(d.decode()?)),
1484 3 => Ok(Self::PlutusV3Script(d.decode()?)),
1485 x => Err(minicbor::decode::Error::message(format!(
1486 "invalid variant for script enum: {}",
1487 x
1488 ))),
1489 }
1490 }
1491}
1492
1493impl<C, T> minicbor::Encode<C> for PseudoScript<T>
1494where
1495 T: minicbor::Encode<C>,
1496{
1497 fn encode<W: minicbor::encode::Write>(
1498 &self,
1499 e: &mut minicbor::Encoder<W>,
1500 ctx: &mut C,
1501 ) -> Result<(), minicbor::encode::Error<W::Error>> {
1502 match self {
1503 Self::NativeScript(x) => e.encode_with((0, x), ctx)?,
1504 Self::PlutusV1Script(x) => e.encode_with((1, x), ctx)?,
1505 Self::PlutusV2Script(x) => e.encode_with((2, x), ctx)?,
1506 Self::PlutusV3Script(x) => e.encode_with((3, x), ctx)?,
1507 };
1508
1509 Ok(())
1510 }
1511}
1512
1513pub use crate::alonzo::AuxiliaryData;
1514
1515use crate::babbage::MintedHeader;
1516
1517#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
1518pub struct PseudoBlock<T1, T2, T3, T4>
1519where
1520 T4: std::clone::Clone,
1521{
1522 #[n(0)]
1523 pub header: T1,
1524
1525 #[b(1)]
1526 pub transaction_bodies: MaybeIndefArray<T2>,
1527
1528 #[n(2)]
1529 pub transaction_witness_sets: MaybeIndefArray<T3>,
1530
1531 #[n(3)]
1532 pub auxiliary_data_set: KeyValuePairs<TransactionIndex, T4>,
1533
1534 #[n(4)]
1535 pub invalid_transactions: Option<MaybeIndefArray<TransactionIndex>>,
1536}
1537
1538pub type Block = PseudoBlock<Header, TransactionBody, WitnessSet, AuxiliaryData>;
1539
1540pub type MintedBlock<'b> = PseudoBlock<
1546 KeepRaw<'b, MintedHeader<'b>>,
1547 KeepRaw<'b, MintedTransactionBody<'b>>,
1548 KeepRaw<'b, MintedWitnessSet<'b>>,
1549 KeepRaw<'b, AuxiliaryData>,
1550>;
1551
1552impl<'b> From<MintedBlock<'b>> for Block {
1553 fn from(x: MintedBlock<'b>) -> Self {
1554 Block {
1555 header: x.header.unwrap().into(),
1556 transaction_bodies: MaybeIndefArray::Def(
1557 x.transaction_bodies
1558 .iter()
1559 .cloned()
1560 .map(|x| x.unwrap())
1561 .map(TransactionBody::from)
1562 .collect(),
1563 ),
1564 transaction_witness_sets: MaybeIndefArray::Def(
1565 x.transaction_witness_sets
1566 .iter()
1567 .cloned()
1568 .map(|x| x.unwrap())
1569 .map(WitnessSet::from)
1570 .collect(),
1571 ),
1572 auxiliary_data_set: x
1573 .auxiliary_data_set
1574 .to_vec()
1575 .into_iter()
1576 .map(|(k, v)| (k, v.unwrap()))
1577 .collect::<Vec<_>>()
1578 .into(),
1579 invalid_transactions: x.invalid_transactions,
1580 }
1581 }
1582}
1583
1584#[derive(Clone, Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq)]
1585pub struct PseudoTx<T1, T2, T3>
1586where
1587 T1: std::clone::Clone,
1588 T2: std::clone::Clone,
1589 T3: std::clone::Clone,
1590{
1591 #[n(0)]
1592 pub transaction_body: T1,
1593
1594 #[n(1)]
1595 pub transaction_witness_set: T2,
1596
1597 #[n(2)]
1598 pub success: bool,
1599
1600 #[n(3)]
1601 pub auxiliary_data: Nullable<T3>,
1602}
1603
1604pub type Tx = PseudoTx<TransactionBody, WitnessSet, AuxiliaryData>;
1605
1606pub type MintedTx<'b> = PseudoTx<
1607 KeepRaw<'b, MintedTransactionBody<'b>>,
1608 KeepRaw<'b, MintedWitnessSet<'b>>,
1609 KeepRaw<'b, AuxiliaryData>,
1610>;
1611
1612impl<'b> From<MintedTx<'b>> for Tx {
1613 fn from(x: MintedTx<'b>) -> Self {
1614 Tx {
1615 transaction_body: x.transaction_body.unwrap().into(),
1616 transaction_witness_set: x.transaction_witness_set.unwrap().into(),
1617 success: x.success,
1618 auxiliary_data: x.auxiliary_data.map(|x| x.unwrap()),
1619 }
1620 }
1621}
1622
1623#[cfg(test)]
1624mod tests {
1625 use pallas_codec::minicbor;
1626
1627 use super::MintedBlock;
1628
1629 type BlockWrapper<'b> = (u16, MintedBlock<'b>);
1630
1631 #[cfg(test)]
1632 mod tests_voter {
1633 use super::super::Voter;
1634 use crate::Hash;
1635 use std::cmp::Ordering;
1636 use test_case::test_case;
1637
1638 fn fake_hash(prefix: &str) -> Hash<28> {
1639 let null_hash: [u8; 28] = [
1640 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1641 ];
1642 Hash::from(&[prefix.as_bytes(), &null_hash].concat()[0..28])
1643 }
1644
1645 fn cc_script(prefix: &str) -> Voter {
1646 Voter::ConstitutionalCommitteeScript(fake_hash(prefix))
1647 }
1648
1649 fn cc_key(prefix: &str) -> Voter {
1650 Voter::ConstitutionalCommitteeKey(fake_hash(prefix))
1651 }
1652
1653 fn drep_script(prefix: &str) -> Voter {
1654 Voter::DRepScript(fake_hash(prefix))
1655 }
1656
1657 fn drep_key(prefix: &str) -> Voter {
1658 Voter::DRepKey(fake_hash(prefix))
1659 }
1660
1661 fn spo(prefix: &str) -> Voter {
1662 Voter::StakePoolKey(fake_hash(prefix))
1663 }
1664
1665 #[test_case(cc_script("alice"), cc_script("alice") => Ordering::Equal)]
1666 #[test_case(cc_script("alice"), cc_key("alice") => Ordering::Less)]
1667 #[test_case(cc_script("alice"), drep_script("alice") => Ordering::Less)]
1668 #[test_case(cc_script("alice"), drep_key("alice") => Ordering::Less)]
1669 #[test_case(cc_script("alice"), spo("alice") => Ordering::Less)]
1670 #[test_case(cc_script("bob"), cc_script("alice") => Ordering::Greater)]
1671 #[test_case(drep_script("alice"), cc_script("alice") => Ordering::Greater)]
1672 #[test_case(drep_script("alice"), cc_key("alice") => Ordering::Greater)]
1673 #[test_case(drep_script("alice"), drep_script("alice") => Ordering::Equal)]
1674 #[test_case(drep_script("alice"), drep_key("alice") => Ordering::Less)]
1675 #[test_case(drep_script("alice"), spo("alice") => Ordering::Less)]
1676 #[test_case(drep_script("bob"), drep_script("alice") => Ordering::Greater)]
1677 fn voter_ordering(left: Voter, right: Voter) -> Ordering {
1678 left.cmp(&right)
1679 }
1680 }
1681
1682 #[test]
1683 fn block_isomorphic_decoding_encoding() {
1684 let test_blocks = [
1685 include_str!("../../../test_data/conway1.block"),
1686 include_str!("../../../test_data/conway2.block"),
1687 include_str!("../../../test_data/conway3.block"),
1689 include_str!("../../../test_data/conway4.block"),
1691 ];
1692
1693 for (idx, block_str) in test_blocks.iter().enumerate() {
1694 println!("decoding test block {}", idx + 1);
1695 let bytes = hex::decode(block_str).unwrap_or_else(|_| panic!("bad block file {idx}"));
1696
1697 let block: BlockWrapper = minicbor::decode(&bytes)
1698 .unwrap_or_else(|e| panic!("error decoding cbor for file {idx}: {e:?}"));
1699
1700 let bytes2 = minicbor::to_vec(block)
1701 .unwrap_or_else(|e| panic!("error encoding block cbor for file {idx}: {e:?}"));
1702
1703 assert!(bytes.eq(&bytes2), "re-encoded bytes didn't match original");
1704 }
1705 }
1706
1707 }