Skip to content

Commit

Permalink
Fix registry and credential transaction state records to use dataclas…
Browse files Browse the repository at this point in the history
…ses correctly

Signed-off-by: pfeairheller <[email protected]>
  • Loading branch information
pfeairheller committed Dec 1, 2023
1 parent f2f434d commit c697023
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 92 deletions.
2 changes: 1 addition & 1 deletion src/keri/app/cli/commands/vc/revoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def revokeDo(self, tymth, tock=0.0):
hab = registry.hab

state = registry.tever.vcState(vci=creder.said)
if state is None or state.ked["et"] not in (coring.Ilks.iss, coring.Ilks.rev):
if state is None or state.et not in (coring.Ilks.iss, coring.Ilks.rev):
raise kering.ValidationError(f"credential {creder.said} not is correct state for revocation")

rserder = registry.revoke(said=creder.said, **kwargs)
Expand Down
96 changes: 41 additions & 55 deletions src/keri/vdr/eventing.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import json
import logging
from dataclasses import asdict
from math import ceil
from ordered_set import OrderedSet as oset

Expand Down Expand Up @@ -512,7 +513,7 @@ def state(pre,
".".format(ba))

rsr = viring.RegStateRecord(
vn=list(version), # version number as list [major, minor]
vn=list(version), # version number as list [major, minor]
i=ri, # qb64 registry SAID
s="{:x}".format(sn), # lowercase hex string no leading zeros
d=said,
Expand Down Expand Up @@ -570,8 +571,6 @@ def vcstate(vcpre,
}
"""

vs = versify(version=version, kind=kind, size=0)

if sn < 0:
raise ValueError("Negative sn = {} in key state.".format(sn))

Expand All @@ -584,18 +583,18 @@ def vcstate(vcpre,
if ra is None:
ra = dict()

vsd = dict(v=vs, # version string
i=vcpre, # qb64 prefix
s="{:x}".format(sn), # lowercase hex string no leading zeros
d=said,
ri=ri,
ra=ra,
a=a,
dt=dts,
et=eilk,
)
vsr = viring.VcStateRecord(vn=list(version), # version string
i=vcpre, # qb64 prefix
s="{:x}".format(sn), # lowercase hex string no leading zeros
d=said,
ri=ri,
ra=ra,
a=a,
dt=dts,
et=eilk,
)

return coring.Serder(ked=vsd) # return serialized vsd
return vsr # return vc state record data class


def query(regk,
Expand Down Expand Up @@ -1685,11 +1684,11 @@ def processQuery(self, serder, source=None, sigers=None, cigars=None):
if ri in self.tevers:
tever = self.tevers[ri]
tsn = tever.state()
self.cues.push(dict(kin="reply", route="/tsn/registry", data=tsn.ked, dest=source))
self.cues.push(dict(kin="reply", route="/tsn/registry", data=asdict(tsn), dest=source))

if vcpre := qry["i"]:
tsn = tever.vcState(vcpre=vcpre)
self.cues.push(dict(kin="reply", route="/tsn/credential", data=tsn.ked, dest=source))
self.cues.push(dict(kin="reply", route="/tsn/credential", data=asdict(tsn), dest=source))

else:
raise ValidationError("invalid query message {} for evt = {}".format(ilk, ked))
Expand Down Expand Up @@ -1769,19 +1768,12 @@ def processReplyRegistryTxnState(self, *, serder, saider, route, cigars=None, ts
data = serder.ked["a"]
dater = coring.Dater(dts=serder.ked["dt"])

tserder = serdering.SerderKERI(sad=data)

for k in TSN_LABELS:
if k not in tserder.ked:
raise ValidationError("Missing element = {} from {} msg."
" tsn = {}.".format(k, Ilks.tsn,
serder.pretty()))
rsr = viring.RegStateRecord(**data)

# fetch from serder to process
ked = tserder.ked
regk = tserder.pre
pre = ked["ii"]
sn = tserder.sn
regk = rsr.i
pre = rsr.ii
sn = int(rsr.s, 16)

if pre not in self.kevers:
if self.reger.txnsb.escrowStateNotice(typ="registry-mae", pre=regk, aid=aid, serder=serder, saider=saider,
Expand All @@ -1791,12 +1783,12 @@ def processReplyRegistryTxnState(self, *, serder, saider, route, cigars=None, ts
raise kering.MissingAnchorError("Failure verify event = {} ".format(serder.ked))

# Load backers from either tsn or Kever of issuer
cnfg = ked["c"]
cnfg = rsr.c
if TraitDex.NoBackers in cnfg:
kevers = self.kevers[pre]
baks = kevers.wits
else:
baks = ked["b"]
baks = rsr.b

wats = set()
for _, habr in self.db.habs.getItemIter():
Expand All @@ -1809,13 +1801,13 @@ def processReplyRegistryTxnState(self, *, serder, saider, route, cigars=None, ts
aid not in baks and \
aid not in wats:
raise kering.UntrustedKeyStateSource("transaction state notice for {} from untrusted source {} "
.format(tserder.pre, aid))
.format(rsr.i, aid))

if regk in self.tevers:
tever = self.tevers[regk]
if tserder.sn < tever.sn:
if int(rsr.s, 16) < tever.sn:
raise ValidationError("Skipped stale transaction state at sn {} for {}."
"".format(tserder.sn, tserder.pre))
"".format(rsr.s, rsr.i))

keys = (regk, aid,)
osaider = self.reger.txnsb.current(keys=keys) # get old said if any
Expand All @@ -1835,9 +1827,9 @@ def processReplyRegistryTxnState(self, *, serder, saider, route, cigars=None, ts
dater=dater, cigars=cigars, tsgs=tsgs):
self.cues.append(dict(kin="telquery", q=dict(ri=regk)))

raise kering.OutOfOrderTxnStateError("Out of order txn state={}.".format(ked))
raise kering.OutOfOrderTxnStateError("Out of order txn state={}.".format(rsr))

tsaider = coring.Saider(qb64=ked["d"])
tsaider = coring.Saider(qb64=rsr.d)
ldig = bytes(ldig)
# retrieve last event itself of signer given sdig
sraw = self.reger.getTvt(key=dgKey(pre=regk, dig=ldig))
Expand All @@ -1846,10 +1838,10 @@ def processReplyRegistryTxnState(self, *, serder, saider, route, cigars=None, ts

if sserder.said != tsaider.qb64: # mismatch events problem with replay
raise ValidationError("Mismatch keystate at sn = {} with db."
"".format(ked["s"]))
"".format(rsr.s))

self.reger.txnsb.updateReply(aid=aid, serder=tserder, saider=tsaider, dater=dater)
self.cues.append(dict(kin="txnStateSaved", serder=tserder))
self.reger.txnsb.updateReply(aid=aid, serder=serder, saider=tsaider, dater=dater)
self.cues.append(dict(kin="txnStateSaved", record=rsr))

def processReplyCredentialTxnState(self, *, serder, saider, route, cigars=None, tsgs=None, **kwargs):
""" Process one reply message for key state = /tsn/registry
Expand Down Expand Up @@ -1907,19 +1899,13 @@ def processReplyCredentialTxnState(self, *, serder, saider, route, cigars=None,
data = serder.ked["a"]
dater = coring.Dater(dts=serder.ked["dt"])

tserder = coring.Serder(ked=data)
for k in CRED_TSN_LABELS:
if k not in tserder.ked:
raise ValidationError("Missing element = {} from {} msg."
" tsn = {}.".format(k, Ilks.tsn,
serder.pretty()))
vsr = viring.VcStateRecord(**data)

# fetch from serder to process
ked = tserder.ked
regk = tserder.ked["ri"]
vci = tserder.pre
sn = tserder.sn
ra = tserder.ked["ra"]
regk = vsr.ri
vci = vsr.i
sn = int(vsr.s, 16)
ra = vsr.ra

if 's' in ra:
regsn = ra["s"]
Expand Down Expand Up @@ -1961,7 +1947,7 @@ def processReplyCredentialTxnState(self, *, serder, saider, route, cigars=None,
aid not in baks and \
aid not in wats:
raise kering.UntrustedKeyStateSource("transaction state notice for {} from untrusted source {} "
.format(tserder.pre, aid))
.format(vsr.i, aid))

keys = (vci, aid,)
osaider = self.reger.txnsb.current(keys=keys) # get old said if any
Expand All @@ -1981,9 +1967,9 @@ def processReplyCredentialTxnState(self, *, serder, saider, route, cigars=None,
saider=saider, dater=dater, cigars=cigars, tsgs=tsgs):
self.cues.append(dict(kin="telquery", q=dict(ri=regk, i=vci)))

raise kering.OutOfOrderTxnStateError("Out of order txn state={}.".format(ked))
raise kering.OutOfOrderTxnStateError("Out of order txn state={}.".format(vsr))

tsaider = coring.Saider(qb64=ked["d"])
tsaider = coring.Saider(qb64=vsr.d)
ldig = bytes(ldig)
# retrieve last event itself of signer given sdig
sraw = self.reger.getTvt(key=dgKey(pre=vci, dig=ldig))
Expand All @@ -1992,14 +1978,14 @@ def processReplyCredentialTxnState(self, *, serder, saider, route, cigars=None,

if sn < sserder.sn:
raise ValidationError("Stale txn state at sn = {} with db."
"".format(ked["s"]))
"".format(vsr.s))

if sserder.said != tsaider.qb64: # mismatch events problem with replay
raise ValidationError("Mismatch txn state at sn = {} with db."
"".format(ked["s"]))
"".format(vsr.s))

self.reger.txnsb.updateReply(aid=aid, serder=tserder, saider=tsaider, dater=dater)
self.cues.append(dict(kin="txnStateSaved", serder=tserder))
self.reger.txnsb.updateReply(aid=aid, serder=serder, saider=tsaider, dater=dater)
self.cues.append(dict(kin="txnStateSaved", record=vsr))

@staticmethod
def registryKey(serder):
Expand Down
8 changes: 4 additions & 4 deletions src/keri/vdr/verifying.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,12 @@ def processCredential(self, creder, prefixer, seqner, saider):
raise kering.MissingRegistryError("credential identifier {} not in Tevers".format(vcid))

dtnow = helping.nowUTC()
dte = helping.fromIso8601(state.ked["dt"])
dte = helping.fromIso8601(state.dt)
if (dtnow - dte) > datetime.timedelta(seconds=self.CredentialExpiry):
if self.escrowMRE(creder, prefixer, seqner, saider):
self.cues.append(dict(kin="telquery", q=dict(ri=regk, i=vcid)))
raise kering.MissingRegistryError("credential identifier {} is out of date".format(vcid))
elif state.ked["et"] in (coring.Ilks.rev, coring.Ilks.brv): # no escrow, credential has been revoked
elif state.et in (coring.Ilks.rev, coring.Ilks.brv): # no escrow, credential has been revoked
logger.error("credential {} in registrying is not in issued state".format(vcid, regk))
# Log this and continue instead of the previous exception so we save a revoked credential.
# raise kering.InvalidCredentialStateError("..."))
Expand Down Expand Up @@ -164,13 +164,13 @@ def processCredential(self, creder, prefixer, seqner, saider):
.format(creder.said, label, nodeSaid))

