1use serde::{Deserialize, Serialize};
6
7use pallas_codec::{
8 minicbor::{self, Decode, Encode},
9 utils::{Bytes, CborWrap, KeepRaw, KeyValuePairs, MaybeIndefArray, Nullable},
10};
11use pallas_crypto::hash::{Hash, Hasher};
12
13pub use crate::{
14 plutus_data::*, AddrKeyhash, AssetName, DatumHash, DnsName, Epoch, ExUnitPrices, ExUnits,
15 GenesisDelegateHash, Genesishash, IPv4, IPv6, Metadata, Metadatum, MetadatumLabel, NetworkId,
16 Nonce, NonceVariant, PlutusScript, PolicyId, PoolKeyhash, PoolMetadata, PoolMetadataHash, Port,
17 PositiveInterval, ProtocolVersion, RationalNumber, Relay, ScriptHash, StakeCredential,
18 TransactionIndex, TransactionInput, UnitInterval, VrfCert, VrfKeyhash,
19};
20
21#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
22pub struct HeaderBody {
23 #[n(0)]
24 pub block_number: u64,
25
26 #[n(1)]
27 pub slot: u64,
28
29 #[n(2)]
30 pub prev_hash: Option<Hash<32>>,
31
32 #[n(3)]
33 pub issuer_vkey: Bytes,
34
35 #[n(4)]
36 pub vrf_vkey: Bytes,
37
38 #[n(5)]
39 pub vrf_result: VrfCert,
40
41 #[n(6)]
42 pub block_body_size: u64,
43
44 #[n(7)]
45 pub block_body_hash: Hash<32>,
46
47 #[n(8)]
48 pub operational_cert: OperationalCert,
49
50 #[n(9)]
51 pub protocol_version: ProtocolVersion,
52}
53
54#[derive(Serialize, Deserialize, Encode, Decode, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
55pub struct OperationalCert {
56 #[n(0)]
57 pub operational_cert_hot_vkey: Bytes,
58
59 #[n(1)]
60 pub operational_cert_sequence_number: u64,
61
62 #[n(2)]
63 pub operational_cert_kes_period: u64,
64
65 #[n(3)]
66 pub operational_cert_sigma: Bytes,
67}
68
69pub type MintedHeaderBody<'a> = KeepRaw<'a, HeaderBody>;
70
71#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
72pub struct PseudoHeader<T1> {
73 #[n(0)]
74 pub header_body: T1,
75
76 #[n(1)]
77 pub body_signature: Bytes,
78}
79
80pub type Header = PseudoHeader<HeaderBody>;
81
82pub type MintedHeader<'a> = KeepRaw<'a, PseudoHeader<MintedHeaderBody<'a>>>;
83
84impl<'a> From<MintedHeader<'a>> for Header {
85 fn from(x: MintedHeader<'a>) -> Self {
86 let x = x.unwrap();
87 Self {
88 header_body: x.header_body.into(),
89 body_signature: x.body_signature,
90 }
91 }
92}
93
94impl<'a> From<MintedHeaderBody<'a>> for HeaderBody {
95 fn from(x: MintedHeaderBody<'a>) -> Self {
96 x.unwrap()
97 }
98}
99
100pub use crate::alonzo::Multiasset;
101
102pub use crate::alonzo::Mint;
103
104pub use crate::alonzo::Coin;
105
106pub use crate::alonzo::Value;
107
108pub use crate::alonzo::TransactionOutput as LegacyTransactionOutput;
109
110pub use crate::alonzo::InstantaneousRewardSource;
111
112pub use crate::alonzo::InstantaneousRewardTarget;
113
114pub use crate::alonzo::MoveInstantaneousReward;
115
116pub use crate::alonzo::RewardAccount;
117
118pub use crate::alonzo::Withdrawals;
119
120pub use crate::alonzo::RequiredSigners;
121
122pub use crate::alonzo::Certificate;
123
124#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
125#[cbor(index_only)]
126pub enum Language {
127 #[n(0)]
128 PlutusV1,
129
130 #[n(1)]
131 PlutusV2,
132}
133
134#[deprecated(since = "0.31.0", note = "use `CostModels` instead")]
135pub type CostMdls = CostModels;
136
137pub use crate::alonzo::CostModel;
138
139#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
140#[cbor(map)]
141pub struct CostModels {
142 #[n(0)]
143 pub plutus_v1: Option<CostModel>,
144
145 #[n(1)]
146 pub plutus_v2: Option<CostModel>,
147}
148
149#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
150#[cbor(map)]
151pub struct ProtocolParamUpdate {
152 #[n(0)]
153 pub minfee_a: Option<u32>,
154 #[n(1)]
155 pub minfee_b: Option<u32>,
156 #[n(2)]
157 pub max_block_body_size: Option<u32>,
158 #[n(3)]
159 pub max_transaction_size: Option<u32>,
160 #[n(4)]
161 pub max_block_header_size: Option<u32>,
162 #[n(5)]
163 pub key_deposit: Option<Coin>,
164 #[n(6)]
165 pub pool_deposit: Option<Coin>,
166 #[n(7)]
167 pub maximum_epoch: Option<Epoch>,
168 #[n(8)]
169 pub desired_number_of_stake_pools: Option<u32>,
170 #[n(9)]
171 pub pool_pledge_influence: Option<RationalNumber>,
172 #[n(10)]
173 pub expansion_rate: Option<UnitInterval>,
174 #[n(11)]
175 pub treasury_growth_rate: Option<UnitInterval>,
176
177 #[n(14)]
178 pub protocol_version: Option<ProtocolVersion>,
179 #[n(16)]
180 pub min_pool_cost: Option<Coin>,
181 #[n(17)]
182 pub ada_per_utxo_byte: Option<Coin>,
183 #[n(18)]
184 pub cost_models_for_script_languages: Option<CostModels>,
185 #[n(19)]
186 pub execution_costs: Option<ExUnitPrices>,
187 #[n(20)]
188 pub max_tx_ex_units: Option<ExUnits>,
189 #[n(21)]
190 pub max_block_ex_units: Option<ExUnits>,
191 #[n(22)]
192 pub max_value_size: Option<u32>,
193 #[n(23)]
194 pub collateral_percentage: Option<u32>,
195 #[n(24)]
196 pub max_collateral_inputs: Option<u32>,
197}
198
199#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
200pub struct Update {
201 #[n(0)]
202 pub proposed_protocol_parameter_updates: KeyValuePairs<Genesishash, ProtocolParamUpdate>,
203
204 #[n(1)]
205 pub epoch: Epoch,
206}
207
208#[derive(Encode, Decode, Debug, PartialEq, Clone)]
209#[cbor(map)]
210pub struct PseudoTransactionBody<T1> {
211 #[n(0)]
212 pub inputs: Vec<TransactionInput>,
213
214 #[n(1)]
215 pub outputs: Vec<T1>,
216
217 #[n(2)]
218 pub fee: u64,
219
220 #[n(3)]
221 pub ttl: Option<u64>,
222
223 #[n(4)]
224 pub certificates: Option<Vec<Certificate>>,
225
226 #[n(5)]
227 pub withdrawals: Option<KeyValuePairs<RewardAccount, Coin>>,
228
229 #[n(6)]
230 pub update: Option<Update>,
231
232 #[n(7)]
233 pub auxiliary_data_hash: Option<Bytes>,
234
235 #[n(8)]
236 pub validity_interval_start: Option<u64>,
237
238 #[n(9)]
239 pub mint: Option<Multiasset<i64>>,
240
241 #[n(11)]
242 pub script_data_hash: Option<Hash<32>>,
243
244 #[n(13)]
245 pub collateral: Option<Vec<TransactionInput>>,
246
247 #[n(14)]
248 pub required_signers: Option<Vec<AddrKeyhash>>,
249
250 #[n(15)]
251 pub network_id: Option<NetworkId>,
252
253 #[n(16)]
254 pub collateral_return: Option<T1>,
255
256 #[n(17)]
257 pub total_collateral: Option<Coin>,
258
259 #[n(18)]
260 pub reference_inputs: Option<Vec<TransactionInput>>,
261}
262
263pub type TransactionBody = PseudoTransactionBody<TransactionOutput>;
264
265pub type MintedTransactionBody<'a> = PseudoTransactionBody<MintedTransactionOutput<'a>>;
266
267impl<'a> From<MintedTransactionBody<'a>> for TransactionBody {
268 fn from(value: MintedTransactionBody<'a>) -> Self {
269 Self {
270 inputs: value.inputs,
271 outputs: value.outputs.into_iter().map(|x| x.into()).collect(),
272 fee: value.fee,
273 ttl: value.ttl,
274 certificates: value.certificates,
275 withdrawals: value.withdrawals,
276 update: value.update,
277 auxiliary_data_hash: value.auxiliary_data_hash,
278 validity_interval_start: value.validity_interval_start,
279 mint: value.mint,
280 script_data_hash: value.script_data_hash,
281 collateral: value.collateral,
282 required_signers: value.required_signers,
283 network_id: value.network_id,
284 collateral_return: value.collateral_return.map(|x| x.into()),
285 total_collateral: value.total_collateral,
286 reference_inputs: value.reference_inputs,
287 }
288 }
289}
290
291pub enum VrfDerivation {
292 Leader,
293 Nonce,
294}
295
296pub fn derive_tagged_vrf_output(
297 block_vrf_output_bytes: &[u8],
298 derivation: VrfDerivation,
299) -> Vec<u8> {
300 let mut tagged_vrf: Vec<u8> = match derivation {
301 VrfDerivation::Leader => vec![0x4C_u8], VrfDerivation::Nonce => vec![0x4E_u8], };
304
305 tagged_vrf.extend(block_vrf_output_bytes);
306 Hasher::<256>::hash(&tagged_vrf).to_vec()
307}
308
309impl HeaderBody {
310 pub fn leader_vrf_output(&self) -> Vec<u8> {
311 derive_tagged_vrf_output(&self.vrf_result.0, VrfDerivation::Leader)
312 }
313
314 pub fn nonce_vrf_output(&self) -> Vec<u8> {
315 derive_tagged_vrf_output(&self.vrf_result.0, VrfDerivation::Nonce)
316 }
317}
318
319#[derive(Debug, PartialEq, Eq, Clone)]
320pub enum PseudoTransactionOutput<T> {
321 Legacy(LegacyTransactionOutput),
322 PostAlonzo(T),
323}
324
325impl<'b, C, T> minicbor::Decode<'b, C> for PseudoTransactionOutput<T>
326where
327 T: minicbor::Decode<'b, C>,
328{
329 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
330 match d.datatype()? {
331 minicbor::data::Type::Array | minicbor::data::Type::ArrayIndef => {
332 Ok(PseudoTransactionOutput::Legacy(d.decode_with(ctx)?))
333 }
334 minicbor::data::Type::Map | minicbor::data::Type::MapIndef => {
335 Ok(PseudoTransactionOutput::PostAlonzo(d.decode_with(ctx)?))
336 }
337 _ => Err(minicbor::decode::Error::message(
338 "invalid type for transaction output struct",
339 )),
340 }
341 }
342}
343
344impl<C, T> minicbor::Encode<C> for PseudoTransactionOutput<T>
345where
346 T: minicbor::Encode<C>,
347{
348 fn encode<W: minicbor::encode::Write>(
349 &self,
350 e: &mut minicbor::Encoder<W>,
351 ctx: &mut C,
352 ) -> Result<(), minicbor::encode::Error<W::Error>> {
353 match self {
354 PseudoTransactionOutput::Legacy(x) => x.encode(e, ctx),
355 PseudoTransactionOutput::PostAlonzo(x) => x.encode(e, ctx),
356 }
357 }
358}
359
360pub type TransactionOutput = PseudoTransactionOutput<PostAlonzoTransactionOutput>;
361
362pub type MintedTransactionOutput<'b> =
363 PseudoTransactionOutput<MintedPostAlonzoTransactionOutput<'b>>;
364
365impl<'b> From<MintedTransactionOutput<'b>> for TransactionOutput {
366 fn from(value: MintedTransactionOutput<'b>) -> Self {
367 match value {
368 PseudoTransactionOutput::Legacy(x) => Self::Legacy(x),
369 PseudoTransactionOutput::PostAlonzo(x) => Self::PostAlonzo(x.into()),
370 }
371 }
372}
373
374#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone)]
375#[cbor(map)]
376pub struct PseudoPostAlonzoTransactionOutput<T1, T2, T3> {
377 #[n(0)]
378 pub address: Bytes,
379
380 #[n(1)]
381 pub value: T1,
382
383 #[n(2)]
384 pub datum_option: Option<T2>,
385
386 #[n(3)]
387 pub script_ref: Option<CborWrap<T3>>,
388}
389
390pub type PostAlonzoTransactionOutput =
391 PseudoPostAlonzoTransactionOutput<Value, DatumOption, ScriptRef>;
392
393pub type MintedPostAlonzoTransactionOutput<'b> =
394 PseudoPostAlonzoTransactionOutput<Value, MintedDatumOption<'b>, MintedScriptRef<'b>>;
395
396impl<'b> From<MintedPostAlonzoTransactionOutput<'b>> for PostAlonzoTransactionOutput {
397 fn from(value: MintedPostAlonzoTransactionOutput<'b>) -> Self {
398 Self {
399 address: value.address,
400 value: value.value,
401 datum_option: value.datum_option.map(|x| x.into()),
402 script_ref: value.script_ref.map(|x| CborWrap(x.unwrap().into())),
403 }
404 }
405}
406
407pub use crate::alonzo::VKeyWitness;
408
409pub use crate::alonzo::NativeScript;
410
411pub use crate::alonzo::RedeemerTag;
412
413pub use crate::alonzo::Redeemer;
414
415pub use crate::alonzo::BootstrapWitness;
416
417#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
418#[cbor(map)]
419pub struct WitnessSet {
420 #[n(0)]
421 pub vkeywitness: Option<Vec<VKeyWitness>>,
422
423 #[n(1)]
424 pub native_script: Option<Vec<NativeScript>>,
425
426 #[n(2)]
427 pub bootstrap_witness: Option<Vec<BootstrapWitness>>,
428
429 #[n(3)]
430 pub plutus_v1_script: Option<Vec<PlutusScript<1>>>,
431
432 #[n(4)]
433 pub plutus_data: Option<Vec<PlutusData>>,
434
435 #[n(5)]
436 pub redeemer: Option<Vec<Redeemer>>,
437
438 #[n(6)]
439 pub plutus_v2_script: Option<Vec<PlutusScript<2>>>,
440}
441
442#[derive(Encode, Decode, Debug, PartialEq, Clone)]
443#[cbor(map)]
444pub struct MintedWitnessSet<'b> {
445 #[n(0)]
446 pub vkeywitness: Option<Vec<VKeyWitness>>,
447
448 #[n(1)]
449 pub native_script: Option<Vec<KeepRaw<'b, NativeScript>>>,
450
451 #[n(2)]
452 pub bootstrap_witness: Option<Vec<BootstrapWitness>>,
453
454 #[n(3)]
455 pub plutus_v1_script: Option<Vec<PlutusScript<1>>>,
456
457 #[b(4)]
458 pub plutus_data: Option<Vec<KeepRaw<'b, PlutusData>>>,
459
460 #[n(5)]
461 pub redeemer: Option<Vec<Redeemer>>,
462
463 #[n(6)]
464 pub plutus_v2_script: Option<Vec<PlutusScript<2>>>,
465}
466
467impl<'b> From<MintedWitnessSet<'b>> for WitnessSet {
468 fn from(x: MintedWitnessSet<'b>) -> Self {
469 WitnessSet {
470 vkeywitness: x.vkeywitness,
471 native_script: x
472 .native_script
473 .map(|x| x.into_iter().map(|x| x.unwrap()).collect()),
474 bootstrap_witness: x.bootstrap_witness,
475 plutus_v1_script: x.plutus_v1_script,
476 plutus_data: x
477 .plutus_data
478 .map(|x| x.into_iter().map(|x| x.unwrap()).collect()),
479 redeemer: x.redeemer,
480 plutus_v2_script: x.plutus_v2_script,
481 }
482 }
483}
484
485#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
486#[cbor(map)]
487pub struct PostAlonzoAuxiliaryData {
488 #[n(0)]
489 pub metadata: Option<Metadata>,
490
491 #[n(1)]
492 pub native_scripts: Option<Vec<NativeScript>>,
493
494 #[n(2)]
495 pub plutus_v1_scripts: Option<Vec<PlutusScript<1>>>,
496
497 #[n(3)]
498 pub plutus_v2_scripts: Option<Vec<PlutusScript<2>>>,
499}
500
501#[derive(Debug, PartialEq, Eq, Clone)]
503pub enum PseudoDatumOption<T1> {
504 Hash(DatumHash),
505 Data(CborWrap<T1>),
506}
507
508impl<'b, C, T> minicbor::Decode<'b, C> for PseudoDatumOption<T>
509where
510 T: minicbor::Decode<'b, C>,
511{
512 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
513 d.array()?;
514
515 match d.u8()? {
516 0 => Ok(Self::Hash(d.decode_with(ctx)?)),
517 1 => Ok(Self::Data(d.decode_with(ctx)?)),
518 _ => Err(minicbor::decode::Error::message(
519 "invalid variant for datum option enum",
520 )),
521 }
522 }
523}
524
525impl<C, T> minicbor::Encode<C> for PseudoDatumOption<T>
526where
527 T: minicbor::Encode<C>,
528{
529 fn encode<W: minicbor::encode::Write>(
530 &self,
531 e: &mut minicbor::Encoder<W>,
532 ctx: &mut C,
533 ) -> Result<(), minicbor::encode::Error<W::Error>> {
534 match self {
535 Self::Hash(x) => e.encode_with((0, x), ctx)?,
536 Self::Data(x) => e.encode_with((1, x), ctx)?,
537 };
538
539 Ok(())
540 }
541}
542
543pub type DatumOption = PseudoDatumOption<PlutusData>;
544
545pub type MintedDatumOption<'b> = PseudoDatumOption<KeepRaw<'b, PlutusData>>;
546
547impl<'b> From<MintedDatumOption<'b>> for DatumOption {
548 fn from(value: MintedDatumOption<'b>) -> Self {
549 match value {
550 PseudoDatumOption::Hash(x) => Self::Hash(x),
551 PseudoDatumOption::Data(x) => Self::Data(CborWrap(x.unwrap().unwrap())),
552 }
553 }
554}
555
556#[deprecated(since = "0.31.0", note = "use `PlutusScript<1>` instead")]
557pub type PlutusV1Script = PlutusScript<1>;
558
559#[deprecated(since = "0.31.0", note = "use `PlutusScript<2>` instead")]
560pub type PlutusV2Script = PlutusScript<2>;
561
562#[derive(Debug, PartialEq, Eq, Clone)]
564pub enum PseudoScript<T1> {
565 NativeScript(T1),
566 PlutusV1Script(PlutusScript<1>),
567 PlutusV2Script(PlutusScript<2>),
568}
569
570pub type ScriptRef = PseudoScript<NativeScript>;
572
573pub type MintedScriptRef<'b> = PseudoScript<KeepRaw<'b, NativeScript>>;
574
575impl<'b> From<MintedScriptRef<'b>> for ScriptRef {
576 fn from(value: MintedScriptRef<'b>) -> Self {
577 match value {
578 PseudoScript::NativeScript(x) => Self::NativeScript(x.unwrap()),
579 PseudoScript::PlutusV1Script(x) => Self::PlutusV1Script(x),
580 PseudoScript::PlutusV2Script(x) => Self::PlutusV2Script(x),
581 }
582 }
583}
584
585impl<'b, C, T> minicbor::Decode<'b, C> for PseudoScript<T>
586where
587 T: minicbor::Decode<'b, ()>,
588{
589 fn decode(
590 d: &mut minicbor::Decoder<'b>,
591 _ctx: &mut C,
592 ) -> Result<Self, minicbor::decode::Error> {
593 d.array()?;
594
595 match d.u8()? {
596 0 => Ok(Self::NativeScript(d.decode()?)),
597 1 => Ok(Self::PlutusV1Script(d.decode()?)),
598 2 => Ok(Self::PlutusV2Script(d.decode()?)),
599 _ => Err(minicbor::decode::Error::message(
600 "invalid variant for script enum",
601 )),
602 }
603 }
604}
605
606impl<C, T> minicbor::Encode<C> for PseudoScript<T>
607where
608 T: minicbor::Encode<C>,
609{
610 fn encode<W: minicbor::encode::Write>(
611 &self,
612 e: &mut minicbor::Encoder<W>,
613 ctx: &mut C,
614 ) -> Result<(), minicbor::encode::Error<W::Error>> {
615 match self {
616 Self::NativeScript(x) => e.encode_with((0, x), ctx)?,
617 Self::PlutusV1Script(x) => e.encode_with((1, x), ctx)?,
618 Self::PlutusV2Script(x) => e.encode_with((2, x), ctx)?,
619 };
620
621 Ok(())
622 }
623}
624
625pub use crate::alonzo::AuxiliaryData;
626
627#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
628pub struct PseudoBlock<T1, T2, T3, T4>
629where
630 T4: std::clone::Clone,
631{
632 #[n(0)]
633 pub header: T1,
634
635 #[b(1)]
636 pub transaction_bodies: MaybeIndefArray<T2>,
637
638 #[n(2)]
639 pub transaction_witness_sets: MaybeIndefArray<T3>,
640
641 #[n(3)]
642 pub auxiliary_data_set: KeyValuePairs<TransactionIndex, T4>,
643
644 #[n(4)]
645 pub invalid_transactions: Option<MaybeIndefArray<TransactionIndex>>,
646}
647
648pub type Block = PseudoBlock<Header, TransactionBody, WitnessSet, AuxiliaryData>;
649
650pub type MintedBlock<'b> = PseudoBlock<
656 KeepRaw<'b, MintedHeader<'b>>,
657 KeepRaw<'b, MintedTransactionBody<'b>>,
658 KeepRaw<'b, MintedWitnessSet<'b>>,
659 KeepRaw<'b, AuxiliaryData>,
660>;
661
662impl<'b> From<MintedBlock<'b>> for Block {
663 fn from(x: MintedBlock<'b>) -> Self {
664 Block {
665 header: x.header.unwrap().into(),
666 transaction_bodies: MaybeIndefArray::Def(
667 x.transaction_bodies
668 .iter()
669 .cloned()
670 .map(|x| x.unwrap())
671 .map(TransactionBody::from)
672 .collect(),
673 ),
674 transaction_witness_sets: MaybeIndefArray::Def(
675 x.transaction_witness_sets
676 .iter()
677 .cloned()
678 .map(|x| x.unwrap())
679 .map(WitnessSet::from)
680 .collect(),
681 ),
682 auxiliary_data_set: x
683 .auxiliary_data_set
684 .to_vec()
685 .into_iter()
686 .map(|(k, v)| (k, v.unwrap()))
687 .collect::<Vec<_>>()
688 .into(),
689 invalid_transactions: x.invalid_transactions,
690 }
691 }
692}
693
694#[derive(Clone, Serialize, Deserialize, Encode, Decode, Debug)]
695pub struct PseudoTx<T1, T2, T3>
696where
697 T1: std::clone::Clone,
698 T2: std::clone::Clone,
699 T3: std::clone::Clone,
700{
701 #[n(0)]
702 pub transaction_body: T1,
703
704 #[n(1)]
705 pub transaction_witness_set: T2,
706
707 #[n(2)]
708 pub success: bool,
709
710 #[n(3)]
711 pub auxiliary_data: Nullable<T3>,
712}
713
714pub type Tx = PseudoTx<TransactionBody, WitnessSet, AuxiliaryData>;
715
716pub type MintedTx<'b> = PseudoTx<
717 KeepRaw<'b, MintedTransactionBody<'b>>,
718 KeepRaw<'b, MintedWitnessSet<'b>>,
719 KeepRaw<'b, AuxiliaryData>,
720>;
721
722impl<'b> From<MintedTx<'b>> for Tx {
723 fn from(x: MintedTx<'b>) -> Self {
724 Tx {
725 transaction_body: x.transaction_body.unwrap().into(),
726 transaction_witness_set: x.transaction_witness_set.unwrap().into(),
727 success: x.success,
728 auxiliary_data: x.auxiliary_data.map(|x| x.unwrap()),
729 }
730 }
731}
732
733#[cfg(test)]
734mod tests {
735 use pallas_codec::minicbor;
736
737 use super::{MintedBlock, TransactionOutput};
738 use crate::Fragment;
739
740 type BlockWrapper<'b> = (u16, MintedBlock<'b>);
741
742 #[test]
743 fn block_isomorphic_decoding_encoding() {
744 let test_blocks = [
745 include_str!("../../../test_data/babbage1.block"),
746 include_str!("../../../test_data/babbage2.block"),
747 include_str!("../../../test_data/babbage3.block"),
748 include_str!("../../../test_data/babbage4.block"),
750 include_str!("../../../test_data/babbage5.block"),
752 include_str!("../../../test_data/babbage6.block"),
754 include_str!("../../../test_data/babbage7.block"),
756 include_str!("../../../test_data/babbage8.block"),
758 include_str!("../../../test_data/babbage9.block"),
760 include_str!("../../../test_data/babbage10.block"),
762 ];
763
764 for (idx, block_str) in test_blocks.iter().enumerate() {
765 println!("decoding test block {}", idx + 1);
766 let bytes = hex::decode(block_str).unwrap_or_else(|_| panic!("bad block file {idx}"));
767
768 let block: BlockWrapper = minicbor::decode(&bytes[..])
769 .unwrap_or_else(|e| panic!("error decoding cbor for file {idx}: {e:?}"));
770
771 let bytes2 = minicbor::to_vec(block)
772 .unwrap_or_else(|e| panic!("error encoding block cbor for file {idx}: {e:?}"));
773
774 assert!(bytes.eq(&bytes2), "re-encoded bytes didn't match original");
775 }
776 }
777
778 #[test]
779 fn fragments_decoding() {
780 let hex = include_str!("../../../test_data/babbage1.fr");
782 let bytes = hex::decode(hex).unwrap();
783 let outputs = Vec::<TransactionOutput>::decode_fragment(&bytes).unwrap();
784
785 dbg!(outputs);
786
787 }
789}