Skip to content

Commit

Permalink
Merge pull request #712 from SmithSamuelM/development
Browse files Browse the repository at this point in the history
Refactor better support for versioning for Serder
  • Loading branch information
SmithSamuelM authored Mar 17, 2024
2 parents b3591e2 + 8521368 commit b8578dd
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 43 deletions.
43 changes: 29 additions & 14 deletions src/keri/core/serdering.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
ShortageError, VersionError, ProtocolError, KindError,
DeserializeError, FieldError, SerializeError)
from ..kering import (Versionage, Version, Vrsn_1_0, Vrsn_2_0,
VERRAWSIZE, VERFMT, MAXVERFULLSPAN,
SMELLSIZE, Smellage, smell)
VERRAWSIZE, VERFMT,
MAXVERFULLSPAN, VER1FULLSPAN, VER2FULLSPAN)
from ..kering import SMELLSIZE, Smellage, smell

from ..kering import Protos, Serials, Rever, versify, deversify, Ilks
from ..core import coring
from .coring import MtrDex, DigDex, PreDex, Saids, Digestage
Expand Down Expand Up @@ -178,6 +180,7 @@ class Serder:
Class Attributes:
Dummy (str): dummy character for computing SAIDs
Spans (dict): version string spans keyed by version
Digests (dict): map of digestive codes. Should be same set of codes as
in coring.DigestCodex coring.DigDex so that .digestive property works.
Use unit tests to ensure codex sets match
Expand Down Expand Up @@ -244,6 +247,9 @@ class Serder:
"""
Dummy = "#" # dummy spaceholder char for SAID. Must not be a valid Base64 char

# Spans dict keyed by version (Versionage instance) of version string span (size)
Spans = {Vrsn_1_0: VER1FULLSPAN, Vrsn_2_0: VER2FULLSPAN}

# should be same set of codes as in coring.DigestCodex coring.DigDex so
# .digestive property works. Use unit tests to ensure codex sets match
Digests = {
Expand Down Expand Up @@ -539,13 +545,13 @@ def __init__(self, *, raw=b'', sad=None, strip=False, version=Version,
except Exception:
self._said = None # no saidive field

if verify: # verify the said(s) provided in sad
try:
self._verify() # raises exception when not verify
except Exception as ex:
logger.error("Invalid sad for Serder %s\n%s",
self.pretty(), ex.args[0])
raise ValidationError(f"Invalid sad for Serder ="
if verify: # verify the said(s) provided in sad
try:
self._verify() # raises exception when not verify
except Exception as ex:
logger.error("Invalid sad for Serder %s\n%s",
self.pretty(), ex.args[0])
raise ValidationError(f"Invalid sad for Serder ="
f"{self._sad}.") from ex

else:
Expand Down Expand Up @@ -738,9 +744,12 @@ def makify(self, sad, *, version=None,
raise SerializeError(f"Expected protocol = {self.Protocol}, got "
f"{proto} instead.")

if version is not None and vrsn != version:
raise SerializeError(f"Expected version = {version}, got "
f"{vrsn.major}.{vrsn.minor}.")
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 @@ -771,6 +780,10 @@ def makify(self, sad, *, version=None,
value = copy.copy(value) # copy iterable defaults
sad[label] = value

# Need to insert required fields in proper place because passed in sad
# may have missing require fields that appear before provided ones so
# can't simply append

if 't' in sad: # when packet type field then force ilk
sad['t'] = ilk # assign ilk

Expand Down Expand Up @@ -823,9 +836,11 @@ def makify(self, sad, *, version=None,
raise SerializeError(f"Missing requires version string field 'v'"
f" in sad = {sad}.")

sad['v'] = self.Dummy * MAXVERFULLSPAN # ensure size of vs
# this size of sad needs to be computed based on actual version string span
# since not same for all versions
sad['v'] = self.Dummy * self.Spans[vrsn] # ensure span of vs is dummied MAXVERFULLSPAN

raw = self.dumps(sad, kind) # get size of fully dummied sad
raw = self.dumps(sad, kind) # get size of sad with fully dummied vs and saids
size = len(raw)

# generate new version string with correct size
Expand Down
9 changes: 6 additions & 3 deletions src/keri/kering.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

VEREX = VEREX2 + b'|' + VEREX1

MAXVERFULLSPAN = max(VER1FULLSPAN, VER2FULLSPAN) # number of characters in full version string
MAXVERFULLSPAN = max(VER1FULLSPAN, VER2FULLSPAN) # max number of characters in full version string

Rever = re.compile(VEREX) # compile is faster

Expand Down Expand Up @@ -114,9 +114,12 @@ def rematch(match, *, version=None):
vrsn = Versionage(major=int(major, 16), minor=int(minor, 16))
if vrsn.major > 1: # version1 vs but major > 1
raise VersionError(f"Incompatible {vrsn=} with version string.")
if version is not None and vrsn != version:
raise VersionError(f"Expected {version=}, got "
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 VersionError(f"Incompatible {version=}, with "
f"{vrsn=}.")

kind = kind.decode("utf-8")
if kind not in Serials:
raise KindError(f"Invalid serialization kind = {kind}.")
Expand Down
22 changes: 13 additions & 9 deletions tests/core/test_eventing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2090,7 +2090,8 @@ def test_kever(mockHelpingNowUTC):
# make with defaults with non-digestive prefix
serder = serdering.SerderKERI(makify=True,
ilk=kering.Ilks.icp,
saids = {'i': coring.PreDex.Ed25519})
saids = {'i': coring.PreDex.Ed25519},
verify=False)

sad = serder.sad
sad['i'] = skp0.verfer.qb64 # non-digestive aid
Expand Down Expand Up @@ -2233,7 +2234,8 @@ def test_kever(mockHelpingNowUTC):
# make with defaults with non-transferable prefix
serder = serdering.SerderKERI(makify=True,
ilk=kering.Ilks.icp,
saids = {'i': coring.PreDex.Ed25519N})
saids = {'i': coring.PreDex.Ed25519N},
verify=False)

sad = serder.sad
sad['i'] = skp0.verfer.qb64 # non-digestive aid
Expand All @@ -2244,7 +2246,7 @@ def test_kever(mockHelpingNowUTC):
sad['n'] = nxt
sad['bt'] = "{:x}".format(toad)

serder = serdering.SerderKERI(makify=True, verify=True, sad=sad)
serder = serdering.SerderKERI(makify=True, verify=False, sad=sad)
assert serder.said == 'EFsuiA86Q5gGuVOO3tou8KSU6LORSExIUxzWNrlnW7WP'
assert serder.pre == skp0.verfer.qb64
aid0 = serder.pre
Expand All @@ -2270,15 +2272,16 @@ def test_kever(mockHelpingNowUTC):
# make with defaults with non-transferable prefix
serder = serdering.SerderKERI(makify=True,
ilk=kering.Ilks.icp,
saids = {'i': coring.PreDex.Ed25519N})
saids = {'i': coring.PreDex.Ed25519N},
verify=False)

sad = serder.sad
sad['i'] = skp0.verfer.qb64 # non-digestive aid
sad['s'] = "{:x}".format(sn) # hex string
sad['kt'] = "{:x}".format(sith) # hex string
sad['k'] = keys
sad['nt'] = 0
sad['n'] = nxt
sad['n'] = nxt # empty nxt
sad['bt'] = "{:x}".format(toad)

serder = serdering.SerderKERI(makify=True, verify=True, sad=sad)
Expand Down Expand Up @@ -2327,7 +2330,8 @@ def test_kever(mockHelpingNowUTC):
# make with defaults with non-transferable prefix
serder = serdering.SerderKERI(makify=True,
ilk=kering.Ilks.icp,
saids = {'i': coring.PreDex.Ed25519N})
saids = {'i': coring.PreDex.Ed25519N},
verify=False)

sad = serder.sad
sad['i'] = skp0.verfer.qb64 # non-digestive aid
Expand All @@ -2339,7 +2343,7 @@ def test_kever(mockHelpingNowUTC):
sad['bt'] = "{:x}".format(toad)
sad['b'] = baks

serder = serdering.SerderKERI(makify=True, verify=True, sad=sad)
serder = serdering.SerderKERI(makify=True, verify=False, sad=sad)
assert serder.said == 'EKcREpfNupJ8oOqdnqDIyJVr1-GgIMBrVOtBUR9Gm6lO'
assert serder.pre == skp0.verfer.qb64

Expand All @@ -2362,7 +2366,7 @@ def test_kever(mockHelpingNowUTC):
sad =serder.sad # makes copy
sad['bt'] = "{:x}".format(toad)

serder = serdering.SerderKERI(makify=True, verify=True, sad=sad)
serder = serdering.SerderKERI(makify=True, verify=False, sad=sad)
assert serder.said == 'EBKhptvqccp0KNBaS45bNPdTE4m19U1IvweHJW2PIEDI'
assert serder.pre == skp0.verfer.qb64

Expand Down Expand Up @@ -2391,7 +2395,7 @@ def test_kever(mockHelpingNowUTC):
sad['b'] = baks
sad['a'] = a

serder = serdering.SerderKERI(makify=True, verify=True, sad=sad)
serder = serdering.SerderKERI(makify=True, verify=False, sad=sad)
assert serder.said == 'EEu-cdj_9b_66XRJ5UuhgEvJxAPpn4RjyaHvRgDU3iyA'
assert serder.pre == skp0.verfer.qb64

Expand Down
Loading

0 comments on commit b8578dd

Please sign in to comment.