@@ -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,55 @@ 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) - preserve raw bytes
685+ if len (txArray ) > 3 && len (txArray [3 ]) > 0 {
686+ metadata , err := common .DecodeAuxiliaryDataToMetadata (txArray [3 ])
687+ if err == nil && metadata != nil {
688+ // Ensure the metadata has the raw auxiliary data bytes stored
689+ if setCbor , ok := interface {}(metadata ).(interface { SetCbor ([]byte ) }); ok {
690+ setCbor .SetCbor ([]byte (txArray [3 ]))
691+ }
692+ t .TxMetadata = metadata
693+ }
694+ }
695+
655696 t .SetCbor (cborData )
656697 return nil
657698}
658699
700+ func (t * AlonzoTransaction ) Metadata () common.TransactionMetadatum {
701+ return t .TxMetadata
702+ }
703+
659704func (AlonzoTransaction ) Type () int {
660705 return TxTypeAlonzo
661706}
@@ -756,10 +801,6 @@ func (t AlonzoTransaction) Donation() uint64 {
756801 return t .Body .Donation ()
757802}
758803
759- func (t AlonzoTransaction ) Metadata () common.TransactionMetadatum {
760- return t .TxMetadata
761- }
762-
763804func (t AlonzoTransaction ) IsValid () bool {
764805 return t .TxIsValid
765806}
@@ -798,30 +839,38 @@ func (t AlonzoTransaction) Witnesses() common.TransactionWitnessSet {
798839 return t .WitnessSet
799840}
800841
801- func (t * AlonzoTransaction ) Cbor () []byte {
802- // Return stored CBOR if we have any
842+ func (t * AlonzoTransaction ) MarshalCBOR () ( []byte , error ) {
843+ // If we have stored CBOR (from decode), return it to preserve metadata bytes
803844 cborData := t .DecodeStoreCbor .Cbor ()
804845 if len (cborData ) > 0 {
805- return cborData [:]
846+ return cborData , nil
806847 }
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
848+ // Otherwise, construct and encode
813849 tmpObj := []any {
814- cbor . RawMessage ( t .Body . Cbor ()) ,
815- cbor . RawMessage ( t .WitnessSet . Cbor ()) ,
850+ t .Body ,
851+ t .WitnessSet ,
816852 t .TxIsValid ,
817853 }
818854 if t .TxMetadata != nil {
819- tmpObj = append (tmpObj , t .TxMetadata )
855+ tmpObj = append (tmpObj , cbor . RawMessage ( t .TxMetadata . Cbor ()) )
820856 } else {
821857 tmpObj = append (tmpObj , nil )
822858 }
823- // This should never fail, since we're only encoding a list and a bool value
824- cborData , err := cbor .Encode (& tmpObj )
859+ return cbor .Encode (tmpObj )
860+ }
861+
862+ func (t * AlonzoTransaction ) Cbor () []byte {
863+ // Return stored CBOR if we have any
864+ cborData := t .DecodeStoreCbor .Cbor ()
865+ if len (cborData ) > 0 {
866+ return cborData [:]
867+ }
868+ // Return immediately if the body CBOR is also empty, which implies an empty TX object
869+ if t .Body .Cbor () == nil {
870+ return nil
871+ }
872+ // Delegate to MarshalCBOR which handles encoding
873+ cborData , err := cbor .Encode (t )
825874 if err != nil {
826875 panic ("CBOR encoding that should never fail has failed: " + err .Error ())
827876 }
0 commit comments