From 7f3b083fa5608d2f07ab007ff21832d917a95888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=BCndler?= Date: Sat, 15 Jul 2023 00:35:06 +0200 Subject: [PATCH 01/13] Implement new default constr ID --- pycardano/plutus.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/pycardano/plutus.py b/pycardano/plutus.py index 2fc7f0a4..dbe50277 100644 --- a/pycardano/plutus.py +++ b/pycardano/plutus.py @@ -12,6 +12,7 @@ from cbor2 import CBORTag from nacl.encoding import RawEncoder from nacl.hash import blake2b +from hashlib import sha256 from pycardano.exception import DeserializeException from pycardano.hash import DATUM_HASH_SIZE, SCRIPT_HASH_SIZE, DatumHash, ScriptHash @@ -46,6 +47,10 @@ "script_hash", ] +# taken from https://stackoverflow.com/a/13624858 +class classproperty(property): + def __get__(self, owner_self, owner_cls): + return self.fget(owner_cls) class CostModels(DictCBORSerializable): KEY_TYPE = int @@ -460,9 +465,18 @@ class will reduce the complexity of serialization and deserialization tremendous >>> assert test == Test.from_cbor("d87a9f187b43333231ff") """ - CONSTR_ID: ClassVar[int] = 0 - """Constructor ID of this plutus data. - It is primarily used by Plutus core to reconstruct a data structure from serialized CBOR bytes.""" + + @classproperty + def CONSTR_ID(cls): + """ + Constructor ID of this plutus data. + It is primarily used by Plutus core to reconstruct a data structure from serialized CBOR bytes. + The default implementation is an almost unique, deterministic constructor ID in the range 1 - 2^32 based + on class attributes, types and class name. + """ + det_string = cls.__name__ + "*" + "*".join([f"{f.name}~{f.type}" for f in fields(cls)]) + det_hash = sha256(det_string.encode("utf8")).hexdigest() + return int(det_hash, 16) % 2**32 def __post_init__(self): valid_types = (PlutusData, dict, IndefiniteList, int, bytes) From 70a984ccd920f98fd390fe6b0f1e5e5935797df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=BCndler?= Date: Sat, 15 Jul 2023 00:44:41 +0200 Subject: [PATCH 02/13] Formatting --- pycardano/plutus.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pycardano/plutus.py b/pycardano/plutus.py index dbe50277..fac0ecb8 100644 --- a/pycardano/plutus.py +++ b/pycardano/plutus.py @@ -6,7 +6,7 @@ import json from dataclasses import dataclass, field, fields from enum import Enum -from typing import Any, ClassVar, Optional, Type, Union +from typing import Any, Optional, Type, Union import cbor2 from cbor2 import CBORTag @@ -47,11 +47,13 @@ "script_hash", ] + # taken from https://stackoverflow.com/a/13624858 class classproperty(property): def __get__(self, owner_self, owner_cls): return self.fget(owner_cls) + class CostModels(DictCBORSerializable): KEY_TYPE = int VALUE_TYPE = dict @@ -465,7 +467,6 @@ class will reduce the complexity of serialization and deserialization tremendous >>> assert test == Test.from_cbor("d87a9f187b43333231ff") """ - @classproperty def CONSTR_ID(cls): """ @@ -474,7 +475,9 @@ def CONSTR_ID(cls): The default implementation is an almost unique, deterministic constructor ID in the range 1 - 2^32 based on class attributes, types and class name. """ - det_string = cls.__name__ + "*" + "*".join([f"{f.name}~{f.type}" for f in fields(cls)]) + det_string = ( + cls.__name__ + "*" + "*".join([f"{f.name}~{f.type}" for f in fields(cls)]) + ) det_hash = sha256(det_string.encode("utf8")).hexdigest() return int(det_hash, 16) % 2**32 From ef449e2c3f8ac4e0201026f1d18975be5ef45577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=BCndler?= Date: Sat, 15 Jul 2023 00:46:53 +0200 Subject: [PATCH 03/13] Fix plutus data hash --- test/pycardano/test_plutus.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/pycardano/test_plutus.py b/test/pycardano/test_plutus.py index 35cc9ff0..222a67c6 100644 --- a/test/pycardano/test_plutus.py +++ b/test/pycardano/test_plutus.py @@ -51,6 +51,7 @@ class DictTest(PlutusData): @dataclass class ListTest(PlutusData): + CONSTR_ID = 0 a: List[LargestTest] @@ -204,7 +205,7 @@ def test_plutus_data_from_json_wrong_data_structure_type(): def test_plutus_data_hash(): assert ( bytes.fromhex( - "923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec" + "19d31e4f3aa9b03ad93b64c8dd2cc822d247c21e2c22762b7b08e6cadfeddb47" ) == PlutusData().hash().payload ) From 55b90e8b08805efa143e9619fb65165174a43a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=BCndler?= Date: Sat, 15 Jul 2023 00:49:05 +0200 Subject: [PATCH 04/13] Introduce Unit default empty constructor --- pycardano/plutus.py | 5 +++++ test/pycardano/test_util.py | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/pycardano/plutus.py b/pycardano/plutus.py index fac0ecb8..1fb58e31 100644 --- a/pycardano/plutus.py +++ b/pycardano/plutus.py @@ -837,3 +837,8 @@ def script_hash(script: ScriptType) -> ScriptHash: ) else: raise TypeError(f"Unexpected script type: {type(script)}") + +@dataclass +class Unit(PlutusData): + """ The default "Unit type" with a 0 constructor ID """ + CONSTR_ID = 0 diff --git a/test/pycardano/test_util.py b/test/pycardano/test_util.py index 50e033b7..118c8e13 100644 --- a/test/pycardano/test_util.py +++ b/test/pycardano/test_util.py @@ -1,7 +1,7 @@ from test.pycardano.util import chain_context from pycardano.hash import SCRIPT_HASH_SIZE, ScriptDataHash -from pycardano.plutus import ExecutionUnits, PlutusData, Redeemer, RedeemerTag +from pycardano.plutus import ExecutionUnits, PlutusData, Redeemer, RedeemerTag, Unit from pycardano.transaction import Value from pycardano.utils import min_lovelace_pre_alonzo, script_data_hash @@ -145,7 +145,7 @@ def test_min_lovelace_multi_asset_9(self, chain_context): def test_script_data_hash(): - unit = PlutusData() + unit = Unit() redeemers = [Redeemer(unit, ExecutionUnits(1000000, 1000000))] redeemers[0].tag = RedeemerTag.SPEND assert ScriptDataHash.from_primitive( @@ -154,14 +154,14 @@ def test_script_data_hash(): def test_script_data_hash_datum_only(): - unit = PlutusData() + unit = Unit() assert ScriptDataHash.from_primitive( "2f50ea2546f8ce020ca45bfcf2abeb02ff18af2283466f888ae489184b3d2d39" ) == script_data_hash(redeemers=[], datums=[unit]) def test_script_data_hash_redeemer_only(): - unit = PlutusData() + unit = Unit() redeemers = [] assert ScriptDataHash.from_primitive( "a88fe2947b8d45d1f8b798e52174202579ecf847b8f17038c7398103df2d27b0" From 6a6425da886fe5d8207d5bdaa7a936cad4e29409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=BCndler?= Date: Sat, 15 Jul 2023 00:56:06 +0200 Subject: [PATCH 05/13] Formatting much --- pycardano/plutus.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pycardano/plutus.py b/pycardano/plutus.py index 1fb58e31..b33d0f5d 100644 --- a/pycardano/plutus.py +++ b/pycardano/plutus.py @@ -838,7 +838,9 @@ def script_hash(script: ScriptType) -> ScriptHash: else: raise TypeError(f"Unexpected script type: {type(script)}") + @dataclass class Unit(PlutusData): - """ The default "Unit type" with a 0 constructor ID """ + """The default "Unit type" with a 0 constructor ID""" + CONSTR_ID = 0 From 586141f2c31e4d5d25190d439987fc78b07bc1e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=BCndler?= Date: Sat, 15 Jul 2023 01:00:11 +0200 Subject: [PATCH 06/13] Add test for constructor id uniqueness --- test/pycardano/test_plutus.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/pycardano/test_plutus.py b/test/pycardano/test_plutus.py index 222a67c6..dd896fec 100644 --- a/test/pycardano/test_plutus.py +++ b/test/pycardano/test_plutus.py @@ -317,3 +317,32 @@ def test_clone_plutus_data(): my_vesting.deadline = 1643235300001 assert cloned_vesting != my_vesting + +def test_unique_constr_ids(): + + @dataclass + class A(PlutusData): + pass + + @dataclass + class B(PlutusData): + pass + + assert A.CONSTR_ID != B.CONSTR_ID, "Different classes (different names) have same default constructor ID" + B_tmp = B + + @dataclass + class B(PlutusData): + a: int + b: bytes + + assert B_tmp.CONSTR_ID != B.CONSTR_ID, "Different classes (different fields) have same default constructor ID" + + B_tmp = B + + @dataclass + class B(PlutusData): + a: bytes + b: bytes + + assert B_tmp.CONSTR_ID != B.CONSTR_ID, "Different classes (different field types) have same default constructor ID" From 5bb4a7ae96cad403d0b8cc0aa571123902b0e918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=BCndler?= Date: Sat, 15 Jul 2023 01:16:03 +0200 Subject: [PATCH 07/13] Add test for determinism of constructor id --- test/pycardano/test_plutus.py | 60 ++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/test/pycardano/test_plutus.py b/test/pycardano/test_plutus.py index dd896fec..eb52cdbd 100644 --- a/test/pycardano/test_plutus.py +++ b/test/pycardano/test_plutus.py @@ -1,4 +1,8 @@ import copy +import pipes +import subprocess +import sys +import tempfile import unittest from dataclasses import dataclass from test.pycardano.util import check_two_way_cbor @@ -318,8 +322,8 @@ def test_clone_plutus_data(): assert cloned_vesting != my_vesting -def test_unique_constr_ids(): +def test_unique_constr_ids(): @dataclass class A(PlutusData): pass @@ -328,7 +332,9 @@ class A(PlutusData): class B(PlutusData): pass - assert A.CONSTR_ID != B.CONSTR_ID, "Different classes (different names) have same default constructor ID" + assert ( + A.CONSTR_ID != B.CONSTR_ID + ), "Different classes (different names) have same default constructor ID" B_tmp = B @dataclass @@ -336,7 +342,9 @@ class B(PlutusData): a: int b: bytes - assert B_tmp.CONSTR_ID != B.CONSTR_ID, "Different classes (different fields) have same default constructor ID" + assert ( + B_tmp.CONSTR_ID != B.CONSTR_ID + ), "Different classes (different fields) have same default constructor ID" B_tmp = B @@ -345,4 +353,48 @@ class B(PlutusData): a: bytes b: bytes - assert B_tmp.CONSTR_ID != B.CONSTR_ID, "Different classes (different field types) have same default constructor ID" + assert ( + B_tmp.CONSTR_ID != B.CONSTR_ID + ), "Different classes (different field types) have same default constructor ID" + + +def test_deterministic_constr_ids_local(): + @dataclass + class A(PlutusData): + a: int + b: bytes + + A_tmp = A + + @dataclass + class A(PlutusData): + a: int + b: bytes + + assert ( + A_tmp.CONSTR_ID == A.CONSTR_ID + ), "Same class has different default constructor ID" + + +def test_deterministic_constr_ids_global(): + code = """ +from dataclasses import dataclass +from pycardano import PlutusData + +@dataclass +class A(PlutusData): + a: int + b: bytes + +print(A.CONSTR_ID) +""" + tmpfile = tempfile.TemporaryFile() + tmpfile.write(code.encode("utf8")) + tmpfile.seek(0) + res = subprocess.run([sys.executable], stdin=tmpfile, capture_output=True).stdout + tmpfile.seek(0) + res2 = subprocess.run([sys.executable], stdin=tmpfile, capture_output=True).stdout + + assert ( + res == res2 + ), "Same class has different default constructor id in two consecutive runs" From 308343c3f92182047c7279904768a898eb66bf7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=BCndler?= Date: Sat, 15 Jul 2023 01:17:18 +0200 Subject: [PATCH 08/13] Remove unused imports --- test/pycardano/test_plutus.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/pycardano/test_plutus.py b/test/pycardano/test_plutus.py index eb52cdbd..f2aba0f9 100644 --- a/test/pycardano/test_plutus.py +++ b/test/pycardano/test_plutus.py @@ -1,9 +1,7 @@ import copy -import pipes import subprocess import sys import tempfile -import unittest from dataclasses import dataclass from test.pycardano.util import check_two_way_cbor from typing import Dict, List, Union @@ -11,7 +9,7 @@ import pytest from cbor2 import CBORTag -from pycardano.exception import DeserializeException, SerializeException +from pycardano.exception import DeserializeException from pycardano.plutus import ( COST_MODELS, ExecutionUnits, From 955cd7a28a886d9a02812de45c12b71b474d84fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=BCndler?= Date: Sat, 15 Jul 2023 10:46:26 +0200 Subject: [PATCH 09/13] Fix integration test --- integration-test/test/test_plutus.py | 2 +- pycardano/plutus.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/integration-test/test/test_plutus.py b/integration-test/test/test_plutus.py index c57119f0..acb554c8 100644 --- a/integration-test/test/test_plutus.py +++ b/integration-test/test/test_plutus.py @@ -26,7 +26,7 @@ def test_plutus_v1(self): builder = TransactionBuilder(self.chain_context) builder.add_input_address(giver_address) - datum = PlutusData() # A Unit type "()" in Haskell + datum = Unit() # A Unit type "()" in Haskell builder.add_output( TransactionOutput(script_address, 50000000, datum_hash=datum_hash(datum)) ) diff --git a/pycardano/plutus.py b/pycardano/plutus.py index b33d0f5d..9e436da1 100644 --- a/pycardano/plutus.py +++ b/pycardano/plutus.py @@ -45,6 +45,7 @@ "datum_hash", "plutus_script_hash", "script_hash", + "Unit", ] From 9bcea9b5f214fb62c5f36f1298efc4c610a12652 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sat, 22 Jul 2023 14:31:37 +0800 Subject: [PATCH 10/13] Cache CONSTR_ID --- pycardano/plutus.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/pycardano/plutus.py b/pycardano/plutus.py index 9e436da1..313606f0 100644 --- a/pycardano/plutus.py +++ b/pycardano/plutus.py @@ -6,13 +6,13 @@ import json from dataclasses import dataclass, field, fields from enum import Enum +from hashlib import sha256 from typing import Any, Optional, Type, Union import cbor2 from cbor2 import CBORTag from nacl.encoding import RawEncoder from nacl.hash import blake2b -from hashlib import sha256 from pycardano.exception import DeserializeException from pycardano.hash import DATUM_HASH_SIZE, SCRIPT_HASH_SIZE, DatumHash, ScriptHash @@ -476,11 +476,16 @@ def CONSTR_ID(cls): The default implementation is an almost unique, deterministic constructor ID in the range 1 - 2^32 based on class attributes, types and class name. """ - det_string = ( - cls.__name__ + "*" + "*".join([f"{f.name}~{f.type}" for f in fields(cls)]) - ) - det_hash = sha256(det_string.encode("utf8")).hexdigest() - return int(det_hash, 16) % 2**32 + if not hasattr(cls, "_CONSTR_ID"): + det_string = ( + cls.__name__ + + "*" + + "*".join([f"{f.name}~{f.type}" for f in fields(cls)]) + ) + det_hash = sha256(det_string.encode("utf8")).hexdigest() + setattr(cls, "_CONSTR_ID", int(det_hash, 16) % 2**32) + + return cls._CONSTR_ID def __post_init__(self): valid_types = (PlutusData, dict, IndefiniteList, int, bytes) From c4e06d6db78fbe44873237544e0c9b5d65661be7 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 23 Jul 2023 16:19:13 +0800 Subject: [PATCH 11/13] Avoid using _CONSTR_ID from parent class by adding class name to _CONSTR_ID --- pycardano/plutus.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pycardano/plutus.py b/pycardano/plutus.py index 313606f0..c8562874 100644 --- a/pycardano/plutus.py +++ b/pycardano/plutus.py @@ -476,16 +476,17 @@ def CONSTR_ID(cls): The default implementation is an almost unique, deterministic constructor ID in the range 1 - 2^32 based on class attributes, types and class name. """ - if not hasattr(cls, "_CONSTR_ID"): + k = f"_CONSTR_ID_{cls.__name__}" + if not hasattr(cls, k): det_string = ( cls.__name__ + "*" + "*".join([f"{f.name}~{f.type}" for f in fields(cls)]) ) det_hash = sha256(det_string.encode("utf8")).hexdigest() - setattr(cls, "_CONSTR_ID", int(det_hash, 16) % 2**32) + setattr(cls, k, int(det_hash, 16) % 2**32) - return cls._CONSTR_ID + return getattr(cls, k) def __post_init__(self): valid_types = (PlutusData, dict, IndefiniteList, int, bytes) From 787e1607fcdd6000379beb8085c637102fa1d282 Mon Sep 17 00:00:00 2001 From: Jerry Date: Sat, 29 Jul 2023 10:19:31 +0800 Subject: [PATCH 12/13] Add a flag to enable/disable auto CONSTR_ID --- pycardano/plutus.py | 8 +++++++- test/pycardano/test_plutus.py | 9 ++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/pycardano/plutus.py b/pycardano/plutus.py index c8562874..2ced5892 100644 --- a/pycardano/plutus.py +++ b/pycardano/plutus.py @@ -7,7 +7,7 @@ from dataclasses import dataclass, field, fields from enum import Enum from hashlib import sha256 -from typing import Any, Optional, Type, Union +from typing import Any, ClassVar, Optional, Type, Union import cbor2 from cbor2 import CBORTag @@ -468,6 +468,9 @@ class will reduce the complexity of serialization and deserialization tremendous >>> assert test == Test.from_cbor("d87a9f187b43333231ff") """ + AUTO_ID: ClassVar[bool] = False + """Enables automatic assignment of a deterministic constructor id (CONSTR_ID) for the Plutus data if set to True.""" + @classproperty def CONSTR_ID(cls): """ @@ -476,6 +479,9 @@ def CONSTR_ID(cls): The default implementation is an almost unique, deterministic constructor ID in the range 1 - 2^32 based on class attributes, types and class name. """ + if not cls.AUTO_ID: + return 0 + k = f"_CONSTR_ID_{cls.__name__}" if not hasattr(cls, k): det_string = ( diff --git a/test/pycardano/test_plutus.py b/test/pycardano/test_plutus.py index f2aba0f9..6773ee5f 100644 --- a/test/pycardano/test_plutus.py +++ b/test/pycardano/test_plutus.py @@ -207,7 +207,7 @@ def test_plutus_data_from_json_wrong_data_structure_type(): def test_plutus_data_hash(): assert ( bytes.fromhex( - "19d31e4f3aa9b03ad93b64c8dd2cc822d247c21e2c22762b7b08e6cadfeddb47" + "923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec" ) == PlutusData().hash().payload ) @@ -324,10 +324,12 @@ def test_clone_plutus_data(): def test_unique_constr_ids(): @dataclass class A(PlutusData): + AUTO_ID = True pass @dataclass class B(PlutusData): + AUTO_ID = True pass assert ( @@ -337,6 +339,7 @@ class B(PlutusData): @dataclass class B(PlutusData): + AUTO_ID = True a: int b: bytes @@ -348,6 +351,7 @@ class B(PlutusData): @dataclass class B(PlutusData): + AUTO_ID = True a: bytes b: bytes @@ -359,6 +363,7 @@ class B(PlutusData): def test_deterministic_constr_ids_local(): @dataclass class A(PlutusData): + AUTO_ID = True a: int b: bytes @@ -366,6 +371,7 @@ class A(PlutusData): @dataclass class A(PlutusData): + AUTO_ID = True a: int b: bytes @@ -381,6 +387,7 @@ def test_deterministic_constr_ids_global(): @dataclass class A(PlutusData): + AUTO_ID = True a: int b: bytes From 8b7d2d6bdd6976f6978ce9a062897f11d28037fc Mon Sep 17 00:00:00 2001 From: Jerry Date: Sun, 30 Jul 2023 15:16:28 +0800 Subject: [PATCH 13/13] Revert "Add a flag to enable/disable auto CONSTR_ID" This reverts commit 787e1607fcdd6000379beb8085c637102fa1d282. --- pycardano/plutus.py | 8 +------- test/pycardano/test_plutus.py | 9 +-------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/pycardano/plutus.py b/pycardano/plutus.py index 2ced5892..c8562874 100644 --- a/pycardano/plutus.py +++ b/pycardano/plutus.py @@ -7,7 +7,7 @@ from dataclasses import dataclass, field, fields from enum import Enum from hashlib import sha256 -from typing import Any, ClassVar, Optional, Type, Union +from typing import Any, Optional, Type, Union import cbor2 from cbor2 import CBORTag @@ -468,9 +468,6 @@ class will reduce the complexity of serialization and deserialization tremendous >>> assert test == Test.from_cbor("d87a9f187b43333231ff") """ - AUTO_ID: ClassVar[bool] = False - """Enables automatic assignment of a deterministic constructor id (CONSTR_ID) for the Plutus data if set to True.""" - @classproperty def CONSTR_ID(cls): """ @@ -479,9 +476,6 @@ def CONSTR_ID(cls): The default implementation is an almost unique, deterministic constructor ID in the range 1 - 2^32 based on class attributes, types and class name. """ - if not cls.AUTO_ID: - return 0 - k = f"_CONSTR_ID_{cls.__name__}" if not hasattr(cls, k): det_string = ( diff --git a/test/pycardano/test_plutus.py b/test/pycardano/test_plutus.py index 6773ee5f..f2aba0f9 100644 --- a/test/pycardano/test_plutus.py +++ b/test/pycardano/test_plutus.py @@ -207,7 +207,7 @@ def test_plutus_data_from_json_wrong_data_structure_type(): def test_plutus_data_hash(): assert ( bytes.fromhex( - "923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec" + "19d31e4f3aa9b03ad93b64c8dd2cc822d247c21e2c22762b7b08e6cadfeddb47" ) == PlutusData().hash().payload ) @@ -324,12 +324,10 @@ def test_clone_plutus_data(): def test_unique_constr_ids(): @dataclass class A(PlutusData): - AUTO_ID = True pass @dataclass class B(PlutusData): - AUTO_ID = True pass assert ( @@ -339,7 +337,6 @@ class B(PlutusData): @dataclass class B(PlutusData): - AUTO_ID = True a: int b: bytes @@ -351,7 +348,6 @@ class B(PlutusData): @dataclass class B(PlutusData): - AUTO_ID = True a: bytes b: bytes @@ -363,7 +359,6 @@ class B(PlutusData): def test_deterministic_constr_ids_local(): @dataclass class A(PlutusData): - AUTO_ID = True a: int b: bytes @@ -371,7 +366,6 @@ class A(PlutusData): @dataclass class A(PlutusData): - AUTO_ID = True a: int b: bytes @@ -387,7 +381,6 @@ def test_deterministic_constr_ids_global(): @dataclass class A(PlutusData): - AUTO_ID = True a: int b: bytes