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, Clone)]
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 ConstitutionalCommitteeKey(AddrKeyhash),
1013 ConstitutionalCommitteeScript(ScriptHash),
1014 DRepKey(AddrKeyhash),
1015 DRepScript(ScriptHash),
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)]
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(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone, Copy)]
1233#[cbor(index_only)]
1234pub enum RedeemerTag {
1235 #[n(0)]
1236 Spend,
1237 #[n(1)]
1238 Mint,
1239 #[n(2)]
1240 Cert,
1241 #[n(3)]
1242 Reward,
1243 #[n(4)]
1244 Vote,
1245 #[n(5)]
1246 Propose,
1247}
1248
1249#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
1250pub struct Redeemer {
1251 #[n(0)]
1252 pub tag: RedeemerTag,
1253
1254 #[n(1)]
1255 pub index: u32,
1256
1257 #[n(2)]
1258 pub data: PlutusData,
1259
1260 #[n(3)]
1261 pub ex_units: ExUnits,
1262}
1263
1264#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
1265pub struct RedeemersKey {
1266 #[n(0)]
1267 pub tag: RedeemerTag,
1268 #[n(1)]
1269 pub index: u32,
1270}
1271
1272#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
1273pub struct RedeemersValue {
1274 #[n(0)]
1275 pub data: PlutusData,
1276 #[n(1)]
1277 pub ex_units: ExUnits,
1278}
1279
1280#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
1281pub enum Redeemers {
1282 List(MaybeIndefArray<Redeemer>),
1283 Map(NonEmptyKeyValuePairs<RedeemersKey, RedeemersValue>),
1284}
1285
1286impl From<NonEmptyKeyValuePairs<RedeemersKey, RedeemersValue>> for Redeemers {
1287 fn from(value: NonEmptyKeyValuePairs<RedeemersKey, RedeemersValue>) -> Self {
1288 Redeemers::Map(value)
1289 }
1290}
1291
1292impl<'b, C> minicbor::Decode<'b, C> for Redeemers {
1293 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
1294 match d.datatype()? {
1295 minicbor::data::Type::Array | minicbor::data::Type::ArrayIndef => {
1296 Ok(Self::List(d.decode_with(ctx)?))
1297 }
1298 minicbor::data::Type::Map | minicbor::data::Type::MapIndef => {
1299 Ok(Self::Map(d.decode_with(ctx)?))
1300 }
1301 _ => Err(minicbor::decode::Error::message(
1302 "invalid type for redeemers struct",
1303 )),
1304 }
1305 }
1306}
1307
1308impl<C> minicbor::Encode<C> for Redeemers {
1309 fn encode<W: minicbor::encode::Write>(
1310 &self,
1311 e: &mut minicbor::Encoder<W>,
1312 ctx: &mut C,
1313 ) -> Result<(), minicbor::encode::Error<W::Error>> {
1314 match self {
1315 Self::List(x) => e.encode_with(x, ctx)?,
1316 Self::Map(x) => e.encode_with(x, ctx)?,
1317 };
1318
1319 Ok(())
1320 }
1321}
1322
1323pub use crate::alonzo::BootstrapWitness;
1324
1325#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
1326#[cbor(map)]
1327pub struct WitnessSet {
1328 #[n(0)]
1329 pub vkeywitness: Option<NonEmptySet<VKeyWitness>>,
1330
1331 #[n(1)]
1332 pub native_script: Option<NonEmptySet<NativeScript>>,
1333
1334 #[n(2)]
1335 pub bootstrap_witness: Option<NonEmptySet<BootstrapWitness>>,
1336
1337 #[n(3)]
1338 pub plutus_v1_script: Option<NonEmptySet<PlutusScript<1>>>,
1339
1340 #[n(4)]
1341 pub plutus_data: Option<NonEmptySet<PlutusData>>,
1342
1343 #[n(5)]
1344 pub redeemer: Option<Redeemers>,
1345
1346 #[n(6)]
1347 pub plutus_v2_script: Option<NonEmptySet<PlutusScript<2>>>,
1348
1349 #[n(7)]
1350 pub plutus_v3_script: Option<NonEmptySet<PlutusScript<3>>>,
1351}
1352
1353#[derive(Encode, Decode, Debug, PartialEq, Clone)]
1354#[cbor(map)]
1355pub struct MintedWitnessSet<'b> {
1356 #[n(0)]
1357 pub vkeywitness: Option<NonEmptySet<VKeyWitness>>,
1358
1359 #[n(1)]
1360 pub native_script: Option<NonEmptySet<KeepRaw<'b, NativeScript>>>,
1361
1362 #[n(2)]
1363 pub bootstrap_witness: Option<NonEmptySet<BootstrapWitness>>,
1364
1365 #[n(3)]
1366 pub plutus_v1_script: Option<NonEmptySet<PlutusScript<1>>>,
1367
1368 #[b(4)]
1369 pub plutus_data: Option<NonEmptySet<KeepRaw<'b, PlutusData>>>,
1370
1371 #[n(5)]
1372 pub redeemer: Option<KeepRaw<'b, Redeemers>>,
1373
1374 #[n(6)]
1375 pub plutus_v2_script: Option<NonEmptySet<PlutusScript<2>>>,
1376
1377 #[n(7)]
1378 pub plutus_v3_script: Option<NonEmptySet<PlutusScript<3>>>,
1379}
1380
1381impl<'b> From<MintedWitnessSet<'b>> for WitnessSet {
1382 fn from(x: MintedWitnessSet<'b>) -> Self {
1383 WitnessSet {
1384 vkeywitness: x.vkeywitness,
1385 native_script: x.native_script.map(Into::into),
1386 bootstrap_witness: x.bootstrap_witness,
1387 plutus_v1_script: x.plutus_v1_script,
1388 plutus_data: x.plutus_data.map(Into::into),
1389 redeemer: x.redeemer.map(|x| x.unwrap()),
1390 plutus_v2_script: x.plutus_v2_script,
1391 plutus_v3_script: x.plutus_v3_script,
1392 }
1393 }
1394}
1395
1396#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
1397#[cbor(map)]
1398pub struct PostAlonzoAuxiliaryData {
1399 #[n(0)]
1400 pub metadata: Option<Metadata>,
1401
1402 #[n(1)]
1403 pub native_scripts: Option<Vec<NativeScript>>,
1404
1405 #[n(2)]
1406 pub plutus_v1_scripts: Option<Vec<PlutusScript<1>>>,
1407
1408 #[n(3)]
1409 pub plutus_v2_scripts: Option<Vec<PlutusScript<2>>>,
1410
1411 #[n(4)]
1412 pub plutus_v3_scripts: Option<Vec<PlutusScript<3>>>,
1413}
1414
1415pub use crate::babbage::DatumHash;
1416
1417pub use crate::babbage::PseudoDatumOption;
1418
1419pub use crate::babbage::DatumOption;
1420
1421pub use crate::babbage::MintedDatumOption;
1422
1423#[deprecated(since = "0.31.0", note = "use `PlutusScript<1>` instead")]
1424pub type PlutusV1Script = PlutusScript<1>;
1425
1426#[deprecated(since = "0.31.0", note = "use `PlutusScript<2>` instead")]
1427pub type PlutusV2Script = PlutusScript<2>;
1428
1429#[deprecated(since = "0.31.0", note = "use `PlutusScript<3>` instead")]
1430pub type PlutusV3Script = PlutusScript<3>;
1431
1432#[derive(Debug, PartialEq, Eq, Clone)]
1434pub enum PseudoScript<T1> {
1435 NativeScript(T1),
1436 PlutusV1Script(PlutusScript<1>),
1437 PlutusV2Script(PlutusScript<2>),
1438 PlutusV3Script(PlutusScript<3>),
1439}
1440
1441pub type ScriptRef = PseudoScript<NativeScript>;
1443
1444pub type MintedScriptRef<'b> = PseudoScript<KeepRaw<'b, NativeScript>>;
1445
1446impl<'b> From<MintedScriptRef<'b>> for ScriptRef {
1447 fn from(value: MintedScriptRef<'b>) -> Self {
1448 match value {
1449 PseudoScript::NativeScript(x) => Self::NativeScript(x.unwrap()),
1450 PseudoScript::PlutusV1Script(x) => Self::PlutusV1Script(x),
1451 PseudoScript::PlutusV2Script(x) => Self::PlutusV2Script(x),
1452 PseudoScript::PlutusV3Script(x) => Self::PlutusV3Script(x),
1453 }
1454 }
1455}
1456
1457impl<'b> From<babbage::MintedScriptRef<'b>> for MintedScriptRef<'b> {
1459 fn from(value: babbage::MintedScriptRef<'b>) -> Self {
1460 match value {
1461 babbage::MintedScriptRef::NativeScript(x) => Self::NativeScript(x),
1462 babbage::MintedScriptRef::PlutusV1Script(x) => Self::PlutusV1Script(x),
1463 babbage::MintedScriptRef::PlutusV2Script(x) => Self::PlutusV2Script(x),
1464 }
1465 }
1466}
1467
1468impl<'b, C, T> minicbor::Decode<'b, C> for PseudoScript<T>
1469where
1470 T: minicbor::Decode<'b, ()>,
1471{
1472 fn decode(
1473 d: &mut minicbor::Decoder<'b>,
1474 _ctx: &mut C,
1475 ) -> Result<Self, minicbor::decode::Error> {
1476 d.array()?;
1477
1478 match d.u8()? {
1479 0 => Ok(Self::NativeScript(d.decode()?)),
1480 1 => Ok(Self::PlutusV1Script(d.decode()?)),
1481 2 => Ok(Self::PlutusV2Script(d.decode()?)),
1482 3 => Ok(Self::PlutusV3Script(d.decode()?)),
1483 x => Err(minicbor::decode::Error::message(format!(
1484 "invalid variant for script enum: {}",
1485 x
1486 ))),
1487 }
1488 }
1489}
1490
1491impl<C, T> minicbor::Encode<C> for PseudoScript<T>
1492where
1493 T: minicbor::Encode<C>,
1494{
1495 fn encode<W: minicbor::encode::Write>(
1496 &self,
1497 e: &mut minicbor::Encoder<W>,
1498 ctx: &mut C,
1499 ) -> Result<(), minicbor::encode::Error<W::Error>> {
1500 match self {
1501 Self::NativeScript(x) => e.encode_with((0, x), ctx)?,
1502 Self::PlutusV1Script(x) => e.encode_with((1, x), ctx)?,
1503 Self::PlutusV2Script(x) => e.encode_with((2, x), ctx)?,
1504 Self::PlutusV3Script(x) => e.encode_with((3, x), ctx)?,
1505 };
1506
1507 Ok(())
1508 }
1509}
1510
1511pub use crate::alonzo::AuxiliaryData;
1512
1513use crate::babbage::MintedHeader;
1514
1515#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
1516pub struct PseudoBlock<T1, T2, T3, T4>
1517where
1518 T4: std::clone::Clone,
1519{
1520 #[n(0)]
1521 pub header: T1,
1522
1523 #[b(1)]
1524 pub transaction_bodies: MaybeIndefArray<T2>,
1525
1526 #[n(2)]
1527 pub transaction_witness_sets: MaybeIndefArray<T3>,
1528
1529 #[n(3)]
1530 pub auxiliary_data_set: KeyValuePairs<TransactionIndex, T4>,
1531
1532 #[n(4)]
1533 pub invalid_transactions: Option<MaybeIndefArray<TransactionIndex>>,
1534}
1535
1536pub type Block = PseudoBlock<Header, TransactionBody, WitnessSet, AuxiliaryData>;
1537
1538pub type MintedBlock<'b> = PseudoBlock<
1544 KeepRaw<'b, MintedHeader<'b>>,
1545 KeepRaw<'b, MintedTransactionBody<'b>>,
1546 KeepRaw<'b, MintedWitnessSet<'b>>,
1547 KeepRaw<'b, AuxiliaryData>,
1548>;
1549
1550impl<'b> From<MintedBlock<'b>> for Block {
1551 fn from(x: MintedBlock<'b>) -> Self {
1552 Block {
1553 header: x.header.unwrap().into(),
1554 transaction_bodies: MaybeIndefArray::Def(
1555 x.transaction_bodies
1556 .iter()
1557 .cloned()
1558 .map(|x| x.unwrap())
1559 .map(TransactionBody::from)
1560 .collect(),
1561 ),
1562 transaction_witness_sets: MaybeIndefArray::Def(
1563 x.transaction_witness_sets
1564 .iter()
1565 .cloned()
1566 .map(|x| x.unwrap())
1567 .map(WitnessSet::from)
1568 .collect(),
1569 ),
1570 auxiliary_data_set: x
1571 .auxiliary_data_set
1572 .to_vec()
1573 .into_iter()
1574 .map(|(k, v)| (k, v.unwrap()))
1575 .collect::<Vec<_>>()
1576 .into(),
1577 invalid_transactions: x.invalid_transactions,
1578 }
1579 }
1580}
1581
1582#[derive(Clone, Serialize, Deserialize, Encode, Decode, Debug)]
1583pub struct PseudoTx<T1, T2, T3>
1584where
1585 T1: std::clone::Clone,
1586 T2: std::clone::Clone,
1587 T3: std::clone::Clone,
1588{
1589 #[n(0)]
1590 pub transaction_body: T1,
1591
1592 #[n(1)]
1593 pub transaction_witness_set: T2,
1594
1595 #[n(2)]
1596 pub success: bool,
1597
1598 #[n(3)]
1599 pub auxiliary_data: Nullable<T3>,
1600}
1601
1602pub type Tx = PseudoTx<TransactionBody, WitnessSet, AuxiliaryData>;
1603
1604pub type MintedTx<'b> = PseudoTx<
1605 KeepRaw<'b, MintedTransactionBody<'b>>,
1606 KeepRaw<'b, MintedWitnessSet<'b>>,
1607 KeepRaw<'b, AuxiliaryData>,
1608>;
1609
1610impl<'b> From<MintedTx<'b>> for Tx {
1611 fn from(x: MintedTx<'b>) -> Self {
1612 Tx {
1613 transaction_body: x.transaction_body.unwrap().into(),
1614 transaction_witness_set: x.transaction_witness_set.unwrap().into(),
1615 success: x.success,
1616 auxiliary_data: x.auxiliary_data.map(|x| x.unwrap()),
1617 }
1618 }
1619}
1620
1621#[cfg(test)]
1622mod tests {
1623 use pallas_codec::minicbor;
1624
1625 use super::MintedBlock;
1626
1627 type BlockWrapper<'b> = (u16, MintedBlock<'b>);
1628
1629 #[test]
1630 fn block_isomorphic_decoding_encoding() {
1631 let test_blocks = [
1632 include_str!("../../../test_data/conway1.block"),
1633 include_str!("../../../test_data/conway2.block"),
1634 include_str!("../../../test_data/conway3.block"),
1636 include_str!("../../../test_data/conway4.block"),
1638 ];
1639
1640 for (idx, block_str) in test_blocks.iter().enumerate() {
1641 println!("decoding test block {}", idx + 1);
1642 let bytes = hex::decode(block_str).unwrap_or_else(|_| panic!("bad block file {idx}"));
1643
1644 let block: BlockWrapper = minicbor::decode(&bytes)
1645 .unwrap_or_else(|e| panic!("error decoding cbor for file {idx}: {e:?}"));
1646
1647 let bytes2 = minicbor::to_vec(block)
1648 .unwrap_or_else(|e| panic!("error encoding block cbor for file {idx}: {e:?}"));
1649
1650 assert!(bytes.eq(&bytes2), "re-encoded bytes didn't match original");
1651 }
1652 }
1653
1654 }