@@ -68,6 +68,11 @@ func (b *AlonzoBlock) UnmarshalCBOR(cborData []byte) error {
6868 }
6969 * b = AlonzoBlock (tmp )
7070 b .SetCbor (cborData )
71+
72+ // Extract and store CBOR for each component
73+ if err := common .ExtractTransactionCbor (cborData , & b .TransactionBodies , & b .TransactionWitnessSets ); err != nil {
74+ return err
75+ }
7176 return nil
7277}
7378
@@ -156,14 +161,15 @@ func (b *AlonzoBlock) Transactions() []common.Transaction {
156161 ret := make ([]common.Transaction , len (b .TransactionBodies ))
157162 // #nosec G115
158163 for idx := range b .TransactionBodies {
159- // Note: Ignoring the presence flag; if distinguishing "missing" vs "present but empty/failed decode" is needed, plumb the second return value through
160- txMetadata , _ := b .TransactionMetadataSet .GetMetadata (uint (idx ))
161- ret [idx ] = & AlonzoTransaction {
164+ tx := & AlonzoTransaction {
162165 Body : b .TransactionBodies [idx ],
163166 WitnessSet : b .TransactionWitnessSets [idx ],
164- TxMetadata : txMetadata ,
165167 TxIsValid : ! invalidTxMap [uint (idx )],
166168 }
169+ if metadata , ok := b .TransactionMetadataSet .GetMetadata (uint (idx )); ok {
170+ tx .TxMetadata = metadata
171+ }
172+ ret [idx ] = tx
167173 }
168174 return ret
169175}
@@ -646,16 +652,52 @@ type AlonzoTransaction struct {
646652}
647653
648654func (t * AlonzoTransaction ) UnmarshalCBOR (cborData []byte ) error {
649- type tAlonzoTransaction AlonzoTransaction
650- var tmp tAlonzoTransaction
651- if _ , err := cbor .Decode (cborData , & tmp ); err != nil {
655+ // Decode as raw array to preserve metadata bytes
656+ var txArray []cbor. RawMessage
657+ if _ , err := cbor .Decode (cborData , & txArray ); err != nil {
652658 return err
653659 }
654- * t = AlonzoTransaction (tmp )
660+
661+ // Ensure we have at least 3 components
662+ if len (txArray ) < 3 {
663+ return fmt .Errorf (
664+ "invalid transaction: expected at least 3 components, got %d" ,
665+ len (txArray ),
666+ )
667+ }
668+
669+ // Decode body
670+ if _ , err := cbor .Decode ([]byte (txArray [0 ]), & t .Body ); err != nil {
671+ return fmt .Errorf ("failed to decode transaction body: %w" , err )
672+ }
673+
674+ // Decode witness set
675+ if _ , err := cbor .Decode ([]byte (txArray [1 ]), & t .WitnessSet ); err != nil {
676+ return fmt .Errorf ("failed to decode transaction witness set: %w" , err )
677+ }
678+
679+ // Decode TxIsValid flag
680+ if _ , err := cbor .Decode ([]byte (txArray [2 ]), & t .TxIsValid ); err != nil {
681+ return fmt .Errorf ("failed to decode TxIsValid: %w" , err )
682+ }
683+
684+ // Handle metadata (component 4)
685+ // DecodeAuxiliaryDataToMetadata already preserves raw bytes via DecodeMetadatumRaw
686+ if len (txArray ) > 3 && len (txArray [3 ]) > 0 {
687+ metadata , err := common .DecodeAuxiliaryDataToMetadata (txArray [3 ])
688+ if err == nil && metadata != nil {
689+ t .TxMetadata = metadata
690+ }
691+ }
692+
655693 t .SetCbor (cborData )
656694 return nil
657695}
658696
697+ func (t * AlonzoTransaction ) Metadata () common.TransactionMetadatum {
698+ return t .TxMetadata
699+ }
700+
659701func (AlonzoTransaction ) Type () int {
660702 return TxTypeAlonzo
661703}
@@ -756,10 +798,6 @@ func (t AlonzoTransaction) Donation() uint64 {
756798 return t .Body .Donation ()
757799}
758800
759- func (t AlonzoTransaction ) Metadata () common.TransactionMetadatum {
760- return t .TxMetadata
761- }
762-
763801func (t AlonzoTransaction ) IsValid () bool {
764802 return t .TxIsValid
765803}
@@ -798,30 +836,38 @@ func (t AlonzoTransaction) Witnesses() common.TransactionWitnessSet {
798836 return t .WitnessSet
799837}
800838
801- func (t * AlonzoTransaction ) Cbor () []byte {
802- // Return stored CBOR if we have any
839+ func (t * AlonzoTransaction ) MarshalCBOR () ( []byte , error ) {
840+ // If we have stored CBOR (from decode), return it to preserve metadata bytes
803841 cborData := t .DecodeStoreCbor .Cbor ()
804842 if len (cborData ) > 0 {
805- return cborData [:]
843+ return cborData , nil
806844 }
807- // Return immediately if the body CBOR is also empty, which implies an empty TX object
808- if t .Body .Cbor () == nil {
809- return nil
810- }
811- // Generate our own CBOR
812- // This is necessary when a transaction is put together from pieces stored separately in a block
845+ // Otherwise, construct and encode
813846 tmpObj := []any {
814- cbor . RawMessage ( t .Body . Cbor ()) ,
815- cbor . RawMessage ( t .WitnessSet . Cbor ()) ,
847+ t .Body ,
848+ t .WitnessSet ,
816849 t .TxIsValid ,
817850 }
818851 if t .TxMetadata != nil {
819- tmpObj = append (tmpObj , t .TxMetadata )
852+ tmpObj = append (tmpObj , cbor . RawMessage ( t .TxMetadata . Cbor ()) )
820853 } else {
821854 tmpObj = append (tmpObj , nil )
822855 }
823- // This should never fail, since we're only encoding a list and a bool value
824- cborData , err := cbor .Encode (& tmpObj )
856+ return cbor .Encode (tmpObj )
857+ }
858+
859+ func (t * AlonzoTransaction ) Cbor () []byte {
860+ // Return stored CBOR if we have any
861+ cborData := t .DecodeStoreCbor .Cbor ()
862+ if len (cborData ) > 0 {
863+ return cborData [:]
864+ }
865+ // Return immediately if the body CBOR is also empty, which implies an empty TX object
866+ if t .Body .Cbor () == nil {
867+ return nil
868+ }
869+ // Delegate to MarshalCBOR which handles encoding
870+ cborData , err := cbor .Encode (t )
825871 if err != nil {
826872 panic ("CBOR encoding that should never fail has failed: " + err .Error ())
827873 }
0 commit comments