diff --git a/src/keri/app/cli/commands/delegate/confirm.py b/src/keri/app/cli/commands/delegate/confirm.py index cf7ea179a..05ef5d69a 100644 --- a/src/keri/app/cli/commands/delegate/confirm.py +++ b/src/keri/app/cli/commands/delegate/confirm.py @@ -119,7 +119,8 @@ def confirmDo(self, tymth, tock=0.0): continue if hab.group: - aids = hab.smids + smids, rmids = hab.members() + aids = smids seqner = coring.Seqner(sn=eserder.sn) anchor = dict(i=eserder.ked["i"], s=seqner.snh, d=eserder.said) if self.interact: @@ -134,8 +135,7 @@ def confirmDo(self, tymth, tock=0.0): serder = coring.Serder(raw=msg) exn, atc = grouping.multisigInteractExn(hab, serder.sner.num, aids, [anchor]) - others = list(oset(hab.smids + (hab.rmids or []))) - #others = list(hab.smids) + others = list(oset(smids + (rmids or []))) others.remove(hab.mhab.pre) for recpt in others: # send notification to other participants as a signalling mechanism diff --git a/src/keri/app/cli/commands/delegate/request.py b/src/keri/app/cli/commands/delegate/request.py index 2b3b3aea6..eea0b57d5 100644 --- a/src/keri/app/cli/commands/delegate/request.py +++ b/src/keri/app/cli/commands/delegate/request.py @@ -91,10 +91,12 @@ def requestDo(self, tymth, tock=0.0): if hab.group: phab = hab.mhab + smids, _ = hab.members() else: phab = self.hby.habByName(f"{self.alias}-proxy") + smids = [] - exn, atc = delegating.delegateRequestExn(hab.mhab, delpre=delpre, ked=srdr.ked, aids=hab.smids) + exn, atc = delegating.delegateRequestExn(hab.mhab, delpre=delpre, ked=srdr.ked, aids=smids) # delegate AID ICP and exn of delegation request EXN self.postman.send(src=phab.pre, dest=delpre, topic="delegate", serder=srdr, attachment=evt) diff --git a/src/keri/app/cli/commands/multisig/incept.py b/src/keri/app/cli/commands/multisig/incept.py index 88a8c60f8..4a12f84b8 100644 --- a/src/keri/app/cli/commands/multisig/incept.py +++ b/src/keri/app/cli/commands/multisig/incept.py @@ -139,7 +139,6 @@ def inceptDo(self, tymth, tock=0.0): aids=ghab.smids, ked=serder.ked) others = list(oset(smids + (rmids or []))) - #others = list(smids) others.remove(ghab.mhab.pre) for recpt in others: # this goes to other participants only as a signaling mechanism diff --git a/src/keri/app/cli/commands/multisig/interact.py b/src/keri/app/cli/commands/multisig/interact.py index e4ffda59e..a909a06fe 100644 --- a/src/keri/app/cli/commands/multisig/interact.py +++ b/src/keri/app/cli/commands/multisig/interact.py @@ -106,14 +106,15 @@ def interactDo(self, tymth, tock=0.0): if ghab is None: raise kering.ConfigurationError(f"invalid alias {self.alias} specified for database {self.hby.name}") - aids = self.aids if self.aids is not None else ghab.smids + smids, rmids = ghab.members() + aids = self.aids if self.aids is not None else smids rmids = None # need to fix ixn = ghab.interact(data=self.data) serder = coring.Serder(raw=ixn) exn, atc = grouping.multisigInteractExn(ghab, serder.sner.num, aids, self.data) - others = list(oset(ghab.smids + (ghab.rmids or []))) + others = list(aids) others.remove(ghab.mhab.pre) diff --git a/src/keri/app/cli/commands/multisig/notice.py b/src/keri/app/cli/commands/multisig/notice.py index fe885478e..a442eab0c 100644 --- a/src/keri/app/cli/commands/multisig/notice.py +++ b/src/keri/app/cli/commands/multisig/notice.py @@ -81,34 +81,34 @@ def noticeDo(self, tymth, tock=0.0): _ = (yield self.tock) hab = self.hby.habByName(name=self.alias) - habord = hab.db.habs.get(keys=self.alias) - if hab.group and habord is not None: + if hab.group: + (smids, rmids) = hab.members() serder = hab.kever.serder rot = hab.makeOwnEvent(sn=hab.kever.sn) eserder = coring.Serder(raw=rot) del rot[:eserder.size] ilk = serder.ked['t'] - others = list(oset(habord.smids + (habord.rmids or []))) # list(rec.smids) + others = list(oset(smids + (rmids or []))) # list(rec.smids) others.remove(hab.mhab.pre) if ilk in (Ilks.rot,): print(f"Sending rot event to {len(others)} participants.") exn, ims = grouping.multisigRotateExn(hab, - aids=habord.smids, - smids=habord.smids, - rmids=habord.rmids, + aids=smids, + smids=smids, + rmids=rmids, ked=serder.ked) elif ilk in (Ilks.icp,): print(f"Sending icp event to {len(others)} participants.") exn, ims = grouping.multisigInceptExn(hab, - aids=habord.smids, + aids=smids, ked=serder.ked) elif ilk in (Ilks.ixn,): print(f"Sending ixn event to {len(others)} participants.") exn, ims = grouping.multisigInteractExn(hab, - aids=habord.smids, + aids=smids, sn=serder.sn, data=serder.ked["a"]) else: diff --git a/src/keri/app/cli/commands/multisig/rotate.py b/src/keri/app/cli/commands/multisig/rotate.py index ca6c206c7..802ae4bb2 100644 --- a/src/keri/app/cli/commands/multisig/rotate.py +++ b/src/keri/app/cli/commands/multisig/rotate.py @@ -113,11 +113,12 @@ def rotateDo(self, tymth, tock=0.0, **opts): if ghab is None: raise kering.ConfigurationError(f"Alias {self.alias} is invalid") + smids, rmids = ghab.members() if self.smids is None: - self.smids = ghab.smids + self.smids = smids if self.rmids is None: - self.rmids = self.smids + self.rmids = rmids if self.wits: if self.adds or self.cuts: diff --git a/src/keri/app/grouping.py b/src/keri/app/grouping.py index 8da12b2c1..2a932d7f0 100644 --- a/src/keri/app/grouping.py +++ b/src/keri/app/grouping.py @@ -127,8 +127,9 @@ def rotate(self, ghab, smids, *, rmids=None, isith=None, nsith=None, """ mid = ghab.mhab.pre - smids = smids if smids is not None else ghab.smids - rmids = rmids if rmids is not None else ghab.rmids + s, r = ghab.members() + smids = smids if smids is not None else s + rmids = rmids if rmids is not None else r both = list(oset(smids + (rmids or []))) if mid not in both: @@ -1050,7 +1051,8 @@ def do(self, tymth, tock=0.0, **opts): logger.error(f"invalid rotate message, not a local group: {pay}") continue - if src not in ghab.smids or src not in ghab.kevers: + smids, _ = ghab.members() + if src not in smids or src not in ghab.kevers: logger.error(f"invalid incept message, source not knows or not part of group. evt: {msg}") continue diff --git a/src/keri/app/habbing.py b/src/keri/app/habbing.py index cf1ef1909..e2c22cc87 100644 --- a/src/keri/app/habbing.py +++ b/src/keri/app/habbing.py @@ -9,6 +9,7 @@ from contextlib import contextmanager from urllib.parse import urlsplit from math import ceil +from ordered_set import OrderedSet as oset from hio.base import doing from hio.core import wiring @@ -2244,3 +2245,45 @@ def query(self, pre, src, query=None, **kwa): return self.mhab.endorse(serder, last=True) + def members(self): + """ Seach local Kevers database to find the current members of this group AID + + Returns: + (smids, rmids): A tuple of lists of signing member AIDs and rotation member AIDs + + """ + + verfers = self.kever.verfers + skeys = oset([verfer.qb64 for verfer in verfers]) + + digers = self.kever.digers + dkeys = oset([diger.qb64 for diger in digers]) + + smids = [None] * len(verfers) + rmids = [None] * len(digers) + for (preb, _, raw) in self.db.getAllItemIter(db=self.db.evts): + pre = bytes(preb).decode("utf-8") + serder = coring.Serder(raw=bytes(raw)) + if not serder.est: + continue + + if len(serder.verfers) != 1 or len(serder.digers) != 1: + continue + + skey = serder.verfers[0].qb64 + if skey in skeys: + idx = skeys.index(skey) + smids[idx] = pre + + dkey = serder.digers[0].qb64 + if dkey in dkeys: + idx = dkeys.index(dkey) + rmids[idx] = pre + + if None not in smids and None not in rmids: + break + + if None in smids or None in rmids: + raise kering.ConfigurationError(f"Unable to find members for {self.pre}") + + return smids, rmids \ No newline at end of file diff --git a/src/keri/app/kiwiing.py b/src/keri/app/kiwiing.py index 4866b6b79..e2974a939 100644 --- a/src/keri/app/kiwiing.py +++ b/src/keri/app/kiwiing.py @@ -1388,8 +1388,8 @@ def on_post_iss(self, req, rep, alias=None): exn, atc = grouping.multisigIssueExn(hab=hab, creder=creder) - others = list(oset(hab.smids + (hab.rmids or []))) - #others = list(hab.smids) + smids, rmids = hab.members() + others = list(oset(smids + (rmids or []))) others.remove(hab.mhab.pre) for recpt in others: diff --git a/src/keri/app/oobiing.py b/src/keri/app/oobiing.py index 5ba3323ad..b7788e850 100644 --- a/src/keri/app/oobiing.py +++ b/src/keri/app/oobiing.py @@ -256,7 +256,8 @@ def on_post_share(self, req, rep, alias): return oobis = body["oobis"] - both = list(set(hab.smids + (hab.rmids or []))) + smids, rmids = hab.members() + both = list(set(smids + (rmids or []))) for mid in both: # hab.smids if mid == hab.mhab.pre: continue diff --git a/src/keri/app/signing.py b/src/keri/app/signing.py index 5480d7cc8..4f1763e25 100644 --- a/src/keri/app/signing.py +++ b/src/keri/app/signing.py @@ -112,7 +112,8 @@ def transSeal(hab): if not hab.group: # not a group use own kever indices = None # use default order else: # group so use gid kever - indices = [hab.smids.index(hab.mhab.pre)] # use group order* + smids, _ = hab.members() + indices = [smids.index(hab.mhab.pre)] # use group order* kever = hab.kever prefixer = kever.prefixer diff --git a/src/keri/vdr/credentialing.py b/src/keri/vdr/credentialing.py index ccf175302..28e4e0a53 100644 --- a/src/keri/vdr/credentialing.py +++ b/src/keri/vdr/credentialing.py @@ -413,8 +413,9 @@ def incept(self, name, pre, conf=None, smids=None, rmids=None): self.rgy.reger.tpwe.add(keys=(registry.regk, rseq.qb64), val=(hab.kever.prefixer, seqner, saider)) else: - smids = smids if smids is not None else hab.smids - rmids = rmids if rmids is not None else hab.rmids + s, r = hab.members() + smids = smids if smids is not None else s + rmids = rmids if rmids is not None else r prefixer, seqner, saider = self.multisigIxn(hab, rseal) self.counselor.start(prefixer=prefixer, seqner=seqner, saider=saider, mid=hab.mhab.pre, smids=smids, rmids=rmids) @@ -465,8 +466,9 @@ def issue(self, regk, said, dt=None, smids=None, rmids=None): return vcid, rseq.sn else: # multisig group hab - smids = smids if smids is not None else hab.smids - rmids = rmids if rmids is not None else hab.rmids + s, r = hab.members() + smids = smids if smids is not None else s + rmids = rmids if rmids is not None else r prefixer, seqner, saider = self.multisigIxn(hab, rseal) self.counselor.start(prefixer=prefixer, seqner=seqner, saider=saider, mid=hab.mhab.pre, smids=smids, rmids=rmids) @@ -518,8 +520,9 @@ def revoke(self, regk, said, dt=None, smids=None, rmids=None): self.rgy.reger.tpwe.add(keys=(vcid, rseq.qb64), val=(hab.kever.prefixer, seqner, saider)) return vcid, rseq.sn else: - smids = smids if smids is not None else hab.smids - rmids = rmids if rmids is not None else hab.rmids + s, r = hab.members() + smids = smids if smids is not None else s + rmids = rmids if rmids is not None else r prefixer, seqner, saider = self.multisigIxn(hab, rseal) self.counselor.start(prefixer=prefixer, seqner=seqner, saider=saider, mid=hab.mhab.pre, smids=smids, rmids=rmids) @@ -748,8 +751,9 @@ def issue(self, creder, smids=None, rmids=None): registry = self.rgy.regs[regk] hab = registry.hab if hab.group: - smids = smids if smids is not None else hab.smids - rmids = rmids if rmids is not None else hab.rmids + s, r = hab.members() + smids = smids if smids is not None else s + rmids = rmids if rmids is not None else r dt = creder.subject["dt"] if "dt" in creder.subject else None @@ -761,7 +765,6 @@ def issue(self, creder, smids=None, rmids=None): craw = signing.ratify(hab=hab, serder=creder) atc = bytearray(craw[creder.size:]) others = list(oset(smids + (rmids or []))) - #others = list(smids) others.remove(hab.mhab.pre) print(f"Sending signed credential to {others} other participants")