Skip to content

Commit 7c8c24e

Browse files
committed
Preserve container type of redeemers and plutus_data
Currently, fields in a witness will be forced to be wrapped in NonEmptyOrderedSet when deserialized from a cbor due to post_init. This behavior will alter transaction id and also result in script_data_hash. This change is to ensure the original data format from a transaction will be preserved when deserialized.
1 parent 943c39e commit 7c8c24e

File tree

4 files changed

+24
-4
lines changed

4 files changed

+24
-4
lines changed

pycardano/txbuilder.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1204,14 +1204,16 @@ def build_witness_set(
12041204
f"Unsupported script type: {type(script)}"
12051205
)
12061206

1207-
return TransactionWitnessSet(
1207+
witness_set = TransactionWitnessSet(
12081208
native_scripts=native_scripts if native_scripts else None,
12091209
plutus_v1_script=plutus_v1_scripts if plutus_v1_scripts else None,
12101210
plutus_v2_script=plutus_v2_scripts if plutus_v2_scripts else None,
12111211
plutus_v3_script=plutus_v3_scripts if plutus_v3_scripts else None,
12121212
redeemer=self.redeemers() if self._redeemer_list else None,
12131213
plutus_data=plutus_data if plutus_data else None,
12141214
)
1215+
witness_set.convert_to_latest_spec()
1216+
return witness_set
12151217

12161218
def _ensure_no_input_exclusion_conflict(self):
12171219
intersection = set(self.inputs).intersection(set(self.excluded_inputs))

pycardano/witness.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class TransactionWitnessSet(MapCBORSerializable):
108108
},
109109
)
110110

111-
plutus_data: Optional[Union[IndefiniteList, List[Any], NonEmptyOrderedSet[Any]]] = (
111+
plutus_data: Optional[Union[List[Any], IndefiniteList, NonEmptyOrderedSet[Any]]] = (
112112
field(
113113
default=None,
114114
metadata={"optional": True, "key": 4},
@@ -140,7 +140,7 @@ class TransactionWitnessSet(MapCBORSerializable):
140140
},
141141
)
142142

143-
def __post_init__(self):
143+
def convert_to_latest_spec(self):
144144
# Convert lists to NonEmptyOrderedSet for fields that should use NonEmptyOrderedSet
145145
if isinstance(self.vkey_witnesses, list):
146146
self.vkey_witnesses = NonEmptyOrderedSet(self.vkey_witnesses)

test/pycardano/test_serialization.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,7 @@ def test_transaction_witness_set_with_ordered_sets():
761761

762762
# Test conversion from list to NonEmptyOrderedSet
763763
witness_set = TransactionWitnessSet(vkey_witnesses=[witness])
764+
witness_set.convert_to_latest_spec()
764765
assert isinstance(witness_set.vkey_witnesses, NonEmptyOrderedSet)
765766
assert witness in witness_set.vkey_witnesses
766767

@@ -772,11 +773,13 @@ def test_transaction_witness_set_with_ordered_sets():
772773

773774
# Test empty list conversion
774775
witness_set = TransactionWitnessSet(vkey_witnesses=[])
776+
witness_set.convert_to_latest_spec()
775777
with pytest.raises(ValueError, match="NonEmptyOrderedSet cannot be empty"):
776778
witness_set.to_validated_primitive()
777779

778780
# Test None value
779781
witness_set = TransactionWitnessSet(vkey_witnesses=None)
782+
witness_set.convert_to_latest_spec()
780783
primitive = witness_set.to_primitive()
781784
restored = TransactionWitnessSet.from_primitive(primitive)
782785
assert restored.vkey_witnesses is None

test/pycardano/test_witness.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1+
import json
12
import tempfile
23

3-
from pycardano import PaymentSigningKey, PaymentVerificationKey, VerificationKeyWitness
4+
from pycardano import (
5+
PaymentSigningKey,
6+
PaymentVerificationKey,
7+
Transaction,
8+
TransactionWitnessSet,
9+
Unit,
10+
VerificationKeyWitness,
11+
)
412

513

614
def test_witness_save_load():
@@ -17,3 +25,10 @@ def test_witness_save_load():
1725
assert witness == loaded_witness
1826

1927
assert witness != vk
28+
29+
30+
def test_redeemer_decode():
31+
witness = TransactionWitnessSet(plutus_data=[Unit()])
32+
encoded = witness.to_cbor()
33+
decoded = TransactionWitnessSet.from_cbor(encoded)
34+
assert isinstance(decoded.plutus_data, list)

0 commit comments

Comments
 (0)