From a2c0566c45c7cbc9e9b06c2fd933e317641164ce Mon Sep 17 00:00:00 2001 From: Philip Feairheller Date: Thu, 27 Jun 2024 10:39:53 -0700 Subject: [PATCH] Fixes to watcher add command to allow for multiple aliases that start with the same name. (#808) Added a feature to turn witnesses search off for MailboxDirector. Signed-off-by: pfeairheller --- src/keri/app/cli/commands/watcher/add.py | 18 ++++++++++-------- src/keri/app/indirecting.py | 16 +++++++++------- src/keri/app/watching.py | 8 +++++++- src/keri/core/parsing.py | 4 ++-- src/keri/vdr/credentialing.py | 2 +- tests/app/test_watching.py | 18 +++++++++++++----- 6 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/keri/app/cli/commands/watcher/add.py b/src/keri/app/cli/commands/watcher/add.py index c993f8e90..546eec96c 100644 --- a/src/keri/app/cli/commands/watcher/add.py +++ b/src/keri/app/cli/commands/watcher/add.py @@ -54,24 +54,26 @@ def __init__(self, name, alias, base, bran, watcher, watched): self.hab = self.hby.habByName(alias) self.org = connecting.Organizer(hby=self.hby) + wat = None if watcher in self.hby.kevers: wat = watcher else: - wat = self.org.find("alias", watcher) - if len(wat) != 1: - raise ValueError(f"invalid recipient {watcher}") - wat = wat[0]['id'] + contacts = self.org.find("alias", watcher) + for contact in contacts: + if contact['alias'] == watcher: + wat = contact['id'] if not wat: raise ValueError(f"unknown watcher {watcher}") + watd = None if watched in self.hby.kevers: watd = watched else: - watd = self.org.find("alias", watched) - if len(watd) != 1: - raise ValueError(f"invalid recipient {watched}") - watd = watd[0]['id'] + contacts = self.org.find("alias", watched) + for contact in contacts: + if contact['alias'] == watched: + watd = contact['id'] if not watd: raise ValueError(f"unknown watched {watched}") diff --git a/src/keri/app/indirecting.py b/src/keri/app/indirecting.py index 4dedb432a..80b3f8865 100644 --- a/src/keri/app/indirecting.py +++ b/src/keri/app/indirecting.py @@ -119,7 +119,7 @@ def createHttpServer(host, port, app, keypath=None, certpath=None, cafilepath=No Parameters: host(str) : host to bind to for this server, or None for default of '0.0.0.0', all ifaces port (int) : port to listen on for all HTTP(s) server instances - app (falcon.App) : application instance to pass to the http.Server instance + app (Any) : WSGI application instance to pass to the http.Server instance keypath (string) : the file path to the TLS private key certpath (string) : the file path to the TLS signed certificate (public key) cafilepath (string): the file path to the TLS CA certificate chain file @@ -506,7 +506,7 @@ class MailboxDirector(doing.DoDoer): """ def __init__(self, hby, topics, ims=None, verifier=None, kvy=None, exc=None, rep=None, cues=None, rvy=None, - tvy=None, **kwa): + tvy=None, witnesses=True, **kwa): """ Initialize instance. @@ -530,6 +530,7 @@ def __init__(self, hby, topics, ims=None, verifier=None, kvy=None, exc=None, rep self.pollers = list() self.prefixes = oset() self.cues = cues if cues is not None else decking.Deck() + self.witnesses = witnesses self.ims = ims if ims is not None else bytearray() @@ -622,11 +623,12 @@ def addPollers(self, hab): self.pollers.append(poller) self.extend([poller]) - wits = hab.kever.wits - for wit in wits: - poller = Poller(hab=hab, topics=self.topics, witness=wit) - self.pollers.append(poller) - self.extend([poller]) + if self.witnesses: + wits = hab.kever.wits + for wit in wits: + poller = Poller(hab=hab, topics=self.topics, witness=wit) + self.pollers.append(poller) + self.extend([poller]) self.prefixes.add(hab.pre) diff --git a/src/keri/app/watching.py b/src/keri/app/watching.py index 3a720d594..1016383a4 100644 --- a/src/keri/app/watching.py +++ b/src/keri/app/watching.py @@ -27,6 +27,7 @@ class DiffState: Uses Stateage to represent whether the remote KSR is even, ahead, behind or duplicitous """ + pre: str # The AID of the KSR wit: str # The entity reporting the KSR (non-local) state: Stateage # The state of the remote KSR relative to local sn: int # The sequence number of the remote KSR @@ -193,11 +194,16 @@ def diffState(wit, preksn, witksn): state (WitnessState): record indicating the differenced between the two provided KSN records """ + mypre = preksn.i + pre = witksn.i mysn = int(preksn.s, 16) mydig = preksn.d sn = int(witksn.s, 16) dig = witksn.d + if pre != mypre: + raise ValueError(f"can't compare key states from different AIDs {mypre}/{pre}") + # At the same sequence number, check the DIGs if mysn == sn: if mydig == dig: @@ -214,4 +220,4 @@ def diffState(wit, preksn, witksn): else: state = States.ahead - return DiffState(wit, state, sn, dig) + return DiffState(pre, wit, state, sn, dig) diff --git a/src/keri/core/parsing.py b/src/keri/core/parsing.py index 4faa7f36a..cd160c235 100644 --- a/src/keri/core/parsing.py +++ b/src/keri/core/parsing.py @@ -528,9 +528,9 @@ def onceParsator(self, ims=None, framed=None, pipeline=None, kvy=None, # Non extraction errors happen after successfully extracted from stream # so we don't flush rest of stream just resume if logger.isEnabledFor(logging.DEBUG): - logger.exception("Kevery msg non-extraction error: %s", ex.args[0]) + logger.exception("Kevery msg non-extraction error: %s", ex) else: - logger.exception("Kevery msg non-extraction error: %s", ex.args[0]) + logger.exception("Kevery msg non-extraction error: %s", ex) finally: done = True diff --git a/src/keri/vdr/credentialing.py b/src/keri/vdr/credentialing.py index 6c9d906fc..49f7e6357 100644 --- a/src/keri/vdr/credentialing.py +++ b/src/keri/vdr/credentialing.py @@ -473,7 +473,7 @@ def revoke(self, said, dt=None): raise kering.ValidationError("Invalid revoke of {} that has not been issued " "pre={}.".format(vci, self.regk)) ievt = self.reger.getTvt(dgKey(pre=vci, dig=vcser)) - iserder = serdering.serderACDC(raw=bytes(ievt)) # Serder(raw=bytes(ievt)) + iserder = serdering.SerderACDC(raw=bytes(ievt)) # Serder(raw=bytes(ievt)) if self.noBackers: serder = eventing.revoke(vcdig=vci, regk=self.regk, dig=iserder.said, dt=dt) diff --git a/tests/app/test_watching.py b/tests/app/test_watching.py index 4c7a49702..de6ca0da9 100644 --- a/tests/app/test_watching.py +++ b/tests/app/test_watching.py @@ -67,13 +67,16 @@ def test_diffstate(): diffstate = watching.diffState(wat, ksr0, ksr1) # Sequence numbers are the same, digest different == duplicitous - assert asdict(diffstate) == {'wit': 'BbIg_3-11d3PYxSInLN-Q9_T2axD6kkXd3XRgbGZTm6s', + assert asdict(diffstate) == {'dig': 'Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkc', + 'pre': 'EZ-i0d8JZAoTNZH3ULaU6JR2nmwyvYAfSVPzhzS6b5CM', + 'sn': 0, 'state': 'duplicitous', - 'sn': 0, 'dig': 'Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkc'} + 'wit': 'BbIg_3-11d3PYxSInLN-Q9_T2axD6kkXd3XRgbGZTm6s'} # Same state == event diffstate = watching.diffState(wat, ksr0, ksr0) assert asdict(diffstate) == {'dig': 'EBiIFxr_o1b4x1YR21PblAFpFG61qDghqFBDyVSOXYW0', + 'pre': 'EZ-i0d8JZAoTNZH3ULaU6JR2nmwyvYAfSVPzhzS6b5CM', 'sn': 0, 'state': 'even', 'wit': 'BbIg_3-11d3PYxSInLN-Q9_T2axD6kkXd3XRgbGZTm6s'} @@ -83,6 +86,7 @@ def test_diffstate(): # Sequence numbers are the same, digest different == duplicitous assert asdict(diffstate) == {'dig': 'Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkc', + 'pre': 'EZ-i0d8JZAoTNZH3ULaU6JR2nmwyvYAfSVPzhzS6b5CM', 'sn': 2, 'state': 'ahead', 'wit': 'BbIg_3-11d3PYxSInLN-Q9_T2axD6kkXd3XRgbGZTm6s'} @@ -92,6 +96,7 @@ def test_diffstate(): # Sequence numbers are the same, digest different == duplicitous assert asdict(diffstate) == {'dig': 'Ey2pXEnaoQVwxA4jB6k0QH5G2Us-0juFL5hOAHAwIEkc', + 'pre': 'EZ-i0d8JZAoTNZH3ULaU6JR2nmwyvYAfSVPzhzS6b5CM', 'sn': 2, 'state': 'behind', 'wit': 'BbIg_3-11d3PYxSInLN-Q9_T2axD6kkXd3XRgbGZTm6s'} @@ -121,7 +126,8 @@ def test_adjudicator(): assert cue == {'cid': 'EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3', 'kin': 'keyStateConsistent', 'oid': 'EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3', - 'states': [DiffState(wit='BbIg_3-11d3PYxSInLN-Q9_T2axD6kkXd3XRgbGZTm6s', + 'states': [DiffState(pre="EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3", + wit='BbIg_3-11d3PYxSInLN-Q9_T2axD6kkXd3XRgbGZTm6s', state='even', sn=0, dig='EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3')], @@ -132,7 +138,8 @@ def test_adjudicator(): adj.adjudicate(hab.pre, 1) assert len(adj.cues) == 1 cue = adj.cues.pull() - assert cue == {'behind': [DiffState(wit='BbIg_3-11d3PYxSInLN-Q9_T2axD6kkXd3XRgbGZTm6s', + assert cue == {'behind': [DiffState(pre="EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3", + wit='BbIg_3-11d3PYxSInLN-Q9_T2axD6kkXd3XRgbGZTm6s', state='behind', sn=0, dig='EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3')], @@ -147,7 +154,8 @@ def test_adjudicator(): assert len(adj.cues) == 1 cue = adj.cues.pull() assert cue == {'cid': 'EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3', - 'dups': [DiffState(wit='BbIg_3-11d3PYxSInLN-Q9_T2axD6kkXd3XRgbGZTm6s', + 'dups': [DiffState(pre="EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3", + wit='BbIg_3-11d3PYxSInLN-Q9_T2axD6kkXd3XRgbGZTm6s', state='duplicitous', sn=1, dig='EIaGMMWJFPmtXznY1IIiKDIrg-vIyge6mBl2QV8dDjI3')],