Skip to content

Commit 67c2c36

Browse files
committed
Add RawPlutusData
Before this change, lists in plutus data are deserialized as finite lists. However, this causes a problem when the plutus data objects are serialized to cbor as finite lists. To solve this problem, this commit introduces RawPlutusData, which will serialize lists as indefinite lists, and will become the default deserialized python object for plutus data.
1 parent 97463aa commit 67c2c36

File tree

5 files changed

+57
-6
lines changed

5 files changed

+57
-6
lines changed

integration-test/docker-compose.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ networks:
99
services:
1010

1111
cardano-node:
12-
image: inputoutput/cardano-node:${CARDANO_NODE_VERSION:-1.35.2}
12+
image: inputoutput/cardano-node:${CARDANO_NODE_VERSION:-1.35.3}
1313
entrypoint: bash
1414
environment:
1515
NETWORK: "${NETWORK:-local-alonzo}"
@@ -32,7 +32,7 @@ services:
3232
max-file: "10"
3333

3434
cardano-pool:
35-
image: inputoutput/cardano-node:${CARDANO_NODE_VERSION:-1.35.2}
35+
image: inputoutput/cardano-node:${CARDANO_NODE_VERSION:-1.35.3}
3636
entrypoint: bash
3737
environment:
3838
NETWORK: "${NETWORK:-local-alonzo}"

pycardano/plutus.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"ExecutionUnits",
3838
"PlutusV1Script",
3939
"PlutusV2Script",
40+
"RawPlutusData",
4041
"Redeemer",
4142
"datum_hash",
4243
"plutus_script_hash",
@@ -419,7 +420,7 @@ def from_primitive(cls: CostModels, value: dict) -> CostModels:
419420
"verifyEd25519Signature-memory-arguments": 10,
420421
"verifySchnorrSecp256k1Signature-cpu-arguments-intercept": 20000000000,
421422
"verifySchnorrSecp256k1Signature-cpu-arguments-slope": 0,
422-
"verifySchnorrSecp256k1Signature-memory-arguments": 20000000000
423+
"verifySchnorrSecp256k1Signature-memory-arguments": 20000000000,
423424
}
424425

425426
COST_MODELS = CostModels({0: PLUTUS_V1_COST_MODEL})
@@ -620,7 +621,33 @@ def from_json(cls: PlutusData, data: str) -> PlutusData:
620621
return cls.from_dict(obj)
621622

622623

623-
Datum = Union[PlutusData, dict, IndefiniteList, int, bytes, RawCBOR]
624+
@dataclass
625+
class RawPlutusData(CBORSerializable):
626+
627+
data: CBORTag
628+
629+
def to_primitive(self) -> CBORTag:
630+
def _dfs(obj):
631+
if isinstance(obj, list) and obj:
632+
return IndefiniteList([_dfs(item) for item in obj])
633+
elif isinstance(obj, dict):
634+
return {_dfs(k): _dfs(v) for k, v in obj.items()}
635+
elif isinstance(obj, CBORTag) and isinstance(obj.value, list) and obj.value:
636+
if obj.tag != 102:
637+
value = IndefiniteList([_dfs(item) for item in obj.value])
638+
else:
639+
value = [_dfs(item) for item in obj.value]
640+
return CBORTag(tag=obj.tag, value=value)
641+
return obj
642+
643+
return _dfs(self.data)
644+
645+
@classmethod
646+
def from_primitive(cls: RawPlutusData, value: CBORTag) -> RawPlutusData:
647+
return cls(value)
648+
649+
650+
Datum = Union[PlutusData, dict, IndefiniteList, int, bytes, RawCBOR, RawPlutusData]
624651
"""Plutus Datum type. A Union type that contains all valid datum types."""
625652

626653

@@ -678,6 +705,8 @@ class Redeemer(ArrayCBORSerializable):
678705

679706
@classmethod
680707
def from_primitive(cls: Redeemer, values: List[Primitive]) -> Redeemer:
708+
if isinstance(values[2], CBORTag) and cls is Redeemer:
709+
values[2] = RawPlutusData.from_primitive(values[2])
681710
redeemer = super(Redeemer, cls).from_primitive(
682711
[values[0], values[2], values[3]]
683712
)

pycardano/serialization.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"ArrayCBORSerializable",
3131
"MapCBORSerializable",
3232
"DictCBORSerializable",
33+
"RawCBOR",
3334
"list_hook",
3435
]
3536

pycardano/witness.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from pycardano.key import ExtendedVerificationKey, VerificationKey
77
from pycardano.nativescript import NativeScript
8-
from pycardano.plutus import Redeemer
8+
from pycardano.plutus import RawPlutusData, Redeemer
99
from pycardano.serialization import (
1010
ArrayCBORSerializable,
1111
MapCBORSerializable,
@@ -58,7 +58,7 @@ class TransactionWitnessSet(MapCBORSerializable):
5858

5959
plutus_data: List[Any] = field(
6060
default=None,
61-
metadata={"optional": True, "key": 4},
61+
metadata={"optional": True, "key": 4, "object_hook": list_hook(RawPlutusData)},
6262
)
6363

6464
redeemer: List[Redeemer] = field(

test/pycardano/test_plutus.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
COST_MODELS,
1010
ExecutionUnits,
1111
PlutusData,
12+
RawPlutusData,
1213
Redeemer,
1314
RedeemerTag,
1415
plutus_script_hash,
@@ -194,3 +195,23 @@ def test_plutus_script_hash():
194195
"36c198e1a9d05461945c1f1db2ffb927c2dfc26dd01b59ea93b678b2"
195196
== plutus_script_hash(plutus_script).payload.hex()
196197
)
198+
199+
200+
def test_raw_plutus_data():
201+
raw_plutus_cbor = (
202+
"d8799f581c23347b25deab0b28b5baa917944f212cfe833e74dd5712d"
203+
"6bcec54de9fd8799fd8799fd8799f581c340ebc5a2d7fdd5ad61c9461"
204+
"ab83a04631a1a2dd2e53dc672b57e309ffd8799fd8799fd8799f581cb"
205+
"c5acf6c6b031be26da4804068f5852b4f119e246d907066627a9f5fff"
206+
"ffffffa140d8799f00a1401a000f2ad0ffffd8799fd8799fd8799f581"
207+
"c70e60f3b5ea7153e0acc7a803e4401d44b8ed1bae1c7baaad1a62a72"
208+
"ffd8799fd8799fd8799f581c1e78aae7c90cc36d624f7b3bb6d86b526"
209+
"96dc84e490f343eba89005fffffffffa140d8799f00a1401a000f2ad0"
210+
"ffffd8799fd8799fd8799f581c23347b25deab0b28b5baa917944f212"
211+
"cfe833e74dd5712d6bcec54deffd8799fd8799fd8799f581c084be0e3"
212+
"85f956227ec1710db40e45fc355c858debea77176aa91d07ffffffffa"
213+
"140d8799f00a1401a004c7a20ffffffff"
214+
)
215+
raw_plutus_data = RawPlutusData.from_cbor(raw_plutus_cbor)
216+
assert raw_plutus_data.to_cbor() == raw_plutus_cbor
217+
check_two_way_cbor(raw_plutus_data)

0 commit comments

Comments
 (0)