Skip to content

Commit b6b48ac

Browse files
committed
Add deserialization for certificates
1 parent d4ec506 commit b6b48ac

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

pycardano/certificate.py

+57-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
from dataclasses import dataclass, field
2-
from typing import Optional, Union
2+
from typing import Optional, Union, Type
33

4+
from pycardano.exception import DeserializeException
45
from pycardano.hash import PoolKeyHash, ScriptHash, VerificationKeyHash
5-
from pycardano.serialization import ArrayCBORSerializable
6+
from pycardano.serialization import (
7+
ArrayCBORSerializable,
8+
ArrayBase,
9+
limit_primitive_type,
10+
)
611

712
__all__ = [
813
"Certificate",
@@ -25,20 +30,56 @@ def __post_init__(self):
2530
else:
2631
self._CODE = 1
2732

33+
@classmethod
34+
@limit_primitive_type(list, tuple)
35+
def from_primitive(
36+
cls: Type[ArrayBase], values: Union[list, tuple]
37+
) -> "StakeCredential":
38+
if len(values) != 2:
39+
raise ValueError(f"Expected 2 values, got {len(values)}")
40+
if values[0] == 0:
41+
return StakeCredential(VerificationKeyHash.from_primitive(values[1]))
42+
elif values[0] == 1:
43+
return StakeCredential(ScriptHash.from_primitive(values[1]))
44+
else:
45+
raise ValueError(f"Unknown code: {values[0]}")
46+
2847

2948
@dataclass(repr=False)
3049
class StakeRegistration(ArrayCBORSerializable):
3150
_CODE: int = field(init=False, default=0)
3251

3352
stake_credential: StakeCredential
3453

54+
@classmethod
55+
@limit_primitive_type(list, tuple)
56+
def from_primitive(
57+
cls: Type[ArrayBase], values: Union[list, tuple]
58+
) -> "StakeRegistration":
59+
if len(values) != 2:
60+
raise DeserializeException(f"Expected 2 values, got {len(values)}")
61+
if values[0] != 0:
62+
raise DeserializeException(f"Expected 0, got {values[0]}")
63+
return StakeRegistration(StakeCredential.from_primitive(values[1]))
64+
3565

3666
@dataclass(repr=False)
3767
class StakeDeregistration(ArrayCBORSerializable):
3868
_CODE: int = field(init=False, default=1)
3969

4070
stake_credential: StakeCredential
4171

72+
@classmethod
73+
@limit_primitive_type(list, tuple)
74+
def from_primitive(
75+
cls: Type[ArrayBase], values: Union[list, tuple]
76+
) -> "StakeDeregistration":
77+
if len(values) != 2:
78+
raise DeserializeException(f"Expected 2 values, got {len(values)}")
79+
if values[0] != 1:
80+
raise DeserializeException(f"Expected 1, got {values[0]}")
81+
return StakeDeregistration(StakeCredential.from_primitive(values[1]))
82+
4283

4384
@dataclass(repr=False)
4485
class StakeDelegation(ArrayCBORSerializable):
@@ -48,5 +89,19 @@ class StakeDelegation(ArrayCBORSerializable):
4889

4990
pool_keyhash: PoolKeyHash
5091

92+
@classmethod
93+
@limit_primitive_type(list, tuple)
94+
def from_primitive(
95+
cls: Type[ArrayBase], values: Union[list, tuple]
96+
) -> "StakeDelegation":
97+
if len(values) != 3:
98+
raise DeserializeException(f"Expected 3 values, got {len(values)}")
99+
if values[0] != 2:
100+
raise DeserializeException(f"Expected 2, got {values[0]}")
101+
return StakeDelegation(
102+
StakeCredential.from_primitive(values[1]),
103+
PoolKeyHash.from_primitive(values[2]),
104+
)
105+
51106

52107
Certificate = Union[StakeRegistration, StakeDeregistration, StakeDelegation]

test/pycardano/test_serialization.py

+10
Original file line numberDiff line numberDiff line change
@@ -316,3 +316,13 @@ def test_deserialize_empty_value():
316316
transaction.transaction_body.outputs[0].amount.multi_asset
317317
== pycardano.MultiAsset()
318318
), "Invalid deserialization of multi asset"
319+
320+
321+
def test_certificate_transaction_deserialize():
322+
"""
323+
This should not crash even though there is an empty value in the transaction
324+
"""
325+
pycardano.Transaction.from_cbor(
326+
"84a6008282582060a6ad87d0bb0a1f6153d908c003a63a2e29d80d64ea243e8a7c322a322b62a700825820c8337cabe7956bf5e903f2591b7cbe1e50bc4dc3402aadd075d4b5eded9ee70d0001818258393025094314c7b532cc1d35f8acd9f7eb307ac0cf49e012e17fd974a03a0f09a6c0f72ebc76d0db9bad8667a24f58734a8f7a8b2839ec1cc8461a00bc5a50021a0002d249031a03178183048282008201581c0f09a6c0f72ebc76d0db9bad8667a24f58734a8f7a8b2839ec1cc84683028201581c0f09a6c0f72ebc76d0db9bad8667a24f58734a8f7a8b2839ec1cc846581c376a90568c7ac62662147f919fc5a919a1ad9ed853e056d244f74b630800a2008382582047cfd2ef0b24eb9316127bb7b0b8d6befafdfd56f37c2892e6098fdc4539a7f7584039abdea2179a593027d5f8249356865cd6ab184063c0196daa4051d8e75ee2ea36648aa190f133e61220798cb8cb0a6e573f339e4ac9938f712577bc38e381028258206864b22adc8d2aa625bd28e7165459bce9057b712026269e53ce372117f6762658402c84d426f506bd76fd35fa4ca7edbb4bea5b2ca0d585894dacf6470bf07117fe61b1c5c137188b93913ca0df7dd8e0ef8a29c75c1a168f370e3ea5120909c804825820d00dcafc4918495980b0768361d051f3ece94cccb887a9f22b9480f9cda0bae75840a257e022f60953bb293af406cc5b399d283a9daf6e787baade74e603476f8474302217d33573dc7029689ac1cc55e5b85fadb39e7ed7104f17949d738417950801838201818200581cf08a3f7f85aea5f58540c6705eefd580efb67e03597d9154b832ac4e8201818200581c74005c045440ef7604f3ebe8bd8a90660024459754eec6a13656a8ad8201818200581c6f3f457a6e4a8b2b23aac8c9b7a010b3631b2cf990ef444a9ef4142ff5f6"
327+
)
328+
# TODO add test for presence of certificate

0 commit comments

Comments
 (0)