From ce148271a3142f016b7b642b5d9777efa69f3bae Mon Sep 17 00:00:00 2001 From: Aurora Gaffney Date: Wed, 17 Jul 2024 21:02:01 -0500 Subject: [PATCH] feat: support for Conway redeemers and PlutusV3 TX witnesses (#672) Fixes #671 --- ledger/alonzo.go | 16 +++++++++++++- ledger/conway.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/ledger/alonzo.go b/ledger/alonzo.go index 0414d80b..ebef8a2a 100644 --- a/ledger/alonzo.go +++ b/ledger/alonzo.go @@ -253,11 +253,25 @@ func (o AlonzoTransactionOutput) Utxorpc() *utxorpc.TxOutput { } } +type AlonzoRedeemer struct { + cbor.StructAsArray + Tag uint8 + Index uint32 + Data cbor.RawMessage + ExUnits RedeemerExUnits +} + +type RedeemerExUnits struct { + cbor.StructAsArray + Memory uint64 + Steps uint64 +} + type AlonzoTransactionWitnessSet struct { ShelleyTransactionWitnessSet PlutusScripts []cbor.RawMessage `cbor:"3,keyasint,omitempty"` PlutusData []cbor.RawMessage `cbor:"4,keyasint,omitempty"` - Redeemers []cbor.RawMessage `cbor:"5,keyasint,omitempty"` + Redeemers []AlonzoRedeemer `cbor:"5,keyasint,omitempty"` } func (t *AlonzoTransactionWitnessSet) UnmarshalCBOR(cborData []byte) error { diff --git a/ledger/conway.go b/ledger/conway.go index cddba314..8dd9ea49 100644 --- a/ledger/conway.go +++ b/ledger/conway.go @@ -38,7 +38,7 @@ type ConwayBlock struct { cbor.DecodeStoreCbor Header *ConwayBlockHeader TransactionBodies []ConwayTransactionBody - TransactionWitnessSets []BabbageTransactionWitnessSet + TransactionWitnessSets []ConwayTransactionWitnessSet TransactionMetadataSet map[uint]*cbor.LazyValue InvalidTransactions []uint } @@ -119,6 +119,57 @@ func (h *ConwayBlockHeader) Era() Era { return eras[EraIdConway] } +type ConwayRedeemerKey struct { + cbor.StructAsArray + Tag uint8 + Index uint32 +} + +type ConwayRedeemerValue struct { + cbor.StructAsArray + Data cbor.RawMessage + ExUnits RedeemerExUnits +} + +type ConwayRedeemers struct { + Redeemers map[ConwayRedeemerKey]ConwayRedeemerValue + legacy bool +} + +func (r *ConwayRedeemers) UnmarshalCBOR(cborData []byte) error { + // Try to parse as legacy redeemer first + var tmpRedeemers []AlonzoRedeemer + if _, err := cbor.Decode(cborData, &tmpRedeemers); err == nil { + // Copy data from legacy redeemer type + for _, redeemer := range tmpRedeemers { + tmpKey := ConwayRedeemerKey{ + Tag: redeemer.Tag, + Index: redeemer.Index, + } + tmpVal := ConwayRedeemerValue{ + Data: redeemer.Data, + ExUnits: redeemer.ExUnits, + } + r.Redeemers[tmpKey] = tmpVal + } + r.legacy = true + } else { + _, err := cbor.Decode(cborData, &(r.Redeemers)) + return err + } + return nil +} + +type ConwayTransactionWitnessSet struct { + BabbageTransactionWitnessSet + Redeemers ConwayRedeemers `cbor:"5,keyasint,omitempty"` + PlutusV3Scripts []cbor.RawMessage `cbor:"7,keyasint,omitempty"` +} + +func (t *ConwayTransactionWitnessSet) UnmarshalCBOR(cborData []byte) error { + return t.UnmarshalCbor(cborData, t) +} + type ConwayTransactionBody struct { BabbageTransactionBody TxVotingProcedures VotingProcedures `cbor:"19,keyasint,omitempty"` @@ -336,7 +387,7 @@ type ConwayTransaction struct { cbor.StructAsArray cbor.DecodeStoreCbor Body ConwayTransactionBody - WitnessSet BabbageTransactionWitnessSet + WitnessSet ConwayTransactionWitnessSet IsTxValid bool TxMetadata *cbor.LazyValue }