diff --git a/src/keri/core/eventing.py b/src/keri/core/eventing.py index e26f9a1c2..a30670031 100644 --- a/src/keri/core/eventing.py +++ b/src/keri/core/eventing.py @@ -7,7 +7,7 @@ import json import logging from collections import namedtuple -from dataclasses import dataclass, astuple +from dataclasses import dataclass, astuple, asdict from urllib.parse import urlsplit from math import ceil from ordered_set import OrderedSet as oset @@ -20,6 +20,7 @@ from .. import help from .. import kering from ..db import basing, dbing +from ..db.basing import KeyStateRecord from ..db.dbing import dgKey, snKey, fnKey, splitKeySN, splitKey from ..kering import (MissingEntryError, @@ -28,7 +29,7 @@ MissingDelegationError, OutOfOrderError, LikelyDuplicitousError, UnverifiedWitnessReceiptError, UnverifiedReceiptError, UnverifiedTransferableReceiptError, QueryNotFoundError) -from ..kering import Version +from ..kering import Version, Versionage from ..kering import (ICP_LABELS, DIP_LABELS, ROT_LABELS, DRT_LABELS, IXN_LABELS, KSN_LABELS, RPY_LABELS) @@ -1144,8 +1145,8 @@ def state(pre, raise ValueError(f"Intersecting cuts = {cuts} and adds = {adds} in " f"latest est event.") - - ksd = dict(v=vs, # version string + ksr = basing.KeyStateRecord( + v=vs, # version string vn=list(version), # version number as list [major, minor] i=pre, # qb64 prefix s=sner.numh, # lowercase hex string no leading zeros @@ -1166,8 +1167,31 @@ def state(pre, ee=eevt._asdict(), # latest est event dict di=dpre if dpre is not None else "", ) - - return Serder(ked=ksd) # return serialized ksd + return ksr # return KeyStateRecord use asdict(ksr) to get dict version + + #ksd = dict(v=vs, # version string + #vn=list(version), # version number as list [major, minor] + #i=pre, # qb64 prefix + #s=sner.numh, # lowercase hex string no leading zeros + #p=pig, + #d=dig, + #f=fner.numh, # lowercase hex string no leading zeros + #dt=stamp, + #et=eilk, + #kt=(tholder.num if intive and tholder.num is not None and + #tholder.num <= MaxIntThold else tholder.sith), + #k=keys, # list of qb64 + #nt=(ntholder.num if intive and ntholder.num is not None and + #ntholder.num <= MaxIntThold else ntholder.sith), + #n=ndigs, + #bt=toader.num if intive and toader.num <= MaxIntThold else toader.numh, + #b=wits, # list of qb64 may be empty + #c=cnfg if cnfg is not None else [], + #ee=eevt._asdict(), # latest est event dict + #di=dpre if dpre is not None else "", + #) + + #return Serder(ked=ksd) # return serialized ksd def query(route="", @@ -1607,7 +1631,7 @@ def __init__(self, *, state=None, serder=None, sigers=None, wigers=None, Verify incepting serder against sigers raises ValidationError if not Parameters: - state (Serder | None): instance of key state notice 'ksn' message body + state (KeyStateRecord | None): instance for key state notice serder (Serder | None): instance of inception event sigers (list | None): of Siger instances of indexed controller signatures of event. Index is offset into keys list from latest est event @@ -1706,8 +1730,10 @@ def __init__(self, *, state=None, serder=None, sigers=None, wigers=None, self.fner = Number(num=fn) self.dater = Dater(dts=dts) self.db.states.pin(keys=self.prefixer.qb64, - val=helping.datify(basing.KeyStateRecord, - self.state().ked)) + val=self.state()) + #self.db.states.pin(keys=self.prefixer.qb64, + #val=helping.datify(basing.KeyStateRecord, + #self.state().ked)) @property @@ -1758,43 +1784,43 @@ def transferable(self): def reload(self, state): """ - Reload Kever attributes (aka its state) from state serder + Reload Kever attributes (aka its state) from state (KeyStateRecord) Parameters: - state (Serder): instance of key state notice 'ksn' message body + state (KeyStateRecord | None): instance for key state notice """ - for k in KSN_LABELS: - if k not in state.ked: - raise ValidationError(f"Missing element = {k} from state." - f" = {state}.") - - self.version = state.version - self.prefixer = Prefixer(qb64=state.pre) - self.sner = state.sner # sequence number Number instance hex str - self.fner = state.fner # first seen ordinal Number hex str - self.dater = Dater(dts=state.ked["dt"]) - self.ilk = state.ked["et"] - self.tholder = Tholder(sith=state.ked["kt"]) - self.ntholder = Tholder(sith=state.ked["nt"]) - self.verfers = [Verfer(qb64=key) for key in state.ked["k"]] - self.digers = [Diger(qb64=dig) for dig in state.ked["n"]] - self.toader = Number(num=state.ked["bt"]) # auto converts from hex num - self.wits = state.ked["b"] - self.cuts = state.ked["ee"]["br"] - self.adds = state.ked["ee"]["ba"] + #for k in KSN_LABELS: + #if k not in state.ked: + #raise ValidationError(f"Missing element = {k} from state." + #f" = {state}.") + + self.version = Versionage._make(state.vn) + self.prefixer = Prefixer(qb64=state.i) + self.sner = Number(numh=state.s) # sequence number Number instance hex str + self.fner = Number(numh=state.f) # first seen ordinal Number hex str + self.dater = Dater(dts=state.dt) + self.ilk = state.et + self.tholder = Tholder(sith=state.kt) + self.ntholder = Tholder(sith=state.nt) + self.verfers = [Verfer(qb64=key) for key in state.k] + self.digers = [Diger(qb64=dig) for dig in state.n] + self.toader = Number(numh=state.bt) # auto converts from hex num + self.wits = state.b + self.cuts = state.ee["br"] + self.adds = state.ee["ba"] self.estOnly = False - self.doNotDelegate = True if "DND" in state.ked["c"] else False - self.estOnly = True if "EO" in state.ked["c"] else False - self.lastEst = LastEstLoc(s=int(state.ked['ee']['s'], 16), - d=state.ked['ee']['d']) - self.delegator = state.ked['di'] if state.ked['di'] else None + self.doNotDelegate = True if "DND" in state.c else False + self.estOnly = True if "EO" in state.c else False + self.lastEst = LastEstLoc(s=int(state.ee['s'], 16), + d=state.ee['d']) + self.delegator = state.di if state.di else None self.delegated = True if self.delegator else False if (raw := self.db.getEvt(key=dgKey(pre=self.prefixer.qb64, - dig=state.ked['d']))) is None: - raise MissingEntryError("Corresponding event for state={} not found." - "".format(state.pretty())) + dig=state.d))) is None: + raise MissingEntryError(f"Corresponding event not found for state=" + f"{state}.") self.serder = Serder(raw=bytes(raw)) # May want to do additional checks here @@ -2586,12 +2612,10 @@ def escrowPWEvent(self, serder, wigers, sigers=None, seqner=None, saider=None): return self.db.addPwe(snKey(serder.preb, serder.sn), serder.saidb) - def state(self, kind=Serials.json): + def state(self): """ - Returns Serder instance of current key state notification message + Returns KeyStateRecord instance of current key state - Parameters: - kind is serialization kind for message json, cbor, mgpk """ eevt = StateEstEvent(s="{:x}".format(self.lastEst.s), d=self.lastEst.d, @@ -2620,7 +2644,6 @@ def state(self, kind=Serials.json): wits=self.wits, cnfg=cnfg, dpre=self.delegator, - kind=kind ) ) diff --git a/src/keri/db/basing.py b/src/keri/db/basing.py index 2c2262ccd..82b06ced0 100644 --- a/src/keri/db/basing.py +++ b/src/keri/db/basing.py @@ -23,7 +23,11 @@ import shutil from contextlib import contextmanager from dataclasses import dataclass, asdict, field +import json + +import cbor2 as cbor +import msgpack import lmdb from ordered_set import OrderedSet as oset @@ -35,6 +39,7 @@ from ..core import coring, eventing, parsing from .. import help +from ..help import helping logger = help.ogler.getLogger() @@ -58,10 +63,10 @@ def __getitem__(self, k): except KeyError as ex: if not self.db: raise ex # reraise KeyError - if (ked := self.db.states.getDict(keys=k)) is None: + if (ksr := self.db.states.get(keys=k)) is None: raise ex # reraise KeyError try: - kever = eventing.Kever(state=coring.Serder(ked=ked), db=self.db) + kever = eventing.Kever(state=ksr, db=self.db) except kering.MissingEntryError: # no kel event for keystate raise ex # reraise KeyError self.__setitem__(k, kever) @@ -83,8 +88,44 @@ def get(self, k, default=None): else: return self.__getitem__(k) + +@dataclass +class RawRecord: + """RawRecord is base class for dataclasses that provides private utility + methods for representing the dataclass as some other format like dict, + json bytes, cbor bytes, mgpk bytes as a raw format. Typically uses case + is to transform dataclass into dict or serialization of its transformation + into dict so that it can be included in messages or stored in a database. + """ + def __iter__(self): + return iter(asdict(self)) + + + def _asdict(self): + """Returns dict version of record""" + return helping.dictify(self) + + + def _asjson(self): + """Returns json bytes version of record""" + return json.dumps(self._asdict(), + separators=(",", ":"), + ensure_ascii=False).encode("utf-8") + + + def _ascbor(self): + """Returns cbor bytes version of record""" + return cbor.dumps(self._asdict()) + + + def _asmgpk(self): + """Returns mgpk bytes version of record""" + return msgpack.dumps(self._asdict()) + + + @dataclass -class KeyStateRecord: # baser.state +class KeyStateRecord(RawRecord): # baser.state """ Key State information keyed by Identifier Prefix of associated KEL. For local AIDs that correspond to Habs this is the Hab AID. @@ -123,8 +164,7 @@ class KeyStateRecord: # baser.state # ba = backer (witness) add list (adds) from latest est event di: str = '' # delegator aid qb64 if any otherwise empty '' str - def __iter__(self): - return iter(asdict(self)) + diff --git a/tests/core/test_eventing.py b/tests/core/test_eventing.py index b003b41d7..59d3260e4 100644 --- a/tests/core/test_eventing.py +++ b/tests/core/test_eventing.py @@ -9,7 +9,7 @@ import pysodium import pytest -from keri import help + from keri.app import habbing, keeping from keri.app.keeping import openKS, Manager from keri.core import coring, eventing, parsing @@ -32,6 +32,9 @@ from keri.db.dbing import dgKey, snKey from keri.kering import (ValidationError, DerivationError) +from keri import help +from keri.help import helping + logger = help.ogler.getLogger() @@ -1570,7 +1573,7 @@ def test_state(mockHelpingNowUTC): br=[preW0], ba=[preW3]) - serderK = state(pre=preC, + ksr = state(pre=preC, sn=4, pig='EAskHI462CuIMS_gNkcl_QewzrRSKH2p9zHQIO132Z30', dig='EANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132Z30', @@ -1584,20 +1587,21 @@ def test_state(mockHelpingNowUTC): wits=wits, ) - assert serderK.raw == (b'{"v":"KERI10JSON0002d5_","vn":[1,0],"i":"DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6l' - b'lSvWQTWZN","s":"4","p":"EAskHI462CuIMS_gNkcl_QewzrRSKH2p9zHQIO132Z30","d":"E' - b'ANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132Z30","f":"4","dt":"2021-01-01T00:00:' - b'00.000000+00:00","et":"ixn","kt":"1","k":["DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz' - b'6llSvWQTWZN"],"nt":"1","n":["EDDOarj1lzr8pqG5a-SSnM2cc_3JgstRRjmzrrA_Bibg"],' - b'"bt":"2","b":["BGhCNcrRBR6mlBduhbuCYL7Bwc3gbuyaGo9opZsd0D8F","BO7x6ctSA7FllJ' - b'x39hlObnetizGFjuZT1jq0geno0NRK","BK7isi_2-A-RE6Pbtdg7S1NSeinNQkJ4oCFASqwRc_9' - b'W"],"c":[],"ee":{"s":"3","d":"EUskHI462CuIMS_gNkcl_QewzrRSKH2p9zHQIO132Z30",' - b'"br":["BDU5LLVHxQSb9EdSKDTYyqViusxGT8Y4DHOyktkOv5Rt"],"ba":["BK7isi_2-A-RE6P' - b'btdg7S1NSeinNQkJ4oCFASqwRc_9W"]},"di":""}') - - assert serderK.said == 'EANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132Z30' - assert serderK.pre == preC == 'DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6llSvWQTWZN' - assert serderK.sn == 4 + raw = ksr._asjson() + assert raw == (b'{"v":"KERI10JSON000000_","vn":[1,0],"i":"DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6l' + b'lSvWQTWZN","s":"4","p":"EAskHI462CuIMS_gNkcl_QewzrRSKH2p9zHQIO132Z30","d":"E' + b'ANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132Z30","f":"4","dt":"2021-01-01T00:00:' + b'00.000000+00:00","et":"ixn","kt":"1","k":["DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz' + b'6llSvWQTWZN"],"nt":"1","n":["EDDOarj1lzr8pqG5a-SSnM2cc_3JgstRRjmzrrA_Bibg"],' + b'"bt":"2","b":["BGhCNcrRBR6mlBduhbuCYL7Bwc3gbuyaGo9opZsd0D8F","BO7x6ctSA7FllJ' + b'x39hlObnetizGFjuZT1jq0geno0NRK","BK7isi_2-A-RE6Pbtdg7S1NSeinNQkJ4oCFASqwRc_9' + b'W"],"c":[],"ee":{"s":"3","d":"EUskHI462CuIMS_gNkcl_QewzrRSKH2p9zHQIO132Z30",' + b'"br":["BDU5LLVHxQSb9EdSKDTYyqViusxGT8Y4DHOyktkOv5Rt"],"ba":["BK7isi_2-A-RE6P' + b'btdg7S1NSeinNQkJ4oCFASqwRc_9W"]},"di":""}') + + assert ksr.d == 'EANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132Z30' + assert ksr.i == preC == 'DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6llSvWQTWZN' + assert ksr.s == '4' # create endorsed ksn with nontrans endorser # create nontrans key pair for endorder of KSN @@ -1606,23 +1610,23 @@ def test_state(mockHelpingNowUTC): preE = signerE.verfer.qb64 # use public key verfer.qb64 as pre assert preE == 'BMrwi0a-Zblpqe5Hg7w7iz9JCKnMgWKu_W9w4aNUL64y' - cigarE = signerE.sign(ser=serderK.raw) - assert signerE.verfer.verify(sig=cigarE.raw, ser=serderK.raw) - msg = messagize(serderK, cigars=[cigarE]) - assert msg == (b'{"v":"KERI10JSON0002d5_","vn":[1,0],"i":"DN6WBhWqp6wC08no2iWhgFY' - b'TaUgrasnqz6llSvWQTWZN","s":"4","p":"EAskHI462CuIMS_gNkcl_QewzrRS' - b'KH2p9zHQIO132Z30","d":"EANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132' - b'Z30","f":"4","dt":"2021-01-01T00:00:00.000000+00:00","et":"ixn",' - b'"kt":"1","k":["DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6llSvWQTWZN"],"n' - b't":"1","n":["EDDOarj1lzr8pqG5a-SSnM2cc_3JgstRRjmzrrA_Bibg"],"bt"' - b':"2","b":["BGhCNcrRBR6mlBduhbuCYL7Bwc3gbuyaGo9opZsd0D8F","BO7x6c' - b'tSA7FllJx39hlObnetizGFjuZT1jq0geno0NRK","BK7isi_2-A-RE6Pbtdg7S1N' - b'SeinNQkJ4oCFASqwRc_9W"],"c":[],"ee":{"s":"3","d":"EUskHI462CuIMS' - b'_gNkcl_QewzrRSKH2p9zHQIO132Z30","br":["BDU5LLVHxQSb9EdSKDTYyqViu' - b'sxGT8Y4DHOyktkOv5Rt"],"ba":["BK7isi_2-A-RE6Pbtdg7S1NSeinNQkJ4oCF' - b'ASqwRc_9W"]},"di":""}-CABBMrwi0a-Zblpqe5Hg7w7iz9JCKnMgWKu_W9w4aN' - b'UL64y0BAxhIlDV7ZlsV2OoDi1ltOQOFA7Z7NnjdoEL_rKdO2mn2q3LEtbPPYgJ9t' - b'UOIE3F0BABStJ5RMOrqnrwntbZesG') + cigarE = signerE.sign(ser=raw) + assert signerE.verfer.verify(sig=cigarE.raw, ser=raw) + #msg = messagize(serderK, cigars=[cigarE]) + #assert msg == (b'{"v":"KERI10JSON0002d5_","vn":[1,0],"i":"DN6WBhWqp6wC08no2iWhgFY' + #b'TaUgrasnqz6llSvWQTWZN","s":"4","p":"EAskHI462CuIMS_gNkcl_QewzrRS' + #b'KH2p9zHQIO132Z30","d":"EANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132' + #b'Z30","f":"4","dt":"2021-01-01T00:00:00.000000+00:00","et":"ixn",' + #b'"kt":"1","k":["DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6llSvWQTWZN"],"n' + #b't":"1","n":["EDDOarj1lzr8pqG5a-SSnM2cc_3JgstRRjmzrrA_Bibg"],"bt"' + #b':"2","b":["BGhCNcrRBR6mlBduhbuCYL7Bwc3gbuyaGo9opZsd0D8F","BO7x6c' + #b'tSA7FllJx39hlObnetizGFjuZT1jq0geno0NRK","BK7isi_2-A-RE6Pbtdg7S1N' + #b'SeinNQkJ4oCFASqwRc_9W"],"c":[],"ee":{"s":"3","d":"EUskHI462CuIMS' + #b'_gNkcl_QewzrRSKH2p9zHQIO132Z30","br":["BDU5LLVHxQSb9EdSKDTYyqViu' + #b'sxGT8Y4DHOyktkOv5Rt"],"ba":["BK7isi_2-A-RE6Pbtdg7S1NSeinNQkJ4oCF' + #b'ASqwRc_9W"]},"di":""}-CABBMrwi0a-Zblpqe5Hg7w7iz9JCKnMgWKu_W9w4aN' + #b'UL64y0BAxhIlDV7ZlsV2OoDi1ltOQOFA7Z7NnjdoEL_rKdO2mn2q3LEtbPPYgJ9t' + #b'UOIE3F0BABStJ5RMOrqnrwntbZesG') # create endorsed ksn with trans endorser # create trans key pair for endorder of KSN @@ -1637,24 +1641,24 @@ def test_state(mockHelpingNowUTC): d='EAuNWHss_H_kH4cG7Li1jn2DXfrEaqN7zhqTEhkeDZ2z') # create endorsed ksn - sigerE = signerE.sign(ser=serderK.raw, index=0) - assert signerE.verfer.verify(sig=sigerE.raw, ser=serderK.raw) - msg = messagize(serderK, sigers=[sigerE], seal=seal) - assert msg == (b'{"v":"KERI10JSON0002d5_","vn":[1,0],"i":"DN6WBhWqp6wC08no2iWhgFY' - b'TaUgrasnqz6llSvWQTWZN","s":"4","p":"EAskHI462CuIMS_gNkcl_QewzrRS' - b'KH2p9zHQIO132Z30","d":"EANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132' - b'Z30","f":"4","dt":"2021-01-01T00:00:00.000000+00:00","et":"ixn",' - b'"kt":"1","k":["DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6llSvWQTWZN"],"n' - b't":"1","n":["EDDOarj1lzr8pqG5a-SSnM2cc_3JgstRRjmzrrA_Bibg"],"bt"' - b':"2","b":["BGhCNcrRBR6mlBduhbuCYL7Bwc3gbuyaGo9opZsd0D8F","BO7x6c' - b'tSA7FllJx39hlObnetizGFjuZT1jq0geno0NRK","BK7isi_2-A-RE6Pbtdg7S1N' - b'SeinNQkJ4oCFASqwRc_9W"],"c":[],"ee":{"s":"3","d":"EUskHI462CuIMS' - b'_gNkcl_QewzrRSKH2p9zHQIO132Z30","br":["BDU5LLVHxQSb9EdSKDTYyqViu' - b'sxGT8Y4DHOyktkOv5Rt"],"ba":["BK7isi_2-A-RE6Pbtdg7S1NSeinNQkJ4oCF' - b'ASqwRc_9W"]},"di":""}-FABDMrwi0a-Zblpqe5Hg7w7iz9JCKnMgWKu_W9w4aN' - b'UL64y0AAAAAAAAAAAAAAAAAAAAAAAEAuNWHss_H_kH4cG7Li1jn2DXfrEaqN7zhq' - b'TEhkeDZ2z-AABAAAxhIlDV7ZlsV2OoDi1ltOQOFA7Z7NnjdoEL_rKdO2mn2q3LEt' - b'bPPYgJ9tUOIE3F0BABStJ5RMOrqnrwntbZesG') + sigerE = signerE.sign(ser=raw, index=0) + assert signerE.verfer.verify(sig=sigerE.raw, ser=raw) + #msg = messagize(serderK, sigers=[sigerE], seal=seal) + #assert msg == (b'{"v":"KERI10JSON0002d5_","vn":[1,0],"i":"DN6WBhWqp6wC08no2iWhgFY' + #b'TaUgrasnqz6llSvWQTWZN","s":"4","p":"EAskHI462CuIMS_gNkcl_QewzrRS' + #b'KH2p9zHQIO132Z30","d":"EANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132' + #b'Z30","f":"4","dt":"2021-01-01T00:00:00.000000+00:00","et":"ixn",' + #b'"kt":"1","k":["DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6llSvWQTWZN"],"n' + #b't":"1","n":["EDDOarj1lzr8pqG5a-SSnM2cc_3JgstRRjmzrrA_Bibg"],"bt"' + #b':"2","b":["BGhCNcrRBR6mlBduhbuCYL7Bwc3gbuyaGo9opZsd0D8F","BO7x6c' + #b'tSA7FllJx39hlObnetizGFjuZT1jq0geno0NRK","BK7isi_2-A-RE6Pbtdg7S1N' + #b'SeinNQkJ4oCFASqwRc_9W"],"c":[],"ee":{"s":"3","d":"EUskHI462CuIMS' + #b'_gNkcl_QewzrRSKH2p9zHQIO132Z30","br":["BDU5LLVHxQSb9EdSKDTYyqViu' + #b'sxGT8Y4DHOyktkOv5Rt"],"ba":["BK7isi_2-A-RE6Pbtdg7S1NSeinNQkJ4oCF' + #b'ASqwRc_9W"]},"di":""}-FABDMrwi0a-Zblpqe5Hg7w7iz9JCKnMgWKu_W9w4aN' + #b'UL64y0AAAAAAAAAAAAAAAAAAAAAAAEAuNWHss_H_kH4cG7Li1jn2DXfrEaqN7zhq' + #b'TEhkeDZ2z-AABAAAxhIlDV7ZlsV2OoDi1ltOQOFA7Z7NnjdoEL_rKdO2mn2q3LEt' + #b'bPPYgJ9tUOIE3F0BABStJ5RMOrqnrwntbZesG') # State Delegated (key state notification) @@ -1707,7 +1711,7 @@ def test_state(mockHelpingNowUTC): preD = signerD.verfer.qb64 # use public key verfer.qb64 as trans pre assert preD == 'DBs-gd3nJGtF0Ch2jn7NLaUKsCKB7l3nLs-993_s5Ie1' - serderK = state(pre=preC, + ksr = state(pre=preC, sn=4, pig='EAskHI462CuIMS_gNkcl_QewzrRSKH2p9zHQIO132Z30', dig='EANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132Z30', @@ -1722,21 +1726,23 @@ def test_state(mockHelpingNowUTC): dpre=preD ) - assert serderK.raw == (b'{"v":"KERI10JSON000301_","vn":[1,0],"i":"DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6l' - b'lSvWQTWZN","s":"4","p":"EAskHI462CuIMS_gNkcl_QewzrRSKH2p9zHQIO132Z30","d":"E' - b'ANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132Z30","f":"4","dt":"2021-01-01T00:00:' - b'00.000000+00:00","et":"ixn","kt":"1","k":["DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz' - b'6llSvWQTWZN"],"nt":"1","n":["EDDOarj1lzr8pqG5a-SSnM2cc_3JgstRRjmzrrA_Bibg"],' - b'"bt":"2","b":["BGhCNcrRBR6mlBduhbuCYL7Bwc3gbuyaGo9opZsd0D8F","BO7x6ctSA7FllJ' - b'x39hlObnetizGFjuZT1jq0geno0NRK","BK7isi_2-A-RE6Pbtdg7S1NSeinNQkJ4oCFASqwRc_9' - b'W"],"c":[],"ee":{"s":"3","d":"EAskHI462CuIMS_gNkcl_QewzrRSKH2p9zHQIO132Z30",' - b'"br":["BDU5LLVHxQSb9EdSKDTYyqViusxGT8Y4DHOyktkOv5Rt"],"ba":["BK7isi_2-A-RE6P' - b'btdg7S1NSeinNQkJ4oCFASqwRc_9W"]},"di":"DBs-gd3nJGtF0Ch2jn7NLaUKsCKB7l3nLs-99' - b'3_s5Ie1"}') - - assert serderK.said == 'EANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132Z30' - assert serderK.pre == preC == 'DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6llSvWQTWZN' - assert serderK.sn == 4 + raw = ksr._asjson() + + assert raw == (b'{"v":"KERI10JSON000000_","vn":[1,0],"i":"DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6l' + b'lSvWQTWZN","s":"4","p":"EAskHI462CuIMS_gNkcl_QewzrRSKH2p9zHQIO132Z30","d":"E' + b'ANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132Z30","f":"4","dt":"2021-01-01T00:00:' + b'00.000000+00:00","et":"ixn","kt":"1","k":["DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz' + b'6llSvWQTWZN"],"nt":"1","n":["EDDOarj1lzr8pqG5a-SSnM2cc_3JgstRRjmzrrA_Bibg"],' + b'"bt":"2","b":["BGhCNcrRBR6mlBduhbuCYL7Bwc3gbuyaGo9opZsd0D8F","BO7x6ctSA7FllJ' + b'x39hlObnetizGFjuZT1jq0geno0NRK","BK7isi_2-A-RE6Pbtdg7S1NSeinNQkJ4oCFASqwRc_9' + b'W"],"c":[],"ee":{"s":"3","d":"EAskHI462CuIMS_gNkcl_QewzrRSKH2p9zHQIO132Z30",' + b'"br":["BDU5LLVHxQSb9EdSKDTYyqViusxGT8Y4DHOyktkOv5Rt"],"ba":["BK7isi_2-A-RE6P' + b'btdg7S1NSeinNQkJ4oCFASqwRc_9W"]},"di":"DBs-gd3nJGtF0Ch2jn7NLaUKsCKB7l3nLs-99' + b'3_s5Ie1"}') + + assert ksr.d == 'EANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132Z30' + assert ksr.i == preC == 'DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6llSvWQTWZN' + assert ksr.s == '4' # create endorsed ksn with nontrans endorser # create nontrans key pair for endorder of KSN @@ -1746,24 +1752,24 @@ def test_state(mockHelpingNowUTC): assert preE == 'BMrwi0a-Zblpqe5Hg7w7iz9JCKnMgWKu_W9w4aNUL64y' # create endorsed ksn - cigarE = signerE.sign(ser=serderK.raw) - assert signerE.verfer.verify(sig=cigarE.raw, ser=serderK.raw) - msg = messagize(serderK, cigars=[cigarE]) - assert msg == (b'{"v":"KERI10JSON000301_","vn":[1,0],"i":"DN6WBhWqp6wC08no2iWhgFY' - b'TaUgrasnqz6llSvWQTWZN","s":"4","p":"EAskHI462CuIMS_gNkcl_QewzrRS' - b'KH2p9zHQIO132Z30","d":"EANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132' - b'Z30","f":"4","dt":"2021-01-01T00:00:00.000000+00:00","et":"ixn",' - b'"kt":"1","k":["DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6llSvWQTWZN"],"n' - b't":"1","n":["EDDOarj1lzr8pqG5a-SSnM2cc_3JgstRRjmzrrA_Bibg"],"bt"' - b':"2","b":["BGhCNcrRBR6mlBduhbuCYL7Bwc3gbuyaGo9opZsd0D8F","BO7x6c' - b'tSA7FllJx39hlObnetizGFjuZT1jq0geno0NRK","BK7isi_2-A-RE6Pbtdg7S1N' - b'SeinNQkJ4oCFASqwRc_9W"],"c":[],"ee":{"s":"3","d":"EAskHI462CuIMS' - b'_gNkcl_QewzrRSKH2p9zHQIO132Z30","br":["BDU5LLVHxQSb9EdSKDTYyqViu' - b'sxGT8Y4DHOyktkOv5Rt"],"ba":["BK7isi_2-A-RE6Pbtdg7S1NSeinNQkJ4oCF' - b'ASqwRc_9W"]},"di":"DBs-gd3nJGtF0Ch2jn7NLaUKsCKB7l3nLs-993_s5Ie1"' - b'}-CABBMrwi0a-Zblpqe5Hg7w7iz9JCKnMgWKu_W9w4aNUL64y0BBTNCmYMYJNNQd' - b'QN9irkUaL_RBdztUlykS6P-fxDUofmfWuTL7Hb0XHjtcT-wJMCYO7G1i5IbuhSHf' - b'o-maDh4EG') + cigarE = signerE.sign(ser=raw) + assert signerE.verfer.verify(sig=cigarE.raw, ser=raw) + #msg = messagize(serderK, cigars=[cigarE]) + #assert msg == (b'{"v":"KERI10JSON000301_","vn":[1,0],"i":"DN6WBhWqp6wC08no2iWhgFY' + #b'TaUgrasnqz6llSvWQTWZN","s":"4","p":"EAskHI462CuIMS_gNkcl_QewzrRS' + #b'KH2p9zHQIO132Z30","d":"EANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132' + #b'Z30","f":"4","dt":"2021-01-01T00:00:00.000000+00:00","et":"ixn",' + #b'"kt":"1","k":["DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6llSvWQTWZN"],"n' + #b't":"1","n":["EDDOarj1lzr8pqG5a-SSnM2cc_3JgstRRjmzrrA_Bibg"],"bt"' + #b':"2","b":["BGhCNcrRBR6mlBduhbuCYL7Bwc3gbuyaGo9opZsd0D8F","BO7x6c' + #b'tSA7FllJx39hlObnetizGFjuZT1jq0geno0NRK","BK7isi_2-A-RE6Pbtdg7S1N' + #b'SeinNQkJ4oCFASqwRc_9W"],"c":[],"ee":{"s":"3","d":"EAskHI462CuIMS' + #b'_gNkcl_QewzrRSKH2p9zHQIO132Z30","br":["BDU5LLVHxQSb9EdSKDTYyqViu' + #b'sxGT8Y4DHOyktkOv5Rt"],"ba":["BK7isi_2-A-RE6Pbtdg7S1NSeinNQkJ4oCF' + #b'ASqwRc_9W"]},"di":"DBs-gd3nJGtF0Ch2jn7NLaUKsCKB7l3nLs-993_s5Ie1"' + #b'}-CABBMrwi0a-Zblpqe5Hg7w7iz9JCKnMgWKu_W9w4aNUL64y0BBTNCmYMYJNNQd' + #b'QN9irkUaL_RBdztUlykS6P-fxDUofmfWuTL7Hb0XHjtcT-wJMCYO7G1i5IbuhSHf' + #b'o-maDh4EG') # create endorsed ksn with trans endorser # create trans key pair for endorder of KSN @@ -1778,25 +1784,25 @@ def test_state(mockHelpingNowUTC): d='EAuNWHss_H_kH4cG7Li1jn2DXfrEaqN7zhqTEhkeDZ2z') # create endorsed ksn - sigerE = signerE.sign(ser=serderK.raw, index=0) - assert signerE.verfer.verify(sig=sigerE.raw, ser=serderK.raw) - msg = messagize(serderK, sigers=[sigerE], seal=seal) - assert msg == (b'{"v":"KERI10JSON000301_","vn":[1,0],"i":"DN6WBhWqp6wC08no2iWhgFY' - b'TaUgrasnqz6llSvWQTWZN","s":"4","p":"EAskHI462CuIMS_gNkcl_QewzrRS' - b'KH2p9zHQIO132Z30","d":"EANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132' - b'Z30","f":"4","dt":"2021-01-01T00:00:00.000000+00:00","et":"ixn",' - b'"kt":"1","k":["DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6llSvWQTWZN"],"n' - b't":"1","n":["EDDOarj1lzr8pqG5a-SSnM2cc_3JgstRRjmzrrA_Bibg"],"bt"' - b':"2","b":["BGhCNcrRBR6mlBduhbuCYL7Bwc3gbuyaGo9opZsd0D8F","BO7x6c' - b'tSA7FllJx39hlObnetizGFjuZT1jq0geno0NRK","BK7isi_2-A-RE6Pbtdg7S1N' - b'SeinNQkJ4oCFASqwRc_9W"],"c":[],"ee":{"s":"3","d":"EAskHI462CuIMS' - b'_gNkcl_QewzrRSKH2p9zHQIO132Z30","br":["BDU5LLVHxQSb9EdSKDTYyqViu' - b'sxGT8Y4DHOyktkOv5Rt"],"ba":["BK7isi_2-A-RE6Pbtdg7S1NSeinNQkJ4oCF' - b'ASqwRc_9W"]},"di":"DBs-gd3nJGtF0Ch2jn7NLaUKsCKB7l3nLs-993_s5Ie1"' - b'}-FABDMrwi0a-Zblpqe5Hg7w7iz9JCKnMgWKu_W9w4aNUL64y0AAAAAAAAAAAAAA' - b'AAAAAAAAAEAuNWHss_H_kH4cG7Li1jn2DXfrEaqN7zhqTEhkeDZ2z-AABAABTNCm' - b'YMYJNNQdQN9irkUaL_RBdztUlykS6P-fxDUofmfWuTL7Hb0XHjtcT-wJMCYO7G1i' - b'5IbuhSHfo-maDh4EG') + sigerE = signerE.sign(ser=raw, index=0) + assert signerE.verfer.verify(sig=sigerE.raw, ser=raw) + #msg = messagize(serderK, sigers=[sigerE], seal=seal) + #assert msg == (b'{"v":"KERI10JSON000301_","vn":[1,0],"i":"DN6WBhWqp6wC08no2iWhgFY' + #b'TaUgrasnqz6llSvWQTWZN","s":"4","p":"EAskHI462CuIMS_gNkcl_QewzrRS' + #b'KH2p9zHQIO132Z30","d":"EANkcl_QewzrRSKH2p9zUskHI462CuIMS_HQIO132' + #b'Z30","f":"4","dt":"2021-01-01T00:00:00.000000+00:00","et":"ixn",' + #b'"kt":"1","k":["DN6WBhWqp6wC08no2iWhgFYTaUgrasnqz6llSvWQTWZN"],"n' + #b't":"1","n":["EDDOarj1lzr8pqG5a-SSnM2cc_3JgstRRjmzrrA_Bibg"],"bt"' + #b':"2","b":["BGhCNcrRBR6mlBduhbuCYL7Bwc3gbuyaGo9opZsd0D8F","BO7x6c' + #b'tSA7FllJx39hlObnetizGFjuZT1jq0geno0NRK","BK7isi_2-A-RE6Pbtdg7S1N' + #b'SeinNQkJ4oCFASqwRc_9W"],"c":[],"ee":{"s":"3","d":"EAskHI462CuIMS' + #b'_gNkcl_QewzrRSKH2p9zHQIO132Z30","br":["BDU5LLVHxQSb9EdSKDTYyqViu' + #b'sxGT8Y4DHOyktkOv5Rt"],"ba":["BK7isi_2-A-RE6Pbtdg7S1NSeinNQkJ4oCF' + #b'ASqwRc_9W"]},"di":"DBs-gd3nJGtF0Ch2jn7NLaUKsCKB7l3nLs-993_s5Ie1"' + #b'}-FABDMrwi0a-Zblpqe5Hg7w7iz9JCKnMgWKu_W9w4aNUL64y0AAAAAAAAAAAAAA' + #b'AAAAAAAAAEAuNWHss_H_kH4cG7Li1jn2DXfrEaqN7zhqTEhkeDZ2z-AABAABTNCm' + #b'YMYJNNQdQN9irkUaL_RBdztUlykS6P-fxDUofmfWuTL7Hb0XHjtcT-wJMCYO7G1i' + #b'5IbuhSHfo-maDh4EG') """Done Test""" diff --git a/tests/db/test_basing.py b/tests/db/test_basing.py index ab839b004..83d63fa29 100644 --- a/tests/db/test_basing.py +++ b/tests/db/test_basing.py @@ -5,7 +5,7 @@ """ import json import os -from dataclasses import asdict +from dataclasses import dataclass, asdict import lmdb import pytest @@ -1971,6 +1971,40 @@ def test_usebaser(): """ End Test """ +def test_rawrecord(): + """ + Test RawRecord dataclass + """ + @dataclass + class TestRecord(basing.RawRecord): + x: str = "" + y: int = 0 + + record = TestRecord() + + assert isinstance(record, TestRecord) + assert isinstance(record, basing.RawRecord) + + assert "x" in record + assert "y" in record + + assert record.x == '' + assert record.y == 0 + + record = TestRecord(x="hi", y=3) + + assert record.x == 'hi' + assert record.y == 3 + + assert record._asdict() == {'x': 'hi', 'y': 3} + assert record._asjson() == b'{"x":"hi","y":3}' + assert record._ascbor() == b'\xa2axbhiay\x03' + assert record._asmgpk() == b'\x82\xa1x\xa2hi\xa1y\x03' + + """End Test""" + + + def test_keystaterecord(): """ Test KeyStateRecord dataclass @@ -2002,6 +2036,20 @@ def test_keystaterecord(): 'di': '' } + assert ksr._asdict() == ksn + assert ksr._asjson() == (b'{"v":"","vn":[],"i":"","s":"0","p":"","d":"","f":"0","dt":"","et":"","kt":"0' + b'","k":[],"nt":"0","n":[],"bt":"0","b":[],"c":[],"ee":{},"di":""}') + assert ksr._ascbor() == (b'\xb2av`bvn\x80ai`asa0ap`ad`afa0bdt`bet`bkta0ak\x80bnta0an\x80bbta0ab' + b'\x80ac\x80bee\xa0bdi`') + assert ksr._asmgpk() == (b'\xde\x00\x12\xa1v\xa0\xa2vn\x90\xa1i\xa0\xa1s\xa10\xa1p\xa0\xa1d\xa0\xa1' + b'f\xa10\xa2dt\xa0\xa2et\xa0\xa2kt\xa10\xa1k\x90\xa2nt\xa10\xa1n\x90\xa2' + b'bt\xa10\xa1b\x90\xa1c\x90\xa2ee\x80\xa2di\xa0') + + assert str(ksr) == repr(ksr) == ("KeyStateRecord(v='', vn=[], i='', s='0'," + " p='', d='', f='0', dt='', et='', " + "kt='0', k=[], nt='0', n=[], bt='0', b=[], " + "c=[], ee={}, di='')") + dksn = dictify(ksr) assert dksn == ksn @@ -2077,22 +2125,23 @@ def test_dbdict(): db.putEvt(key=dgkey, val=serder.raw) assert db.getEvt(key=dgkey) is not None - db.states.pin(keys=pre, val=datify(KeyStateRecord, - state.ked)) # put state in database - assert db.states.getDict(keys=pre) is not None + db.states.pin(keys=pre, val=state) # put state in database + dbstate = db.states.get(keys=pre) + assert dbstate is not None + assert dbstate == state kever = eventing.Kever(state=state, db=db) - assert kever.state().ked == state.ked + assert kever.state() == state dkever = dbd[pre] # read through cache works here dstate = dkever.state() - assert dstate.ked == state.ked + assert dstate == state del dbd[pre] # not in dbd memory assert pre in dbd # read through cache works dkever = dbd[pre] dstate = dkever.state() - assert dstate.ked == state.ked + assert dstate == state db.states.rem(keys=pre) assert pre in dbd # still in memory