Skip to content

Commit

Permalink
added ._cvrsn to Serder to support CESR Code table version tracking i…
Browse files Browse the repository at this point in the history
…n CESR native serializations
  • Loading branch information
SmithSamuelM committed Mar 25, 2024
1 parent 38146bd commit a601a92
Showing 1 changed file with 50 additions and 32 deletions.
82 changes: 50 additions & 32 deletions src/keri/core/serdering.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ class Serder:
Proto = Protocols.keri # default message protocol type for makify on base Serder
Vrsn = Vrsn_1_0 # default protocol version for protocol type
Kind = Serials.json # default serialization kind
CVrsn = Vrsn_2_0 # default CESR code table version


# Nested dict keyed by protocol.
Expand Down Expand Up @@ -439,8 +440,8 @@ class Serder:
}


def __init__(self, *, raw=b'', sad=None, strip=False,
smellage=None, verify=True, makify=False,
def __init__(self, *, raw=b'', sad=None, strip=False, smellage=None,
cvrsn=None, verify=True, makify=False,
proto=None, vrsn=None, kind=None, ilk=None, saids=None):
"""Deserialize raw if provided. Update properties from deserialized raw.
Verifies said(s) embedded in sad as given by labels.
Expand All @@ -462,6 +463,8 @@ def __init__(self, *, raw=b'', sad=None, strip=False,
version string elements. If none or empty ignore otherwise assume
that raw already had its version string extracted (reaped) into the
elements of smellage.
cvrsn (Versionage | None): instance desired CESR code table version
If None then its extracted from raw or uses default .CVrsn
verify (bool): True means verify said(s) of given raw or sad.
Raises ValidationError if verification fails
Ignore when raw not provided or when raw and saidify is True
Expand All @@ -486,10 +489,12 @@ def __init__(self, *, raw=b'', sad=None, strip=False,
"""
cvrsn = cvrsn if cvrsn is not None else self.CVrsn

if raw: # deserialize raw using property setter
# self._inhale works because it only references class attributes
self._inhale(raw=raw, smellage=smellage)
self._inhale(raw=raw, smellage=smellage, cvrsn=cvrsn)
# ._inhale updates ._raw, ._sad, ._cvrsn, ._proto, ._vrsn, ._kind, ._size

# primary said field label
try:
label = list(self.Fields[self.proto][self.vrsn][self.ilk].saids)[0]
Expand Down Expand Up @@ -517,21 +522,22 @@ def __init__(self, *, raw=b'', sad=None, strip=False,
elif sad or makify: # serialize sad into raw or make sad
if makify: # recompute properties and said(s) and reset sad
# makify resets sad, raw, proto, vrsn, kind, ilk, and size
self.makify(sad=sad, proto=proto, vrsn=vrsn, kind=kind,
self.makify(sad=sad, cvrsn=cvrsn, proto=proto, vrsn=vrsn, kind=kind,
ilk=ilk, saids=saids)
# .makify updates ._raw, ._sad, ._cvrsn, ._proto, ._vrsn, ._kind, ._size

else:
# self._exhale works because it only access class attributes
self._exhale(sad=sad)
self._exhale(sad=sad, cvrsn=cvrsn)
# .exhale updates ._raw, ._sad, ._cvrsn, ._proto, ._vrsn, ._kind, ._size

# primary said field label
try:
label = list(self.Fields[self.proto][self.vrsn][self.ilk].saids)[0]
if label not in self._sad:
raise DeserializeError(f"Missing primary said field in {self._sad}.")
self._said = self._sad[label] # not verified
except Exception:
self._said = None # no saidive field
# primary said field label
try:
label = list(self.Fields[self.proto][self.vrsn][self.ilk].saids)[0]
if label not in self._sad:
raise DeserializeError(f"Missing primary said field in {self._sad}.")
self._said = self._sad[label] # not verified
except Exception:
self._said = None # no saidive field

if verify: # verify the said(s) provided in sad
try:
Expand Down Expand Up @@ -662,7 +668,8 @@ def _verify(self):
# verified successfully since no exception


def makify(self, sad, *, proto=None, vrsn=None, kind=None, ilk=None, saids=None):
def makify(self, sad, *, cvrsn=None, proto=None, vrsn=None, kind=None,
ilk=None, saids=None):
"""Makify given sad dict makes the versions string and computes the said
field values and sets associated properties:
raw, sad, proto, version, kind, size
Expand All @@ -680,6 +687,8 @@ def makify(self, sad, *, proto=None, vrsn=None, kind=None, ilk=None, saids=None)
Parameters:
sad (dict): serializable saidified field map of message.
Ignored if raw provided
cvrsn (Versionage | None): instance desired CESR code table version
If None then its extracted from raw or uses default .CVrsn
proto (str | None): desired protocol type str value of Protocols
If None then its extracted from sad or uses default .Proto
vrsn (Versionage | None): instance desired protocol version
Expand All @@ -706,6 +715,8 @@ def makify(self, sad, *, proto=None, vrsn=None, kind=None, ilk=None, saids=None)
else:
silk = sad.get('t') # if 't' not in sad .get returns None which may be valid

cvrsn = cvrsn if cvrsn is not None else self.CVrsn

if proto is None:
proto = sproto if sproto is not None else self.Proto

Expand All @@ -729,12 +740,6 @@ def makify(self, sad, *, proto=None, vrsn=None, kind=None, ilk=None, saids=None)
raise SerializeError(f"Expected protocol = {self.Protocol}, got "
f"{proto} instead.")

#if version is not None: # compatible version with vrsn
#if (vrsn.major > version.major or
#(vrsn.major == version.major and vrsn.minor > version.minor)):
#raise SerializeError(f"Incompatible {version=}, with "
#f"{vrsn=}.")


if kind not in Serials:
raise SerializeError(f"Invalid serialization kind = {kind}")
Expand Down Expand Up @@ -858,21 +863,14 @@ def makify(self, sad, *, proto=None, vrsn=None, kind=None, ilk=None, saids=None)

self._raw = raw
self._sad = sad
self._cvrsn = cvrsn
self._proto = proto
self._vrsn = vrsn
self._kind = kind
self._size = size
# primary said field label
try:
label = list(self.Fields[self.proto][self.vrsn][self.ilk].saids)[0]
if label not in self._sad:
raise SerializeError(f"Missing primary said field in {self._sad}.")
self._said = self._sad[label] # implicitly verified
except Exception:
self._said = None # no saidive field


def _inhale(self, raw, *, smellage=None):
def _inhale(self, raw, *, smellage=None, cvrsn=None):
"""Deserializes raw.
Parses serilized event ser of serialization kind and assigns to
instance attributes and returns tuple of associated elements.
Expand All @@ -895,6 +893,8 @@ def _inhale(self, raw, *, smellage=None):
elements. If none or empty ignore otherwise assume that raw
already had its version string extracted (reaped) into the
elements of smellage.
cvrsn (Versionage | None): instance desired CESR code table version
If None then its extracted from raw or uses default .CVrsn
Note:
loads and jumps of json use str whereas cbor and msgpack use bytes
Expand All @@ -908,17 +908,21 @@ def _inhale(self, raw, *, smellage=None):

sad = self.loads(raw=raw, size=size, kind=kind)

cvrsn = cvrsn if cvrsn is not None else self.CVrsn

if "v" not in sad: # Regex does not check for version string label itself
raise FieldError(f"Missing version string field in {sad}.")

self._raw = bytes(raw[:size]) # crypto ops require bytes not bytearray
self._sad = sad
self._cvrsn = cvrsn
self._proto = proto
self._vrsn = vrsn
self._kind = kind
self._size = size



def loads(self, raw, size=None, kind=Serials.json):
"""Utility static method to handle deserialization by kind
Expand Down Expand Up @@ -975,7 +979,7 @@ def _loads(self, raw, size=None):
pass


def _exhale(self, sad):
def _exhale(self, sad, cvrsn=None):
"""Serializes sad and sets the serialized size in its version string.
As classmethod enables bootstrap of valid sad dict that has correct size
Expand All @@ -992,6 +996,8 @@ def _exhale(self, sad):
Parameters:
clas (Serder): class reference
sad (dict): serializable attribute dict of saidified data
cvrsn (Versionage | None): instance desired CESR code table version
If None then its extracted from raw or uses default .CVrsn
"""
Expand All @@ -1007,6 +1013,8 @@ def _exhale(self, sad):
# generate new version string with correct size
vs = versify(protocol=proto, version=vrsn, kind=kind, size=size)

cvrsn = cvrsn if cvrsn is not None else self.CVrsn

# find location of old version string inside raw
match = Rever.search(raw) # Rever's regex takes bytes
if not match or match.start() > 12:
Expand All @@ -1021,6 +1029,7 @@ def _exhale(self, sad):

self._raw = raw
self._sad = sad
self._cvrsn = cvrsn
self._proto = proto
self._vrsn = vrsn
self._kind = kind
Expand Down Expand Up @@ -1259,6 +1268,15 @@ def sad(self):
"""
return dict(self._sad) # return copy

@property
def cvrsn(self):
"""cvrsn (version) property getter
Returns:
cvrsn (Versionage): instance of CESR code table version for this Serder
"""
return self._cvrsn


@property
def kind(self):
Expand Down

0 comments on commit a601a92

Please sign in to comment.