dtnow = helping.nowUTC()
dte = helping.fromIso8601(state.ked["dt"])
dte = helping.fromIso8601(state.dt)
if (dtnow - dte) > datetime.timedelta(seconds=self.CredentialExpiry):
self.escrowMCE(creder, prefixer, seqner, saider)
self.cues.append(dict(kin="query", q=dict(r="tels", pre=nodeSaid)))
raise kering.MissingChainError("Failure to verify credential {} chain {}({})"
.format(creder.said, label, nodeSaid))
elif state.ked["et"] in (coring.Ilks.rev, coring.Ilks.brv):
elif state.et in (coring.Ilks.rev, coring.Ilks.brv):
raise kering.RevokedChainError("Failure to verify credential {} chain {}({})"
.format(creder.said, label, nodeSaid))
else: # VcStatus == VcStates.Issued
Expand Down
24 changes: 17 additions & 7 deletions src/keri/vdr/viring.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
A special purpose Verifiable Data Registry (VDR)
"""

from dataclasses import dataclass, field
from dataclasses import dataclass, field, asdict
from ordered_set import OrderedSet as oset

from ..db import koming, subing, escrowing
Expand Down Expand Up @@ -135,18 +135,28 @@ class RegStateRecord(basing.RawRecord): # reger.state
"""
vn: list[int] = field(default_factory=list) # version number [major, minor] round trip serializable
i: str ='' # identifier prefix qb64
s: str ='0' # sequence number of latest event in KEL as hex str
d: str ='' # latest event digest qb64
i: str = '' # identifier prefix qb64
s: str = '0' # sequence number of latest event in KEL as hex str
d: str = '' # latest event digest qb64
ii: str = '' # issuer identifier of registry aid qb64
dt: str = '' # datetime of update of state record
et: str = '' # TEL evt packet type (ilk)
bt: str = '0' # backer threshold hex num str
b: list = field(default_factory=list) # backer AID list qb64
c: list[str] = field(default_factory=list) # config trait list

