From 1c7a982ee787cd6eebb3ad12df9af86dc9c52d0d Mon Sep 17 00:00:00 2001 From: pfeairheller Date: Wed, 14 Aug 2024 06:24:17 -0700 Subject: [PATCH] 2 fixes for delegation: - Update clone delegation to not raise an exception if the delegator's KEL is not in local kevers - Fix event handling to walk the KEL to find an anchoring event if it exists. These changes close #842 by allowing for a witness to return a KEL for a delegated AID without the AES couple for approved events and without the delegator's KEL. This is the expected behavior for a witness as it should not be assumed that a witness perform watcher functionality. Any validator will have to be introduced to the delegator or OOBI with the delegator before validating the KEL of the delegate. Signed-off-by: pfeairheller --- scripts/demo/basic/delegate.sh | 13 ++++++ src/keri/core/eventing.py | 78 +++++++++++++++++++--------------- src/keri/db/basing.py | 2 +- 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/scripts/demo/basic/delegate.sh b/scripts/demo/basic/delegate.sh index 4a1e40dfb..9237a5deb 100755 --- a/scripts/demo/basic/delegate.sh +++ b/scripts/demo/basic/delegate.sh @@ -30,3 +30,16 @@ PID_LIST+=" $pid" wait $PID_LIST kli status --name delegate --alias delegate + +kli init --name validator --nopasscode --config-dir ${KERI_SCRIPT_DIR} --config-file demo-witness-oobis --salt 0ACDEyMzQ1Njc4OWxtbm9vAl + +OOBI=$(kli oobi generate --name delegator --alias delegator --role witness | head -n 1) +kli oobi resolve --name validator --oobi-alias delegator --oobi "${OOBI}" +OOBI=$(kli oobi generate --name delegate --alias delegate --role witness | head -n 1) +kli oobi resolve --name validator --oobi-alias delegate --oobi "${OOBI}" + +AID=$(kli aid --name delegate --alias delegate) +kli kevers --name validator --prefix "${AID}" + + + diff --git a/src/keri/core/eventing.py b/src/keri/core/eventing.py index 6be424a32..5443e7d86 100644 --- a/src/keri/core/eventing.py +++ b/src/keri/core/eventing.py @@ -1561,16 +1561,16 @@ def __init__(self, *, state=None, serder=None, sigers=None, wigers=None, # Validates signers, delegation if any, and witnessing when applicable # If does not validate then escrows as needed and raises ValidationError - sigers, wigers, delpre = self.valSigsWigsDel(serder=serder, - sigers=sigers, - verfers=serder.verfers, - tholder=self.tholder, - wigers=wigers, - toader=self.toader, - wits=self.wits, - local=local, - delseqner=delseqner, - delsaider=delsaider) + sigers, wigers, delpre, delseqner, delsaider = self.valSigsWigsDel(serder=serder, + sigers=sigers, + verfers=serder.verfers, + tholder=self.tholder, + wigers=wigers, + toader=self.toader, + wits=self.wits, + local=local, + delseqner=delseqner, + delsaider=delsaider) self.delpre = delpre # may be None self.delegated = True if self.delpre else False @@ -1920,16 +1920,16 @@ def update(self, serder, sigers, wigers=None, delseqner=None, delsaider=None, # Validates signers, delegation if any, and witnessing when applicable # returned sigers and wigers are verified signatures # If does not validate then escrows as needed and raises ValidationError - sigers, wigers, delpre = self.valSigsWigsDel(serder=serder, - sigers=sigers, - verfers=serder.verfers, - tholder=tholder, - wigers=wigers, - toader=toader, - wits=wits, - local=local, - delseqner=delseqner, - delsaider=delsaider) + sigers, wigers, delpre, delseqner, delsaider = self.valSigsWigsDel(serder=serder, + sigers=sigers, + verfers=serder.verfers, + tholder=tholder, + wigers=wigers, + toader=toader, + wits=wits, + local=local, + delseqner=delseqner, + delsaider=delsaider) @@ -1985,18 +1985,18 @@ def update(self, serder, sigers, wigers=None, delseqner=None, delsaider=None, # Validates signers, delegation if any, and witnessing when applicable # If does not validate then escrows as needed and raises ValidationError - sigers, wigers, delpre = self.valSigsWigsDel(serder=serder, - sigers=sigers, - verfers=self.verfers, - tholder=self.tholder, - wigers=wigers, - toader=self.toader, - wits=self.wits, - local=local) + sigers, wigers, delpre, delseqner, delsaider = self.valSigsWigsDel(serder=serder, + sigers=sigers, + verfers=self.verfers, + tholder=self.tholder, + wigers=wigers, + toader=self.toader, + wits=self.wits, + local=local) # .validateSigsDelWigs above ensures thresholds met otherwise raises exception # all validated above so may add to KEL and FEL logs as first seen - fn, dts = self.logEvent(serder=serder, sigers=sigers, wigers=wigers, + fn, dts = self.logEvent(serder=serder, sigers=sigers, wigers=wigers, seqner=delseqner, saider=delsaider, first=True if not check else False) # First seen accepted # validates so update state @@ -2314,12 +2314,19 @@ def valSigsWigsDel(self, serder, sigers, verfers, tholder, f"for event={serder.ked}.") if delpre: + if not (delseqner and delsaider): + seal = dict(i=serder.ked["i"], s=serder.snh, d=serder.said) + srdr = self.db.findAnchoringSealEvent(pre=delpre, seal=seal) + if srdr is not None: + delseqner = coring.Seqner(sn=srdr.sn) + delsaider = coring.Saider(qb64=srdr.said) + self.validateDelegation(serder, sigers=sigers, wigers=wigers, wits=wits, local=local, delpre=delpre, delseqner=delseqner, delsaider=delsaider) - return sigers, wigers, delpre + return sigers, wigers, delpre, delseqner, delsaider def exposeds(self, sigers): @@ -2593,7 +2600,6 @@ def validateDelegation(self, serder, sigers, wigers, wits, local=True, if self.locallyOwned() or self.locallyWitnessed(wits=wits): return - if self.kevers is None or delpre not in self.kevers: # drop event # ToDo XXXX cue a trigger to get the KEL of the delegator # the processDelegableEvent should also cue a trigger to get KEL @@ -2827,7 +2833,12 @@ def logEvent(self, serder, sigers=None, wigers=None, wits=None, first=False, self.db.putEvt(dgkey, serder.raw) # idempotent (maybe already excrowed) # update event source - if (esr := self.db.esrs.get(keys=dgkeys)): # preexisting esr + + if seqner and saider: # delegation for authorized delegated or issued event + couple = seqner.qb64b + saider.qb64b + self.db.setAes(dgkey, couple) # authorizer (delegator/issuer) event seal + + if esr := self.db.esrs.get(keys=dgkeys): # preexisting esr if local and not esr.local: # local overwrites prexisting remote esr.local = local self.db.esrs.pin(keys=dgkeys, val=esr) @@ -2837,9 +2848,6 @@ def logEvent(self, serder, sigers=None, wigers=None, wits=None, first=False, self.db.esrs.put(keys=dgkeys, val=esr) if first: # append event dig to first seen database in order - if seqner and saider: # delegation for authorized delegated or issued event - couple = seqner.qb64b + saider.qb64b - self.db.setAes(dgkey, couple) # authorizer (delegator/issuer) event seal fn = self.db.appendFe(serder.preb, serder.saidb) if firner and fn != firner.sn: # cloned replay but replay fn not match if self.cues is not None: # cue to notice BadCloneFN diff --git a/src/keri/db/basing.py b/src/keri/db/basing.py index d50b8b12e..2fc0b8e58 100644 --- a/src/keri/db/basing.py +++ b/src/keri/db/basing.py @@ -1617,7 +1617,7 @@ def cloneDelegation(self, kever): kever (Kever): Kever from which to clone the delegator's AID. """ - if kever.delegated: + if kever.delegated and kever.delpre in self.kevers: dkever = self.kevers[kever.delpre] yield from self.cloneDelegation(dkever)