1use pallas_codec::minicbor::{bytes::ByteVec, Decode, Encode};
6use pallas_crypto::hash::Hash;
7
8use pallas_codec::utils::{
9 CborWrap, EmptyMap, KeepRaw, KeyValuePairs, MaybeIndefArray, TagWrap, ZeroOrOneArray,
10};
11
12use pallas_codec::minicbor;
14
15use std::hash::Hash as StdHash;
16
17pub type Blake2b256 = Hash<32>;
20
21pub type TxId = Blake2b256;
22pub type BlockId = Blake2b256;
23pub type UpdId = Blake2b256;
24pub type ByronHash = Blake2b256;
25
26pub type Blake2b224 = Hash<28>;
27
28pub type AddressId = Blake2b224;
29pub type StakeholderId = Blake2b224;
30
31pub type EpochId = u64;
32
33#[derive(Encode, Decode, Debug, Clone)]
34pub struct SlotId {
35 #[n(0)]
36 pub epoch: EpochId,
37
38 #[n(1)]
39 pub slot: u64,
40}
41
42pub type PubKey = ByteVec;
43pub type Signature = ByteVec;
44
45pub type Attributes = EmptyMap;
52
53#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, PartialOrd, Ord)]
58pub struct Address {
59 #[n(0)]
60 pub payload: TagWrap<ByteVec, 24>,
61
62 #[n(1)]
63 pub crc: u32,
64}
65
66#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq)]
70pub struct TxOut {
71 #[n(0)]
72 pub address: Address,
73
74 #[n(1)]
75 pub amount: u64,
76}
77
78#[derive(Debug, Clone, PartialEq, Eq, StdHash)]
79pub enum TxIn {
80 Variant0(CborWrap<(TxId, u32)>),
82
83 Other(u8, ByteVec),
85}
86
87impl<'b, C> minicbor::Decode<'b, C> for TxIn {
88 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
89 d.array()?;
90
91 let variant = d.u8()?;
92
93 match variant {
94 0 => Ok(TxIn::Variant0(d.decode_with(ctx)?)),
95 x => Ok(TxIn::Other(x, d.decode_with(ctx)?)),
96 }
97 }
98}
99
100impl<C> minicbor::Encode<C> for TxIn {
101 fn encode<W: minicbor::encode::Write>(
102 &self,
103 e: &mut minicbor::Encoder<W>,
104 ctx: &mut C,
105 ) -> Result<(), minicbor::encode::Error<W::Error>> {
106 match self {
107 TxIn::Variant0(x) => {
108 e.array(2)?;
109 e.u8(0)?;
110 e.encode_with(x, ctx)?;
111
112 Ok(())
113 }
114 TxIn::Other(a, b) => {
115 e.array(2)?;
116 e.u8(*a)?;
117 e.encode_with(b, ctx)?;
118
119 Ok(())
120 }
121 }
122 }
123}
124
125#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq)]
127pub struct Tx {
128 #[n(0)]
129 pub inputs: MaybeIndefArray<TxIn>,
130
131 #[n(1)]
132 pub outputs: MaybeIndefArray<TxOut>,
133
134 #[n(2)]
135 pub attributes: Attributes,
136}
137
138pub type TxProof = (u32, ByronHash, ByronHash);
140
141pub type ValidatorScript = (u16, ByteVec);
142pub type RedeemerScript = (u16, ByteVec);
143
144#[derive(Debug, Clone)]
145pub enum Twit {
146 PkWitness(CborWrap<(PubKey, Signature)>),
148
149 ScriptWitness(CborWrap<(ValidatorScript, RedeemerScript)>),
151
152 RedeemWitness(CborWrap<(PubKey, Signature)>),
154
155 Other(u8, ByteVec),
157}
158
159impl<'b, C> minicbor::Decode<'b, C> for Twit {
160 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
161 d.array()?;
162
163 let variant = d.u8()?;
164
165 match variant {
166 0 => Ok(Twit::PkWitness(d.decode_with(ctx)?)),
167 1 => Ok(Twit::ScriptWitness(d.decode_with(ctx)?)),
168 2 => Ok(Twit::RedeemWitness(d.decode_with(ctx)?)),
169 x => Ok(Twit::Other(x, d.decode_with(ctx)?)),
170 }
171 }
172}
173
174impl<C> minicbor::Encode<C> for Twit {
175 fn encode<W: minicbor::encode::Write>(
176 &self,
177 e: &mut minicbor::Encoder<W>,
178 ctx: &mut C,
179 ) -> Result<(), minicbor::encode::Error<W::Error>> {
180 match self {
181 Twit::PkWitness(x) => {
182 e.array(2)?;
183 e.u8(0)?;
184 e.encode_with(x, ctx)?;
185
186 Ok(())
187 }
188 Twit::ScriptWitness(x) => {
189 e.array(2)?;
190 e.u8(1)?;
191 e.encode_with(x, ctx)?;
192
193 Ok(())
194 }
195 Twit::RedeemWitness(x) => {
196 e.array(2)?;
197 e.u8(2)?;
198 e.encode(x)?;
199
200 Ok(())
201 }
202 Twit::Other(a, b) => {
203 e.array(2)?;
204 e.u8(*a)?;
205 e.encode(b)?;
206
207 Ok(())
208 }
209 }
210 }
211}
212
213pub type VssPubKey = ByteVec;
219
220pub type VssSec = ByteVec;
224
225pub type VssEnc = MaybeIndefArray<ByteVec>;
230
231pub type VssDec = ByteVec;
235
236pub type VssProof = (ByteVec, ByteVec, ByteVec, MaybeIndefArray<ByteVec>);
240
241pub type SscComm = (
243 PubKey,
244 (KeyValuePairs<VssPubKey, VssEnc>, VssProof),
245 Signature,
246);
247
248pub type SscComms = TagWrap<MaybeIndefArray<SscComm>, 258>;
250
251pub type SscOpens = KeyValuePairs<StakeholderId, VssSec>;
253
254pub type SscShares = KeyValuePairs<AddressId, KeyValuePairs<AddressId, MaybeIndefArray<VssDec>>>;
256
257pub type SscCert = (VssPubKey, EpochId, PubKey, Signature);
260
261pub type SscCerts = TagWrap<MaybeIndefArray<SscCert>, 258>;
263
264#[derive(Debug, Clone)]
265pub enum Ssc {
266 Variant0(SscComms, SscCerts),
267 Variant1(SscOpens, SscCerts),
268 Variant2(SscShares, SscCerts),
269 Variant3(SscCerts),
270}
271
272impl<'b, C> minicbor::Decode<'b, C> for Ssc {
273 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
274 d.array()?;
275
276 let variant = d.u8()?;
277
278 match variant {
279 0 => Ok(Ssc::Variant0(d.decode_with(ctx)?, d.decode_with(ctx)?)),
280 1 => Ok(Ssc::Variant1(d.decode_with(ctx)?, d.decode_with(ctx)?)),
281 2 => Ok(Ssc::Variant2(d.decode_with(ctx)?, d.decode_with(ctx)?)),
282 3 => Ok(Ssc::Variant3(d.decode_with(ctx)?)),
283 _ => Err(minicbor::decode::Error::message("invalid variant for ssc")),
284 }
285 }
286}
287
288impl<C> minicbor::Encode<C> for Ssc {
289 fn encode<W: minicbor::encode::Write>(
290 &self,
291 e: &mut minicbor::Encoder<W>,
292 ctx: &mut C,
293 ) -> Result<(), minicbor::encode::Error<W::Error>> {
294 match self {
295 Ssc::Variant0(a, b) => {
296 e.array(3)?;
297 e.u8(0)?;
298 e.encode_with(a, ctx)?;
299 e.encode_with(b, ctx)?;
300
301 Ok(())
302 }
303 Ssc::Variant1(a, b) => {
304 e.array(3)?;
305 e.u8(1)?;
306 e.encode_with(a, ctx)?;
307 e.encode_with(b, ctx)?;
308
309 Ok(())
310 }
311 Ssc::Variant2(a, b) => {
312 e.array(3)?;
313 e.u8(2)?;
314 e.encode_with(a, ctx)?;
315 e.encode_with(b, ctx)?;
316
317 Ok(())
318 }
319 Ssc::Variant3(x) => {
320 e.array(2)?;
321 e.u8(3)?;
322 e.encode_with(x, ctx)?;
323
324 Ok(())
325 }
326 }
327 }
328}
329
330#[derive(Debug, Clone)]
331pub enum SscProof {
332 Variant0(ByronHash, ByronHash),
333 Variant1(ByronHash, ByronHash),
334 Variant2(ByronHash, ByronHash),
335 Variant3(ByronHash),
336}
337
338impl<'b, C> minicbor::Decode<'b, C> for SscProof {
339 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
340 d.array()?;
341
342 let variant = d.u8()?;
343
344 match variant {
345 0 => Ok(SscProof::Variant0(d.decode_with(ctx)?, d.decode_with(ctx)?)),
346 1 => Ok(SscProof::Variant1(d.decode_with(ctx)?, d.decode_with(ctx)?)),
347 2 => Ok(SscProof::Variant2(d.decode_with(ctx)?, d.decode_with(ctx)?)),
348 3 => Ok(SscProof::Variant3(d.decode_with(ctx)?)),
349 _ => Err(minicbor::decode::Error::message(
350 "invalid variant for sscproof",
351 )),
352 }
353 }
354}
355
356impl<C> minicbor::Encode<C> for SscProof {
357 fn encode<W: minicbor::encode::Write>(
358 &self,
359 e: &mut minicbor::Encoder<W>,
360 ctx: &mut C,
361 ) -> Result<(), minicbor::encode::Error<W::Error>> {
362 match self {
363 SscProof::Variant0(a, b) => {
364 e.array(3)?;
365 e.u8(0)?;
366 e.encode_with(a, ctx)?;
367 e.encode_with(b, ctx)?;
368
369 Ok(())
370 }
371 SscProof::Variant1(a, b) => {
372 e.array(3)?;
373 e.u8(1)?;
374 e.encode_with(a, ctx)?;
375 e.encode_with(b, ctx)?;
376
377 Ok(())
378 }
379 SscProof::Variant2(a, b) => {
380 e.array(3)?;
381 e.u8(2)?;
382 e.encode_with(a, ctx)?;
383 e.encode_with(b, ctx)?;
384
385 Ok(())
386 }
387 SscProof::Variant3(x) => {
388 e.array(2)?;
389 e.u8(3)?;
390 e.encode_with(x, ctx)?;
391
392 Ok(())
393 }
394 }
395 }
396}
397
398#[derive(Debug, Encode, Decode, Clone)]
401pub struct Dlg {
402 #[n(0)]
403 pub epoch: EpochId,
404
405 #[n(1)]
406 pub issuer: PubKey,
407
408 #[n(2)]
409 pub delegate: PubKey,
410
411 #[n(3)]
412 pub certificate: Signature,
413}
414
415pub type DlgSig = (Dlg, Signature);
416
417#[derive(Debug, Encode, Decode, Clone)]
418pub struct Lwdlg {
419 #[n(0)]
420 pub epoch_range: (EpochId, EpochId),
421
422 #[n(1)]
423 pub issuer: PubKey,
424
425 #[n(2)]
426 pub delegate: PubKey,
427
428 #[n(3)]
429 pub certificate: Signature,
430}
431
432pub type LwdlgSig = (Lwdlg, Signature);
433
434pub type BVer = (u16, u16, u8);
437
438#[derive(Debug, Clone)]
439pub enum TxFeePol {
440 Variant0(CborWrap<(i64, i64)>),
442
443 Other(u8, ByteVec),
445}
446
447impl<'b, C> minicbor::Decode<'b, C> for TxFeePol {
448 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
449 d.array()?;
450
451 let variant = d.u8()?;
452
453 match variant {
454 0 => Ok(TxFeePol::Variant0(d.decode_with(ctx)?)),
455 x => Ok(TxFeePol::Other(x, d.decode_with(ctx)?)),
456 }
457 }
458}
459
460impl<C> minicbor::Encode<C> for TxFeePol {
461 fn encode<W: minicbor::encode::Write>(
462 &self,
463 e: &mut minicbor::Encoder<W>,
464 ctx: &mut C,
465 ) -> Result<(), minicbor::encode::Error<W::Error>> {
466 match self {
467 TxFeePol::Variant0(x) => {
468 e.array(2)?;
469 e.u8(0)?;
470 e.encode_with(x, ctx)?;
471
472 Ok(())
473 }
474 TxFeePol::Other(a, b) => {
475 e.array(2)?;
476 e.u8(*a)?;
477 e.encode_with(b, ctx)?;
478
479 Ok(())
480 }
481 }
482 }
483}
484
485#[derive(Debug, Encode, Decode, Clone)]
486pub struct BVerMod {
487 #[n(0)]
488 pub script_version: ZeroOrOneArray<u16>,
489
490 #[n(1)]
491 pub slot_duration: ZeroOrOneArray<u64>,
492
493 #[n(2)]
494 pub max_block_size: ZeroOrOneArray<u64>,
495
496 #[n(3)]
497 pub max_header_size: ZeroOrOneArray<u64>,
498
499 #[n(4)]
500 pub max_tx_size: ZeroOrOneArray<u64>,
501
502 #[n(5)]
503 pub max_proposal_size: ZeroOrOneArray<u64>,
504
505 #[n(6)]
506 pub mpc_thd: ZeroOrOneArray<u64>,
507
508 #[n(7)]
509 pub heavy_del_thd: ZeroOrOneArray<u64>,
510
511 #[n(8)]
512 pub update_vote_thd: ZeroOrOneArray<u64>,
513
514 #[n(9)]
515 pub update_proposal_thd: ZeroOrOneArray<u64>,
516
517 #[n(10)]
518 pub update_implicit: ZeroOrOneArray<u64>,
519
520 #[n(11)]
521 pub soft_fork_rule: ZeroOrOneArray<(u64, u64, u64)>,
522
523 #[n(12)]
524 pub tx_fee_policy: ZeroOrOneArray<TxFeePol>,
525
526 #[n(13)]
527 pub unlock_stake_epoch: ZeroOrOneArray<EpochId>,
528}
529
530pub type UpData = (ByronHash, ByronHash, ByronHash, ByronHash);
531
532#[derive(Debug, Encode, Decode, Clone)]
533pub struct UpProp {
534 #[n(0)]
535 pub block_version: Option<BVer>,
536
537 #[n(1)]
538 pub block_version_mod: Option<BVerMod>,
539
540 #[n(2)]
541 pub software_version: Option<(String, u32)>,
542
543 #[n(3)]
544 pub data: KeyValuePairs<String, UpData>,
547
548 #[n(4)]
549 pub attributes: Option<Attributes>,
550
551 #[n(5)]
552 pub from: Option<PubKey>,
553
554 #[n(6)]
555 pub signature: Option<Signature>,
556}
557
558#[derive(Debug, Encode, Decode, Clone)]
559pub struct UpVote {
560 #[n(0)]
561 pub voter: PubKey,
562
563 #[n(1)]
564 pub proposal_id: UpdId,
565
566 #[n(2)]
567 pub vote: bool,
568
569 #[n(3)]
570 pub signature: Signature,
571}
572
573#[derive(Debug, Encode, Decode, Clone)]
574pub struct Up {
575 #[n(0)]
576 pub proposal: ZeroOrOneArray<UpProp>,
577
578 #[n(1)]
579 pub votes: MaybeIndefArray<UpVote>,
580}
581
582pub type Difficulty = MaybeIndefArray<u64>;
585
586#[derive(Debug, Clone)]
587pub enum BlockSig {
588 Signature(Signature),
589 LwdlgSig(LwdlgSig),
590 DlgSig(DlgSig),
591}
592
593impl<'b, C> minicbor::Decode<'b, C> for BlockSig {
594 fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
595 d.array()?;
596
597 let variant = d.u8()?;
598
599 match variant {
600 0 => Ok(BlockSig::Signature(d.decode_with(ctx)?)),
601 1 => Ok(BlockSig::LwdlgSig(d.decode_with(ctx)?)),
602 2 => Ok(BlockSig::DlgSig(d.decode_with(ctx)?)),
603 _ => Err(minicbor::decode::Error::message(
604 "unknown variant for blocksig",
605 )),
606 }
607 }
608}
609
610impl<C> minicbor::Encode<C> for BlockSig {
611 fn encode<W: minicbor::encode::Write>(
612 &self,
613 e: &mut minicbor::Encoder<W>,
614 _ctx: &mut C,
615 ) -> Result<(), minicbor::encode::Error<W::Error>> {
616 match self {
617 BlockSig::Signature(x) => {
618 e.array(2)?;
619 e.u8(0)?;
620 e.encode(x)?;
621
622 Ok(())
623 }
624 BlockSig::LwdlgSig(x) => {
625 e.array(2)?;
626 e.u8(1)?;
627 e.encode(x)?;
628
629 Ok(())
630 }
631 BlockSig::DlgSig(x) => {
632 e.array(2)?;
633 e.u8(2)?;
634 e.encode(x)?;
635
636 Ok(())
637 }
638 }
639 }
640}
641
642#[derive(Encode, Decode, Debug, Clone)]
643pub struct BlockCons(
644 #[n(0)] pub SlotId,
645 #[n(1)] pub PubKey,
646 #[n(2)] pub Difficulty,
647 #[n(3)] pub BlockSig,
648);
649
650#[derive(Encode, Decode, Debug, Clone)]
651pub struct BlockHeadEx {
652 #[n(0)]
653 pub block_version: BVer,
654
655 #[n(1)]
656 pub software_version: (String, u32),
657
658 #[n(2)]
659 pub attributes: Option<Attributes>,
660
661 #[n(3)]
662 pub extra_proof: ByronHash,
663}
664
665#[derive(Encode, Decode, Debug, Clone)]
666pub struct BlockProof {
667 #[n(0)]
668 pub tx_proof: TxProof,
669
670 #[n(1)]
671 pub ssc_proof: SscProof,
672
673 #[n(2)]
674 pub dlg_proof: ByronHash,
675
676 #[n(3)]
677 pub upd_proof: ByronHash,
678}
679
680#[derive(Encode, Decode, Debug, Clone)]
681pub struct BlockHead {
682 #[n(0)]
683 pub protocol_magic: u32,
684
685 #[n(1)]
686 pub prev_block: BlockId,
687
688 #[n(2)]
689 pub body_proof: BlockProof,
690
691 #[n(3)]
692 pub consensus_data: BlockCons,
693
694 #[n(4)]
695 pub extra_data: BlockHeadEx,
696}
697
698pub type Witnesses = MaybeIndefArray<Twit>;
699
700#[derive(Debug, Encode, Decode)]
701pub struct TxPayload {
702 #[n(0)]
703 pub transaction: Tx,
704
705 #[n(1)]
706 pub witness: Witnesses,
707}
708
709#[derive(Debug, Encode, Decode, Clone)]
710pub struct MintedTxPayload<'b> {
711 #[b(0)]
712 pub transaction: KeepRaw<'b, Tx>,
713
714 #[n(1)]
715 pub witness: KeepRaw<'b, Witnesses>,
716}
717
718#[derive(Encode, Decode, Debug)]
719pub struct BlockBody {
720 #[n(0)]
721 pub tx_payload: MaybeIndefArray<TxPayload>,
722
723 #[n(1)]
724 pub ssc_payload: Ssc,
725
726 #[n(2)]
727 pub dlg_payload: MaybeIndefArray<Dlg>,
728
729 #[n(3)]
730 pub upd_payload: Up,
731}
732
733#[derive(Encode, Decode, Debug, Clone)]
734pub struct MintedBlockBody<'b> {
735 #[b(0)]
736 pub tx_payload: MaybeIndefArray<MintedTxPayload<'b>>,
737
738 #[b(1)]
739 pub ssc_payload: Ssc,
740
741 #[b(2)]
742 pub dlg_payload: MaybeIndefArray<Dlg>,
743
744 #[b(3)]
745 pub upd_payload: Up,
746}
747
748#[derive(Encode, Decode, Debug, Clone)]
751pub struct EbbCons {
752 #[n(0)]
753 pub epoch_id: EpochId,
754
755 #[n(1)]
756 pub difficulty: Difficulty,
757}
758
759#[derive(Encode, Decode, Debug, Clone)]
760pub struct EbbHead {
761 #[n(0)]
762 pub protocol_magic: u32,
763
764 #[n(1)]
765 pub prev_block: BlockId,
766
767 #[n(2)]
768 pub body_proof: ByronHash,
769
770 #[n(3)]
771 pub consensus_data: EbbCons,
772
773 #[n(4)]
774 pub extra_data: (Attributes,),
775}
776
777#[derive(Encode, Decode, Debug)]
778pub struct Block {
779 #[n(0)]
780 pub header: BlockHead,
781
782 #[n(1)]
783 pub body: BlockBody,
784
785 #[n(2)]
786 pub extra: MaybeIndefArray<Attributes>,
787}
788
789#[derive(Encode, Decode, Debug, Clone)]
790pub struct MintedBlock<'b> {
791 #[b(0)]
792 pub header: KeepRaw<'b, BlockHead>,
793
794 #[b(1)]
795 pub body: MintedBlockBody<'b>,
796
797 #[n(2)]
798 pub extra: MaybeIndefArray<Attributes>,
799}
800
801#[derive(Encode, Decode, Debug, Clone)]
802pub struct EbBlock {
803 #[n(0)]
804 pub header: EbbHead,
805
806 #[n(1)]
807 pub body: MaybeIndefArray<StakeholderId>,
808
809 #[n(2)]
810 pub extra: MaybeIndefArray<Attributes>,
811}
812
813#[derive(Encode, Decode, Debug, Clone)]
814pub struct MintedEbBlock<'b> {
815 #[b(0)]
816 pub header: KeepRaw<'b, EbbHead>,
817
818 #[n(1)]
819 pub body: MaybeIndefArray<StakeholderId>,
820
821 #[n(2)]
822 pub extra: MaybeIndefArray<Attributes>,
823}
824
825#[cfg(test)]
826mod tests {
827 use super::{BlockHead, EbBlock, MintedBlock};
828 use pallas_codec::minicbor::{self, to_vec};
829
830 #[test]
831 fn boundary_block_isomorphic_decoding_encoding() {
832 type BlockWrapper = (u16, EbBlock);
833
834 let test_blocks = [include_str!("../../../test_data/genesis.block")];
835
836 for (idx, block_str) in test_blocks.iter().enumerate() {
837 println!("decoding test block {}", idx + 1);
838 let bytes = hex::decode(block_str).unwrap_or_else(|_| panic!("bad block file {idx}"));
839
840 let block: BlockWrapper = minicbor::decode(&bytes[..])
841 .unwrap_or_else(|_| panic!("error decoding cbor for file {idx}"));
842
843 let bytes2 = to_vec(block)
844 .unwrap_or_else(|_| panic!("error encoding block cbor for file {idx}"));
845
846 assert_eq!(hex::encode(bytes), hex::encode(bytes2));
847 }
848 }
849
850 #[test]
851 fn main_block_isomorphic_decoding_encoding() {
852 type BlockWrapper<'b> = (u16, MintedBlock<'b>);
853
854 let test_blocks = [
855 include_str!("../../../test_data/byron1.block"),
857 include_str!("../../../test_data/byron2.block"),
858 include_str!("../../../test_data/byron3.block"),
859 include_str!("../../../test_data/byron4.block"),
860 include_str!("../../../test_data/byron5.block"),
861 include_str!("../../../test_data/byron6.block"),
862 include_str!("../../../test_data/byron7.block"),
863 include_str!("../../../test_data/byron8.block"),
864 ];
865
866 for (idx, block_str) in test_blocks.iter().enumerate() {
867 println!("decoding test block {}", idx + 1);
868 let bytes = hex::decode(block_str).unwrap_or_else(|_| panic!("bad block file {idx}"));
869
870 let block: BlockWrapper = minicbor::decode(&bytes[..])
871 .unwrap_or_else(|_| panic!("error decoding cbor for file {idx}"));
872
873 let bytes2 = to_vec(block)
874 .unwrap_or_else(|_| panic!("error encoding block cbor for file {idx}"));
875
876 assert_eq!(hex::encode(bytes), hex::encode(bytes2));
877 }
878 }
879
880 #[test]
881 fn header_isomorphic_decoding_encoding() {
882 let subjects = [include_str!("../../../test_data/byron1.header")];
883
884 for (idx, str) in subjects.iter().enumerate() {
885 println!("decoding test header {}", idx + 1);
886 let bytes = hex::decode(str).unwrap_or_else(|_| panic!("bad header file {idx}"));
887
888 let block: BlockHead = minicbor::decode(&bytes[..])
889 .unwrap_or_else(|_| panic!("error decoding cbor for file {idx}"));
890
891 let bytes2 = to_vec(block)
892 .unwrap_or_else(|_| panic!("error encoding header cbor for file {idx}"));
893
894 assert_eq!(bytes, bytes2);
895 }
896 }
897}