c: list[str] = field(default_factory=list) # config trait list


@dataclass
class VcStateRecord(basing.RawRecord):
vn: list[str] = field(default_factory=list) # version number [major, minor] round trip serializable
i: str = '' # identifier prefix qb64
s: str = '0' # sequence number of latest event in KEL as hex str
d: str = '' # latest event digest qb64
ri: str = '' # registry identifier of registry aid qb64
ra: dict = field(default_factory=dict) # registry anchor for registry with backers
a: dict = field(default_factory=dict) # seal for anchor in KEL
dt: str = '' # datetime of update of state record
et: str = '' # TEL evt packet type (ilk)


def openReger(name="test", **kwa):
Expand Down Expand Up @@ -409,7 +419,7 @@ def cloneCreds(self, saids, db):
pre=creder.issuer,
schema=schemer.sed,
chains=chains,
status=status.ked,
status=asdict(status),
anchor=dict(
pre=prefixer.qb64,
sn=seqner.sn,
Expand Down
8 changes: 4 additions & 4 deletions tests/vdr/test_eventing.py
Original file line number Diff line number Diff line change
Expand Up @@ -731,8 +731,8 @@ def test_tevery():

tvy.processEvent(serder=iss, seqner=seqner, saider=diger)
status = tev.vcState(vcdig.decode("utf-8"))
assert status.ked['et'] == Ilks.iss
assert status.sn == 0
assert status.et == Ilks.iss
assert status.s == '0'

# revoke the vc
rev = eventing.revoke(vcdig=vcdig.decode("utf-8"), regk=regk, dig=iss.said)
Expand All @@ -746,8 +746,8 @@ def test_tevery():

tvy.processEvent(serder=rev, seqner=seqner, saider=diger)
status = tev.vcState(vcdig.decode("utf-8"))
assert status.ked["et"] == Ilks.rev
assert status.sn == 1
assert status.et == Ilks.rev
assert status.s == '1'


def test_tevery_process_escrow(mockCoringRandomNonce):
Expand Down
Loading

0 comments on commit c697023

Please sign in to comment.